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-05-22 04:02:02 +0400
committerJason Wilkins <Jason.A.Wilkins@gmail.com>2014-05-22 04:02:02 +0400
commit6eff1cbebcf0766d2fe69db9b0fb3f76ede2c06b (patch)
tree3af4122e291f53f88b63ec6ded2e0fa7790e04ac
parent49de1ada8dcba35862759e0f7da5ca2209b4f588 (diff)
parent146a1c77eacb925eb7c86bb49495c0f09adc607c (diff)
Merge branch 'soc-2014-viewport' into soc-2013-viewport_fx
Conflicts: intern/cycles/device/device_cuda.cpp intern/ghost/intern/GHOST_WindowCocoa.mm source/blender/blenfont/intern/blf_font.c source/blender/blenfont/intern/blf_translation.c source/blender/blenkernel/BKE_brush.h source/blender/blenkernel/BKE_pbvh.h source/blender/blenkernel/intern/cdderivedmesh.c source/blender/blenkernel/intern/editderivedmesh.c source/blender/blenkernel/intern/mesh.c source/blender/blenkernel/intern/subsurf_ccg.c source/blender/blenlib/BLI_fileops.h source/blender/blenlib/BLI_math_matrix.h source/blender/blenlib/intern/fileops.c source/blender/blenlib/intern/math_matrix.c source/blender/editors/animation/anim_channels_defines.c source/blender/editors/animation/anim_draw.c source/blender/editors/animation/keyframes_draw.c source/blender/editors/include/ED_armature.h source/blender/editors/interface/interface.c source/blender/editors/interface/interface_draw.c source/blender/editors/interface/interface_icons.c source/blender/editors/interface/interface_panel.c source/blender/editors/interface/interface_widgets.c source/blender/editors/interface/view2d.c source/blender/editors/mask/mask_draw.c source/blender/editors/mesh/editmesh_select.c source/blender/editors/render/render_opengl.c source/blender/editors/screen/area.c source/blender/editors/screen/glutil.c source/blender/editors/sculpt_paint/paint_cursor.c source/blender/editors/sculpt_paint/paint_image.c source/blender/editors/sculpt_paint/paint_image_proj.c source/blender/editors/sculpt_paint/paint_utils.c source/blender/editors/sculpt_paint/sculpt_intern.h source/blender/editors/space_buttons/space_buttons.c source/blender/editors/space_clip/clip_dopesheet_draw.c source/blender/editors/space_clip/clip_draw.c source/blender/editors/space_clip/clip_graph_draw.c source/blender/editors/space_clip/clip_utils.c source/blender/editors/space_console/console_draw.c source/blender/editors/space_file/file_draw.c source/blender/editors/space_file/file_ops.c source/blender/editors/space_graph/graph_draw.c source/blender/editors/space_info/info_draw.c source/blender/editors/space_info/textview.c source/blender/editors/space_logic/logic_window.c source/blender/editors/space_nla/nla_draw.c source/blender/editors/space_outliner/outliner_draw.c source/blender/editors/space_sequencer/sequencer_draw.c source/blender/editors/space_view3d/drawanimviz.c source/blender/editors/space_view3d/drawarmature.c source/blender/editors/space_view3d/drawmesh.c source/blender/editors/space_view3d/drawobject.c source/blender/editors/space_view3d/view3d_draw.c source/blender/editors/space_view3d/view3d_fly.c source/blender/editors/space_view3d/view3d_intern.h source/blender/editors/space_view3d/view3d_walk.c source/blender/editors/transform/transform.c source/blender/editors/transform/transform_manipulator.c source/blender/editors/util/ed_util.c source/blender/editors/uvedit/uvedit_draw.c source/blender/gpu/GPU_buffers.h source/blender/gpu/intern/gpu_buffers.c source/blender/gpu/intern/gpu_codegen.c source/blender/gpu/intern/gpu_codegen.h source/blender/gpu/intern/gpu_draw.c source/blender/render/intern/source/convertblender.c source/blender/windowmanager/intern/wm_operators.c source/blender/windowmanager/intern/wm_subwindow.c source/blender/windowmanager/intern/wm_window.c
-rw-r--r--CMakeLists.txt178
-rw-r--r--GNUmakefile2
-rw-r--r--SConstruct23
-rw-r--r--[-rwxr-xr-x]build_files/build_environment/install_deps.sh434
-rw-r--r--[-rwxr-xr-x]build_files/build_environment/prepare_release_env.sh2
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py5
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py5
-rw-r--r--build_files/buildbot/slave_compile.py1
-rw-r--r--build_files/cmake/Modules/FindOpenEXR.cmake5
-rw-r--r--build_files/cmake/Modules/FindPythonLibsUnix.cmake4
-rw-r--r--build_files/cmake/buildinfo.cmake78
-rw-r--r--build_files/cmake/clang_array_check.py87
-rw-r--r--[-rwxr-xr-x]build_files/cmake/cmake_consistency_check.py0
-rw-r--r--[-rwxr-xr-x]build_files/cmake/cmake_netbeans_project.py2
-rw-r--r--[-rwxr-xr-x]build_files/cmake/cmake_qtcreator_project.py6
-rw-r--r--build_files/cmake/cmake_static_check_clang_array.py2
-rw-r--r--build_files/cmake/cmake_static_check_cppcheck.py2
-rw-r--r--build_files/cmake/cmake_static_check_smatch.py2
-rw-r--r--build_files/cmake/cmake_static_check_sparse.py2
-rw-r--r--build_files/cmake/cmake_static_check_splint.py2
-rw-r--r--build_files/cmake/config/blender_lite.cmake5
-rw-r--r--[-rwxr-xr-x]build_files/cmake/example_scripts/cmake_linux_install.sh4
-rw-r--r--[-rwxr-xr-x]build_files/cmake/example_scripts/make_quicky.py0
-rw-r--r--[-rwxr-xr-x]build_files/cmake/example_scripts/make_quiet.sh0
-rw-r--r--build_files/cmake/macros.cmake71
-rw-r--r--[-rwxr-xr-x]build_files/cmake/project_info.py25
-rw-r--r--[-rwxr-xr-x]build_files/package_spec/build_archive.py0
-rw-r--r--[-rwxr-xr-x]build_files/package_spec/build_debian.sh0
-rw-r--r--[-rwxr-xr-x]build_files/package_spec/debian/rules0
-rw-r--r--build_files/scons/config/Modules/FindPython.py2
-rw-r--r--build_files/scons/config/darwin-config.py13
-rw-r--r--build_files/scons/config/freebsd8-config.py205
-rw-r--r--build_files/scons/config/freebsd9-config.py210
-rw-r--r--build_files/scons/config/linux-config.py2
-rw-r--r--build_files/scons/config/linuxcross-config.py189
-rw-r--r--build_files/scons/config/win32-mingw-config.py12
-rw-r--r--build_files/scons/config/win32-vc-config.py20
-rw-r--r--build_files/scons/config/win64-mingw-config.py9
-rw-r--r--build_files/scons/config/win64-vc-config.py19
-rw-r--r--build_files/scons/tools/Blender.py128
-rw-r--r--build_files/scons/tools/btools.py6
-rw-r--r--build_files/scons/tools/unordered_map.py32
-rw-r--r--[-rwxr-xr-x]doc/blender_file_format/BlendFileDnaExporter_25.py0
-rw-r--r--doc/manpage/blender.12
-rw-r--r--doc/manpage/blender.1.py6
-rw-r--r--doc/python_api/rst/bge.constraints.rst56
-rw-r--r--doc/python_api/rst/bge.events.rst18
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst2
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst100
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst6
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst4
-rw-r--r--doc/python_api/rst_from_bmesh_opdefines.py4
-rw-r--r--doc/python_api/sphinx_doc_gen.py3
-rw-r--r--[-rwxr-xr-x]doc/python_api/sphinx_doc_gen.sh0
-rw-r--r--extern/Eigen3/Eigen/Core48
-rw-r--r--extern/Eigen3/Eigen/Eigen2Support15
-rw-r--r--extern/Eigen3/Eigen/Eigenvalues2
-rw-r--r--extern/Eigen3/Eigen/IterativeLinearSolvers2
-rw-r--r--extern/Eigen3/Eigen/MetisSupport28
-rw-r--r--extern/Eigen3/Eigen/OrderingMethods51
-rw-r--r--extern/Eigen3/Eigen/SPQRSupport29
-rw-r--r--extern/Eigen3/Eigen/Sparse14
-rw-r--r--extern/Eigen3/Eigen/SparseCholesky21
-rw-r--r--extern/Eigen3/Eigen/SparseCore4
-rw-r--r--extern/Eigen3/Eigen/SparseLU49
-rw-r--r--extern/Eigen3/Eigen/SparseQR33
-rw-r--r--extern/Eigen3/Eigen/src/Cholesky/LDLT.h74
-rw-r--r--extern/Eigen3/Eigen/src/Cholesky/LLT.h20
-rw-r--r--extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h66
-rw-r--r--extern/Eigen3/Eigen/src/Core/Array.h34
-rw-r--r--extern/Eigen3/Eigen/src/Core/ArrayBase.h2
-rw-r--r--extern/Eigen3/Eigen/src/Core/ArrayWrapper.h68
-rw-r--r--extern/Eigen3/Eigen/src/Core/Assign.h32
-rw-r--r--extern/Eigen3/Eigen/src/Core/Assign_MKL.h2
-rw-r--r--extern/Eigen3/Eigen/src/Core/Block.h182
-rw-r--r--extern/Eigen3/Eigen/src/Core/BooleanRedux.h36
-rw-r--r--extern/Eigen3/Eigen/src/Core/CommaInitializer.h4
-rw-r--r--extern/Eigen3/Eigen/src/Core/CoreIterators.h61
-rw-r--r--extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h22
-rw-r--r--extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h134
-rw-r--r--extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h8
-rw-r--r--extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h16
-rw-r--r--extern/Eigen3/Eigen/src/Core/DenseBase.h72
-rw-r--r--extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h12
-rw-r--r--extern/Eigen3/Eigen/src/Core/DenseStorage.h114
-rw-r--r--extern/Eigen3/Eigen/src/Core/Diagonal.h41
-rw-r--r--extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h26
-rw-r--r--extern/Eigen3/Eigen/src/Core/DiagonalProduct.h51
-rw-r--r--extern/Eigen3/Eigen/src/Core/Dot.h12
-rw-r--r--extern/Eigen3/Eigen/src/Core/EigenBase.h29
-rw-r--r--extern/Eigen3/Eigen/src/Core/Functors.h130
-rw-r--r--extern/Eigen3/Eigen/src/Core/Fuzzy.h22
-rw-r--r--extern/Eigen3/Eigen/src/Core/GeneralProduct.h100
-rw-r--r--extern/Eigen3/Eigen/src/Core/GenericPacketMath.h50
-rw-r--r--extern/Eigen3/Eigen/src/Core/GlobalFunctions.h49
-rw-r--r--extern/Eigen3/Eigen/src/Core/IO.h13
-rw-r--r--extern/Eigen3/Eigen/src/Core/Map.h30
-rw-r--r--extern/Eigen3/Eigen/src/Core/MapBase.h50
-rw-r--r--extern/Eigen3/Eigen/src/Core/MathFunctions.h354
-rw-r--r--extern/Eigen3/Eigen/src/Core/Matrix.h10
-rw-r--r--extern/Eigen3/Eigen/src/Core/MatrixBase.h79
-rw-r--r--extern/Eigen3/Eigen/src/Core/NoAlias.h9
-rw-r--r--extern/Eigen3/Eigen/src/Core/NumTraits.h3
-rw-r--r--extern/Eigen3/Eigen/src/Core/PermutationMatrix.h46
-rw-r--r--extern/Eigen3/Eigen/src/Core/PlainObjectBase.h179
-rw-r--r--extern/Eigen3/Eigen/src/Core/ProductBase.h20
-rw-r--r--extern/Eigen3/Eigen/src/Core/Random.h14
-rw-r--r--extern/Eigen3/Eigen/src/Core/Redux.h6
-rw-r--r--extern/Eigen3/Eigen/src/Core/Ref.h256
-rw-r--r--extern/Eigen3/Eigen/src/Core/Replicate.h28
-rw-r--r--extern/Eigen3/Eigen/src/Core/ReturnByValue.h2
-rw-r--r--extern/Eigen3/Eigen/src/Core/Select.h14
-rw-r--r--extern/Eigen3/Eigen/src/Core/SelfAdjointView.h16
-rw-r--r--extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h5
-rw-r--r--extern/Eigen3/Eigen/src/Core/StableNorm.h192
-rw-r--r--extern/Eigen3/Eigen/src/Core/Swap.h34
-rw-r--r--extern/Eigen3/Eigen/src/Core/Transpose.h45
-rw-r--r--extern/Eigen3/Eigen/src/Core/Transpositions.h18
-rw-r--r--extern/Eigen3/Eigen/src/Core/TriangularMatrix.h17
-rw-r--r--extern/Eigen3/Eigen/src/Core/VectorBlock.h189
-rw-r--r--extern/Eigen3/Eigen/src/Core/VectorwiseOp.h52
-rw-r--r--extern/Eigen3/Eigen/src/Core/Visitor.h28
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h3
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h10
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h50
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h22
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h101
-rw-r--r--extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h29
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h2
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h302
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h7
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h112
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h54
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h6
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h66
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h10
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h33
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h4
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h20
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h18
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h40
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h24
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h32
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h16
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h18
-rw-r--r--extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h4
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/BlasUtil.h10
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/Constants.h15
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h7
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/Macros.h37
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/Memory.h74
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/Meta.h20
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/StaticAssert.h3
-rw-r--r--extern/Eigen3/Eigen/src/Core/util/XprHelper.h28
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h4
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h4
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h4
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h24
-rw-r--r--extern/Eigen3/Eigen/src/Eigen2Support/SVD.h13
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h26
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h102
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h4
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h71
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h341
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h6
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h3
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/RealQZ.h624
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h123
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h2
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h33
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h4
-rw-r--r--extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h12
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/AlignedBox.h14
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/AngleAxis.h13
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/EulerAngles.h60
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Homogeneous.h2
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Hyperplane.h11
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h30
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h8
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Quaternion.h96
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Rotation2D.h15
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Scaling.h6
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Transform.h22
-rw-r--r--extern/Eigen3/Eigen/src/Geometry/Umeyama.h25
-rw-r--r--extern/Eigen3/Eigen/src/Householder/Householder.h13
-rw-r--r--extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h14
-rw-r--r--extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h31
-rw-r--r--extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h26
-rw-r--r--extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h215
-rw-r--r--extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h2
-rw-r--r--extern/Eigen3/Eigen/src/Jacobi/Jacobi.h99
-rw-r--r--extern/Eigen3/Eigen/src/LU/Determinant.h2
-rw-r--r--extern/Eigen3/Eigen/src/LU/FullPivLU.h10
-rw-r--r--extern/Eigen3/Eigen/src/LU/Inverse.h6
-rw-r--r--extern/Eigen3/Eigen/src/LU/PartialPivLU.h9
-rw-r--r--extern/Eigen3/Eigen/src/MetisSupport/MetisSupport.h137
-rw-r--r--extern/Eigen3/Eigen/src/OrderingMethods/Amd.h6
-rw-r--r--extern/Eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h1850
-rw-r--r--extern/Eigen3/Eigen/src/OrderingMethods/Ordering.h150
-rw-r--r--extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h23
-rw-r--r--extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h30
-rw-r--r--extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h107
-rw-r--r--extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h7
-rw-r--r--extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h92
-rw-r--r--extern/Eigen3/Eigen/src/QR/HouseholderQR.h47
-rw-r--r--extern/Eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h314
-rw-r--r--extern/Eigen3/Eigen/src/SVD/JacobiSVD.h89
-rw-r--r--extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h2
-rw-r--r--extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h4
-rw-r--r--extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h214
-rw-r--r--extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h199
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h10
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h8
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h40
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h2
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h436
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseColEtree.h206
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h6
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h19
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h34
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseDot.h19
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h615
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h77
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h4
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h12
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h45
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h23
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h12
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h31
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h24
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseVector.h159
-rw-r--r--extern/Eigen3/Eigen/src/SparseCore/SparseView.h5
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU.h758
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLUImpl.h64
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_Memory.h227
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_Structs.h111
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h298
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_Utils.h80
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h180
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h177
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h106
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h279
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h127
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h130
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h223
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h258
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h134
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h135
-rw-r--r--extern/Eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h83
-rw-r--r--extern/Eigen3/Eigen/src/SparseQR/SparseQR.h657
-rw-r--r--extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h29
-rw-r--r--extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h37
-rw-r--r--extern/Eigen3/Eigen/src/misc/SparseSolve.h17
-rw-r--r--extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h20
-rw-r--r--extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h1
-rw-r--r--extern/Eigen3/Eigen/src/plugins/BlockMethods.h435
-rw-r--r--extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h4
-rw-r--r--[-rwxr-xr-x]extern/Eigen3/eigen-update.sh2
-rw-r--r--[-rwxr-xr-x]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp0
-rw-r--r--[-rwxr-xr-x]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h0
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h7
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp6
-rw-r--r--extern/bullet2/src/SConscript7
-rw-r--r--extern/carve/CMakeLists.txt1
-rw-r--r--[-rwxr-xr-x]extern/carve/bundle.sh1
-rw-r--r--extern/carve/carve-capi.cc562
-rw-r--r--extern/carve/carve-util.cc269
-rw-r--r--extern/carve/carve-util.h174
-rw-r--r--extern/carve/files.txt1
-rw-r--r--extern/carve/include/carve/config.h18
-rw-r--r--extern/carve/include/carve/csg_triangulator.hpp1
-rw-r--r--extern/carve/include/carve/mesh_ops.hpp2
-rw-r--r--extern/carve/include/carve/mesh_simplify.hpp33
-rw-r--r--extern/carve/include/carve/triangle_intersection.hpp53
-rw-r--r--extern/carve/lib/intersect_face_division.cpp8
-rw-r--r--extern/carve/lib/triangulator.cpp18
-rw-r--r--[-rwxr-xr-x]extern/carve/mkfiles.sh0
-rw-r--r--extern/carve/patches/clang_is_heap_fix.patch42
-rw-r--r--extern/carve/patches/face_hole_merge_workaround.patch14
-rw-r--r--extern/carve/patches/files/config.h18
-rw-r--r--extern/carve/patches/memory_leak_fix.patch11
-rw-r--r--extern/carve/patches/mesh_simplify_dissolve_edges.patch64
-rw-r--r--extern/carve/patches/msvc_fix.patch14
-rw-r--r--extern/carve/patches/series4
-rw-r--r--extern/libmv/CMakeLists.txt13
-rw-r--r--extern/libmv/ChangeLog696
-rw-r--r--extern/libmv/SConscript5
-rw-r--r--[-rwxr-xr-x]extern/libmv/bundle.sh12
-rw-r--r--extern/libmv/files.txt5
-rw-r--r--extern/libmv/libmv-capi.cc1044
-rw-r--r--extern/libmv/libmv-capi.h42
-rw-r--r--extern/libmv/libmv-capi_stub.cc43
-rw-r--r--extern/libmv/libmv-util.cc309
-rw-r--r--extern/libmv/libmv-util.h69
-rw-r--r--extern/libmv/libmv/base/aligned_malloc.cc74
-rw-r--r--extern/libmv/libmv/base/aligned_malloc.h34
-rw-r--r--extern/libmv/libmv/image/correlation.h28
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.cc246
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.h13
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc493
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.h470
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics_impl.h192
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.cc56
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.h35
-rw-r--r--extern/libmv/libmv/simple_pipeline/distortion_models.cc197
-rw-r--r--extern/libmv/libmv/simple_pipeline/distortion_models.h131
-rw-r--r--extern/libmv/libmv/simple_pipeline/intersect.cc20
-rw-r--r--extern/libmv/libmv/simple_pipeline/keyframe_selection.cc61
-rw-r--r--extern/libmv/libmv/simple_pipeline/keyframe_selection.h7
-rw-r--r--extern/libmv/libmv/tracking/brute_region_tracker.cc55
-rw-r--r--[-rwxr-xr-x]extern/libmv/mkfiles.sh0
-rw-r--r--extern/libmv/third_party/ceres/CMakeLists.txt42
-rw-r--r--extern/libmv/third_party/ceres/SConscript45
-rw-r--r--[-rwxr-xr-x]extern/libmv/third_party/ceres/bundle.sh87
-rw-r--r--[-rwxr-xr-x]extern/libmv/third_party/ceres/mkfiles.sh0
-rw-r--r--extern/libmv/third_party/gflags/gflags/gflags_declare.h6
-rw-r--r--extern/libmv/third_party/glog/ChangeLog15
-rw-r--r--extern/libmv/third_party/glog/README.libmv26
-rw-r--r--extern/libmv/third_party/glog/src/base/commandlineflags.h59
-rw-r--r--extern/libmv/third_party/glog/src/base/mutex.h14
-rw-r--r--extern/libmv/third_party/glog/src/config_freebsd.h6
-rw-r--r--extern/libmv/third_party/glog/src/config_hurd.h6
-rw-r--r--extern/libmv/third_party/glog/src/config_linux.h6
-rw-r--r--extern/libmv/third_party/glog/src/config_mac.h6
-rw-r--r--extern/libmv/third_party/glog/src/glog/logging.h298
-rw-r--r--extern/libmv/third_party/glog/src/glog/raw_logging.h6
-rw-r--r--extern/libmv/third_party/glog/src/logging.cc439
-rw-r--r--extern/libmv/third_party/glog/src/raw_logging.cc4
-rw-r--r--extern/libmv/third_party/glog/src/signalhandler.cc11
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h2
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.cc4
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.h2
-rw-r--r--extern/libmv/third_party/glog/src/utilities.cc6
-rw-r--r--extern/libmv/third_party/glog/src/utilities.h4
-rw-r--r--extern/libmv/third_party/glog/src/vlog_is_on.cc12
-rw-r--r--extern/libmv/third_party/glog/src/windows/config.h116
-rw-r--r--extern/libmv/third_party/glog/src/windows/glog/logging.h301
-rw-r--r--extern/libmv/third_party/glog/src/windows/port.cc1
-rw-r--r--extern/libmv/third_party/glog/src/windows/port.h14
-rw-r--r--[-rwxr-xr-x]extern/libmv/third_party/glog/src/windows/preprocess.sh0
-rw-r--r--extern/rangetree/range_tree.hh4
-rw-r--r--intern/SConscript3
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp65
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h17
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.cpp20
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.h7
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h5
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.cpp1
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.cpp2
-rw-r--r--intern/cycles/CMakeLists.txt83
-rw-r--r--intern/cycles/SConscript10
-rw-r--r--intern/cycles/app/cycles_standalone.cpp109
-rw-r--r--intern/cycles/app/cycles_xml.cpp139
-rw-r--r--intern/cycles/app/cycles_xml.h11
-rw-r--r--intern/cycles/blender/CCL_api.h7
-rw-r--r--intern/cycles/blender/CMakeLists.txt5
-rw-r--r--intern/cycles/blender/addon/__init__.py5
-rw-r--r--intern/cycles/blender/addon/engine.py6
-rw-r--r--intern/cycles/blender/addon/properties.py86
-rw-r--r--intern/cycles/blender/addon/ui.py160
-rw-r--r--intern/cycles/blender/blender_camera.cpp28
-rw-r--r--intern/cycles/blender/blender_curves.cpp62
-rw-r--r--intern/cycles/blender/blender_mesh.cpp261
-rw-r--r--intern/cycles/blender/blender_object.cpp138
-rw-r--r--intern/cycles/blender/blender_particles.cpp5
-rw-r--r--intern/cycles/blender/blender_python.cpp38
-rw-r--r--intern/cycles/blender/blender_session.cpp346
-rw-r--r--intern/cycles/blender/blender_session.h5
-rw-r--r--intern/cycles/blender/blender_shader.cpp11
-rw-r--r--intern/cycles/blender/blender_sync.cpp4
-rw-r--r--intern/cycles/blender/blender_sync.h12
-rw-r--r--intern/cycles/blender/blender_util.h66
-rw-r--r--intern/cycles/bvh/bvh.cpp115
-rw-r--r--intern/cycles/bvh/bvh.h4
-rw-r--r--intern/cycles/bvh/bvh_binning.cpp18
-rw-r--r--intern/cycles/bvh/bvh_build.cpp117
-rw-r--r--intern/cycles/bvh/bvh_build.h6
-rw-r--r--intern/cycles/bvh/bvh_params.h30
-rw-r--r--intern/cycles/bvh/bvh_sort.cpp4
-rw-r--r--intern/cycles/bvh/bvh_split.cpp44
-rw-r--r--intern/cycles/bvh/bvh_split.h4
-rw-r--r--intern/cycles/device/device.cpp11
-rw-r--r--intern/cycles/device/device.h12
-rw-r--r--intern/cycles/device/device_cpu.cpp14
-rw-r--r--intern/cycles/device/device_cuda.cpp340
-rw-r--r--intern/cycles/device/device_memory.h17
-rw-r--r--intern/cycles/device/device_multi.cpp9
-rw-r--r--intern/cycles/device/device_network.cpp8
-rw-r--r--intern/cycles/device/device_network.h10
-rw-r--r--intern/cycles/device/device_opencl.cpp126
-rw-r--r--intern/cycles/kernel/CMakeLists.txt87
-rw-r--r--intern/cycles/kernel/SConscript25
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h14
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h8
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h4
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h13
-rw-r--r--intern/cycles/kernel/closure/bsdf_westin.h7
-rw-r--r--intern/cycles/kernel/geom/geom.h44
-rw-r--r--intern/cycles/kernel/geom/geom_attribute.h71
-rw-r--r--intern/cycles/kernel/geom/geom_bvh.h318
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_shadow.h375
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_subsurface.h (renamed from intern/cycles/kernel/kernel_bvh_subsurface.h)65
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_traversal.h (renamed from intern/cycles/kernel/kernel_bvh_traversal.h)75
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h1035
-rw-r--r--intern/cycles/kernel/geom/geom_motion_curve.h148
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle.h392
-rw-r--r--intern/cycles/kernel/geom/geom_object.h (renamed from intern/cycles/kernel/kernel_object.h)201
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h (renamed from intern/cycles/kernel/kernel_primitive.h)149
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h379
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h75
-rw-r--r--intern/cycles/kernel/kernel.cpp10
-rw-r--r--intern/cycles/kernel/kernel.cu96
-rw-r--r--intern/cycles/kernel/kernel.h2
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h25
-rw-r--r--intern/cycles/kernel/kernel_avx.cpp2
-rw-r--r--intern/cycles/kernel/kernel_bvh.h1258
-rw-r--r--intern/cycles/kernel/kernel_camera.h6
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h133
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h2
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h23
-rw-r--r--intern/cycles/kernel/kernel_curve.h137
-rw-r--r--intern/cycles/kernel/kernel_displace.h302
-rw-r--r--intern/cycles/kernel/kernel_emission.h102
-rw-r--r--intern/cycles/kernel/kernel_film.h4
-rw-r--r--intern/cycles/kernel/kernel_light.h75
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h5
-rw-r--r--intern/cycles/kernel/kernel_passes.h3
-rw-r--r--intern/cycles/kernel/kernel_path.h495
-rw-r--r--intern/cycles/kernel/kernel_path_state.h5
-rw-r--r--intern/cycles/kernel/kernel_projection.h8
-rw-r--r--intern/cycles/kernel/kernel_random.h3
-rw-r--r--intern/cycles/kernel/kernel_shader.h338
-rw-r--r--intern/cycles/kernel/kernel_shadow.h222
-rw-r--r--intern/cycles/kernel/kernel_sse2.cpp2
-rw-r--r--intern/cycles/kernel/kernel_sse3.cpp2
-rw-r--r--intern/cycles/kernel/kernel_sse41.cpp2
-rw-r--r--intern/cycles/kernel/kernel_textures.h57
-rw-r--r--intern/cycles/kernel/kernel_triangle.h180
-rw-r--r--intern/cycles/kernel/kernel_types.h154
-rw-r--r--intern/cycles/kernel/kernel_volume.h689
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp115
-rw-r--r--intern/cycles/kernel/osl/osl_services.h6
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp14
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/shaders/node_absorption_volume.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_glass_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl13
-rw-r--r--intern/cycles/kernel/shaders/node_light_path.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_math.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_mix.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_refraction_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_scatter_volume.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_uv_map.osl45
-rw-r--r--intern/cycles/kernel/svm/svm.h20
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h4
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h123
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h22
-rw-r--r--intern/cycles/kernel/svm/svm_image.h119
-rw-r--r--intern/cycles/kernel/svm/svm_light_path.h1
-rw-r--r--intern/cycles/kernel/svm/svm_math.h2
-rw-r--r--intern/cycles/kernel/svm/svm_mix.h2
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h14
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_hsv.h12
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h2
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h77
-rw-r--r--intern/cycles/kernel/svm/svm_texture.h93
-rw-r--r--intern/cycles/kernel/svm/svm_types.h13
-rw-r--r--intern/cycles/kernel/svm/svm_vector_transform.h6
-rw-r--r--intern/cycles/kernel/svm/svm_voronoi.h19
-rw-r--r--intern/cycles/kernel/svm/svm_wavelength.h54
-rw-r--r--intern/cycles/kernel/svm/svm_wireframe.h12
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/attribute.cpp174
-rw-r--r--intern/cycles/render/attribute.h26
-rw-r--r--intern/cycles/render/background.cpp4
-rw-r--r--intern/cycles/render/bake.cpp206
-rw-r--r--intern/cycles/render/bake.h77
-rw-r--r--intern/cycles/render/blackbody.cpp54
-rw-r--r--intern/cycles/render/buffers.cpp4
-rw-r--r--intern/cycles/render/buffers.h3
-rw-r--r--intern/cycles/render/camera.cpp22
-rw-r--r--intern/cycles/render/camera.h2
-rw-r--r--intern/cycles/render/curves.cpp2
-rw-r--r--intern/cycles/render/film.cpp7
-rw-r--r--intern/cycles/render/graph.cpp18
-rw-r--r--intern/cycles/render/graph.h3
-rw-r--r--intern/cycles/render/image.cpp221
-rw-r--r--intern/cycles/render/image.h33
-rw-r--r--intern/cycles/render/integrator.cpp27
-rw-r--r--intern/cycles/render/integrator.h5
-rw-r--r--intern/cycles/render/light.cpp70
-rw-r--r--intern/cycles/render/mesh.cpp252
-rw-r--r--intern/cycles/render/mesh.h15
-rw-r--r--intern/cycles/render/mesh_displace.cpp12
-rw-r--r--intern/cycles/render/nodes.cpp163
-rw-r--r--intern/cycles/render/nodes.h35
-rw-r--r--intern/cycles/render/object.cpp185
-rw-r--r--intern/cycles/render/object.h12
-rw-r--r--intern/cycles/render/osl.cpp40
-rw-r--r--intern/cycles/render/scene.cpp40
-rw-r--r--intern/cycles/render/scene.h9
-rw-r--r--intern/cycles/render/session.cpp48
-rw-r--r--intern/cycles/render/session.h10
-rw-r--r--intern/cycles/render/shader.cpp3
-rw-r--r--intern/cycles/render/shader.h1
-rw-r--r--intern/cycles/render/sky_model.cpp2
-rw-r--r--intern/cycles/render/svm.cpp256
-rw-r--r--intern/cycles/render/svm.h12
-rw-r--r--intern/cycles/render/tables.cpp5
-rw-r--r--intern/cycles/subd/subd_split.cpp2
-rw-r--r--intern/cycles/util/util_color.h34
-rw-r--r--intern/cycles/util/util_cuda.h3
-rw-r--r--intern/cycles/util/util_half.h22
-rw-r--r--intern/cycles/util/util_hash.h4
-rw-r--r--intern/cycles/util/util_math.h86
-rw-r--r--intern/cycles/util/util_md5.cpp2
-rw-r--r--intern/cycles/util/util_opencl.h4
-rw-r--r--intern/cycles/util/util_path.cpp5
-rw-r--r--intern/cycles/util/util_path.h1
-rw-r--r--intern/cycles/util/util_simd.h92
-rw-r--r--intern/cycles/util/util_system.cpp19
-rw-r--r--intern/cycles/util/util_transform.cpp9
-rw-r--r--intern/cycles/util/util_transform.h6
-rw-r--r--intern/cycles/util/util_types.h63
-rw-r--r--intern/cycles/util/util_view.cpp22
-rw-r--r--intern/elbeem/intern/mvmcoords.cpp2
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h19
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp6
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h4
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.mm6
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerX11.cpp41
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp10
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp26
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp12
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h3
-rw-r--r--intern/ghost/test/multitest/MultiTest.c2
-rw-r--r--intern/guardedalloc/intern/mallocn.c9
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c10
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h8
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c15
-rw-r--r--intern/itasc/SConscript5
-rw-r--r--intern/itasc/kdl/frameacc.hpp39
-rw-r--r--intern/itasc/kdl/frames.hpp29
-rw-r--r--intern/itasc/kdl/framevel.hpp37
-rw-r--r--intern/itasc/kdl/jacobian.hpp3
-rw-r--r--intern/itasc/kdl/jntarray.hpp4
-rw-r--r--intern/itasc/kdl/jntarrayacc.hpp5
-rw-r--r--intern/itasc/kdl/jntarrayvel.hpp5
-rw-r--r--intern/locale/CMakeLists.txt15
-rw-r--r--intern/locale/SConscript6
-rw-r--r--intern/locale/boost_locale_wrapper.cpp8
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp4
-rw-r--r--intern/utfconv/utfconv.c2
-rw-r--r--[-rwxr-xr-x]release/bin/blender-softwaregl0
-rw-r--r--[-rwxr-xr-x]release/bin/blender-thumbnailer.py61
-rw-r--r--release/darwin/codesigning_rules_blender.plist2
-rw-r--r--release/darwin/codesigning_rules_player.plist2
-rw-r--r--release/datafiles/blender_icons.svg1970
-rw-r--r--release/datafiles/blender_icons16/icon16_action_tweak.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_back.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_bezier.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_bounce.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_circ.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_constant.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_cubic.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_ease_in.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_ease_in_out.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_ease_out.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_elastic.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_expo.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_linear.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_quad.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_quart.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_quint.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_sine.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_line_data.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_nla_pushdown.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_action_tweak.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_back.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_bezier.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_bounce.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_circ.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_constant.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_cubic.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_ease_in.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_ease_in_out.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_ease_out.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_elastic.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_expo.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_linear.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_quad.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_quart.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_quint.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_ipo_sine.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_line_data.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_nla_pushdown.datbin0 -> 4120 bytes
-rw-r--r--[-rwxr-xr-x]release/datafiles/blender_icons_update.py0
-rw-r--r--release/datafiles/brushicons/clone.pngbin8425 -> 10732 bytes
-rw-r--r--release/datafiles/brushicons/smear.pngbin7037 -> 8459 bytes
-rw-r--r--release/datafiles/brushicons/soften.pngbin6892 -> 7984 bytes
-rw-r--r--release/datafiles/brushicons/texdraw.pngbin6944 -> 9213 bytes
-rw-r--r--[-rwxr-xr-x]release/datafiles/ctodata.py0
-rw-r--r--[-rwxr-xr-x]release/datafiles/datatoc.py0
-rw-r--r--[-rwxr-xr-x]release/datafiles/prvicons_update.py0
-rw-r--r--release/datafiles/splash.pngbin220834 -> 206467 bytes
-rw-r--r--release/datafiles/splash_2x.pngbin0 -> 660326 bytes
-rw-r--r--release/datafiles/splash_template.xcfbin21898 -> 1274820 bytes
-rw-r--r--release/scripts/freestyle/modules/freestyle/chainingiterators.py6
-rw-r--r--release/scripts/freestyle/modules/freestyle/predicates.py36
-rw-r--r--release/scripts/freestyle/modules/freestyle/shaders.py2
-rw-r--r--release/scripts/freestyle/modules/freestyle/utils.py41
-rw-r--r--release/scripts/freestyle/modules/parameter_editor.py59
-rw-r--r--release/scripts/freestyle/styles/anisotropic_diffusion.py1
-rw-r--r--release/scripts/modules/addon_utils.py4
-rw-r--r--release/scripts/modules/animsys_refactor.py164
-rw-r--r--[-rwxr-xr-x]release/scripts/modules/bl_i18n_utils/merge_po.py0
-rw-r--r--[-rwxr-xr-x]release/scripts/modules/bl_i18n_utils/utils_languages_menu.py0
-rw-r--r--[-rwxr-xr-x]release/scripts/modules/bl_i18n_utils/utils_rtl.py0
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py9
-rw-r--r--[-rwxr-xr-x]release/scripts/modules/blend_render_info.py0
-rw-r--r--release/scripts/modules/bpy/ops.py31
-rw-r--r--release/scripts/modules/bpy/utils.py15
-rw-r--r--release/scripts/modules/bpy_extras/keyconfig_utils.py15
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py5
-rw-r--r--release/scripts/modules/bpy_types.py6
-rw-r--r--release/scripts/modules/nodeitems_utils.py2
-rw-r--r--release/scripts/modules/rna_keymap_ui.py43
-rw-r--r--release/scripts/modules/rna_prop_ui.py15
-rw-r--r--release/scripts/presets/camera/1__colon__2.3_inch.py4
-rw-r--r--release/scripts/presets/camera/1__colon__2.5_inch.py4
-rw-r--r--release/scripts/presets/camera/2__colon__3_inch.py4
-rw-r--r--release/scripts/presets/camera/4__colon__3_inch.py4
-rw-r--r--release/scripts/presets/camera/Arri_Alexa.py4
-rw-r--r--release/scripts/presets/camera/Blackmagic_Cinema_Camera.py4
-rw-r--r--release/scripts/presets/camera/Canon_1D.py4
-rw-r--r--release/scripts/presets/camera/Canon_1DS.py4
-rw-r--r--release/scripts/presets/camera/Canon_500D.py4
-rw-r--r--release/scripts/presets/camera/Canon_550D.py4
-rw-r--r--release/scripts/presets/camera/Canon_5D.py4
-rw-r--r--release/scripts/presets/camera/Canon_600D.py4
-rw-r--r--release/scripts/presets/camera/Canon_60D.py4
-rw-r--r--release/scripts/presets/camera/Canon_7D.py4
-rw-r--r--release/scripts/presets/camera/Canon_APS-C.py (renamed from release/scripts/presets/camera/APS-C_DSLR.py)0
-rw-r--r--release/scripts/presets/camera/Canon_APS-H.py4
-rw-r--r--release/scripts/presets/camera/Canon_C300.py4
-rw-r--r--release/scripts/presets/camera/Full_Frame_35mm_Camera.py (renamed from release/scripts/presets/camera/full_frame_35mm_film.py)0
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_Black.py6
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_Silver.py6
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_White.py6
-rw-r--r--release/scripts/presets/camera/Nexus_5.py5
-rw-r--r--release/scripts/presets/camera/Nikon_D3S.py4
-rw-r--r--release/scripts/presets/camera/Nikon_D5000.py4
-rw-r--r--release/scripts/presets/camera/Nikon_D5100.py4
-rw-r--r--release/scripts/presets/camera/Nikon_D7000.py4
-rw-r--r--release/scripts/presets/camera/Nikon_D90.py4
-rw-r--r--release/scripts/presets/camera/Nikon_DX.py (renamed from release/scripts/presets/camera/Nikon_D300S.py)0
-rw-r--r--release/scripts/presets/camera/Panasonic_AG-HVX200.py4
-rw-r--r--release/scripts/presets/camera/Panasonic_LX2.py4
-rw-r--r--release/scripts/presets/camera/Samsung_Galaxy_S3.py5
-rw-r--r--release/scripts/presets/camera/Samsung_Galaxy_S4.py5
-rw-r--r--release/scripts/presets/camera/Sony_EX1.py4
-rw-r--r--release/scripts/presets/camera/Sony_F65.py4
-rw-r--r--release/scripts/presets/camera/Super_16_Film.py (renamed from release/scripts/presets/camera/super_16_film.py)0
-rw-r--r--release/scripts/presets/camera/Super_35_Film.py (renamed from release/scripts/presets/camera/super_35_film.py)0
-rw-r--r--release/scripts/presets/camera/iPhone_4.py5
-rw-r--r--release/scripts/presets/camera/iPhone_4S.py5
-rw-r--r--release/scripts/presets/camera/iPhone_5.py5
-rw-r--r--release/scripts/presets/camera/micro_four_thirds.py4
-rw-r--r--release/scripts/presets/cloth/rubber.py12
-rw-r--r--release/scripts/presets/keyconfig/3dsmax.py28
-rw-r--r--release/scripts/presets/keyconfig/maya.py28
-rw-r--r--release/scripts/presets/tracking_camera/1__colon__2.3_inch.py (renamed from release/scripts/presets/tracking_camera/Canon_1D.py)4
-rw-r--r--release/scripts/presets/tracking_camera/1__colon__2.5_inch.py (renamed from release/scripts/presets/tracking_camera/Canon_1DS.py)4
-rw-r--r--release/scripts/presets/tracking_camera/2__colon__3_inch.py (renamed from release/scripts/presets/tracking_camera/Canon_500D.py)4
-rw-r--r--release/scripts/presets/tracking_camera/4__colon__3_inch.py (renamed from release/scripts/presets/tracking_camera/Canon_550D.py)4
-rw-r--r--release/scripts/presets/tracking_camera/Arri_Alexa.py10
-rw-r--r--release/scripts/presets/tracking_camera/Blackmagic_Cinema_Camera.py9
-rw-r--r--release/scripts/presets/tracking_camera/Canon_1100D.py2
-rw-r--r--release/scripts/presets/tracking_camera/Canon_5D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_60D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_7D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_APS-C.py (renamed from release/scripts/presets/tracking_camera/Canon_600D.py)2
-rw-r--r--release/scripts/presets/tracking_camera/Canon_APS-H.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_C300.py10
-rw-r--r--release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py10
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py11
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py11
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_White.py11
-rw-r--r--release/scripts/presets/tracking_camera/Nexus_5.py11
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D3100.py1
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D35.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D5000.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D5100.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D7000.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D90.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_DX.py (renamed from release/scripts/presets/tracking_camera/Nikon_D300S.py)1
-rw-r--r--release/scripts/presets/tracking_camera/Panasonic_AG-HVX200.py9
-rw-r--r--release/scripts/presets/tracking_camera/Panasonic_LX2.py9
-rw-r--r--release/scripts/presets/tracking_camera/Red_Epic.py1
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_2K.py1
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_3K.py1
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_4K.py1
-rw-r--r--release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py11
-rw-r--r--release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py11
-rw-r--r--release/scripts/presets/tracking_camera/Sony_A55.py1
-rw-r--r--release/scripts/presets/tracking_camera/Sony_EX1.py9
-rw-r--r--release/scripts/presets/tracking_camera/Sony_F65.py9
-rw-r--r--release/scripts/presets/tracking_camera/Super_16.py10
-rw-r--r--release/scripts/presets/tracking_camera/Super_35.py10
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_4.py11
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_4S.py11
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_5.py11
-rw-r--r--release/scripts/presets/tracking_settings/blurry_footage.py1
-rw-r--r--release/scripts/presets/tracking_settings/default.py5
-rw-r--r--release/scripts/presets/tracking_settings/fast_motion.py1
-rw-r--r--release/scripts/presets/tracking_settings/planar.py1
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py1
-rw-r--r--release/scripts/startup/bl_operators/anim.py83
-rw-r--r--release/scripts/startup/bl_operators/clip.py12
-rw-r--r--release/scripts/startup/bl_operators/freestyle.py4
-rw-r--r--release/scripts/startup/bl_operators/image.py10
-rw-r--r--release/scripts/startup/bl_operators/mesh.py1
-rw-r--r--release/scripts/startup/bl_operators/node.py1
-rw-r--r--release/scripts/startup/bl_operators/object.py31
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py2
-rw-r--r--release/scripts/startup/bl_operators/presets.py56
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py3
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py34
-rw-r--r--release/scripts/startup/bl_operators/vertexpaint_dirt.py3
-rw-r--r--release/scripts/startup/bl_operators/view3d.py1
-rw-r--r--release/scripts/startup/bl_operators/wm.py16
-rw-r--r--release/scripts/startup/bl_ui/__init__.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py34
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py19
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py45
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py65
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py50
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py20
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py31
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py14
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_softbody.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py34
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py83
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py1
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py2
-rw-r--r--release/scripts/startup/bl_ui/space_image.py342
-rw-r--r--release/scripts/startup/bl_ui/space_info.py15
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py8
-rw-r--r--release/scripts/startup/bl_ui/space_node.py5
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py17
-rw-r--r--release/scripts/startup/bl_ui/space_time.py4
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py39
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py92
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py296
-rw-r--r--release/scripts/startup/nodeitems_builtins.py2
-rw-r--r--release/scripts/templates_py/custom_nodes.py13
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py1
-rw-r--r--release/scripts/templates_py/ui_panel.py8
-rw-r--r--release/text/readme.html2
-rw-r--r--source/blender/avi/intern/avi_codecs.c8
-rw-r--r--source/blender/avi/intern/avi_mjpeg.c26
-rw-r--r--source/blender/avi/intern/avi_options.c1
-rw-r--r--source/blender/blenfont/BLF_api.h4
-rw-r--r--source/blender/blenfont/intern/blf.c2
-rw-r--r--source/blender/blenfont/intern/blf_font.c8
-rw-r--r--source/blender/blenfont/intern/blf_lang.c1
-rw-r--r--source/blender/blenfont/intern/blf_translation.c12
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h61
-rw-r--r--source/blender/blenkernel/BKE_addon.h2
-rw-r--r--source/blender/blenkernel/BKE_anim.h14
-rw-r--r--source/blender/blenkernel/BKE_animsys.h10
-rw-r--r--source/blender/blenkernel/BKE_armature.h6
-rw-r--r--source/blender/blenkernel/BKE_blender.h10
-rw-r--r--source/blender/blenkernel/BKE_brush.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h2
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h2
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h2
-rw-r--r--source/blender/blenkernel/BKE_constraint.h50
-rw-r--r--source/blender/blenkernel/BKE_context.h3
-rw-r--r--source/blender/blenkernel/BKE_crazyspace.h54
-rw-r--r--source/blender/blenkernel/BKE_curve.h17
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h6
-rw-r--r--source/blender/blenkernel/BKE_displist.h11
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h1
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_freestyle.h8
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h13
-rw-r--r--source/blender/blenkernel/BKE_lattice.h6
-rw-r--r--source/blender/blenkernel/BKE_library.h8
-rw-r--r--source/blender/blenkernel/BKE_library_query.h57
-rw-r--r--source/blender/blenkernel/BKE_mask.h38
-rw-r--r--source/blender/blenkernel/BKE_material.h6
-rw-r--r--source/blender/blenkernel/BKE_mesh.h26
-rw-r--r--source/blender/blenkernel/BKE_modifier.h3
-rw-r--r--source/blender/blenkernel/BKE_nla.h24
-rw-r--r--source/blender/blenkernel/BKE_node.h12
-rw-r--r--source/blender/blenkernel/BKE_object.h11
-rw-r--r--source/blender/blenkernel/BKE_paint.h36
-rw-r--r--source/blender/blenkernel/BKE_particle.h37
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h26
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h2
-rw-r--r--source/blender/blenkernel/BKE_report.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h33
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h9
-rw-r--r--source/blender/blenkernel/BKE_sound.h6
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h6
-rw-r--r--source/blender/blenkernel/BKE_texture.h5
-rw-r--r--source/blender/blenkernel/BKE_tracking.h6
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h1
-rw-r--r--source/blender/blenkernel/CMakeLists.txt6
-rw-r--r--source/blender/blenkernel/depsgraph_private.h1
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c66
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c281
-rw-r--r--source/blender/blenkernel/intern/action.c40
-rw-r--r--source/blender/blenkernel/intern/addon.c2
-rw-r--r--source/blender/blenkernel/intern/anim.c29
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c119
-rw-r--r--source/blender/blenkernel/intern/armature.c181
-rw-r--r--source/blender/blenkernel/intern/blender.c78
-rw-r--r--source/blender/blenkernel/intern/boids.c37
-rw-r--r--source/blender/blenkernel/intern/bpath.c9
-rw-r--r--source/blender/blenkernel/intern/brush.c70
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c73
-rw-r--r--source/blender/blenkernel/intern/camera.c18
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c480
-rw-r--r--source/blender/blenkernel/intern/cloth.c51
-rw-r--r--source/blender/blenkernel/intern/collision.c10
-rw-r--r--source/blender/blenkernel/intern/colortools.c11
-rw-r--r--source/blender/blenkernel/intern/constraint.c405
-rw-r--r--source/blender/blenkernel/intern/context.c55
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c (renamed from source/blender/editors/util/crazyspace.c)60
-rw-r--r--source/blender/blenkernel/intern/curve.c333
-rw-r--r--source/blender/blenkernel/intern/customdata.c44
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c208
-rw-r--r--source/blender/blenkernel/intern/displist.c302
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c41
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c349
-rw-r--r--source/blender/blenkernel/intern/editmesh.c25
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c14
-rw-r--r--source/blender/blenkernel/intern/effect.c22
-rw-r--r--source/blender/blenkernel/intern/fcurve.c367
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c2
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c3
-rw-r--r--source/blender/blenkernel/intern/font.c6
-rw-r--r--source/blender/blenkernel/intern/freestyle.c27
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/group.c15
-rw-r--r--source/blender/blenkernel/intern/idprop.c23
-rw-r--r--source/blender/blenkernel/intern/image.c125
-rw-r--r--source/blender/blenkernel/intern/image_gen.c10
-rw-r--r--source/blender/blenkernel/intern/implicit.c24
-rw-r--r--source/blender/blenkernel/intern/ipo.c5
-rw-r--r--source/blender/blenkernel/intern/key.c18
-rw-r--r--source/blender/blenkernel/intern/lamp.c8
-rw-r--r--source/blender/blenkernel/intern/lattice.c74
-rw-r--r--source/blender/blenkernel/intern/library.c171
-rw-r--r--source/blender/blenkernel/intern/library_query.c474
-rw-r--r--source/blender/blenkernel/intern/linestyle.c37
-rw-r--r--source/blender/blenkernel/intern/mask.c203
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c73
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c52
-rw-r--r--source/blender/blenkernel/intern/material.c108
-rw-r--r--source/blender/blenkernel/intern/mball.c20
-rw-r--r--source/blender/blenkernel/intern/mesh.c314
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c123
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c3
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c90
-rw-r--r--source/blender/blenkernel/intern/modifier.c25
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c14
-rw-r--r--source/blender/blenkernel/intern/movieclip.c110
-rw-r--r--source/blender/blenkernel/intern/multires.c6
-rw-r--r--source/blender/blenkernel/intern/navmesh_conversion.c10
-rw-r--r--source/blender/blenkernel/intern/nla.c57
-rw-r--r--source/blender/blenkernel/intern/node.c104
-rw-r--r--source/blender/blenkernel/intern/object.c148
-rw-r--r--source/blender/blenkernel/intern/object_deform.c6
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c57
-rw-r--r--source/blender/blenkernel/intern/ocean.c11
-rw-r--r--source/blender/blenkernel/intern/packedFile.c106
-rw-r--r--source/blender/blenkernel/intern/paint.c274
-rw-r--r--source/blender/blenkernel/intern/particle.c98
-rw-r--r--source/blender/blenkernel/intern/particle_system.c154
-rw-r--r--source/blender/blenkernel/intern/pbvh.c166
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c564
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h13
-rw-r--r--source/blender/blenkernel/intern/pointcache.c40
-rw-r--r--source/blender/blenkernel/intern/report.c6
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c17
-rw-r--r--source/blender/blenkernel/intern/scene.c106
-rw-r--r--source/blender/blenkernel/intern/screen.c8
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c92
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c22
-rw-r--r--source/blender/blenkernel/intern/sequencer.c304
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c28
-rw-r--r--source/blender/blenkernel/intern/smoke.c53
-rw-r--r--source/blender/blenkernel/intern/softbody.c3
-rw-r--r--source/blender/blenkernel/intern/sound.c224
-rw-r--r--source/blender/blenkernel/intern/speaker.c8
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c403
-rw-r--r--source/blender/blenkernel/intern/text.c62
-rw-r--r--source/blender/blenkernel/intern/texture.c106
-rw-r--r--source/blender/blenkernel/intern/tracking.c104
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_region_tracker.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c65
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c6
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c67
-rw-r--r--source/blender/blenkernel/intern/treehash.c16
-rw-r--r--source/blender/blenkernel/intern/unit.c4
-rw-r--r--source/blender/blenkernel/intern/world.c12
-rw-r--r--source/blender/blenkernel/intern/writeavi.c2
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c132
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c2
-rw-r--r--source/blender/blenkernel/tracking_private.h9
-rw-r--r--source/blender/blenlib/BLI_alloca.h3
-rw-r--r--source/blender/blenlib/BLI_compiler_attrs.h9
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h (renamed from source/blender/compositor/nodes/COM_CombineRGBANode.h)30
-rw-r--r--source/blender/blenlib/BLI_easing.h78
-rw-r--r--source/blender/blenlib/BLI_edgehash.h37
-rw-r--r--source/blender/blenlib/BLI_fileops.h2
-rw-r--r--source/blender/blenlib/BLI_ghash.h50
-rw-r--r--source/blender/blenlib/BLI_jitter.h6
-rw-r--r--source/blender/blenlib/BLI_kdtree.h32
-rw-r--r--source/blender/blenlib/BLI_link_utils.h (renamed from source/blender/editors/include/ED_fluidsim.h)50
-rw-r--r--source/blender/blenlib/BLI_linklist_stack.h32
-rw-r--r--source/blender/blenlib/BLI_math_base.h22
-rw-r--r--source/blender/blenlib/BLI_math_color.h12
-rw-r--r--source/blender/blenlib/BLI_math_geom.h62
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h17
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h15
-rw-r--r--source/blender/blenlib/BLI_math_vector.h20
-rw-r--r--source/blender/blenlib/BLI_mempool.h4
-rw-r--r--source/blender/blenlib/BLI_noise.h2
-rw-r--r--source/blender/blenlib/BLI_path_util.h8
-rw-r--r--source/blender/blenlib/BLI_quadric.h2
-rw-r--r--source/blender/blenlib/BLI_rand.h7
-rw-r--r--source/blender/blenlib/BLI_rect.h5
-rw-r--r--source/blender/blenlib/BLI_stack.h2
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h16
-rw-r--r--source/blender/blenlib/BLI_string_cursor_utf8.h4
-rw-r--r--source/blender/blenlib/BLI_sys_types.h18
-rw-r--r--source/blender/blenlib/BLI_system.h (renamed from source/blender/blenlib/BLI_cpu.h)13
-rw-r--r--source/blender/blenlib/BLI_threads.h3
-rw-r--r--source/blender/blenlib/BLI_utildefines.h85
-rw-r--r--source/blender/blenlib/BLI_winstuff.h4
-rw-r--r--source/blender/blenlib/CMakeLists.txt8
-rw-r--r--source/blender/blenlib/intern/BLI_args.c4
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c113
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c174
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c48
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c274
-rw-r--r--source/blender/blenlib/intern/boxpack2d.c415
-rw-r--r--source/blender/blenlib/intern/convexhull2d.c33
-rw-r--r--source/blender/blenlib/intern/easing.c357
-rw-r--r--source/blender/blenlib/intern/edgehash.c103
-rw-r--r--source/blender/blenlib/intern/fileops.c9
-rw-r--r--source/blender/blenlib/intern/freetypefont.c159
-rw-r--r--source/blender/blenlib/intern/graph.c6
-rw-r--r--source/blender/blenlib/intern/jitter.c87
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c33
-rw-r--r--source/blender/blenlib/intern/math_color.c116
-rw-r--r--source/blender/blenlib/intern/math_geom.c345
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c116
-rw-r--r--source/blender/blenlib/intern/math_matrix.c46
-rw-r--r--source/blender/blenlib/intern/math_rotation.c259
-rw-r--r--source/blender/blenlib/intern/math_vector.c223
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c34
-rw-r--r--source/blender/blenlib/intern/noise.c8
-rw-r--r--source/blender/blenlib/intern/path_util.c230
-rw-r--r--source/blender/blenlib/intern/polyfill2d.c12
-rw-r--r--source/blender/blenlib/intern/quadric.c6
-rw-r--r--source/blender/blenlib/intern/rand.c85
-rw-r--r--source/blender/blenlib/intern/rct.c10
-rw-r--r--source/blender/blenlib/intern/scanfill.c5
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c27
-rw-r--r--source/blender/blenlib/intern/smallhash.c1
-rw-r--r--source/blender/blenlib/intern/storage.c25
-rw-r--r--source/blender/blenlib/intern/string.c2
-rw-r--r--source/blender/blenlib/intern/string_cursor_utf8.c12
-rw-r--r--source/blender/blenlib/intern/string_utf8.c30
-rw-r--r--source/blender/blenlib/intern/system.c (renamed from source/blender/blenlib/intern/cpu.c)10
-rw-r--r--source/blender/blenlib/intern/threads.c5
-rw-r--r--source/blender/blenlib/intern/timecode.c3
-rw-r--r--source/blender/blenlib/intern/uvproject.c8
-rw-r--r--source/blender/blenlib/intern/voronoi.c34
-rw-r--r--source/blender/blenlib/intern/winstuff.c6
-rw-r--r--source/blender/blenloader/CMakeLists.txt1
-rw-r--r--source/blender/blenloader/intern/readblenentry.c10
-rw-r--r--source/blender/blenloader/intern/readfile.c209
-rw-r--r--source/blender/blenloader/intern/readfile.h1
-rw-r--r--source/blender/blenloader/intern/runtime.c4
-rw-r--r--source/blender/blenloader/intern/versioning_250.c9
-rw-r--r--source/blender/blenloader/intern/versioning_260.c71
-rw-r--r--source/blender/blenloader/intern/versioning_270.c282
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c15
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c6
-rw-r--r--source/blender/blenloader/intern/writefile.c52
-rw-r--r--source/blender/bmesh/bmesh_class.h13
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c175
-rw-r--r--source/blender/bmesh/intern/bmesh_delete.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c16
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c39
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c190
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h9
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c104
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c283
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c76
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_validate.c21
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c55
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c27
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c58
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c119
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c74
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c151
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_private.h5
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c14
-rw-r--r--source/blender/bmesh/operators/bmo_connect_nonplanar.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c4
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c141
-rw-r--r--source/blender/bmesh/operators/bmo_edgenet.c2
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c2
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c10
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c76
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c2
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c4
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c35
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.c58
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c83
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c7
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c26
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_wireframe.c69
-rw-r--r--source/blender/collada/AnimationExporter.cpp10
-rw-r--r--source/blender/collada/ArmatureImporter.cpp27
-rw-r--r--source/blender/collada/ControllerExporter.cpp89
-rw-r--r--source/blender/collada/DocumentImporter.cpp2
-rw-r--r--source/blender/collada/GeometryExporter.cpp86
-rw-r--r--source/blender/collada/GeometryExporter.h3
-rw-r--r--source/blender/collada/MeshImporter.cpp115
-rw-r--r--source/blender/collada/MeshImporter.h14
-rw-r--r--source/blender/collada/SceneExporter.cpp6
-rw-r--r--source/blender/collada/collada_utils.cpp2
-rw-r--r--source/blender/compositor/CMakeLists.txt60
-rw-r--r--source/blender/compositor/COM_compositor.h4
-rw-r--r--source/blender/compositor/COM_defines.h11
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.cpp2
-rw-r--r--source/blender/compositor/intern/COM_ChannelInfo.h10
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.h6
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp153
-rw-r--r--source/blender/compositor/intern/COM_Converter.h38
-rw-r--r--source/blender/compositor/intern/COM_Debug.cpp141
-rw-r--r--source/blender/compositor/intern/COM_Debug.h31
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp106
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.h49
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cpp210
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.h91
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp171
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystemHelper.h126
-rw-r--r--source/blender/compositor/intern/COM_InputSocket.cpp159
-rw-r--r--source/blender/compositor/intern/COM_InputSocket.h149
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cpp25
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h1
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.h1
-rw-r--r--source/blender/compositor/intern/COM_Node.cpp235
-rw-r--r--source/blender/compositor/intern/COM_Node.h234
-rw-r--r--source/blender/compositor/intern/COM_NodeBase.cpp96
-rw-r--r--source/blender/compositor/intern/COM_NodeBase.h185
-rw-r--r--source/blender/compositor/intern/COM_NodeConverter.cpp158
-rw-r--r--source/blender/compositor/intern/COM_NodeConverter.h114
-rw-r--r--source/blender/compositor/intern/COM_NodeGraph.cpp290
-rw-r--r--source/blender/compositor/intern/COM_NodeGraph.h115
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cpp138
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h175
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cpp666
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.h158
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cpp4
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.h2
-rw-r--r--source/blender/compositor/intern/COM_OutputSocket.cpp119
-rw-r--r--source/blender/compositor/intern/COM_OutputSocket.h84
-rw-r--r--source/blender/compositor/intern/COM_SingleThreadedOperation.cpp (renamed from source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp)12
-rw-r--r--source/blender/compositor/intern/COM_SingleThreadedOperation.h (renamed from source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h)8
-rw-r--r--source/blender/compositor/intern/COM_Socket.cpp68
-rw-r--r--source/blender/compositor/intern/COM_Socket.h100
-rw-r--r--source/blender/compositor/intern/COM_SocketConnection.cpp95
-rw-r--r--source/blender/compositor/intern/COM_SocketConnection.h127
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp12
-rw-r--r--source/blender/compositor/intern/COM_compositor.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_AlphaOverNode.cpp24
-rw-r--r--source/blender/compositor/nodes/COM_AlphaOverNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BilateralBlurNode.cpp14
-rw-r--r--source/blender/compositor/nodes/COM_BilateralBlurNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.cpp98
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BokehBlurNode.cpp39
-rw-r--r--source/blender/compositor/nodes/COM_BokehBlurNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BokehImageNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_BokehImageNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BoxMaskNode.cpp40
-rw-r--r--source/blender/compositor/nodes/COM_BoxMaskNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_BrightnessNode.cpp13
-rw-r--r--source/blender/compositor/nodes/COM_BrightnessNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ChannelMatteNode.cpp56
-rw-r--r--source/blender/compositor/nodes/COM_ChannelMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ChromaMatteNode.cpp58
-rw-r--r--source/blender/compositor/nodes/COM_ChromaMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorBalanceNode.cpp19
-rw-r--r--source/blender/compositor/nodes/COM_ColorBalanceNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp14
-rw-r--r--source/blender/compositor/nodes/COM_ColorCorrectionNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorCurveNode.cpp34
-rw-r--r--source/blender/compositor/nodes/COM_ColorCurveNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorMatteNode.cpp57
-rw-r--r--source/blender/compositor/nodes/COM_ColorMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorNode.cpp9
-rw-r--r--source/blender/compositor/nodes/COM_ColorNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorRampNode.cpp29
-rw-r--r--source/blender/compositor/nodes/COM_ColorRampNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorSpillNode.cpp21
-rw-r--r--source/blender/compositor/nodes/COM_ColorSpillNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ColorToBWNode.cpp13
-rw-r--r--source/blender/compositor/nodes/COM_ColorToBWNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_CombineColorNode.cpp96
-rw-r--r--source/blender/compositor/nodes/COM_CombineColorNode.h74
-rw-r--r--source/blender/compositor/nodes/COM_CombineHSVANode.cpp46
-rw-r--r--source/blender/compositor/nodes/COM_CombineHSVANode.h38
-rw-r--r--source/blender/compositor/nodes/COM_CombineRGBANode.cpp64
-rw-r--r--source/blender/compositor/nodes/COM_CombineYCCANode.cpp45
-rw-r--r--source/blender/compositor/nodes/COM_CombineYCCANode.h37
-rw-r--r--source/blender/compositor/nodes/COM_CombineYUVANode.cpp40
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.cpp37
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp12
-rw-r--r--source/blender/compositor/nodes/COM_ConvertAlphaNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_CornerPinNode.cpp58
-rw-r--r--source/blender/compositor/nodes/COM_CornerPinNode.h (renamed from source/blender/compositor/nodes/COM_CombineYUVANode.h)24
-rw-r--r--source/blender/compositor/nodes/COM_CropNode.cpp9
-rw-r--r--source/blender/compositor/nodes/COM_CropNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DefocusNode.cpp96
-rw-r--r--source/blender/compositor/nodes/COM_DefocusNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DespeckleNode.cpp25
-rw-r--r--source/blender/compositor/nodes/COM_DespeckleNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp32
-rw-r--r--source/blender/compositor/nodes/COM_DifferenceMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DilateErodeNode.cpp101
-rw-r--r--source/blender/compositor/nodes/COM_DilateErodeNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp12
-rw-r--r--source/blender/compositor/nodes/COM_DirectionalBlurNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DisplaceNode.cpp17
-rw-r--r--source/blender/compositor/nodes/COM_DisplaceNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DistanceMatteNode.cpp83
-rw-r--r--source/blender/compositor/nodes/COM_DistanceMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_EllipseMaskNode.cpp42
-rw-r--r--source/blender/compositor/nodes/COM_EllipseMaskNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_FilterNode.cpp20
-rw-r--r--source/blender/compositor/nodes/COM_FilterNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_FlipNode.cpp12
-rw-r--r--source/blender/compositor/nodes/COM_FlipNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_GammaNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_GammaNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_GlareNode.cpp46
-rw-r--r--source/blender/compositor/nodes/COM_GlareNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_GroupNode.cpp216
-rw-r--r--source/blender/compositor/nodes/COM_GroupNode.h61
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp38
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp38
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_IDMaskNode.cpp19
-rw-r--r--source/blender/compositor/nodes/COM_IDMaskNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp170
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_InpaintNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_InpaintNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_InvertNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_InvertNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.cpp276
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.h22
-rw-r--r--source/blender/compositor/nodes/COM_KeyingScreenNode.cpp22
-rw-r--r--source/blender/compositor/nodes/COM_KeyingScreenNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_LensDistortionNode.cpp33
-rw-r--r--source/blender/compositor/nodes/COM_LensDistortionNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp39
-rw-r--r--source/blender/compositor/nodes/COM_LuminanceMatteNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MapRangeNode.cpp34
-rw-r--r--source/blender/compositor/nodes/COM_MapRangeNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MapUVNode.cpp15
-rw-r--r--source/blender/compositor/nodes/COM_MapUVNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MapValueNode.cpp15
-rw-r--r--source/blender/compositor/nodes/COM_MapValueNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MaskNode.cpp16
-rw-r--r--source/blender/compositor/nodes/COM_MaskNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MathNode.cpp21
-rw-r--r--source/blender/compositor/nodes/COM_MathNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.cpp25
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MovieClipNode.cpp78
-rw-r--r--source/blender/compositor/nodes/COM_MovieClipNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MovieDistortionNode.cpp15
-rw-r--r--source/blender/compositor/nodes/COM_MovieDistortionNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_MuteNode.cpp175
-rw-r--r--source/blender/compositor/nodes/COM_MuteNode.h51
-rw-r--r--source/blender/compositor/nodes/COM_NormalNode.cpp27
-rw-r--r--source/blender/compositor/nodes/COM_NormalNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_NormalizeNode.cpp9
-rw-r--r--source/blender/compositor/nodes/COM_NormalizeNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.cpp48
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_PixelateNode.cpp21
-rw-r--r--source/blender/compositor/nodes/COM_PixelateNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp65
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.cpp101
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_RotateNode.cpp21
-rw-r--r--source/blender/compositor/nodes/COM_RotateNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ScaleNode.cpp71
-rw-r--r--source/blender/compositor/nodes/COM_ScaleNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_SeparateColorNode.cpp120
-rw-r--r--source/blender/compositor/nodes/COM_SeparateColorNode.h74
-rw-r--r--source/blender/compositor/nodes/COM_SeparateHSVANode.cpp44
-rw-r--r--source/blender/compositor/nodes/COM_SeparateHSVANode.h39
-rw-r--r--source/blender/compositor/nodes/COM_SeparateRGBANode.cpp76
-rw-r--r--source/blender/compositor/nodes/COM_SeparateYCCANode.cpp46
-rw-r--r--source/blender/compositor/nodes/COM_SeparateYUVANode.cpp42
-rw-r--r--source/blender/compositor/nodes/COM_SeparateYUVANode.h38
-rw-r--r--source/blender/compositor/nodes/COM_SetAlphaNode.cpp16
-rw-r--r--source/blender/compositor/nodes/COM_SetAlphaNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.cpp94
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.h13
-rw-r--r--source/blender/compositor/nodes/COM_SplitViewerNode.cpp25
-rw-r--r--source/blender/compositor/nodes/COM_SplitViewerNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_Stabilize2dNode.cpp61
-rw-r--r--source/blender/compositor/nodes/COM_Stabilize2dNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_SwitchNode.cpp26
-rw-r--r--source/blender/compositor/nodes/COM_SwitchNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TextureNode.cpp37
-rw-r--r--source/blender/compositor/nodes/COM_TextureNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TonemapNode.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_TonemapNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TrackPositionNode.cpp27
-rw-r--r--source/blender/compositor/nodes/COM_TrackPositionNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TransformNode.cpp47
-rw-r--r--source/blender/compositor/nodes/COM_TransformNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_TranslateNode.cpp53
-rw-r--r--source/blender/compositor/nodes/COM_TranslateNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ValueNode.cpp9
-rw-r--r--source/blender/compositor/nodes/COM_ValueNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_VectorBlurNode.cpp17
-rw-r--r--source/blender/compositor/nodes/COM_VectorBlurNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_VectorCurveNode.cpp12
-rw-r--r--source/blender/compositor/nodes/COM_VectorCurveNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ViewLevelsNode.cpp52
-rw-r--r--source/blender/compositor/nodes/COM_ViewLevelsNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.cpp38
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.h2
-rw-r--r--source/blender/compositor/nodes/COM_ZCombineNode.cpp96
-rw-r--r--source/blender/compositor/nodes/COM_ZCombineNode.h2
-rw-r--r--source/blender/compositor/operations/COM_BlurBaseOperation.cpp38
-rw-r--r--source/blender/compositor/operations/COM_BlurBaseOperation.h7
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cpp18
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_DisplaceOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp38
-rw-r--r--source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MapRangeOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.cpp13
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_MixOperation.cpp16
-rw-r--r--source/blender/compositor/operations/COM_OpenCLKernels.cl8
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp24
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.h13
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp223
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.h (renamed from source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h)43
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp (renamed from source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp)105
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h (renamed from source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h)32
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp70
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cpp (renamed from source/blender/compositor/operations/COM_PlaneTrackCommonOperation.cpp)68
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h (renamed from source/blender/compositor/operations/COM_PlaneTrackCommonOperation.h)54
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.cpp3
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.h1
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cpp10
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.cpp8
-rw-r--r--source/blender/compositor/operations/COM_SetVectorOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_SocketProxyOperation.cpp18
-rw-r--r--source/blender/compositor/operations/COM_SocketProxyOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_SplitOperation.cpp1
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp24
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.h3
-rw-r--r--[-rwxr-xr-x]source/blender/datatoc/datatoc_icon.py0
-rw-r--r--[-rwxr-xr-x]source/blender/datatoc/datatoc_icon_split.py3
-rw-r--r--[-rwxr-xr-x]source/blender/datatoc/datatoc_icon_split_to_png.py0
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c447
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c141
-rw-r--r--source/blender/editors/animation/anim_deps.c4
-rw-r--r--source/blender/editors/animation/anim_draw.c6
-rw-r--r--source/blender/editors/animation/anim_filter.c15
-rw-r--r--source/blender/editors/animation/anim_markers.c38
-rw-r--r--source/blender/editors/animation/anim_ops.c21
-rw-r--r--source/blender/editors/animation/drivers.c33
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c88
-rw-r--r--source/blender/editors/animation/keyframes_draw.c221
-rw-r--r--source/blender/editors/animation/keyframes_edit.c201
-rw-r--r--source/blender/editors/animation/keyframes_general.c3
-rw-r--r--source/blender/editors/animation/keyframing.c87
-rw-r--r--source/blender/editors/animation/keyingsets.c22
-rw-r--r--source/blender/editors/armature/armature_add.c8
-rw-r--r--source/blender/editors/armature/armature_edit.c66
-rw-r--r--source/blender/editors/armature/armature_intern.h1
-rw-r--r--source/blender/editors/armature/armature_naming.c2
-rw-r--r--source/blender/editors/armature/armature_ops.c47
-rw-r--r--source/blender/editors/armature/armature_relations.c7
-rw-r--r--source/blender/editors/armature/armature_select.c12
-rw-r--r--source/blender/editors/armature/armature_skinning.c12
-rw-r--r--source/blender/editors/armature/armature_utils.c27
-rw-r--r--source/blender/editors/armature/editarmature_generate.c4
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c19
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c3
-rw-r--r--source/blender/editors/armature/meshlaplacian.c49
-rw-r--r--source/blender/editors/armature/pose_edit.c81
-rw-r--r--source/blender/editors/armature/pose_group.c10
-rw-r--r--source/blender/editors/armature/pose_lib.c4
-rw-r--r--source/blender/editors/armature/pose_select.c7
-rw-r--r--source/blender/editors/armature/pose_slide.c14
-rw-r--r--source/blender/editors/armature/pose_transform.c12
-rw-r--r--source/blender/editors/armature/reeb.c28
-rw-r--r--source/blender/editors/curve/curve_ops.c16
-rw-r--r--source/blender/editors/curve/editcurve.c330
-rw-r--r--source/blender/editors/curve/editfont.c108
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt3
-rw-r--r--source/blender/editors/datafiles/SConscript1
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c11
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c37
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c24
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c34
-rw-r--r--source/blender/editors/include/BIF_gl.h9
-rw-r--r--source/blender/editors/include/ED_anim_api.h43
-rw-r--r--source/blender/editors/include/ED_armature.h10
-rw-r--r--source/blender/editors/include/ED_buttons.h1
-rw-r--r--source/blender/editors/include/ED_clip.h2
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_datafiles.h3
-rw-r--r--source/blender/editors/include/ED_gpencil.h2
-rw-r--r--source/blender/editors/include/ED_image.h4
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h13
-rw-r--r--source/blender/editors/include/ED_keyframing.h23
-rw-r--r--source/blender/editors/include/ED_markers.h2
-rw-r--r--source/blender/editors/include/ED_mask.h6
-rw-r--r--source/blender/editors/include/ED_mesh.h7
-rw-r--r--source/blender/editors/include/ED_node.h2
-rw-r--r--source/blender/editors/include/ED_numinput.h12
-rw-r--r--source/blender/editors/include/ED_object.h4
-rw-r--r--source/blender/editors/include/ED_screen.h8
-rw-r--r--source/blender/editors/include/ED_sculpt.h12
-rw-r--r--source/blender/editors/include/ED_transform.h2
-rw-r--r--source/blender/editors/include/ED_transverts.h17
-rw-r--r--source/blender/editors/include/ED_util.h7
-rw-r--r--source/blender/editors/include/ED_uvedit.h3
-rw-r--r--source/blender/editors/include/ED_view3d.h9
-rw-r--r--source/blender/editors/include/UI_icons.h40
-rw-r--r--source/blender/editors/include/UI_interface.h11
-rw-r--r--source/blender/editors/include/UI_resources.h3
-rw-r--r--source/blender/editors/include/UI_view2d.h39
-rw-r--r--source/blender/editors/interface/interface.c313
-rw-r--r--source/blender/editors/interface/interface_anim.c11
-rw-r--r--source/blender/editors/interface/interface_draw.c345
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c11
-rw-r--r--source/blender/editors/interface/interface_handlers.c966
-rw-r--r--source/blender/editors/interface/interface_icons.c23
-rw-r--r--source/blender/editors/interface/interface_intern.h20
-rw-r--r--source/blender/editors/interface/interface_layout.c101
-rw-r--r--source/blender/editors/interface/interface_ops.c90
-rw-r--r--source/blender/editors/interface/interface_panel.c69
-rw-r--r--source/blender/editors/interface/interface_regions.c254
-rw-r--r--source/blender/editors/interface/interface_style.c6
-rw-r--r--source/blender/editors/interface/interface_templates.c302
-rw-r--r--source/blender/editors/interface/interface_utils.c11
-rw-r--r--source/blender/editors/interface/interface_widgets.c374
-rw-r--r--source/blender/editors/interface/resources.c93
-rw-r--r--source/blender/editors/interface/view2d.c321
-rw-r--r--source/blender/editors/interface/view2d_ops.c215
-rw-r--r--source/blender/editors/io/io_collada.c46
-rw-r--r--source/blender/editors/mask/mask_add.c215
-rw-r--r--source/blender/editors/mask/mask_draw.c224
-rw-r--r--source/blender/editors/mask/mask_edit.c44
-rw-r--r--source/blender/editors/mask/mask_editaction.c14
-rw-r--r--source/blender/editors/mask/mask_intern.h18
-rw-r--r--source/blender/editors/mask/mask_ops.c932
-rw-r--r--source/blender/editors/mask/mask_relationships.c5
-rw-r--r--source/blender/editors/mask/mask_select.c70
-rw-r--r--source/blender/editors/mask/mask_shapekey.c18
-rw-r--r--source/blender/editors/mesh/editface.c5
-rw-r--r--source/blender/editors/mesh/editmesh_add.c1
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c1
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c52
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c2
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c6
-rw-r--r--source/blender/editors/mesh/editmesh_path.c30
-rw-r--r--source/blender/editors/mesh/editmesh_select.c395
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c137
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c29
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c4
-rw-r--r--source/blender/editors/mesh/meshtools.c293
-rw-r--r--source/blender/editors/metaball/mball_edit.c3
-rw-r--r--source/blender/editors/metaball/mball_ops.c6
-rw-r--r--source/blender/editors/object/CMakeLists.txt2
-rw-r--r--source/blender/editors/object/object_add.c131
-rw-r--r--source/blender/editors/object/object_bake.c17
-rw-r--r--source/blender/editors/object/object_bake_api.c1109
-rw-r--r--source/blender/editors/object/object_constraint.c55
-rw-r--r--source/blender/editors/object/object_edit.c28
-rw-r--r--source/blender/editors/object/object_group.c8
-rw-r--r--source/blender/editors/object/object_hook.c92
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_lattice.c4
-rw-r--r--source/blender/editors/object/object_lod.c12
-rw-r--r--source/blender/editors/object/object_modifier.c109
-rw-r--r--source/blender/editors/object/object_ops.c41
-rw-r--r--source/blender/editors/object/object_random.c148
-rw-r--r--source/blender/editors/object/object_relations.c158
-rw-r--r--source/blender/editors/object/object_select.c23
-rw-r--r--source/blender/editors/object/object_shapekey.c4
-rw-r--r--source/blender/editors/object/object_transform.c50
-rw-r--r--source/blender/editors/object/object_vgroup.c27
-rw-r--r--source/blender/editors/object/object_warp.c14
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c2
-rw-r--r--source/blender/editors/physics/particle_boids.c1
-rw-r--r--source/blender/editors/physics/particle_edit.c84
-rw-r--r--source/blender/editors/physics/particle_object.c8
-rw-r--r--source/blender/editors/physics/physics_fluid.c41
-rw-r--r--source/blender/editors/physics/physics_ops.c12
-rw-r--r--source/blender/editors/physics/physics_pointcache.c9
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c5
-rw-r--r--source/blender/editors/physics/rigidbody_object.c1
-rw-r--r--source/blender/editors/physics/rigidbody_world.c9
-rw-r--r--source/blender/editors/render/render_internal.c63
-rw-r--r--source/blender/editors/render/render_opengl.c27
-rw-r--r--source/blender/editors/render/render_preview.c47
-rw-r--r--source/blender/editors/render/render_shading.c31
-rw-r--r--source/blender/editors/render/render_update.c27
-rw-r--r--source/blender/editors/render/render_view.c20
-rw-r--r--source/blender/editors/screen/area.c201
-rw-r--r--source/blender/editors/screen/glutil.c32
-rw-r--r--source/blender/editors/screen/screen_context.c7
-rw-r--r--source/blender/editors/screen/screen_edit.c58
-rw-r--r--source/blender/editors/screen/screen_intern.h5
-rw-r--r--source/blender/editors/screen/screen_ops.c152
-rw-r--r--source/blender/editors/screen/screendump.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c51
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c23
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c103
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c40
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c187
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h20
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c40
-rw-r--r--source/blender/editors/sculpt_paint/paint_undo.c71
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c188
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c118
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c758
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c87
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c55
-rw-r--r--source/blender/editors/sound/sound_ops.c25
-rw-r--r--source/blender/editors/space_action/action_draw.c1
-rw-r--r--source/blender/editors/space_action/action_edit.c99
-rw-r--r--source/blender/editors/space_action/action_ops.c54
-rw-r--r--source/blender/editors/space_action/action_select.c7
-rw-r--r--source/blender/editors/space_action/space_action.c24
-rw-r--r--source/blender/editors/space_api/spacetypes.c6
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c111
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c44
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c5
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c39
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c15
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c11
-rw-r--r--source/blender/editors/space_clip/clip_draw.c73
-rw-r--r--source/blender/editors/space_clip/clip_editor.c55
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c15
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c33
-rw-r--r--source/blender/editors/space_clip/clip_intern.h1
-rw-r--r--source/blender/editors/space_clip/clip_ops.c86
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c2
-rw-r--r--source/blender/editors/space_clip/clip_utils.c6
-rw-r--r--source/blender/editors/space_clip/space_clip.c84
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c101
-rw-r--r--source/blender/editors/space_clip/tracking_select.c43
-rw-r--r--source/blender/editors/space_console/console_draw.c7
-rw-r--r--source/blender/editors/space_console/console_ops.c9
-rw-r--r--source/blender/editors/space_console/space_console.c14
-rw-r--r--source/blender/editors/space_file/file_draw.c1
-rw-r--r--source/blender/editors/space_file/file_ops.c83
-rw-r--r--source/blender/editors/space_file/file_panels.c24
-rw-r--r--source/blender/editors/space_file/filelist.c23
-rw-r--r--source/blender/editors/space_file/filesel.c25
-rw-r--r--source/blender/editors/space_file/fsmenu.c6
-rw-r--r--source/blender/editors/space_file/space_file.c31
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c179
-rw-r--r--source/blender/editors/space_graph/graph_draw.c29
-rw-r--r--source/blender/editors/space_graph/graph_edit.c138
-rw-r--r--source/blender/editors/space_graph/graph_intern.h4
-rw-r--r--source/blender/editors/space_graph/graph_ops.c95
-rw-r--r--source/blender/editors/space_graph/graph_select.c151
-rw-r--r--source/blender/editors/space_graph/space_graph.c4
-rw-r--r--source/blender/editors/space_image/image_buttons.c83
-rw-r--r--source/blender/editors/space_image/image_draw.c76
-rw-r--r--source/blender/editors/space_image/image_edit.c14
-rw-r--r--source/blender/editors/space_image/image_intern.h9
-rw-r--r--source/blender/editors/space_image/image_ops.c281
-rw-r--r--source/blender/editors/space_image/space_image.c129
-rw-r--r--source/blender/editors/space_info/info_draw.c17
-rw-r--r--source/blender/editors/space_info/info_report.c12
-rw-r--r--source/blender/editors/space_info/info_stats.c3
-rw-r--r--source/blender/editors/space_info/space_info.c1
-rw-r--r--source/blender/editors/space_info/textview.c9
-rw-r--r--source/blender/editors/space_logic/logic_ops.c10
-rw-r--r--source/blender/editors/space_logic/logic_window.c589
-rw-r--r--source/blender/editors/space_logic/space_logic.c3
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c65
-rw-r--r--source/blender/editors/space_nla/nla_channels.c101
-rw-r--r--source/blender/editors/space_nla/nla_draw.c239
-rw-r--r--source/blender/editors/space_nla/nla_edit.c246
-rw-r--r--source/blender/editors/space_nla/nla_intern.h8
-rw-r--r--source/blender/editors/space_nla/nla_ops.c48
-rw-r--r--source/blender/editors/space_nla/nla_select.c37
-rw-r--r--source/blender/editors/space_nla/space_nla.c1
-rw-r--r--source/blender/editors/space_node/drawnode.c338
-rw-r--r--source/blender/editors/space_node/node_add.c2
-rw-r--r--source/blender/editors/space_node/node_buttons.c20
-rw-r--r--source/blender/editors/space_node/node_draw.c21
-rw-r--r--source/blender/editors/space_node/node_edit.c114
-rw-r--r--source/blender/editors/space_node/node_group.c25
-rw-r--r--source/blender/editors/space_node/node_ops.c35
-rw-r--r--source/blender/editors/space_node/node_relationships.c323
-rw-r--r--source/blender/editors/space_node/node_select.c45
-rw-r--r--source/blender/editors/space_node/node_templates.c26
-rw-r--r--source/blender/editors/space_node/node_view.c40
-rw-r--r--source/blender/editors/space_node/space_node.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c32
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h5
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c24
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c39
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c20
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c4
-rw-r--r--source/blender/editors/space_script/script_edit.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c103
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c100
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c216
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c113
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c71
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c12
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c12
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_text/space_text.c29
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c8
-rw-r--r--source/blender/editors/space_text/text_draw.c8
-rw-r--r--source/blender/editors/space_text/text_format.h2
-rw-r--r--source/blender/editors/space_text/text_format_lua.c2
-rw-r--r--source/blender/editors/space_text/text_format_osl.c2
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_header.c12
-rw-r--r--source/blender/editors/space_text/text_ops.c35
-rw-r--r--source/blender/editors/space_time/space_time.c13
-rw-r--r--source/blender/editors/space_time/time_ops.c1
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c17
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c82
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c118
-rw-r--r--source/blender/editors/space_view3d/drawobject.c345
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c32
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c44
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c608
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c916
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c150
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c26
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h46
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c160
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c59
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c256
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c180
-rw-r--r--source/blender/editors/transform/transform.c360
-rw-r--r--source/blender/editors/transform/transform.h40
-rw-r--r--source/blender/editors/transform/transform_constraints.c18
-rw-r--r--source/blender/editors/transform/transform_conversions.c685
-rw-r--r--source/blender/editors/transform/transform_generics.c283
-rw-r--r--source/blender/editors/transform/transform_input.c6
-rw-r--r--source/blender/editors/transform/transform_manipulator.c242
-rw-r--r--source/blender/editors/transform/transform_ops.c31
-rw-r--r--source/blender/editors/transform/transform_orientations.c45
-rw-r--r--source/blender/editors/transform/transform_snap.c67
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_transverts.c90
-rw-r--r--source/blender/editors/util/ed_util.c10
-rw-r--r--source/blender/editors/util/editmode_undo.c6
-rw-r--r--source/blender/editors/util/numinput.c155
-rw-r--r--source/blender/editors/util/undo.c80
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c15
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c150
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c20
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.h4
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c86
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c23
-rw-r--r--source/blender/freestyle/CMakeLists.txt11
-rw-r--r--source/blender/freestyle/intern/application/AppConfig.cpp1
-rw-r--r--source/blender/freestyle/intern/application/AppConfig.h1
-rw-r--r--source/blender/freestyle/intern/application/AppView.h2
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp22
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp4
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp420
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h6
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h3
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp101
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp10
-rw-r--r--source/blender/freestyle/intern/geometry/Bezier.h4
-rw-r--r--source/blender/freestyle/intern/geometry/FastGrid.cpp23
-rw-r--r--source/blender/freestyle/intern/geometry/FastGrid.h4
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.cpp13
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.h2
-rw-r--r--source/blender/freestyle/intern/geometry/GeomCleaner.h2
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp8
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.h21
-rw-r--r--source/blender/freestyle/intern/geometry/Grid.cpp5
-rw-r--r--source/blender/freestyle/intern/geometry/Grid.h6
-rw-r--r--source/blender/freestyle/intern/geometry/GridHelpers.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/HashGrid.h2
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.h2
-rw-r--r--source/blender/freestyle/intern/geometry/VecMat.h3
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.h1
-rw-r--r--source/blender/freestyle/intern/geometry/normal_cycle.h2
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.h2
-rw-r--r--source/blender/freestyle/intern/image/ImagePyramid.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_BBox.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ContextFunctions.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.h3
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp19
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsNoise.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.h3
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.cpp52
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.cpp12
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/Director.cpp24
-rw-r--r--source/blender/freestyle/intern/python/Director.h14
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp14
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h4
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h6
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h3
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h6
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h6
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h7
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp125
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h57
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp114
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h55
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/LineRep.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/Node.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeCamera.h6
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h4
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeGroup.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeLight.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeShape.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeTransform.cpp2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeTransform.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/OrientedLineRep.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/Rep.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneVisitor.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/TriangleRep.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/VertexRep.h2
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h12
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h12
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h12
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp93
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.h110
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/ChainingIterators.cpp14
-rw-r--r--source/blender/freestyle/intern/stroke/ChainingIterators.h24
-rw-r--r--source/blender/freestyle/intern/stroke/ContextFunctions.h9
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.cpp11
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.h8
-rw-r--r--source/blender/freestyle/intern/stroke/CurveIterators.h14
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.cpp14
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.h2
-rw-r--r--source/blender/freestyle/intern/stroke/PSStrokeRenderer.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates0D.cpp (renamed from source/blender/render/intern/include/gammaCorrectionTables.h)40
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates0D.h16
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates1D.cpp (renamed from source/blender/compositor/nodes/COM_SeparateYCCANode.h)39
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates1D.h16
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp17
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h48
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeIO.h3
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeIterators.h14
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.h6
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp287
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.h54
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeShader.cpp (renamed from source/blender/compositor/nodes/COM_SeparateRGBANode.h)35
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeShader.h13
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeTesselator.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/TextStrokeRenderer.h2
-rw-r--r--source/blender/freestyle/intern/system/BaseObject.h4
-rw-r--r--source/blender/freestyle/intern/system/Exception.h4
-rw-r--r--source/blender/freestyle/intern/system/FreestyleConfig.h40
-rw-r--r--source/blender/freestyle/intern/system/Interpreter.h4
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.cpp1
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.h3
-rw-r--r--source/blender/freestyle/intern/system/PythonInterpreter.cpp7
-rw-r--r--source/blender/freestyle/intern/system/PythonInterpreter.h66
-rw-r--r--source/blender/freestyle/intern/system/RandGen.h4
-rw-r--r--source/blender/freestyle/intern/system/StringUtils.h7
-rw-r--r--source/blender/freestyle/intern/system/TimeStamp.cpp1
-rw-r--r--source/blender/freestyle/intern/system/TimeStamp.h4
-rw-r--r--source/blender/freestyle/intern/system/TimeUtils.h2
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.h2
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp1
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h4
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.cpp6
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.h51
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.h65
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.cpp123
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.h104
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.cpp75
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.h47
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.h14
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp7
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h2
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h2
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.h2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h12
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h18
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp256
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.cpp14
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.h8
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIterators.h12
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h2
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp7
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.h14
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.cpp1
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.h17
-rw-r--r--source/blender/freestyle/intern/winged_edge/WFillGrid.h2
-rw-r--r--source/blender/freestyle/intern/winged_edge/WSFillGrid.h2
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.cpp70
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.h2
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h2
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h2
-rw-r--r--source/blender/gpu/CMakeLists.txt4
-rw-r--r--source/blender/gpu/GPU_buffers.h36
-rw-r--r--source/blender/gpu/GPU_draw.h8
-rw-r--r--source/blender/gpu/GPU_extensions.h2
-rw-r--r--source/blender/gpu/GPU_material.h18
-rw-r--r--source/blender/gpu/GPU_raster.h1
-rw-r--r--source/blender/gpu/SConscript2
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c374
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c52
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h3
-rw-r--r--source/blender/gpu/intern/gpu_draw.c60
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c6
-rw-r--r--source/blender/gpu/intern/gpu_material.c51
-rw-r--r--source/blender/gpu/intern/gpu_raster.c13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl43
-rw-r--r--source/blender/ikplugin/SConscript5
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c4
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp4
-rw-r--r--source/blender/imbuf/IMB_imbuf.h24
-rw-r--r--source/blender/imbuf/intern/IMB_allocimbuf.h3
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c24
-rw-r--r--source/blender/imbuf/intern/anim_movie.c27
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c5
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c5
-rw-r--r--source/blender/imbuf/intern/colormanagement.c41
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp16
-rw-r--r--source/blender/imbuf/intern/divers.c143
-rw-r--r--source/blender/imbuf/intern/filter.c6
-rw-r--r--source/blender/imbuf/intern/imageprocess.c3
-rw-r--r--source/blender/imbuf/intern/imbuf.h3
-rw-r--r--source/blender/imbuf/intern/indexer.c30
-rw-r--r--source/blender/imbuf/intern/indexer_dv.c4
-rw-r--r--source/blender/imbuf/intern/iris.c2
-rw-r--r--source/blender/imbuf/intern/jp2.c12
-rw-r--r--source/blender/imbuf/intern/jpeg.c17
-rw-r--r--source/blender/imbuf/intern/module.c6
-rw-r--r--source/blender/imbuf/intern/moviecache.c26
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp26
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c1
-rw-r--r--source/blender/imbuf/intern/readimage.c12
-rw-r--r--source/blender/imbuf/intern/scaling.c34
-rw-r--r--source/blender/imbuf/intern/targa.c13
-rw-r--r--source/blender/imbuf/intern/thumbs.c57
-rw-r--r--source/blender/imbuf/intern/tiff.c2
-rw-r--r--source/blender/imbuf/intern/util.c28
-rw-r--r--source/blender/imbuf/intern/writeimage.c6
-rw-r--r--source/blender/makesdna/DNA_action_types.h6
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h3
-rw-r--r--source/blender/makesdna/DNA_anim_types.h3
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h18
-rw-r--r--source/blender/makesdna/DNA_controller_types.h1
-rw-r--r--source/blender/makesdna/DNA_curve_types.h49
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h14
-rw-r--r--source/blender/makesdna/DNA_linestyle_types.h34
-rw-r--r--source/blender/makesdna/DNA_material_types.h8
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h8
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h39
-rw-r--r--source/blender/makesdna/DNA_object_types.h17
-rw-r--r--source/blender/makesdna/DNA_particle_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h136
-rw-r--r--source/blender/makesdna/DNA_screen_types.h19
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/makesdna/DNA_texture_types.h1
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h20
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h31
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h9
-rw-r--r--source/blender/makesdna/intern/SConscript10
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c51
-rw-r--r--source/blender/makesdna/intern/makesdna.c22
-rw-r--r--source/blender/makesrna/RNA_access.h40
-rw-r--r--source/blender/makesrna/RNA_enum_types.h10
-rw-r--r--source/blender/makesrna/RNA_types.h30
-rw-r--r--source/blender/makesrna/intern/SConscript5
-rw-r--r--source/blender/makesrna/intern/makesrna.c46
-rw-r--r--source/blender/makesrna/intern/rna_ID.c6
-rw-r--r--source/blender/makesrna/intern/rna_access.c558
-rw-r--r--source/blender/makesrna/intern/rna_action.c8
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c11
-rw-r--r--source/blender/makesrna/intern/rna_animation.c2
-rw-r--r--source/blender/makesrna/intern/rna_armature.c17
-rw-r--r--source/blender/makesrna/intern/rna_armature_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_brush.c53
-rw-r--r--source/blender/makesrna/intern/rna_camera_api.c10
-rw-r--r--source/blender/makesrna/intern/rna_color.c25
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c157
-rw-r--r--source/blender/makesrna/intern/rna_controller.c5
-rw-r--r--source/blender/makesrna/intern/rna_curve.c74
-rw-r--r--source/blender/makesrna/intern/rna_define.c16
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c4
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c169
-rw-r--r--source/blender/makesrna/intern/rna_group.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c15
-rw-r--r--source/blender/makesrna/intern/rna_internal.h23
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c262
-rw-r--r--source/blender/makesrna/intern/rna_main.c2
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c218
-rw-r--r--source/blender/makesrna/intern/rna_mask.c100
-rw-r--r--source/blender/makesrna/intern/rna_material.c10
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c127
-rw-r--r--source/blender/makesrna/intern/rna_meta.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c473
-rw-r--r--source/blender/makesrna/intern/rna_nla.c29
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c149
-rw-r--r--source/blender/makesrna/intern/rna_object.c31
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_particle.c3
-rw-r--r--source/blender/makesrna/intern/rna_pose.c18
-rw-r--r--source/blender/makesrna/intern/rna_render.c171
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c4
-rw-r--r--source/blender/makesrna/intern/rna_rna.c30
-rw-r--r--source/blender/makesrna/intern/rna_scene.c277
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c7
-rw-r--r--source/blender/makesrna/intern/rna_screen.c19
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c26
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c5
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c89
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c143
-rw-r--r--source/blender/makesrna/intern/rna_space.c130
-rw-r--r--source/blender/makesrna/intern/rna_speaker.c14
-rw-r--r--source/blender/makesrna/intern/rna_texture.c3
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c10
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c117
-rw-r--r--source/blender/makesrna/intern/rna_ui.c8
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c127
-rw-r--r--source/blender/makesrna/intern/rna_vfont.c4
-rw-r--r--source/blender/makesrna/intern/rna_wm.c8
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c6
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/rna_cleanup/rna_cleaner.py0
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py0
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/rna_cleanup/rna_update.sh0
-rw-r--r--source/blender/modifiers/CMakeLists.txt9
-rw-r--r--source/blender/modifiers/intern/MOD_array.c26
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c4
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c102
-rw-r--r--source/blender/modifiers/intern/MOD_build.c1
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c1
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c2
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c3
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c2
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c2
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c9
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c3
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c2
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c67
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c41
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c14
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c1
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c25
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c3
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c15
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c18
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c2
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c1
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c2
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c4
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c24
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c119
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c7
-rw-r--r--source/blender/modifiers/intern/MOD_util.c1
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c4
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c1
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c5
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c2
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c3
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c5
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c8
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c6
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_composite.h1
-rw-r--r--source/blender/nodes/NOD_shader.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c8
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_common.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_cornerpin.c59
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c2
-rw-r--r--source/blender/nodes/intern/node_common.c62
-rw-r--r--source/blender/nodes/intern/node_exec.c5
-rw-r--r--source/blender/nodes/intern/node_exec.h2
-rw-r--r--source/blender/nodes/intern/node_socket.c1
-rw-r--r--source/blender/nodes/intern/node_util.c138
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c2
-rw-r--r--source/blender/nodes/shader/node_shader_util.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_camera.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.c29
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.c24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_path.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c118
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.c58
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectMath.c2
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c14
-rw-r--r--source/blender/nodes/texture/node_texture_util.c6
-rw-r--r--source/blender/nodes/texture/node_texture_util.h5
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_common.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_coord.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_distance.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_math.c11
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_viewer.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c20
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c1
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c2
-rw-r--r--source/blender/python/generic/bgl.c4
-rw-r--r--source/blender/python/generic/blf_py_api.c8
-rw-r--r--source/blender/python/generic/bpy_internal_import.c13
-rw-r--r--source/blender/python/generic/idprop_py_api.c19
-rw-r--r--source/blender/python/generic/py_capi_utils.c25
-rw-r--r--source/blender/python/generic/py_capi_utils.h4
-rw-r--r--source/blender/python/intern/bpy.c54
-rw-r--r--source/blender/python/intern/bpy_app_build_options.c1
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/bpy_driver.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c45
-rw-r--r--source/blender/python/intern/bpy_library.c1
-rw-r--r--source/blender/python/intern/bpy_operator.c10
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c2
-rw-r--r--source/blender/python/intern/bpy_props.c24
-rw-r--r--source/blender/python/intern/bpy_rna.c7
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c9
-rw-r--r--source/blender/python/intern/bpy_rna_array.c6
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c6
-rw-r--r--source/blender/python/intern/bpy_traceback.c34
-rw-r--r--source/blender/python/intern/bpy_util.c2
-rw-r--r--source/blender/python/intern/bpy_util.h4
-rw-r--r--source/blender/python/intern/gpu.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c308
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c154
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c4
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.c8
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c3
-rw-r--r--source/blender/quicktime/apple/qtkit_import.m2
-rw-r--r--source/blender/render/CMakeLists.txt5
-rw-r--r--source/blender/render/extern/include/RE_bake.h105
-rw-r--r--source/blender/render/extern/include/RE_engine.h4
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h17
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h11
-rw-r--r--source/blender/render/intern/include/initrender.h2
-rw-r--r--source/blender/render/intern/include/rayintersection.h2
-rw-r--r--source/blender/render/intern/include/rayobject.h1
-rw-r--r--source/blender/render/intern/include/render_result.h2
-rw-r--r--source/blender/render/intern/include/render_types.h5
-rw-r--r--source/blender/render/intern/include/renderdatabase.h9
-rw-r--r--source/blender/render/intern/include/texture.h4
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp37
-rw-r--r--source/blender/render/intern/raytrace/rayobject_blibvh.cpp169
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp4
-rw-r--r--source/blender/render/intern/raytrace/reorganize.h17
-rw-r--r--source/blender/render/intern/raytrace/svbvh.h3
-rw-r--r--source/blender/render/intern/source/bake.c11
-rw-r--r--source/blender/render/intern/source/bake_api.c867
-rw-r--r--source/blender/render/intern/source/convertblender.c487
-rw-r--r--source/blender/render/intern/source/envmap.c16
-rw-r--r--source/blender/render/intern/source/external_engine.c89
-rw-r--r--source/blender/render/intern/source/gammaCorrectionTables.c140
-rw-r--r--source/blender/render/intern/source/imagetexture.c21
-rw-r--r--source/blender/render/intern/source/initrender.c17
-rw-r--r--source/blender/render/intern/source/multires_bake.c45
-rw-r--r--source/blender/render/intern/source/occlusion.c4
-rw-r--r--source/blender/render/intern/source/pipeline.c157
-rw-r--r--source/blender/render/intern/source/pixelblending.c3
-rw-r--r--source/blender/render/intern/source/pixelshading.c15
-rw-r--r--source/blender/render/intern/source/pointdensity.c10
-rw-r--r--source/blender/render/intern/source/rayshade.c44
-rw-r--r--source/blender/render/intern/source/render_result.c49
-rw-r--r--source/blender/render/intern/source/render_texture.c90
-rw-r--r--source/blender/render/intern/source/rendercore.c47
-rw-r--r--source/blender/render/intern/source/renderdatabase.c10
-rw-r--r--source/blender/render/intern/source/shadbuf.c18
-rw-r--r--source/blender/render/intern/source/shadeinput.c31
-rw-r--r--source/blender/render/intern/source/shadeoutput.c19
-rw-r--r--source/blender/render/intern/source/sss.c5
-rw-r--r--source/blender/render/intern/source/strand.c8
-rw-r--r--source/blender/render/intern/source/sunsky.c5
-rw-r--r--source/blender/render/intern/source/texture_ocean.c2
-rw-r--r--source/blender/render/intern/source/volume_precache.c5
-rw-r--r--source/blender/render/intern/source/volumetric.c10
-rw-r--r--source/blender/render/intern/source/voxeldata.c8
-rw-r--r--source/blender/render/intern/source/zbuf.c42
-rw-r--r--source/blender/windowmanager/WM_api.h10
-rw-r--r--source/blender/windowmanager/WM_types.h14
-rw-r--r--source/blender/windowmanager/intern/wm.c1
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c4
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c5
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c20
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c203
-rw-r--r--source/blender/windowmanager/intern/wm_files.c95
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c10
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c11
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c45
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c12
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c273
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c167
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c83
-rw-r--r--source/blender/windowmanager/intern/wm_window.c36
-rw-r--r--source/blender/windowmanager/wm.h4
-rw-r--r--source/blender/windowmanager/wm_event_types.h4
-rw-r--r--source/blender/windowmanager/wm_subwindow.h15
-rw-r--r--source/blenderplayer/CMakeLists.txt5
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c33
-rw-r--r--source/creator/CMakeLists.txt74
-rw-r--r--source/creator/creator.c46
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp3
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp19
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h3
-rw-r--r--source/gameengine/Converter/BL_ArmatureActuator.cpp2
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp133
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.h24
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp458
-rw-r--r--source/gameengine/Converter/BL_ModifierDeformer.cpp26
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp38
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.h2
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp95
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h2
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.cpp3
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp151
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp8
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp19
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.h3
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp27
-rw-r--r--source/gameengine/Converter/KX_SoftBodyDeformer.cpp1
-rw-r--r--source/gameengine/Expressions/IfExpr.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h1
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp12
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp205
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp66
-rw-r--r--source/gameengine/Ketsji/BL_Action.h6
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp88
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h27
-rw-r--r--source/gameengine/Ketsji/BL_Material.h3
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt2
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h155
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp584
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp24
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h6
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp56
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h16
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp445
-rw-r--r--source/gameengine/Ketsji/KX_Light.h34
-rw-r--r--source/gameengine/Ketsji/KX_LightIpoSGController.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_LightIpoSGController.h2
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp167
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h1
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp35
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h9
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp542
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h15
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h20
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h5
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h23
-rw-r--r--source/gameengine/Rasterizer/CMakeLists.txt2
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp14
-rw-r--r--source/gameengine/Rasterizer/RAS_ILightObject.h (renamed from source/gameengine/Rasterizer/RAS_LightObject.h)31
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp3
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp276
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h (renamed from source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h)51
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp38
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h13
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp2
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp3
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp15
-rw-r--r--source/tests/CMakeLists.txt11
-rw-r--r--source/tests/bl_pyapi_mathutils.py38
-rw-r--r--source/tests/bl_rna_wiki_reference.py2
-rw-r--r--source/tests/bl_run_operators.py2
-rw-r--r--source/tests/pep8.py15
-rw-r--r--source/tests/rst_to_doctree_mini.py1
2391 files changed, 75077 insertions, 40943 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 461faf3de9b..65296731bed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -155,18 +155,7 @@ mark_as_advanced(WITH_HEADLESS)
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
mark_as_advanced(WITH_AUDASPACE)
-option(WITH_BOOL_COMPAT "Continue defining \"TRUE\" and \"FALSE\" until these can be replaced with \"true\" and \"false\" from stdbool.h" ON)
-mark_as_advanced(WITH_BOOL_COMPAT)
-
-# (unix defaults to OpenMP On)
-if((UNIX AND NOT APPLE) OR (MINGW))
- set(PLATFORM_DEFAULT ON)
-else()
- set(PLATFORM_DEFAULT OFF)
-endif()
-option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ${PLATFORM_DEFAULT})
-unset(PLATFORM_DEFAULT)
-
+option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
if(UNIX AND NOT APPLE)
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
@@ -267,13 +256,17 @@ option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install fol
set(PYTHON_NUMPY_PATH "" CACHE PATH "Python to python site-packages or dist-packages containing 'numpy' module")
mark_as_advanced(PYTHON_NUMPY_PATH)
+if(UNIX AND NOT APPLE)
+ option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
+endif()
+
# Cycles
option(WITH_CYCLES "Enable cycles Render Engine" ON)
option(WITH_CYCLES_STANDALONE "Build cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build cycles standalone with GUI" OFF)
option(WITH_CYCLES_OSL "Build Cycles with OSL support" OFF)
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
-set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 CACHE STRING "CUDA architectures to build binaries for")
+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)
@@ -545,16 +538,16 @@ TEST_STDBOOL_SUPPORT()
if(HAVE_STDBOOL_H)
add_definitions(-DHAVE_STDBOOL_H)
endif()
-if(WITH_BOOL_COMPAT)
- add_definitions(-DWITH_BOOL_COMPAT)
-endif()
#-----------------------------------------------------------------------------
# Check for valid directories
# ... a partial checkout may cause this.
+#
+# note: we need to check for a known subdir in both cases.
+# since uninitialized git submodules will give blank dirs
if(WITH_INTERNATIONAL)
- if(NOT EXISTS "${CMAKE_SOURCE_DIR}/release/datafiles/locale")
+ if(NOT EXISTS "${CMAKE_SOURCE_DIR}/release/datafiles/locale/languages")
message(WARNING "Translation path '${CMAKE_SOURCE_DIR}/release/datafiles/locale' is missing, "
"This is a 'git submodule', which are known not to work with bridges to other version "
"control systems, disabling 'WITH_INTERNATIONAL'.")
@@ -563,7 +556,7 @@ if(WITH_INTERNATIONAL)
endif()
if(WITH_PYTHON)
- if(NOT EXISTS "${CMAKE_SOURCE_DIR}/release/scripts/addons")
+ if(NOT EXISTS "${CMAKE_SOURCE_DIR}/release/scripts/addons/modules")
message(WARNING "Addons path '${CMAKE_SOURCE_DIR}/release/scripts/addons' is missing, "
"This is a 'git submodule', which are known not to work with bridges to other version "
"control systems: * CONTINUING WITHOUT ADDONS *")
@@ -603,14 +596,14 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
# For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
# On Unix:
# cmake ../blender \
-# -D PYTHON_VERSION=3.3 \
-# -D PYTHON_INCLUDE_DIR=/opt/py33/include/python3.3d \
-# -D PYTHON_LIBRARY=/opt/py33/lib/libpython3.3d.so
+# -D PYTHON_VERSION=3.4 \
+# -D PYTHON_INCLUDE_DIR=/opt/py34/include/python3.4d \
+# -D PYTHON_LIBRARY=/opt/py34/lib/libpython3.4d.so
#
# On Macs:
# cmake ../blender \
-# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.3/include/python3.3 \
-# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config \
+# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.4/include/python3.4 \
+# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/config \
# -G Xcode
#
# When changing any of this remember to update the notes in doc/build_systems/cmake.txt
@@ -638,7 +631,7 @@ if(UNIX AND NOT APPLE)
find_package_wrapper(Freetype REQUIRED)
if(WITH_PYTHON)
- # No way to set py33. remove for now.
+ # No way to set py34. remove for now.
# find_package(PythonLibs)
# Use our own instead, since wothout py is such a rare case,
@@ -867,6 +860,7 @@ if(UNIX AND NOT APPLE)
OUTPUT_VARIABLE LLVM_LIBPATH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LLVM_LIBPATH ${LLVM_LIBPATH} CACHE PATH "Path to the LLVM library path")
+ mark_as_advanced(LLVM_LIBPATH)
endif()
if(LLVM_STATIC)
@@ -1003,6 +997,7 @@ elseif(WIN32)
add_definitions(-DWIN32)
if(MSVC)
+
set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid psapi)
# MSVC11 SDL is not hard linked to dxguid.lib
@@ -1010,35 +1005,67 @@ elseif(WIN32)
set(PLATFORM_LINKLIBS ${PLATFORM_LINKLIBS} dxguid)
endif()
- add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB)
+ add_definitions(
+ -D_CRT_NONSTDC_NO_DEPRECATE
+ -D_CRT_SECURE_NO_DEPRECATE
+ -D_SCL_SECURE_NO_DEPRECATE
+ -D_CONSOLE
+ -D_LIB
+ )
# MSVC11 needs _ALLOW_KEYWORD_MACROS to build
- if(MSVC11 OR MSVC12)
- add_definitions(/D_ALLOW_KEYWORD_MACROS)
+ if(NOT MSVC_VERSION VERSION_LESS 1700)
+ add_definitions(-D_ALLOW_KEYWORD_MACROS)
+ endif()
+
+ if(CMAKE_CL_64)
+ # We want to support Vista level ABI for x64
+ if(NOT MSVC_VERSION VERSION_LESS 1700)
+ add_definitions(-D_WIN32_WINNT=0x600)
+ endif()
endif()
set(CMAKE_CXX_FLAGS "/nologo /J /Gd /EHsc /MP" CACHE STRING "MSVC MT C++ flags " FORCE)
set(CMAKE_C_FLAGS "/nologo /J /Gd /MP" CACHE STRING "MSVC MT C++ flags " FORCE)
if(CMAKE_CL_64)
- set(CMAKE_CXX_FLAGS_DEBUG "/Od /Gm /RTC1 /MTd /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
+ set(CMAKE_CXX_FLAGS_DEBUG "/Od /RTC1 /MTd /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
else()
- set(CMAKE_CXX_FLAGS_DEBUG "/Od /Gm /RTC1 /MTd /ZI /MP" CACHE STRING "MSVC MT flags " FORCE)
+ set(CMAKE_CXX_FLAGS_DEBUG "/Od /RTC1 /MTd /ZI /MP" CACHE STRING "MSVC MT flags " FORCE)
endif()
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /Ob2 /MT /MP" CACHE STRING "MSVC MT flags " FORCE)
set(CMAKE_CXX_FLAGS_MINSIZEREL "/O1 /Ob1 /MT /MP" CACHE STRING "MSVC MT flags " FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /MT /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
if(CMAKE_CL_64)
- set(CMAKE_C_FLAGS_DEBUG "/Od /Gm /RTC1 /MTd /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
+ set(CMAKE_C_FLAGS_DEBUG "/Od /RTC1 /MTd /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
else()
- set(CMAKE_C_FLAGS_DEBUG "/Od /Gm /RTC1 /MTd /ZI /MP" CACHE STRING "MSVC MT flags " FORCE)
+ set(CMAKE_C_FLAGS_DEBUG "/Od /RTC1 /MTd /ZI /MP" CACHE STRING "MSVC MT flags " FORCE)
endif()
set(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /MT /MP" CACHE STRING "MSVC MT flags " FORCE)
set(CMAKE_C_FLAGS_MINSIZEREL "/O1 /Ob1 /MT /MP" CACHE STRING "MSVC MT flags " FORCE)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /MT /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
# most msvc warnings are C & C++
- set(_WARNINGS "/W3 /wd4018 /wd4244 /wd4305 /wd4800 /wd4181 /wd4065 /wd4267 /we4013 /wd4200")
+ set(_WARNINGS
+ # warning level:
+ "/W3"
+ "/w34062" # switch statement contains 'default' but no 'case' labels
+ # disable:
+ "/wd4018" # signed/unsigned mismatch
+ "/wd4065" # switch statement contains 'default' but no 'case' labels
+ "/wd4127" # conditional expression is constant
+ "/wd4181" # qualifier applied to reference type; ignored
+ "/wd4200" # zero-sized array in struct/union
+ "/wd4244" # conversion from 'type1' to 'type2', possible loss of data
+ "/wd4267" # conversion from 'size_t' to 'type', possible loss of data
+ "/wd4305" # truncation from 'type1' to 'type2'
+ "/wd4800" # forcing value to bool 'true' or 'false'
+ # errors:
+ "/we4013" # 'function' undefined; assuming extern returning int
+ "/we4431" # missing type specifier - int assumed
+ )
+
+ string(REPLACE ";" " " _WARNINGS "${_WARNINGS}")
set(C_WARNINGS "${_WARNINGS}")
set(CXX_WARNINGS "${_WARNINGS}")
unset(_WARNINGS)
@@ -1102,6 +1129,9 @@ elseif(WIN32)
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
endif()
+ if(MSVC90)
+ set(JPEG_NAMES ${JPEG_NAMES} libjpeg)
+ endif()
find_package(jpeg REQUIRED)
set(PTHREADS_INCLUDE_DIRS ${LIBDIR}/pthreads/include)
@@ -1163,8 +1193,8 @@ elseif(WIN32)
set(FFMPEG_LIBRARY_VERSION 54)
set(FFMPEG_LIBRARY_VERSION_AVU 52)
else()
- set(FFMPEG_LIBRARY_VERSION 53)
- set(FFMPEG_LIBRARY_VERSION_AVU 51)
+ set(FFMPEG_LIBRARY_VERSION 55)
+ set(FFMPEG_LIBRARY_VERSION_AVU 52)
endif()
set(FFMPEG_LIBRARIES
${LIBDIR}/ffmpeg/lib/avcodec-${FFMPEG_LIBRARY_VERSION}.lib
@@ -1211,11 +1241,11 @@ elseif(WIN32)
${LIBDIR}/jack/include/jack
${LIBDIR}/jack/include
)
- set(JACK_LIBRARIES ${LIBDIR}/jack/lib/libjack.lib)
+ set(JACK_LIBRARIES optimized ${LIBDIR}/jack/lib/libjack.lib debug ${LIBDIR}/jack/lib/libjack_d.lib)
endif()
if(WITH_PYTHON)
- set(PYTHON_VERSION 3.3) # CACHE STRING)
+ set(PYTHON_VERSION 3.4) # CACHE STRING)
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
# Use shared libs for vc2008 and vc2010 until we actually have vc2010 libs
@@ -1291,7 +1321,27 @@ elseif(WIN32)
if(WITH_LLVM)
set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
- file(GLOB LLVM_LIBRARY ${LLVM_DIRECTORY}/lib/*.lib)
+ file(GLOB LLVM_LIBRARY_OPTIMIZED ${LLVM_DIRECTORY}/lib/*.lib)
+
+ if(EXISTS ${LLVM_DIRECTORY}/debug/lib)
+ foreach(LLVM_OPTIMIZED_LIB ${LLVM_LIBRARY_OPTIMIZED})
+ get_filename_component(LIBNAME ${LLVM_OPTIMIZED_LIB} ABSOLUTE)
+ list(APPEND LLVM_LIBS optimized ${LIBNAME})
+ endforeach(LLVM_OPTIMIZED_LIB)
+
+ file(GLOB LLVM_LIBRARY_DEBUG ${LLVM_DIRECTORY}/debug/lib/*.lib)
+
+ foreach(LLVM_DEBUG_LIB ${LLVM_LIBRARY_DEBUG})
+ get_filename_component(LIBNAME ${LLVM_DEBUG_LIB} ABSOLUTE)
+ list(APPEND LLVM_LIBS debug ${LIBNAME})
+ endforeach(LLVM_DEBUG_LIB)
+
+ set(LLVM_LIBRARY ${LLVM_LIBS})
+ else()
+ message(WARNING "LLVM debug libs not present on this system. Using release libs for debug builds.")
+ set(LLVM_LIBRARY ${LLVM_LIBRARY_OPTIMIZED})
+ endif()
+
endif()
if(WITH_OPENCOLORIO)
@@ -1349,8 +1399,6 @@ elseif(WIN32)
set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} -lpthread")
add_definitions(-DFREE_WINDOWS64 -DMS_WIN64)
- # Turn off OpenMP since it causes crashes on render for subsurfed/multiresolution meshes
- set(WITH_OPENMP OFF)
endif()
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
@@ -1417,7 +1465,7 @@ elseif(WIN32)
if(WITH_MINGW64)
set(FFMPEG_LIBRARIES avcodec.dll avformat.dll avdevice.dll avutil.dll swscale.dll swresample.dll)
else()
- set(FFMPEG_LIBRARIES avcodec-53 avformat-53 avdevice-53 avutil-51 swscale-2)
+ set(FFMPEG_LIBRARIES avcodec-55 avformat-55 avdevice-55 avutil-52 swscale-2)
endif()
set(FFMPEG_LIBPATH ${FFMPEG}/lib)
endif()
@@ -1449,9 +1497,11 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.3) # CACHE STRING)
+ set(PYTHON_VERSION 3.4) # CACHE STRING)
+ string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH)
- set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python33mw.lib") # CACHE FILEPATH)
+ set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}mw.lib") # CACHE FILEPATH)
+ unset(_PYTHON_VERSION_NO_DOTS)
# uncached vars
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
@@ -1580,7 +1630,10 @@ elseif(WIN32)
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
- list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
+ find_library(OSL_LIB_EXEC_DEBUG NAMES oslexec_d PATHS ${CYCLES_OSL}/lib)
+ find_library(OSL_LIB_COMP_DEBUG NAMES oslcomp_d PATHS ${CYCLES_OSL}/lib)
+ find_library(OSL_LIB_QUERY_DEBUG NAMES oslquery_d PATHS ${CYCLES_OSL}/lib)
+ list(APPEND OSL_LIBRARIES optimized ${OSL_LIB_COMP} optimized ${OSL_LIB_EXEC} optimized ${OSL_LIB_QUERY} debug ${OSL_LIB_EXEC_DEBUG} debug ${OSL_LIB_COMP_DEBUG} debug ${OSL_LIB_QUERY_DEBUG})
find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
@@ -1636,8 +1689,8 @@ elseif(APPLE)
endif()
if(WITH_PYTHON)
- # we use precompiled libraries for py 3.3 and up by default
- set(PYTHON_VERSION 3.3)
+ # we use precompiled libraries for py 3.4 and up by default
+ set(PYTHON_VERSION 3.4)
if(NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
# normally cached but not since we include them with blender
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m")
@@ -1797,7 +1850,6 @@ elseif(APPLE)
set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt)
if(WITH_INTERNATIONAL)
list(APPEND BOOST_LIBRARIES boost_locale-mt)
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -liconv") # boost_locale needs it !
endif()
if(WITH_CYCLES_NETWORK)
list(APPEND BOOST_LIBRARIES boost_serialization-mt)
@@ -1805,6 +1857,10 @@ elseif(APPLE)
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS)
endif()
+
+ if(WITH_INTERNATIONAL OR WITH_CODEC_FFMPEG)
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -liconv") # boost_locale and ffmpeg needs it !
+ endif()
if(WITH_OPENIMAGEIO)
set(OPENIMAGEIO ${LIBDIR}/openimageio)
@@ -1875,6 +1931,18 @@ elseif(APPLE)
message(STATUS "OSL not found")
endif()
endif()
+
+ if(WITH_OPENMP AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
+ set(OPENMP_FOUND ON)
+ set(OpenMP_C_FLAGS "-fopenmp" CACHE STRING "C compiler flags for OpenMP parallization" FORCE)
+ set(OpenMP_CXX_FLAGS "-fopenmp" CACHE STRING "C++ compiler flags for OpenMP parallization" FORCE)
+ include_directories(${LIBDIR}/openmp/include)
+ LINK_DIRECTORIES(${LIBDIR}/openmp/lib)
+ execute_process(COMMAND ditto -arch ${CMAKE_OSX_ARCHITECTURES} ${LIBDIR}/openmp/lib/libiomp5.dylib ${CMAKE_BINARY_DIR}/bin/libiomp5.dylib) # for intermediate binaries, lib id is @loader_path
+ else()
+ set(OpenMP_C_FLAGS "" CACHE STRING "C compiler flags for OpenMP parallization" FORCE) # unset
+ set(OpenMP_CXX_FLAGS "" CACHE STRING "C++ compiler flags for OpenMP parallization" FORCE) # unset
+ endif()
set(EXETYPE MACOSX_BUNDLE)
@@ -2310,7 +2378,9 @@ if(WITH_PYTHON)
"Python.h for python version \"${PYTHON_VERSION}\"")
endif()
- if(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
+ if(WIN32)
+ # pass, we have this in an archive to extract
+ elseif(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
# set but invalid
# -- disabled until we make numpy bundled with blender - campbell
if((NOT ${PYTHON_NUMPY_PATH} STREQUAL "") AND (NOT ${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
@@ -2354,6 +2424,20 @@ if(WITH_PYTHON)
unset(_PY_VER_MAJOR)
endif()
endif()
+
+ if(WIN32 OR APPLE)
+ # pass, we have this in lib/python/site-packages
+ elseif(WITH_PYTHON_INSTALL_REQUESTS)
+ if(NOT EXISTS ${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/requests)
+ # gets annoying otherwise...
+ if(FIRST_RUN)
+ message(WARNING "'requests' path could not be found in:\n"
+ "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/requests'\n"
+ "WITH_PYTHON_INSTALL_REQUESTS option will be ignored when installing python")
+ endif()
+ set(WITH_PYTHON_INSTALL_REQUESTS OFF)
+ endif()
+ endif()
endif()
if(WITH_GCC_MUDFLAP)
diff --git a/GNUmakefile b/GNUmakefile
index 8ae2efbe53c..566a44b500f 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -74,7 +74,7 @@ endif
# Get the number of cores for threaded build
NPROCS:=1
ifeq ($(OS), Linux)
- NPROCS:=$(shell grep -c ^processor /proc/cpuinfo)
+ NPROCS:=$(shell nproc)
endif
ifeq ($(OS), Darwin)
NPROCS:=$(shell sysctl -a | grep "hw.ncpu " | cut -d" " -f3)
diff --git a/SConstruct b/SConstruct
index 0d6bf60faa8..0258f776824 100644
--- a/SConstruct
+++ b/SConstruct
@@ -293,8 +293,14 @@ if env['OURPLATFORM']=='darwin':
frontend = re.search(r'gcc', line) or re.search(r'clang', line) or re.search(r'llvm-gcc', line) or re.search(r'icc', line)
if frontend:
env['C_COMPILER_ID'] = frontend.group(0)
+
+ vendor = re.search(r'Apple', line)
+ if vendor:
+ C_VENDOR = vendor.group(0)
+ else:
+ C_VENDOR = 'Open Source'
- print B.bc.OKGREEN + "Using Compiler: " + B.bc.ENDC + env['C_COMPILER_ID'] + '-' + env['CCVERSION']
+ print B.bc.OKGREEN + "Using Compiler: " + B.bc.ENDC + env['C_COMPILER_ID'] + '-' + env['CCVERSION'] + ' ( ' + C_VENDOR + ' )'
cmd = 'sw_vers -productVersion'
MAC_CUR_VER=cmd_res=commands.getoutput(cmd)
@@ -410,9 +416,13 @@ if env['OURPLATFORM']=='darwin':
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
# if your compiler does not have accurate suffix you may have to enable it by hand !
if env['WITH_BF_OPENMP'] == 1:
- if env['C_COMPILER_ID'] == 'gcc' and env['CCVERSION'] >= '4.6.1' or env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4':
+ if env['C_COMPILER_ID'] == 'gcc' and env['CCVERSION'] >= '4.6.1' or env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4' and C_VENDOR != 'Apple':
env['WITH_BF_OPENMP'] = 1 # multithreading for fluids, cloth, sculpt and smoke
print B.bc.OKGREEN + "Using OpenMP"
+ if env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4':
+ OSX_OMP_LIBPATH = Dir(env.subst(env['LCGDIR'])).abspath
+ env.Append(BF_PROGRAM_LINKFLAGS=['-L'+OSX_OMP_LIBPATH+'/openmp/lib','-liomp5'])
+ env['CCFLAGS'].append('-I'+OSX_OMP_LIBPATH+'/openmp/include') # include for omp.h
else:
env['WITH_BF_OPENMP'] = 0
print B.bc.OKGREEN + "Disabled OpenMP, not supported by compiler"
@@ -495,7 +505,6 @@ else:
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
env['CPPFLAGS'].append('-DWITH_AVI')
env['CPPFLAGS'].append('-DWITH_OPENNL')
-env['CPPFLAGS'].append('-DWITH_BOOL_COMPAT')
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc') and env['MSVC_VERSION'] == '11.0':
env['CPPFLAGS'].append('-D_ALLOW_KEYWORD_MACROS')
@@ -684,6 +693,7 @@ if B.targets != ['cudakernels']:
data_to_c_simple("release/datafiles/bmonofont.ttf")
data_to_c_simple("release/datafiles/splash.png")
+ data_to_c_simple("release/datafiles/splash_2x.png")
# data_to_c_simple("release/datafiles/blender_icons16.png")
# data_to_c_simple("release/datafiles/blender_icons32.png")
@@ -885,6 +895,7 @@ if env['OURPLATFORM']!='darwin':
source.remove('CMakeLists.txt')
source.remove('svm')
source.remove('closure')
+ source.remove('geom')
source.remove('shaders')
source.remove('osl')
source=['intern/cycles/kernel/'+s for s in source]
@@ -906,6 +917,12 @@ if env['OURPLATFORM']!='darwin':
if '__pycache__' in source: source.remove('__pycache__')
source=['intern/cycles/kernel/closure/'+s for s in source]
scriptinstall.append(env.Install(dir=dir,source=source))
+ # geom
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'kernel', 'geom')
+ source=os.listdir('intern/cycles/kernel/geom')
+ if '__pycache__' in source: source.remove('__pycache__')
+ source=['intern/cycles/kernel/geom/'+s for s in source]
+ scriptinstall.append(env.Install(dir=dir,source=source))
# licenses
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'license')
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 1fadf987b0f..4fa7946bb8b 100755..100644
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -25,8 +25,8 @@
ARGS=$( \
getopt \
-o s:i:t:h \
---long source:,install:,tmp:,threads:,help,with-all,with-opencollada,force-all,\
-force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-opencollada,\
+--long source:,install:,tmp:,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,libyaml-cpp-ver: \
-- "$@" \
@@ -45,10 +45,7 @@ WITH_ALL=false
# Do not yet enable opencollada, use --with-opencollada (or --with-all) option to try it.
WITH_OPENCOLLADA=false
-THREADS=`cat /proc/cpuinfo | grep processor | wc -l`
-if [ -z "$THREADS" ]; then
- THREADS=1
-fi
+THREADS=$(nproc)
COMMON_INFO="\"Source code of dependencies needed to be compiled will be downloaded and extracted into '\$SRC'.
Built libs of dependencies needed to be compiled will be installed into '\$INST'.
@@ -80,6 +77,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
-t n, --threads=n
Use a specific number of threads when building the libraries (auto-detected as '\$THREADS').
+ --no_sudo
+ Disable use of sudo (this script won't be able to do much though, will just print needed packages...).
+
--with-all
By default, a number of optional and not-so-often needed libraries are not installed.
This option will try to install them, at the cost of potential conflicts (depending on
@@ -89,6 +89,22 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--with-opencollada
Build and install the OpenCOLLADA libraries.
+ --ver-ocio=<ver>
+ Force version of OCIO library.
+
+ --ver-oiio=<ver>
+ Force version of OIIO library.
+
+ --ver-llvm=<ver>
+ Force version of LLVM library.
+
+ --ver-osl=<ver>
+ Force version of OSL library.
+
+ Note about the --ver-foo options:
+ It may not always work as expected (some libs are actually checked out from a git rev...), yet it might help
+ to fix some build issues (like LLVM mismatch with the version used by your graphic system).
+
--force-all
Force the rebuild of all built libraries.
@@ -161,7 +177,7 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--required-numpy
Use this in case your distro features a valid python package, but no matching Numpy one.
- It will force compilation of both python 3.3 and numpy 1.7.
+ It will force compilation of both python and numpy
--libyaml-cpp-ver=<ver>
Ubuntu hack: you may have to force installation of a non-defaut version of libyaml-cpp
@@ -169,28 +185,25 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
##### Main Vars #####
-PYTHON_VERSION="3.3.3"
-PYTHON_VERSION_MIN="3.3"
-PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.bz2"
+SUDO="sudo"
+
+PYTHON_VERSION="3.4.0"
+PYTHON_VERSION_MIN="3.4"
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
-NUMPY_VERSION="1.7.0"
-NUMPY_VERSION_MIN="1.7"
-NUMPY_SOURCE="http://sourceforge.net/projects/numpy/files/NumPy/$NUMPY_VERSION/numpy-$NUMPY_VERSION.tar.gz"
+NUMPY_VERSION="1.8.1"
+NUMPY_VERSION_MIN="1.8"
NUMPY_FORCE_REBUILD=false
NUMPY_SKIP=false
NUMPY_REQUIRED=false
BOOST_VERSION="1.51.0"
-_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
-BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download"
BOOST_VERSION_MIN="1.49"
BOOST_FORCE_REBUILD=false
BOOST_SKIP=false
OCIO_VERSION="1.0.7"
-OCIO_SOURCE="https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION"
OCIO_VERSION_MIN="1.0"
OCIO_FORCE_REBUILD=false
OCIO_SKIP=false
@@ -199,49 +212,34 @@ LIBYAML_CPP_VER="0.0"
OPENEXR_VERSION="2.1.0"
OPENEXR_VERSION_MIN="2.0.1"
-#OPENEXR_SOURCE="http://download.savannah.nongnu.org/releases/openexr/openexr-$OPENEXR_VERSION.tar.gz"
-OPENEXR_SOURCE="https://github.com/mont29/openexr.git"
-OPENEXR_REPO_UID="2787aa1cf652d244ed45ae124eb1553f6cff11ee"
ILMBASE_VERSION="2.1.0"
-ILMBASE_SOURCE="http://download.savannah.nongnu.org/releases/openexr/ilmbase-$ILMBASE_VERSION.tar.gz"
OPENEXR_FORCE_REBUILD=false
OPENEXR_SKIP=false
_with_built_openexr=false
-OIIO_VERSION="1.3.9"
-OIIO_VERSION_MIN="1.3.9"
-#OIIO_SOURCE="https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION.tar.gz"
-OIIO_SOURCE="https://github.com/mont29/oiio.git"
-OIIO_REPO_UID="99113d12619c90cf44721195a759674ea61f02b1"
+OIIO_VERSION="1.4.0"
+OIIO_VERSION_MIN="1.4.0"
OIIO_FORCE_REBUILD=false
OIIO_SKIP=false
LLVM_VERSION="3.3"
LLVM_VERSION_MIN="3.3"
LLVM_VERSION_FOUND=""
-LLVM_SOURCE="http://llvm.org/releases/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz"
-LLVM_CLANG_SOURCE="http://llvm.org/releases/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz"
LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
OSL_VERSION="1.4.0"
OSL_VERSION_MIN=$OSL_VERSION
-#OSL_SOURCE="https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz"
-OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage.git"
-OSL_REPO_UID="175989f2610a7d54e8edfb5ace0143e28e11ac70"
OSL_FORCE_REBUILD=false
OSL_SKIP=false
# Version??
OPENCOLLADA_VERSION="1.3"
-OPENCOLLADA_SOURCE="https://github.com/KhronosGroup/OpenCOLLADA.git"
-OPENCOLLADA_REPO_UID="18da7f4109a8eafaa290a33f5550501cc4c8bae8"
OPENCOLLADA_FORCE_REBUILD=false
OPENCOLLADA_SKIP=false
-FFMPEG_VERSION="1.0"
-FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2"
+FFMPEG_VERSION="2.1.4"
FFMPEG_VERSION_MIN="0.7.6"
FFMPEG_FORCE_REBUILD=false
FFMPEG_SKIP=false
@@ -342,12 +340,39 @@ while true; do
PRINT ""
exit 0
;;
+ --no-sudo)
+ PRINT ""
+ WARNING "--no-sudo enabled, this script might not be able to do much..."
+ PRINT ""
+ SUDO=""; shift; continue
+ ;;
--with-all)
WITH_ALL=true; shift; continue
;;
--with-opencollada)
WITH_OPENCOLLADA=true; shift; continue
;;
+ --ver-ocio)
+ OCIO_VERSION="$2"
+ OCIO_VERSION_MIN=$OCIO_VERSION
+ echo $OCIO_VERSION
+ shift; shift; continue
+ ;;
+ --ver-oiio)
+ OIIO_VERSION="$2"
+ OIIO_VERSION_MIN=$OIIO_VERSION
+ shift; shift; continue
+ ;;
+ --ver-llvm)
+ LLVM_VERSION="$2"
+ LLVM_VERSION_MIN=$LLVM_VERSION
+ shift; shift; continue
+ ;;
+ --ver-osl)
+ OSL_VERSION="$2"
+ OSL_VERSION_MIN=$OSL_VERSION
+ shift; shift; continue
+ ;;
--force-all)
PYTHON_FORCE_REBUILD=true
NUMPY_FORCE_REBUILD=true
@@ -451,6 +476,35 @@ if $WITH_ALL; then
WITH_OPENCOLLADA=true
fi
+
+# This has to be done here, because user might force some versions...
+PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz"
+NUMPY_SOURCE="http://sourceforge.net/projects/numpy/files/NumPy/$NUMPY_VERSION/numpy-$NUMPY_VERSION.tar.gz"
+_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
+BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download"
+
+OCIO_SOURCE="https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION"
+#OPENEXR_SOURCE="http://download.savannah.nongnu.org/releases/openexr/openexr-$OPENEXR_VERSION.tar.gz"
+OPENEXR_SOURCE="https://github.com/mont29/openexr.git"
+OPENEXR_REPO_UID="2787aa1cf652d244ed45ae124eb1553f6cff11ee"
+ILMBASE_SOURCE="http://download.savannah.nongnu.org/releases/openexr/ilmbase-$ILMBASE_VERSION.tar.gz"
+
+#OIIO_SOURCE="https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION.tar.gz"
+OIIO_SOURCE="https://github.com/mont29/oiio.git"
+OIIO_REPO_UID="99113d12619c90cf44721195a759674ea61f02b1"
+
+LLVM_SOURCE="http://llvm.org/releases/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz"
+LLVM_CLANG_SOURCE="http://llvm.org/releases/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz"
+#OSL_SOURCE="https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz"
+#OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage.git"
+OSL_SOURCE="https://github.com/imageworks/OpenShadingLanguage.git"
+OSL_REPO_UID="4abd672ed3979e5e965323201a5ba5ab802a76a9"
+
+OPENCOLLADA_SOURCE="https://github.com/KhronosGroup/OpenCOLLADA.git"
+OPENCOLLADA_REPO_UID="18da7f4109a8eafaa290a33f5550501cc4c8bae8"
+FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2"
+
+
##### Generic Helpers #####
# Return 0 if $1 = $2 (i.e. 1.01.0 = 1.1, but 1.1.1 != 1.1), else 1.
@@ -540,13 +594,16 @@ version_match() {
##### Generic compile helpers #####
prepare_opt() {
INFO "Ensuring $INST exists and is writable by us"
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, might be impossible to create install dir..."
+ fi
if [ ! -d $INST ]; then
- sudo mkdir -p $INST
+ $SUDO mkdir -p $INST
fi
if [ ! -w $INST ]; then
- sudo chown $USER $INST
- sudo chmod 775 $INST
+ $SUDO chown $USER $INST
+ $SUDO chmod 775 $INST
fi
}
@@ -585,9 +642,13 @@ run_ldconfig() {
_lib_path="$INST/$1/lib"
_ldconf_path="/etc/ld.so.conf.d/$1.conf"
PRINT ""
- INFO "Running ldconfig for $1..."
- sudo sh -c "echo \"$_lib_path\" > $_ldconf_path"
- sudo /sbin/ldconfig # XXX OpenSuse does not include sbin in command path with sudo!!!
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run ldconfig for $1, you'll have to do it yourself..."
+ else
+ INFO "Running ldconfig for $1..."
+ $SUDO sh -c "echo \"$_lib_path\" > $_ldconf_path"
+ $SUDO /sbin/ldconfig # XXX OpenSuse does not include sbin in command path with sudo!!!
+ fi
PRINT ""
}
@@ -596,7 +657,7 @@ _init_python() {
_src=$SRC/Python-$PYTHON_VERSION
_git=false
_inst=$INST/python-$PYTHON_VERSION
- _inst_shortcut=$INST/python-3.3
+ _inst_shortcut=$INST/python-$PYTHON_VERSION_MIN
}
clean_Python() {
@@ -623,10 +684,10 @@ compile_Python() {
if [ ! -d $_src ]; then
mkdir -p $SRC
- wget -c $PYTHON_SOURCE -O $_src.tar.bz2
+ wget -c $PYTHON_SOURCE -O $_src.tgz
INFO "Unpacking Python-$PYTHON_VERSION"
- tar -C $SRC -xf $_src.tar.bz2
+ tar -C $SRC -xf $_src.tgz
fi
cd $_src
@@ -661,7 +722,7 @@ _init_numpy() {
_git=false
_inst=$INST/numpy-$NUMPY_VERSION
_python=$INST/python-$PYTHON_VERSION
- _site=lib/python3.3/site-packages
+ _site=lib/python$PYTHON_VERSION_MIN/site-packages
_inst_shortcut=$_python/$_site/numpy
}
@@ -1141,11 +1202,12 @@ compile_OIIO() {
cmake_d="$cmake_d -D BUILDSTATIC=OFF"
cmake_d="$cmake_d -D LINKSTATIC=OFF"
+ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
+ cmake_d="$cmake_d -D OPENEXR_VERSION=$OPENEXR_VERSION"
+
if [ $_with_built_openexr == true ]; then
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
- cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
cmake_d="$cmake_d -D OPENEXR_HOME=$INST/openexr"
- cmake_d="$cmake_d -D OPENEXR_VERSION=$OPENEXR_VERSION"
fi
# Optional tests and cmd tools
@@ -1275,6 +1337,7 @@ EOF
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D LLVM_ENABLE_FFI=ON"
cmake_d="$cmake_d -D LLVM_TARGETS_TO_BUILD=X86"
+ cmake_d="$cmake_d -D -DLLVM_ENABLE_TERMINFO=OFF"
if [ -d $_FFI_INCLUDE_DIR ]; then
cmake_d="$cmake_d -D FFI_INCLUDE_DIR=$_FFI_INCLUDE_DIR"
@@ -1320,7 +1383,7 @@ clean_OSL() {
compile_OSL() {
# To be changed each time we make edits that would modify the compiled result!
- osl_magic=14
+ osl_magic=15
_init_osl
# Clean install if needed!
@@ -1349,8 +1412,10 @@ compile_OSL() {
cd $_src
+ git remote set-url origin $OSL_SOURCE
+
# XXX For now, always update from latest repo...
- git pull origin master
+ git pull -X theirs origin master
# Stick to same rev as windows' libs...
git checkout $OSL_REPO_UID
@@ -1369,9 +1434,10 @@ compile_OSL() {
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
cmake_d="$cmake_d -D BUILDSTATIC=OFF"
+ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
+
if [ $_with_built_openexr == true ]; then
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
- cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
fi
if [ -d $INST/boost ]; then
@@ -1572,8 +1638,9 @@ compile_FFmpeg() {
--disable-bzlib --disable-libgsm --disable-libspeex \
--enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
--disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
- --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
+ --disable-postproc --disable-librtmp --disable-libopencore-amrnb \
--disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
+ --disable-outdev=xv \
--disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \
--disable-indev=lavfi $extra
@@ -1646,10 +1713,14 @@ check_package_version_ge_DEB() {
}
install_packages_DEB() {
- sudo apt-get install -y --force-yes $@
- if [ $? -ge 1 ]; then
- ERROR "apt-get failed to install requested packages, exiting."
- exit 1
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run apt-get install for $@, you'll have to do it yourself..."
+ else
+ $SUDO apt-get install -y --force-yes $@
+ if [ $? -ge 1 ]; then
+ ERROR "apt-get failed to install requested packages, exiting."
+ exit 1
+ fi
fi
}
@@ -1657,9 +1728,10 @@ install_DEB() {
PRINT ""
INFO "Installing dependencies for DEB-based distribution"
PRINT ""
- WARNING "Ubuntu users: Beware of Trusty!!!"
- PRINT "Ubuntu 14.4 comes with a default libyaml-cpp in 0.5 version, while their ocio package still uses the 0.3 version"
- PRINT "You have to use '--libyaml-cpp-ver=0.3' option (else Blender will builds with 0.5, and break when using packaged ocio)..."
+ WARNING "Beware of recent Ubuntu/Debian!!!"
+ PRINT "Ubuntu 14.4 and Debian Jessie come with a default libyaml-cpp in 0.5 version, while their ocio package still"
+ PRINT "uses the 0.3 version. You have to use '--libyaml-cpp-ver=0.3' option (else Blender will builds with 0.5,"
+ PRINT "and break when using packaged ocio)..."
PRINT ""
PRINT "`eval _echo "$COMMON_INFO"`"
PRINT ""
@@ -1691,7 +1763,11 @@ install_DEB() {
fi
fi
- sudo apt-get update
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run apt-get update, you'll have to do it yourself..."
+ else
+ $SUDO apt-get update
+ fi
# These libs should always be available in debian/ubuntu official repository...
OPENJPEG_DEV="libopenjpeg-dev"
@@ -1836,9 +1912,9 @@ install_DEB() {
if $NUMPY_SKIP; then
WARNING "Skipping NumPy installation, as requested..."
else
- check_package_DEB python$PYTHON_VERSION_MIN-numpy
+ check_package_DEB python3-numpy
if [ $? -eq 0 ]; then
- install_packages_DEB python$PYTHON_VERSION_MIN-numpy
+ install_packages_DEB python3-numpy
elif $NUMPY_REQUIRED; then
WARNING "Valid python package but no valid numpy package!" \
" Building both Python and Numpy from sources!"
@@ -2076,17 +2152,25 @@ check_package_version_ge_RPM() {
install_packages_RPM() {
rpm_flavour
if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
- sudo yum install -y $@
- if [ $? -ge 1 ]; then
- ERROR "yum failed to install requested packages, exiting."
- exit 1
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run yum install for $@, you'll have to do it yourself..."
+ else
+ $SUDO yum install -y $@
+ if [ $? -ge 1 ]; then
+ ERROR "yum failed to install requested packages, exiting."
+ exit 1
+ fi
fi
elif [ $RPM = "SUSE" ]; then
- sudo zypper --non-interactive install --auto-agree-with-licenses $@
- if [ $? -ge 1 ]; then
- ERROR "zypper failed to install requested packages, exiting."
- exit 1
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run zypper install for $@, you'll have to do it yourself..."
+ else
+ $SUDO zypper --non-interactive install --auto-agree-with-licenses $@
+ if [ $? -ge 1 ]; then
+ ERROR "zypper failed to install requested packages, exiting."
+ exit 1
+ fi
fi
fi
}
@@ -2102,57 +2186,61 @@ install_RPM() {
[ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
# Enable non-free repositories for all flavours
- rpm_flavour
- if [ $RPM = "FEDORA" ]; then
- _fedora_rel="`egrep "[0-9]{1,}" /etc/fedora-release -o`"
- sudo yum -y localinstall --nogpgcheck \
- http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$_fedora_rel.noarch.rpm \
- http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$_fedora_rel.noarch.rpm
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to install third party repositories, you'll have to do it yourself..."
+ else
+ rpm_flavour
+ if [ $RPM = "FEDORA" ]; then
+ _fedora_rel="`egrep "[0-9]{1,}" /etc/fedora-release -o`"
+ $SUDO yum -y localinstall --nogpgcheck \
+ http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$_fedora_rel.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$_fedora_rel.noarch.rpm
- sudo yum -y update
+ $SUDO yum -y update
- # Install cmake now because of difference with RHEL
- sudo yum -y install cmake
+ # Install cmake now because of difference with RHEL
+ $SUDO yum -y install cmake
- elif [ $RPM = "RHEL" ]; then
- sudo yum -y localinstall --nogpgcheck \
- http://download.fedoraproject.org/pub/epel/6/$(uname -i)/epel-release-6-8.noarch.rpm \
- http://download1.rpmfusion.org/free/el/updates/6/$(uname -i)/rpmfusion-free-release-6-1.noarch.rpm \
- http://download1.rpmfusion.org/nonfree/el/updates/6/$(uname -i)/rpmfusion-nonfree-release-6-1.noarch.rpm
+ elif [ $RPM = "RHEL" ]; then
+ $SUDO yum -y localinstall --nogpgcheck \
+ http://download.fedoraproject.org/pub/epel/6/$(uname -i)/epel-release-6-8.noarch.rpm \
+ http://download1.rpmfusion.org/free/el/updates/6/$(uname -i)/rpmfusion-free-release-6-1.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/el/updates/6/$(uname -i)/rpmfusion-nonfree-release-6-1.noarch.rpm
- sudo yum -y update
+ $SUDO yum -y update
- # Install cmake 2.8 from other repo
- mkdir -p $SRC
- if [ -f $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm ]; then
- PRINT ""
- INFO "Special cmake already installed"
- else
- curl -O ftp://ftp.pbone.net/mirror/atrpms.net/el6-$(uname -i)/atrpms/testing/cmake-2.8.8-4.el6.$(uname -m).rpm
- mv cmake-2.8.8-4.el6.$(uname -m).rpm $SRC/
- sudo rpm -ihv $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm
- fi
+ # Install cmake 2.8 from other repo
+ mkdir -p $SRC
+ if [ -f $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm ]; then
+ PRINT ""
+ INFO "Special cmake already installed"
+ else
+ curl -O ftp://ftp.pbone.net/mirror/atrpms.net/el6-$(uname -i)/atrpms/testing/cmake-2.8.8-4.el6.$(uname -m).rpm
+ mv cmake-2.8.8-4.el6.$(uname -m).rpm $SRC/
+ $SUDO rpm -ihv $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm
+ fi
- elif [ $RPM = "SUSE" ]; then
- # Install this now to avoid using the version from packman repository...
- if $WITH_ALL; then
- install_packages_RPM libjack-devel
- fi
+ elif [ $RPM = "SUSE" ]; then
+ # Install this now to avoid using the version from packman repository...
+ if $WITH_ALL; then
+ install_packages_RPM libjack-devel
+ fi
- _suse_rel="`grep VERSION /etc/SuSE-release | gawk '{print $3}'`"
+ _suse_rel="`grep VERSION /etc/SuSE-release | gawk '{print $3}'`"
- PRINT ""
- INFO "About to add 'packman' repository from http://packman.inode.at/suse/openSUSE_$_suse_rel/"
- INFO "This is only needed if you do not already have a packman repository enabled..."
- read -p "Do you want to add this repo (Y/n)?"
- if [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" == "y" ]; then
- INFO " Installing packman..."
- sudo zypper ar --refresh --name 'Packman Repository' http://ftp.gwdg.de/pub/linux/packman/suse/openSUSE_$_suse_rel/ ftp.gwdg.de-suse
- INFO " Done."
- else
- INFO " Skipping packman installation."
+ PRINT ""
+ INFO "About to add 'packman' repository from http://packman.inode.at/suse/openSUSE_$_suse_rel/"
+ INFO "This is only needed if you do not already have a packman repository enabled..."
+ read -p "Do you want to add this repo (Y/n)?"
+ if [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" == "y" ]; then
+ INFO " Installing packman..."
+ $SUDO zypper ar --refresh --name 'Packman Repository' http://ftp.gwdg.de/pub/linux/packman/suse/openSUSE_$_suse_rel/ ftp.gwdg.de-suse
+ INFO " Done."
+ else
+ INFO " Skipping packman installation."
+ fi
+ $SUDO zypper --non-interactive --gpg-auto-import-keys update --auto-agree-with-licenses
fi
- sudo zypper --non-interactive --gpg-auto-import-keys update --auto-agree-with-licenses
fi
# These libs should always be available in fedora/suse official repository...
@@ -2467,10 +2555,14 @@ check_package_version_ge_ARCH() {
}
install_packages_ARCH() {
- sudo pacman -S --needed --noconfirm $@
- if [ $? -ge 1 ]; then
- ERROR "pacman failed to install requested packages, exiting."
- exit 1
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run pacman for $@, you'll have to do it yourself..."
+ else
+ $SUDO pacman -S --needed --noconfirm $@
+ if [ $? -ge 1 ]; then
+ ERROR "pacman failed to install requested packages, exiting."
+ exit 1
+ fi
fi
}
@@ -2485,17 +2577,23 @@ install_ARCH() {
[ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
# Check for sudo...
- if [ ! -x "/usr/bin/sudo" ]; then
- PRINT ""
- ERROR "This script requires sudo but it is not installed."
- PRINT "Please setup sudo according to:"
- PRINT "https://wiki.archlinux.org/index.php/Sudo"
- PRINT "and try again."
- PRINT ""
- exit
+ if [ $SUDO ]; then
+ if [ ! -x "/usr/bin/sudo" ]; then
+ PRINT ""
+ ERROR "This script requires sudo but it is not installed."
+ PRINT "Please setup sudo according to:"
+ PRINT "https://wiki.archlinux.org/index.php/Sudo"
+ PRINT "and try again."
+ PRINT ""
+ exit
+ fi
fi
- sudo pacman -Sy
+ if [ ! $SUDO ]; then
+ WARNING "--no-sudo enabled, impossible to run pacman -Sy, you'll have to do it yourself..."
+ else
+ $SUDO pacman -Sy
+ fi
# These libs should always be available in arch official repository...
OPENJPEG_DEV="openjpeg"
@@ -2845,21 +2943,29 @@ print_info() {
_buildargs="$_buildargs $_1"
fi
- _1="-D WITH_CYCLES_OSL=ON"
- _2="-D WITH_LLVM=ON"
- _3="-D LLVM_VERSION=$LLVM_VERSION_FOUND"
- PRINT " $_1"
- PRINT " $_2"
- PRINT " $_3"
- _buildargs="$_buildargs $_1 $_2 $_3"
- if [ -d $INST/osl ]; then
- _1="-D CYCLES_OSL=$INST/osl"
+ if [ "$OSL_SKIP" = false ]; then
+ _1="-D WITH_CYCLES_OSL=ON"
+ _2="-D WITH_LLVM=ON"
+ _3="-D LLVM_VERSION=$LLVM_VERSION_FOUND"
PRINT " $_1"
- _buildargs="$_buildargs $_1"
- fi
- if [ -d $INST/llvm ]; then
- _1="-D LLVM_DIRECTORY=$INST/llvm"
- _2="-D LLVM_STATIC=ON"
+ PRINT " $_2"
+ PRINT " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
+ if [ -d $INST/osl ]; then
+ _1="-D CYCLES_OSL=$INST/osl"
+ PRINT " $_1"
+ _buildargs="$_buildargs $_1"
+ fi
+ if [ -d $INST/llvm ]; then
+ _1="-D LLVM_DIRECTORY=$INST/llvm"
+ _2="-D LLVM_STATIC=ON"
+ PRINT " $_1"
+ PRINT " $_2"
+ _buildargs="$_buildargs $_1 $_2"
+ fi
+ else
+ _1="-D WITH_CYCLES_OSL=OFF"
+ _2="-D WITH_LLVM=OFF"
PRINT " $_1"
PRINT " $_2"
_buildargs="$_buildargs $_1 $_2"
@@ -2871,15 +2977,17 @@ print_info() {
_buildargs="$_buildargs $_1"
fi
- _1="-D WITH_CODEC_FFMPEG=ON"
- _2="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
- PRINT " $_1"
- PRINT " $_2"
- _buildargs="$_buildargs $_1 $_2"
- if [ -d $INST/ffmpeg ]; then
- _1="-D FFMPEG=$INST/ffmpeg"
+ if [ "$FFMPEG_SKIP" = false ]; then
+ _1="-D WITH_CODEC_FFMPEG=ON"
+ _2="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
PRINT " $_1"
- _buildargs="$_buildargs $_1"
+ PRINT " $_2"
+ _buildargs="$_buildargs $_1 $_2"
+ if [ -d $INST/ffmpeg ]; then
+ _1="-D FFMPEG=$INST/ffmpeg"
+ PRINT " $_1"
+ _buildargs="$_buildargs $_1"
+ fi
fi
PRINT ""
@@ -2894,9 +3002,11 @@ print_info() {
PRINT "BF_PYTHON_ABI_FLAGS = 'm'"
fi
- PRINT "WITH_BF_OCIO = True"
- if [ -d $INST/ocio ]; then
- PRINT "BF_OCIO = '$INST/ocio'"
+ if [ "$OCIO_SKIP" = false ]; then
+ PRINT "WITH_BF_OCIO = True"
+ if [ -d $INST/ocio ]; then
+ PRINT "BF_OCIO = '$INST/ocio'"
+ fi
fi
if [ -d $INST/openexr ]; then
@@ -2914,9 +3024,11 @@ print_info() {
PRINT "WITH_BF_STATICOPENEXR = True"
fi
- PRINT "WITH_BF_OIIO = True"
- if [ -d $INST/oiio ]; then
- PRINT "BF_OIIO = '$INST/oiio'"
+ if [ "$OIIO_SKIP" = false ]; then
+ PRINT "WITH_BF_OIIO = True"
+ if [ -d $INST/oiio ]; then
+ PRINT "BF_OIIO = '$INST/oiio'"
+ fi
fi
PRINT "WITH_BF_CYCLES = True"
@@ -2925,9 +3037,11 @@ print_info() {
PRINT "BF_OSL = '$INST/osl'"
fi
- PRINT "WITH_BF_BOOST = True"
- if [ -d $INST/boost ]; then
- PRINT "BF_BOOST = '$INST/boost'"
+ if [ "$BOOST_SKIP" = false ]; then
+ PRINT "WITH_BF_BOOST = True"
+ if [ -d $INST/boost ]; then
+ PRINT "BF_BOOST = '$INST/boost'"
+ fi
fi
if $WITH_OPENCOLLADA; then
@@ -2937,13 +3051,15 @@ print_info() {
fi
fi
- _ffmpeg_list_sep=" "
- if [ -d $INST/ffmpeg ]; then
- PRINT "BF_FFMPEG = '$INST/ffmpeg'"
+ if [ "$FFMPEG_SKIP" = false ]; then
+ _ffmpeg_list_sep=" "
+ if [ -d $INST/ffmpeg ]; then
+ PRINT "BF_FFMPEG = '$INST/ffmpeg'"
+ fi
+ PRINT "BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'"
fi
- PRINT "BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'"
- if ! $WITH_ALL; then
+ if [ "$WITH_ALL" = false ]; then
PRINT "WITH_BF_3DMOUSE = False"
# No libspacenav in official arch repos...
elif [ "$DISTRO" = "ARCH" ]; then
diff --git a/build_files/build_environment/prepare_release_env.sh b/build_files/build_environment/prepare_release_env.sh
index 9889feadcd2..f003507b25f 100755..100644
--- a/build_files/build_environment/prepare_release_env.sh
+++ b/build_files/build_environment/prepare_release_env.sh
@@ -60,7 +60,7 @@ AMD64_PATH="$ENV_PATH/buildbot_${DEBIAN_BRANCH}_x86_64"
I686_PATH="$ENV_PATH/buildbot_${DEBIAN_BRANCH}_i686"
SOURCES_PATH="$ENV_PATH/sources"
-THREADS=`cat /proc/cpuinfo | grep cores | uniq | sed -e "s/.*: *\(.*\)/\\1/"`
+THREADS=$(nproc)
# Force vpx be installed from the backports
VPX_V="1.0.0-2~bpo60+1"
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
index 69053d7ff39..854f535398b 100644
--- a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
@@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
BF_NUMJOBS = 1
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
index c9b765f55ac..7e928948762 100644
--- a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
@@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
BF_NUMJOBS = 1
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index f40c35ab3d7..41d6a4a78dc 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -4,10 +4,11 @@ BF_NUMJOBS = 4
WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/lib/python-3.3'
+BF_PYTHON = '/opt/lib/python-3.4'
WITH_BF_PYTHON_INSTALL_NUMPY = True
+WITH_BF_PYTHON_INSTALL_REQUESTS = True
WITH_BF_STATICPYTHON = 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 76accb54826..d94923cc39d 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -4,10 +4,11 @@ BF_NUMJOBS = 4
WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/lib/python-3.3'
+BF_PYTHON = '/opt/lib/python-3.4'
WITH_BF_PYTHON_INSTALL_NUMPY = True
+WITH_BF_PYTHON_INSTALL_REQUESTS = True
WITH_BF_STATICPYTHON = 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 5bc13442f7e..641dbe082ad 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -3,10 +3,11 @@ BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
BF_NUMJOBS = 4
# Python configuration
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/lib/python-3.3'
+BF_PYTHON = '/opt/lib/python-3.4'
WITH_BF_PYTHON_INSTALL_NUMPY = True
+WITH_BF_PYTHON_INSTALL_REQUESTS = True
WITH_BF_STATICPYTHON = 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 edeac9eb018..80503268b44 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
@@ -3,10 +3,11 @@ BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
BF_NUMJOBS = 4
# Python configuration
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/lib/python-3.3'
+BF_PYTHON = '/opt/lib/python-3.4'
WITH_BF_PYTHON_INSTALL_NUMPY = True
+WITH_BF_PYTHON_INSTALL_REQUESTS = True
WITH_BF_STATICPYTHON = True
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index 2d8548cbba0..8d5d3a5eb79 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -64,6 +64,7 @@ else:
install_dir = os.path.join('..', 'install', builder)
# Clean install directory so we'll be sure there's no
+ # residual libs and files remained from the previous install.
if os.path.isdir(install_dir):
shutil.rmtree(install_dir)
diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake
index 547f3e0dc38..7190cfc5a88 100644
--- a/build_files/cmake/Modules/FindOpenEXR.cmake
+++ b/build_files/cmake/Modules/FindOpenEXR.cmake
@@ -126,7 +126,10 @@ IF(OPENEXR_FOUND)
SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIR}/OpenEXR)
ENDIF()
-MARK_AS_ADVANCED(OPENEXR_INCLUDE_DIR)
+MARK_AS_ADVANCED(
+ OPENEXR_INCLUDE_DIR
+ OPENEXR_VERSION
+)
FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
MARK_AS_ADVANCED(OPENEXR_${UPPERCOMPONENT}_LIBRARY)
diff --git a/build_files/cmake/Modules/FindPythonLibsUnix.cmake b/build_files/cmake/Modules/FindPythonLibsUnix.cmake
index 30019eb0b70..5656d33c934 100644
--- a/build_files/cmake/Modules/FindPythonLibsUnix.cmake
+++ b/build_files/cmake/Modules/FindPythonLibsUnix.cmake
@@ -37,7 +37,7 @@ IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
ENDIF()
-SET(PYTHON_VERSION 3.3 CACHE STRING "Python Version (major and minor only)")
+SET(PYTHON_VERSION 3.4 CACHE STRING "Python Version (major and minor only)")
MARK_AS_ADVANCED(PYTHON_VERSION)
@@ -188,7 +188,7 @@ IF(PYTHONLIBSUNIX_FOUND)
SET(PYTHON_LIBRARIES ${PYTHON_LIBRARY})
# we need this for installation
- # XXX No more valid with debian-like py3.3 packages...
+ # XXX No more valid with debian-like py3.4 packages...
# GET_FILENAME_COMPONENT(PYTHON_LIBPATH ${PYTHON_LIBRARY} PATH)
# not used
diff --git a/build_files/cmake/buildinfo.cmake b/build_files/cmake/buildinfo.cmake
index 9b8f93584b8..c1d21c413dc 100644
--- a/build_files/cmake/buildinfo.cmake
+++ b/build_files/cmake/buildinfo.cmake
@@ -14,25 +14,79 @@ if(EXISTS ${SOURCE_DIR}/.git)
if(GIT_FOUND)
message(STATUS "-- Found Git: ${GIT_EXECUTABLE}")
- execute_process(COMMAND git rev-parse --short @{u}
+ execute_process(COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
- OUTPUT_VARIABLE MY_WC_HASH
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_QUIET)
+ OUTPUT_VARIABLE MY_WC_BRANCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (MY_WC_HASH STREQUAL "")
- # Local branch, not set to upstream.
- # Well, let's use HEAD for now
+ if(MY_WC_BRANCH STREQUAL "HEAD")
+ # Detached HEAD, check whether commit hash is reachable
+ # in the master branch
execute_process(COMMAND git rev-parse --short HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
- endif()
- execute_process(COMMAND git rev-parse --abbrev-ref HEAD
- WORKING_DIRECTORY ${SOURCE_DIR}
- OUTPUT_VARIABLE MY_WC_BRANCH
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND git branch --list master --contains ${MY_WC_HASH}
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE _git_contains_check
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ STRING(REGEX REPLACE "^[ \t]+" "" _git_contains_check "${_git_contains_check}")
+ if(_git_contains_check STREQUAL "master")
+ set(MY_WC_BRANCH "master")
+ else()
+ execute_process(COMMAND git show-ref --tags -d
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE _git_tag_hashes
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(COMMAND git rev-parse HEAD
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE _git_head_hash
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(_git_tag_hashes MATCHES "${_git_head_hash}")
+ set(MY_WC_BRANCH "master")
+ endif()
+
+ unset(_git_tag_hashes)
+ unset(_git_head_hashs)
+ endif()
+
+
+ unset(_git_contains_check)
+ else()
+ execute_process(COMMAND git log HEAD..@{u}
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE _git_below_check
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT _git_below_check STREQUAL "")
+ # If there're commits between HEAD and upstream this means
+ # that we're reset-ed to older revision. Use it's hash then.
+ execute_process(COMMAND git rev-parse --short HEAD
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE MY_WC_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ execute_process(COMMAND git rev-parse --short @{u}
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE MY_WC_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+
+ if(MY_WC_HASH STREQUAL "")
+ # Local branch, not set to upstream.
+ # Well, let's use HEAD for now
+ execute_process(COMMAND git rev-parse --short HEAD
+ WORKING_DIRECTORY ${SOURCE_DIR}
+ OUTPUT_VARIABLE MY_WC_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ endif()
+
+ unset(_git_below_check)
+ endif()
execute_process(COMMAND git log -1 --format=%ct
WORKING_DIRECTORY ${SOURCE_DIR}
diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py
index f29d3c75608..9f22a9c43c1 100644
--- a/build_files/cmake/clang_array_check.py
+++ b/build_files/cmake/clang_array_check.py
@@ -41,7 +41,7 @@ defs_precalc = {
"glColor3dv": {0: 3},
"glColor4dv": {0: 4},
-
+
"glVertex2fv": {0: 2},
"glVertex3fv": {0: 3},
"glVertex4fv": {0: 4},
@@ -50,27 +50,27 @@ defs_precalc = {
"glEvalCoord1dv": {0: 1},
"glEvalCoord2fv": {0: 2},
"glEvalCoord2dv": {0: 2},
-
+
"glRasterPos2dv": {0: 2},
"glRasterPos3dv": {0: 3},
"glRasterPos4dv": {0: 4},
-
+
"glRasterPos2fv": {0: 2},
"glRasterPos3fv": {0: 3},
"glRasterPos4fv": {0: 4},
-
+
"glRasterPos2sv": {0: 2},
"glRasterPos3sv": {0: 3},
"glRasterPos4sv": {0: 4},
-
+
"glTexCoord2fv": {0: 2},
"glTexCoord3fv": {0: 3},
"glTexCoord4fv": {0: 4},
-
+
"glTexCoord2dv": {0: 2},
"glTexCoord3dv": {0: 3},
"glTexCoord4dv": {0: 4},
-
+
"glNormal3fv": {0: 3},
"glNormal3dv": {0: 3},
"glNormal3bv": {0: 3},
@@ -84,17 +84,17 @@ import sys
if 0:
# Examples with LLVM as the root dir: '/dsk/src/llvm'
-
+
# path containing 'clang/__init__.py'
CLANG_BIND_DIR = "/dsk/src/llvm/tools/clang/bindings/python"
-
+
# path containing libclang.so
CLANG_LIB_DIR = "/opt/llvm/lib"
else:
import os
CLANG_BIND_DIR = os.environ.get("CLANG_BIND_DIR")
CLANG_LIB_DIR = os.environ.get("CLANG_LIB_DIR")
-
+
if CLANG_BIND_DIR is None:
print("$CLANG_BIND_DIR python binding dir not set")
if CLANG_LIB_DIR is None:
@@ -117,6 +117,7 @@ args = sys.argv[2:]
tu = index.parse(sys.argv[1], args)
# print('Translation unit: %s' % tu.spelling)
+filepath = tu.spelling
# -----------------------------------------------------------------------------
@@ -127,7 +128,7 @@ def function_parm_wash_tokens(parm):
CursorKind.VAR_DECL, # XXX, double check this
CursorKind.FIELD_DECL,
)
-
+
"""
Return tolens without trailing commads and 'const'
"""
@@ -135,14 +136,14 @@ def function_parm_wash_tokens(parm):
tokens = [t for t in parm.get_tokens()]
if not tokens:
return tokens
-
- #if tokens[-1].kind == To
+
+ # if tokens[-1].kind == To
# remove trailing char
if tokens[-1].kind == TokenKind.PUNCTUATION:
if tokens[-1].spelling in (",", ")", ";"):
tokens.pop()
- #else:
- # print(tokens[-1].spelling)
+ # else:
+ # print(tokens[-1].spelling)
t_new = []
for t in tokens:
@@ -156,17 +157,17 @@ def function_parm_wash_tokens(parm):
ok = False # __restrict
elif t_kind in (TokenKind.COMMENT, ):
ok = False
-
+
# Use these
elif t_kind in (TokenKind.LITERAL,
TokenKind.PUNCTUATION,
TokenKind.IDENTIFIER):
# use but ignore
pass
-
+
else:
print("Unknown!", t_kind, t_spelling)
-
+
# if its OK we will add
if ok:
t_new.append(t)
@@ -175,9 +176,9 @@ def function_parm_wash_tokens(parm):
def parm_size(node_child):
tokens = function_parm_wash_tokens(node_child)
-
+
# print(" ".join([t.spelling for t in tokens]))
-
+
# NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS
if len(tokens) >= 3: # foo [ 1 ]
if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and
@@ -200,14 +201,12 @@ def function_get_arg_sizes(node):
for i, node_child in enumerate(node_parms):
# print(node_child.kind, node_child.spelling)
- #print(node_child.type.kind, node_child.spelling) # TypeKind.POINTER
-
- if node_child.type.kind == TypeKind.POINTER:
+ # print(node_child.type.kind, node_child.spelling)
+ if node_child.type.kind == TypeKind.CONSTANTARRAY:
pointee = node_child.type.get_pointee()
- if pointee.is_pod():
- size = parm_size(node_child)
- if size != -1:
- arg_sizes[i] = size
+ size = parm_size(node_child)
+ if size != -1:
+ arg_sizes[i] = size
return arg_sizes
@@ -229,14 +228,14 @@ def lookup_function_size_def(func_id):
def file_check_arg_sizes(tu):
-
+
# main checking function
def validate_arg_size(node):
"""
Loop over args and validate sizes for args we KNOW the size of.
"""
assert node.kind == CursorKind.CALL_EXPR
-
+
if 0:
print("---",
" <~> ".join(
@@ -244,15 +243,15 @@ def file_check_arg_sizes(tu):
for C in node.get_children()]
))
# print(node.location)
-
+
# first child is the function call, skip that.
children = list(node.get_children())
if not children:
return # XXX, look into this, happens on C++
-
+
func = children[0]
-
+
# get the func declaration!
# works but we can better scan for functions ahead of time.
if 0:
@@ -264,42 +263,42 @@ def file_check_arg_sizes(tu):
print("AA", " ".join([t.spelling for t in node.get_tokens()]))
else:
args_size_definition = () # dummy
-
+
# get the key
tok = list(func.get_tokens())
if tok:
func_id = tok[0].spelling
args_size_definition = lookup_function_size_def(func_id)
-
+
if not args_size_definition:
return
children = children[1:]
for i, node_child in enumerate(children):
children = list(node_child.get_children())
-
+
# skip if we dont have an index...
size_def = args_size_definition.get(i, -1)
if size_def == -1:
continue
-
- #print([c.kind for c in children])
+
+ # print([c.kind for c in children])
# print(" ".join([t.spelling for t in node_child.get_tokens()]))
-
+
if len(children) == 1:
arg = children[0]
if arg.kind in (CursorKind.DECL_REF_EXPR,
CursorKind.UNEXPOSED_EXPR):
- if arg.type.kind == TypeKind.POINTER:
+ if arg.type.kind == TypeKind.CONSTANTARRAY:
dec = arg.get_definition()
if dec:
size = parm_size(dec)
-
+
# size == 0 is for 'float *a'
if size != -1 and size != 0:
-
+
# nice print!
if 0:
print("".join([t.spelling for t in func.get_tokens()]),
@@ -324,7 +323,7 @@ def file_check_arg_sizes(tu):
location.line,
location.column,
i + 1, size, size_def,
- args[0] # always the same but useful when running threaded
+ filepath # always the same but useful when running threaded
))
# we dont really care what we are looking at, just scan entire file for
@@ -350,8 +349,8 @@ def recursive_arg_sizes(node, ):
args_sizes = node
else:
args_sizes = function_get_arg_sizes(node)
- #if args_sizes:
- # print(node.spelling, args_sizes)
+ # if args_sizes:
+ # print(node.spelling, args_sizes)
_defs[node.spelling] = args_sizes
# print("adding", node.spelling)
for c in node.get_children():
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index c2044fcc21d..c2044fcc21d 100755..100644
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 17490e36bb3..17668f10c0c 100755..100644
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -68,7 +68,7 @@ def create_nb_project_main():
PROJECT_NAME = "Blender"
else:
# be tricky, get the project name from SVN if we can!
- PROJECT_NAME = project_name_get(SOURCE_DIR)
+ PROJECT_NAME = project_name_get()
# --------------- NB spesific
defines = [("%s=%s" % cdef) if cdef[1] else cdef[0] for cdef in defines]
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 4cf854aad77..76f1efa6ccb 100755..100644
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -92,8 +92,8 @@ def create_qtc_project_main():
if 0:
PROJECT_NAME = "Blender"
else:
- # be tricky, get the project name from SVN if we can!
- PROJECT_NAME = project_name_get(SOURCE_DIR)
+ # be tricky, get the project name from CMake if we can!
+ PROJECT_NAME = project_name_get()
FILE_NAME = PROJECT_NAME.lower()
f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w')
@@ -134,7 +134,7 @@ def create_qtc_project_python():
PROJECT_NAME = "Blender_Python"
else:
# be tricky, get the project name from SVN if we can!
- PROJECT_NAME = project_name_get(SOURCE_DIR) + "_Python"
+ PROJECT_NAME = project_name_get() + "_Python"
FILE_NAME = PROJECT_NAME.lower()
f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w')
diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py
index 17298599bdd..45b262a13ce 100644
--- a/build_files/cmake/cmake_static_check_clang_array.py
+++ b/build_files/cmake/cmake_static_check_clang_array.py
@@ -41,6 +41,8 @@ CHECKER_ARGS = [
os.path.join(os.path.dirname(__file__), "clang_array_check.py"),
# not sure why this is needed, but it is.
"-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
+ # stupid but needed
+ "-Dbool=char"
]
diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py
index aac522dfdd3..9f012cb7f6d 100644
--- a/build_files/cmake/cmake_static_check_cppcheck.py
+++ b/build_files/cmake/cmake_static_check_cppcheck.py
@@ -70,7 +70,7 @@ def main():
def my_process(i, c, cmd):
if not USE_QUIET:
- percent = 100.0 * (i / (len(check_commands) - 1))
+ percent = 100.0 * (i / len(check_commands))
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
sys.stdout.flush()
diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py
index ad8b872b22c..de13d141276 100644
--- a/build_files/cmake/cmake_static_check_smatch.py
+++ b/build_files/cmake/cmake_static_check_smatch.py
@@ -61,7 +61,7 @@ def main():
def my_process(i, c, cmd):
if not USE_QUIET:
- percent = 100.0 * (i / (len(check_commands) - 1))
+ percent = 100.0 * (i / len(check_commands))
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
sys.stdout.flush()
diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py
index ff6b1af98b7..2ee99925adb 100644
--- a/build_files/cmake/cmake_static_check_sparse.py
+++ b/build_files/cmake/cmake_static_check_sparse.py
@@ -59,7 +59,7 @@ def main():
def my_process(i, c, cmd):
if not USE_QUIET:
- percent = 100.0 * (i / (len(check_commands) - 1))
+ percent = 100.0 * (i / len(check_commands))
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
sys.stdout.flush()
diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py
index 6ad03f2bdca..5a967ecc7a3 100644
--- a/build_files/cmake/cmake_static_check_splint.py
+++ b/build_files/cmake/cmake_static_check_splint.py
@@ -89,7 +89,7 @@ def main():
def my_process(i, c, cmd):
if not USE_QUIET:
- percent = 100.0 * (i / (len(check_commands) - 1))
+ percent = 100.0 * (i / len(check_commands))
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
sys.stdout.write("%s %s\n" % (percent_str, c))
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index ca9aadd649c..bf5c4f9e103 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -51,3 +51,8 @@ set(WITH_RAYOPTIMIZATION OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
+
+if(APPLE)
+ set(WITH_CODEC_QUICKTIME OFF CACHE BOOL "" FORCE)
+endif()
+
diff --git a/build_files/cmake/example_scripts/cmake_linux_install.sh b/build_files/cmake/example_scripts/cmake_linux_install.sh
index 6ef50742c42..34bbe104b3b 100755..100644
--- a/build_files/cmake/example_scripts/cmake_linux_install.sh
+++ b/build_files/cmake/example_scripts/cmake_linux_install.sh
@@ -16,7 +16,7 @@ git submodule update --init --recursive
git submodule foreach git checkout master
git submodule foreach git pull --rebase origin master
-# create cmake dir
+# create build dir
mkdir ~/blender-git/build-cmake
cd ~/blender-git/build-cmake
@@ -25,7 +25,7 @@ cd ~/blender-git/build-cmake
cmake ../blender
# make blender, will take some time
-make
+make -j$(nproc)
# link the binary to blenders source directory to run quickly
ln -s ~/blender-git/build-cmake/bin/blender ~/blender-git/blender/blender.bin
diff --git a/build_files/cmake/example_scripts/make_quicky.py b/build_files/cmake/example_scripts/make_quicky.py
index 76d4df32f86..76d4df32f86 100755..100644
--- a/build_files/cmake/example_scripts/make_quicky.py
+++ b/build_files/cmake/example_scripts/make_quicky.py
diff --git a/build_files/cmake/example_scripts/make_quiet.sh b/build_files/cmake/example_scripts/make_quiet.sh
index 9e179201541..9e179201541 100755..100644
--- a/build_files/cmake/example_scripts/make_quiet.sh
+++ b/build_files/cmake/example_scripts/make_quiet.sh
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 5ff84eca248..c0934dee942 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -484,6 +484,77 @@ macro(TEST_STDBOOL_SUPPORT)
HAVE_STDBOOL_H)
endmacro()
+macro(TEST_UNORDERED_MAP_SUPPORT)
+ # - Detect unordered_map availability
+ # Test if a valid implementation of unordered_map exists
+ # and define the include path
+ # This module defines
+ # HAVE_UNORDERED_MAP, whether unordered_map implementation was found
+ #
+ # HAVE_STD_UNORDERED_MAP_HEADER, <unordered_map.h> was found
+ # HAVE_UNORDERED_MAP_IN_STD_NAMESPACE, unordered_map is in namespace std
+ # HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE, unordered_map is in namespace std::tr1
+ #
+ # UNORDERED_MAP_INCLUDE_PREFIX, include path prefix for unordered_map, if found
+ # UNORDERED_MAP_NAMESPACE, namespace for unordered_map, if found
+
+ include(CheckIncludeFileCXX)
+ CHECK_INCLUDE_FILE_CXX("unordered_map" HAVE_STD_UNORDERED_MAP_HEADER)
+ if(HAVE_STD_UNORDERED_MAP_HEADER)
+ # Even so we've found unordered_map header file it doesn't
+ # mean unordered_map and unordered_set will be declared in
+ # std namespace.
+ #
+ # Namely, MSVC 2008 have unordered_map header which declares
+ # unordered_map class in std::tr1 namespace. In order to support
+ # this, we do extra check to see which exactly namespace is
+ # to be used.
+
+ include(CheckCXXSourceCompiles)
+ CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
+ int main() {
+ std::unordered_map<int, int> map;
+ return 0;
+ }"
+ HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
+ message(STATUS "Found unordered_map/set in std namespace.")
+
+ set(HAVE_UNORDERED_MAP "TRUE")
+ set(UNORDERED_MAP_INCLUDE_PREFIX "")
+ set(UNORDERED_MAP_NAMESPACE "std")
+ else()
+ CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
+ int main() {
+ std::tr1::unordered_map<int, int> map;
+ return 0;
+ }"
+ HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
+ message(STATUS "Found unordered_map/set in std::tr1 namespace.")
+
+ set(HAVE_UNORDERED_MAP "TRUE")
+ set(UNORDERED_MAP_INCLUDE_PREFIX "")
+ set(UNORDERED_MAP_NAMESPACE "std::tr1")
+ else()
+ message(STATUS "Found <unordered_map> but cannot find either std::unordered_map "
+ "or std::tr1::unordered_map.")
+ endif()
+ endif()
+ else()
+ CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
+ message(STATUS "Found unordered_map/set in std::tr1 namespace.")
+
+ set(HAVE_UNORDERED_MAP "TRUE")
+ set(UNORDERED_MAP_INCLUDE_PREFIX "tr1")
+ set(UNORDERED_MAP_NAMESPACE "std::tr1")
+ else()
+ message(STATUS "Unable to find <unordered_map> or <tr1/unordered_map>. ")
+ endif()
+ endif()
+endmacro()
+
# when we have warnings as errors applied globally this
# needs to be removed for some external libs which we dont maintain.
diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py
index 5d756a6320f..fcd4501f231 100755..100644
--- a/build_files/cmake/project_info.py
+++ b/build_files/cmake/project_info.py
@@ -239,26 +239,5 @@ def cmake_compiler_defines():
return lines
-def project_name_get(path, fallback="Blender", prefix="Blender_"):
- if not os.path.isdir(os.path.join(path, ".svn")):
- return fallback
-
- import subprocess
- try:
- info = subprocess.Popen(["svn", "info", path],
- stdout=subprocess.PIPE).communicate()[0]
- except:
- # possibly 'svn' isnt found/installed
- return fallback
-
- # string version, we only want the URL
- info = info.decode(encoding="utf-8", errors="ignore")
-
- for l in info.split("\n"):
- l = l.strip()
- if l.startswith("URL"):
- # https://svn.blender.org/svnroot/bf-blender/branches/bmesh/blender
- # --> bmesh
- if "/branches/" in l:
- return prefix + l.rsplit("/branches/", 1)[-1].split("/", 1)[0]
- return fallback
+def project_name_get():
+ return cmake_cache_var("CMAKE_PROJECT_NAME")
diff --git a/build_files/package_spec/build_archive.py b/build_files/package_spec/build_archive.py
index 0329d16b1ec..0329d16b1ec 100755..100644
--- a/build_files/package_spec/build_archive.py
+++ b/build_files/package_spec/build_archive.py
diff --git a/build_files/package_spec/build_debian.sh b/build_files/package_spec/build_debian.sh
index 4594095451f..4594095451f 100755..100644
--- a/build_files/package_spec/build_debian.sh
+++ b/build_files/package_spec/build_debian.sh
diff --git a/build_files/package_spec/debian/rules b/build_files/package_spec/debian/rules
index 7a3d2d52adc..7a3d2d52adc 100755..100644
--- a/build_files/package_spec/debian/rules
+++ b/build_files/package_spec/debian/rules
diff --git a/build_files/scons/config/Modules/FindPython.py b/build_files/scons/config/Modules/FindPython.py
index f7956e96580..a0ead88ebb4 100644
--- a/build_files/scons/config/Modules/FindPython.py
+++ b/build_files/scons/config/Modules/FindPython.py
@@ -6,7 +6,7 @@ def FindPython():
python = "/usr"
abi_flags = "m" # Most common for linux distros
- version = "3.3"
+ version = "3.4"
_arch = platform.uname()[4] + "-linux-gnu"
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index 6a126d47620..aac7ed4fa04 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -26,10 +26,10 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
#bz2 is a standard osx dynlib
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
WITH_OSX_STATICPYTHON = True
-# python 3.3 uses precompiled libraries in bf svn /lib by default
+# python 3.4 uses precompiled libraries in bf svn /lib by default
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
@@ -82,13 +82,6 @@ BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf
WITH_BF_DDS = True
-#Color Management System
-WITH_BF_LCMS = False
-BF_LCMS = LIBDIR + '/lcms'
-BF_LCMS_INC = '${BF_LCMS}/include'
-BF_LCMS_LIB = 'lcms'
-BF_LCMS_LIBPATH = '${BF_LCMS}/lib'
-
WITH_BF_JPEG = True
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
@@ -206,7 +199,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
#Freestyle
WITH_BF_FREESTYLE = True
diff --git a/build_files/scons/config/freebsd8-config.py b/build_files/scons/config/freebsd8-config.py
deleted file mode 100644
index b7c6fed45c2..00000000000
--- a/build_files/scons/config/freebsd8-config.py
+++ /dev/null
@@ -1,205 +0,0 @@
-CC = 'gcc44'
-CXX = 'g++44'
-
-LCGDIR = '../lib/freebsd8'
-LIBDIR = "${LCGDIR}"
-
-BF_PYTHON_ABI_FLAGS = ''
-BF_PYTHON = '/usr/local'
-BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-BF_PYTHON_VERSION = '3.3'
-WITH_BF_STATICPYTHON = False
-BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
-BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
-BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
-BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = False
-BF_OPENAL = '/usr/local'
-BF_OPENAL_INC = '${BF_OPENAL}/include'
-BF_OPENAL_LIB = 'openal'
-BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
-
-BF_CXX = '/usr/local'
-WITH_BF_STATICCXX = False
-BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
-
-WITH_BF_JACK = True
-BF_JACK = '/usr/local'
-BF_JACK_INC = '${BF_JACK}/include/jack'
-BF_JACK_LIB = 'jack'
-BF_JACK_LIBPATH = '${BF_JACK}/lib'
-
-WITH_BF_SNDFILE = True
-BF_SNDFILE = '/usr/local'
-BF_SNDFILE_INC = '${BF_SNDFILE}/include/sndfile'
-BF_SNDFILE_LIB = 'sndfile'
-BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib'
-
-WITH_BF_SDL = True
-BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
-BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
-BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = False
-BF_OPENEXR = '/usr/local'
-# when compiling with your own openexr lib you might need to set...
-# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
-
-BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
-BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
-BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
-# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
-
-WITH_BF_DDS = True
-
-WITH_BF_JPEG = True
-BF_JPEG = '/usr/local'
-BF_JPEG_INC = '${BF_JPEG}/include'
-BF_JPEG_LIB = 'jpeg'
-
-WITH_BF_PNG = True
-BF_PNG = '/usr/local'
-BF_PNG_INC = '${BF_PNG}/include'
-BF_PNG_LIB = 'png'
-
-WITH_BF_TIFF = True
-BF_TIFF = '/usr/local'
-BF_TIFF_INC = '${BF_TIFF}/include'
-BF_TIFF_LIB = 'tiff'
-
-WITH_BF_ZLIB = True
-BF_ZLIB = '/usr'
-BF_ZLIB_INC = '${BF_ZLIB}/include'
-BF_ZLIB_LIB = 'z'
-
-WITH_BF_INTERNATIONAL = True
-
-WITH_BF_GAMEENGINE = False
-WITH_BF_PLAYER = True
-WITH_BF_OCEANSIM = True
-
-WITH_BF_BULLET = True
-BF_BULLET = '#extern/bullet2/src'
-BF_BULLET_INC = '${BF_BULLET}'
-BF_BULLET_LIB = 'extern_bullet'
-
-BF_FREETYPE = '/usr/local'
-BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
-BF_FREETYPE_LIB = 'freetype'
-
-WITH_BF_ICONV = True
-BF_ICONV = LIBDIR + "/iconv"
-BF_ICONV_INC = '${BF_ICONV}/include'
-BF_ICONV_LIB = 'iconv'
-BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
-
-WITH_BF_BINRELOC = True
-
-# enable ffmpeg support
-WITH_BF_FFMPEG = True
-BF_FFMPEG = '/usr/local'
-BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice'
-BF_FFMPEG_INC = '${BF_FFMPEG}/include'
-BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-
-# enable ogg, vorbis and theora in ffmpeg
-WITH_BF_OGG = True
-BF_OGG = '/usr/local'
-BF_OGG_INC = '${BF_OGG}/include'
-BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec'
-
-WITH_BF_OPENJPEG = True
-BF_OPENJPEG = '#extern/libopenjpeg'
-BF_OPENJPEG_LIB = ''
-BF_OPENJPEG_INC = '${BF_OPENJPEG}'
-BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
-
-WITH_BF_FFTW3 = True
-BF_FFTW3 = LIBDIR + '/usr/local'
-BF_FFTW3_INC = '${BF_FFTW3}/include'
-BF_FFTW3_LIB = 'fftw3'
-BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
-
-WITH_BF_REDCODE = False
-BF_REDCODE = '#extern/libredcode'
-BF_REDCODE_LIB = ''
-# BF_REDCODE_INC = '${BF_REDCODE}/include'
-BF_REDCODE_INC = '${BF_REDCODE}/../' #C files request "libredcode/format.h" which is in "#extern/libredcode/format.h", stupid but compiles for now.
-BF_REDCODE_LIBPATH='${BF_REDCODE}/lib'
-
-# Mesa Libs should go here if your using them as well....
-WITH_BF_STATICOPENGL = False
-BF_OPENGL = '/usr/local'
-BF_OPENGL_INC = '${BF_OPENGL}/include'
-BF_OPENGL_LIB = 'GL GLU X11 Xi Xxf86vm'
-BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
-BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
-
-WITH_BF_COLLADA = False
-BF_COLLADA = '#source/blender/collada'
-BF_COLLADA_INC = '${BF_COLLADA}'
-BF_COLLADA_LIB = 'bf_collada'
-BF_OPENCOLLADA = '/usr'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
-BF_PCRE = '/usr/local'
-BF_PCRE_LIB = 'pcre'
-BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
-BF_EXPAT = '/usr/local'
-BF_EXPAT_LIB = 'expat'
-BF_EXPAT_LIBPATH = '${BF_EXPAT}/lib'
-
-WITH_BF_OPENMP = True
-
-WITH_GHOST_XDND = False
-
-#Freestyle
-WITH_BF_FREESTYLE = True
-
-#Ray trace optimization
-WITH_BF_RAYOPTIMIZATION = True
-BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
-
-CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE','-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
-
-CPPFLAGS = []
-CXXFLAGS = []
-if WITH_BF_FFMPEG:
- # libavutil needs UINT64_C()
- CXXFLAGS += ['-D__STDC_CONSTANT_MACROS', ]
-REL_CFLAGS = []
-REL_CXXFLAGS = []
-REL_CCFLAGS = ['-DNDEBUG', '-O2']
-##BF_DEPEND = True
-##
-##AR = ar
-##ARFLAGS = ruv
-##ARFLAGSQUIET = ru
-##
-C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-prototypes']
-CC_WARN = ['-Wall']
-CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
-
-
-##FIX_STUBS_WARNINGS = -Wno-unused
-
-LLIBS = ['util', 'c', 'm', 'pthread', 'stdc++']
-##LOPTS = --dynamic
-##DYNLDFLAGS = -shared $(LDFLAGS)
-
-BF_PROFILE = False
-BF_PROFILE_CCFLAGS = ['-pg','-g']
-BF_PROFILE_LINKFLAGS = ['-pg']
-
-BF_DEBUG = False
-BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
-
-BF_BUILDDIR = '../build/freebsd8'
-BF_INSTALLDIR='../install/freebsd8'
-
-#Link against pthread
-PLATFORM_LINKFLAGS = ['-pthread']
diff --git a/build_files/scons/config/freebsd9-config.py b/build_files/scons/config/freebsd9-config.py
deleted file mode 100644
index 8535ececb24..00000000000
--- a/build_files/scons/config/freebsd9-config.py
+++ /dev/null
@@ -1,210 +0,0 @@
-CC = 'gcc44'
-CXX = 'g++44'
-
-LCGDIR = '../lib/freebsd9'
-LIBDIR = "${LCGDIR}"
-
-BF_PYTHON_ABI_FLAGS = ''
-BF_PYTHON = '/usr/local'
-BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-BF_PYTHON_VERSION = '3.3'
-WITH_BF_STATICPYTHON = False
-BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
-BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
-BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
-BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = False
-BF_OPENAL = '/usr/local'
-BF_OPENAL_INC = '${BF_OPENAL}/include'
-BF_OPENAL_LIB = 'openal'
-BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
-
-BF_CXX = '/usr/local'
-WITH_BF_STATICCXX = False
-BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
-
-WITH_BF_JACK = True
-BF_JACK = '/usr/local'
-BF_JACK_INC = '${BF_JACK}/include/jack'
-BF_JACK_LIB = 'jack'
-BF_JACK_LIBPATH = '${BF_JACK}/lib'
-
-WITH_BF_SNDFILE = True
-BF_SNDFILE = '/usr/local'
-BF_SNDFILE_INC = '${BF_SNDFILE}/include/sndfile'
-BF_SNDFILE_LIB = 'sndfile'
-BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib'
-
-WITH_BF_SDL = True
-BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
-BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
-BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = False
-BF_OPENEXR = '/usr/local'
-# when compiling with your own openexr lib you might need to set...
-# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
-
-BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
-BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
-BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
-# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
-
-WITH_BF_DDS = True
-
-WITH_BF_JPEG = True
-BF_JPEG = '/usr/local'
-BF_JPEG_INC = '${BF_JPEG}/include'
-BF_JPEG_LIB = 'jpeg'
-
-WITH_BF_PNG = True
-BF_PNG = '/usr/local'
-BF_PNG_INC = '${BF_PNG}/include'
-BF_PNG_LIB = 'png'
-
-WITH_BF_TIFF = True
-BF_TIFF = '/usr/local'
-BF_TIFF_INC = '${BF_TIFF}/include'
-BF_TIFF_LIB = 'tiff'
-
-WITH_BF_ZLIB = True
-BF_ZLIB = '/usr'
-BF_ZLIB_INC = '${BF_ZLIB}/include'
-BF_ZLIB_LIB = 'z'
-
-WITH_BF_INTERNATIONAL = True
-
-WITH_BF_GAMEENGINE = False
-WITH_BF_PLAYER = True
-WITH_BF_OCEANSIM = True
-
-WITH_BF_BULLET = True
-BF_BULLET = '#extern/bullet2/src'
-BF_BULLET_INC = '${BF_BULLET}'
-BF_BULLET_LIB = 'extern_bullet'
-
-BF_FREETYPE = '/usr/local'
-BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
-BF_FREETYPE_LIB = 'freetype'
-
-### XXX Find what this actually wants; it doesn't want libquicktime.
-WITH_BF_QUICKTIME = False
-BF_QUICKTIME = '/usr/local'
-BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
-
-WITH_BF_ICONV = True
-BF_ICONV = LIBDIR + "/iconv"
-BF_ICONV_INC = '${BF_ICONV}/include'
-BF_ICONV_LIB = 'iconv'
-BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
-
-WITH_BF_BINRELOC = True
-
-# enable ffmpeg support
-WITH_BF_FFMPEG = True
-BF_FFMPEG = '/usr/local'
-BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice'
-BF_FFMPEG_INC = '${BF_FFMPEG}/include'
-BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-
-# enable ogg, vorbis and theora in ffmpeg
-WITH_BF_OGG = True
-BF_OGG = '/usr/local'
-BF_OGG_INC = '${BF_OGG}/include'
-BF_OGG_LIB = 'ogg vorbis vorbisenc theoraenc theoradec'
-
-WITH_BF_OPENJPEG = True
-BF_OPENJPEG = '#extern/libopenjpeg'
-BF_OPENJPEG_LIB = ''
-BF_OPENJPEG_INC = '${BF_OPENJPEG}'
-BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
-
-WITH_BF_FFTW3 = True
-BF_FFTW3 = LIBDIR + '/usr/local'
-BF_FFTW3_INC = '${BF_FFTW3}/include'
-BF_FFTW3_LIB = 'fftw3'
-BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
-
-WITH_BF_REDCODE = False
-BF_REDCODE = '#extern/libredcode'
-BF_REDCODE_LIB = ''
-# BF_REDCODE_INC = '${BF_REDCODE}/include'
-BF_REDCODE_INC = '${BF_REDCODE}/../' #C files request "libredcode/format.h" which is in "#extern/libredcode/format.h", stupid but compiles for now.
-BF_REDCODE_LIBPATH='${BF_REDCODE}/lib'
-
-# Mesa Libs should go here if your using them as well....
-WITH_BF_STATICOPENGL = False
-BF_OPENGL = '/usr/local'
-BF_OPENGL_INC = '${BF_OPENGL}/include'
-BF_OPENGL_LIB = 'GL GLU X11 Xi Xxf86vm'
-BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
-BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
-
-WITH_BF_COLLADA = False
-BF_COLLADA = '#source/blender/collada'
-BF_COLLADA_INC = '${BF_COLLADA}'
-BF_COLLADA_LIB = 'bf_collada'
-BF_OPENCOLLADA = '/usr'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
-BF_PCRE = '/usr/local'
-BF_PCRE_LIB = 'pcre'
-BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
-BF_EXPAT = '/usr/local'
-BF_EXPAT_LIB = 'expat'
-BF_EXPAT_LIBPATH = '${BF_EXPAT}/lib'
-
-WITH_BF_OPENMP = True
-
-WITH_GHOST_XDND = False
-
-#Freestyle
-WITH_BF_FREESTYLE = True
-
-#Ray trace optimization
-WITH_BF_RAYOPTIMIZATION = True
-BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
-
-CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE','-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
-CXXFLAGS = []
-
-CPPFLAGS = []
-if WITH_BF_FFMPEG:
- # libavutil needs UINT64_C()
- CXXFLAGS += ['-D__STDC_CONSTANT_MACROS', ]
-REL_CFLAGS = []
-REL_CXXFLAGS = []
-REL_CCFLAGS = ['-DNDEBUG', '-O2']
-##BF_DEPEND = True
-##
-##AR = ar
-##ARFLAGS = ruv
-##ARFLAGSQUIET = ru
-##
-C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-prototypes']
-CC_WARN = ['-Wall']
-CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
-
-
-##FIX_STUBS_WARNINGS = -Wno-unused
-
-LLIBS = ['util', 'c', 'm', 'pthread', 'stdc++']
-##LOPTS = --dynamic
-##DYNLDFLAGS = -shared $(LDFLAGS)
-
-BF_PROFILE = False
-BF_PROFILE_CCFLAGS = ['-pg','-g']
-BF_PROFILE_LINKFLAGS = ['-pg']
-
-BF_DEBUG = False
-BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
-
-BF_BUILDDIR = '../build/freebsd9'
-BF_INSTALLDIR='../install/freebsd9'
-
-#Link against pthread
-PLATFORM_LINKFLAGS = ['-pthread']
diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py
index ce2d07f782c..8f2c5ca30f4 100644
--- a/build_files/scons/config/linux-config.py
+++ b/build_files/scons/config/linux-config.py
@@ -206,7 +206,7 @@ WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
WITH_BF_OPENMP = True
diff --git a/build_files/scons/config/linuxcross-config.py b/build_files/scons/config/linuxcross-config.py
deleted file mode 100644
index 36b29a309af..00000000000
--- a/build_files/scons/config/linuxcross-config.py
+++ /dev/null
@@ -1,189 +0,0 @@
-LCGDIR = '#../lib/windows'
-LIBDIR = '${LCGDIR}'
-
-BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
-BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
-BF_PYTHON_DLL = 'python31'
-BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = False
-BF_OPENAL = LIBDIR + '/openal'
-BF_OPENAL_INC = '${BF_OPENAL}/include'
-BF_OPENAL_LIB = 'OpenAL32 wrap_oal'
-BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
-# Warning, this static lib configuration is untested! users of this OS please confirm.
-BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
-
-# Warning, this static lib configuration is untested! users of this OS please confirm.
-BF_CXX = '/usr'
-WITH_BF_STATICCXX = False
-BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
-
-WITH_BF_SDL = True
-BF_SDL = LIBDIR + '/sdl'
-BF_SDL_INC = '${BF_SDL}/include'
-BF_SDL_LIB = 'SDL'
-BF_SDL_LIBPATH = '${BF_SDL}/lib'
-
-WITH_BF_JACK = False
-BF_JACK = LIBDIR + '/jack'
-BF_JACK_INC = '${BF_JACK}/include'
-BF_JACK_LIB = 'jack'
-BF_JACK_LIBPATH = '${BF_JACK}/lib'
-
-WITH_BF_SNDFILE = False
-BF_SNDFILE = LIBDIR + '/sndfile'
-BF_SNDFILE_INC = '${BF_SNDFILE}/include'
-BF_SNDFILE_LIB = 'sndfile-1'
-BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib'
-
-BF_PTHREADS = LIBDIR + '/pthreads'
-BF_PTHREADS_INC = '${BF_PTHREADS}/include'
-BF_PTHREADS_LIB = 'pthreadGC2'
-BF_PTHREADS_LIBPATH = '${BF_PTHREADS}/lib'
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = False
-BF_OPENEXR = LIBDIR + '/gcc/openexr'
-BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
-BF_OPENEXR_LIB = ' Half IlmImf Iex IlmThread '
-BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
-# Warning, this static lib configuration is untested! users of this OS please confirm.
-BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
-
-WITH_BF_DDS = True
-
-WITH_BF_JPEG = True
-BF_JPEG = LIBDIR + '/jpeg'
-BF_JPEG_INC = '${BF_JPEG}/include'
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
-
-WITH_BF_PNG = True
-BF_PNG = LIBDIR + '/png'
-BF_PNG_INC = '${BF_PNG}/include'
-BF_PNG_LIB = 'png'
-BF_PNG_LIBPATH = '${BF_PNG}/lib'
-
-WITH_BF_TIFF = True
-BF_TIFF = LIBDIR + '/gcc/tiff'
-BF_TIFF_INC = '${BF_TIFF}/include'
-BF_TIFF_LIB = 'tiff'
-BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
-
-WITH_BF_ZLIB = True
-BF_ZLIB = LIBDIR + '/zlib'
-BF_ZLIB_INC = '${BF_ZLIB}/include'
-BF_ZLIB_LIB = 'libz_st'
-BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
-
-WITH_BF_INTERNATIONAL = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_PLAYER = False
-WITH_BF_OCEANSIM = True
-
-WITH_BF_BULLET = True
-BF_BULLET = '#extern/bullet2/src'
-BF_BULLET_INC = '${BF_BULLET}'
-BF_BULLET_LIB = 'extern_bullet'
-
-BF_WINTAB = LIBDIR + '/wintab'
-BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE'
-
-BF_WITH_FREETYPE = True
-BF_FREETYPE = LIBDIR + '/gcc/freetype'
-BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
-BF_FREETYPE_LIB = 'freetype'
-BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
-
-WITH_BF_ICONV = False
-BF_ICONV = LIBDIR + "/gcc/iconv"
-BF_ICONV_INC = '${BF_ICONV}/include'
-BF_ICONV_LIB = 'iconv'
-BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
-
-WITH_BF_BINRELOC = False
-
-# enable ffmpeg support
-WITH_BF_FFMPEG = True
-BF_FFMPEG = LIBDIR + '/ffmpeg'
-BF_FFMPEG_LIB = 'avformat-53 avcodec-53 avdevice-53 avutil-51 swscale-2'
-BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
-BF_FFMPEG_INC = '${BF_FFMPEG}/include'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib'
-BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
-
-WITH_BF_OPENJPEG = True
-BF_OPENJPEG = '#extern/libopenjpeg'
-BF_OPENJPEG_LIB = ''
-BF_OPENJPEG_INC = '${BF_OPENJPEG}'
-BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
-
-WITH_BF_FFTW3 = False
-BF_FFTW3 = LIBDIR + '/gcc/fftw3'
-BF_FFTW3_INC = '${BF_FFTW3}/include'
-BF_FFTW3_LIB = 'fftw3'
-BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
-
-WITH_BF_REDCODE = False
-BF_REDCODE_INC = '#extern'
-
-# Mesa Libs should go here if your using them as well....
-WITH_BF_STATICOPENGL = False
-BF_OPENGL = 'C:\\MingW'
-BF_OPENGL_INC = '${BF_OPENGL}/include'
-BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
-BF_OPENGL_LIB = 'opengl32 glu32'
-BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a']
-
-WITH_BF_OPENMP = False
-BF_OPENMP = LIBDIR + '/gcc/gomp'
-BF_OPENMP_INC = '${BF_OPENMP}/include'
-BF_OPENMP_LIBPATH = '${BF_OPENMP}/lib'
-
-WITH_BF_COLLADA = False
-BF_COLLADA = '#source/blender/collada'
-BF_COLLADA_INC = '${BF_COLLADA}'
-BF_COLLADA_LIB = 'bf_collada'
-
-BF_OPENCOLLADA = LIBDIR + '/gcc/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib ${BF_ICONV_LIBPATH}'
-
-#Freestyle
-WITH_BF_FREESTYLE = True
-
-#Ray trace optimization
-WITH_BF_RAYOPTIMIZATION = True
-BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
-
-CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
-CXXFLAGS = []
-
-CPPFLAGS = ['-DWIN32', '-DFREE_WINDOWS', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE64_SOURCE']
-REL_CFLAGS = []
-REL_CXXFLAGS = []
-REL_CCFLAGS = ['-DNDEBUG', '-O2']
-C_WARN = ['-Wall', '-Wstrict-prototypes', '-Wno-char-subscripts', '-Wdeclaration-after-statement']
-
-CC_WARN = [ '-Wall' ]
-
-LLIBS = [ '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++', '-luuid', '-lole32'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread' ]
-
-PLATFORM_LINKFLAGS = ['--stack,2097152']
-
-BF_DEBUG = False
-BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
-
-BF_PROFILE = False
-BF_PROFILE_CCFLAGS = ['-pg','-g']
-BF_PROFILE_LINKFLAGS = ['-pg']
-
-BF_BUILDDIR = '../build/linuxcross'
-BF_INSTALLDIR='../install/linuxcross'
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index 213efcbb2df..a6d1a7d7996 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw32'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
-BF_PYTHON_DLL = 'python33'
+BF_PYTHON_DLL = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a'
@@ -18,10 +18,10 @@ BF_OPENAL_LIB = 'wrap_oal'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_FFMPEG = True
-BF_FFMPEG_LIB = 'avformat-53 avcodec-53 avdevice-53 avutil-51 swscale-2'
+BF_FFMPEG_LIB = 'avformat-55 avcodec-55 avdevice-55 avutil-52 swscale-2'
BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
BF_FFMPEG_INC = LIBDIR + '/ffmpeg/include'
-BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
+BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-55.dll ${BF_FFMPEG_LIBPATH}/avcodec-55.dll ${BF_FFMPEG_LIBPATH}/avdevice-55.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
WITH_BF_JACK = False
BF_JACK = LIBDIR + '/jack'
@@ -145,7 +145,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
@@ -175,7 +175,7 @@ WITH_BF_OPENMP = True
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
#Freestyle
WITH_BF_FREESTYLE = True
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 90a02820f8c..54ab4af318e 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -27,17 +27,19 @@ if VC_VERSION == '11.0':
BF_FFMPEG_LIB = 'avformat-54.lib avcodec-54.lib avdevice-54.lib avutil-52.lib avfilter-3.lib swscale-2.lib swresample-0.lib'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-54.dll ${BF_FFMPEG_LIBPATH}/avcodec-54.dll ${BF_FFMPEG_LIBPATH}/avdevice-54.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/avfilter-3.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll'
else:
- BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
- BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
+ BF_FFMPEG_LIB = 'avformat-55.lib avcodec-55.lib avdevice-55.lib avutil-52.lib swscale-2.lib'
+ BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-55.dll ${BF_FFMPEG_LIBPATH}/avcodec-55.dll ${BF_FFMPEG_LIBPATH}/avdevice-55.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python33'
+BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
+WITH_BF_PYTHON_INSTALL_NUMPY = False
+
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
@@ -226,7 +228,7 @@ WITH_BF_CYCLES_CUDA_BINARIES = False
if VC_VERSION == '11.0':
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
else:
- BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+ BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
@@ -246,7 +248,7 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
CC = 'cl.exe'
CXX = 'cl.exe'
-CCFLAGS = ['/nologo', '/J', '/W1', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013']
+CCFLAGS = ['/nologo', '/J', '/W3', '/Gd', '/w34062', '/wd4018', '/wd4065', '/wd4127', '/wd4181', '/wd4200', '/wd4244', '/wd4267', '/wd4305', '/wd4800', '/we4013', '/we4431']
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/Ob2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE']
@@ -272,7 +274,11 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/IN
BF_BSC=False
-if VC_VERSION == '11.0':
+if VC_VERSION == '12.0':
+ BF_CYCLES_CUDA_ENV="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd"
+ BF_BUILDDIR = '..\\build\\win32-vc12'
+ BF_INSTALLDIR='..\\install\\win32-vc12'
+elif VC_VERSION == '11.0':
BF_BUILDDIR = '..\\build\\win32-vc11'
BF_INSTALLDIR='..\\install\\win32-vc11'
else:
diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py
index bb55354d591..dcdea6583d7 100644
--- a/build_files/scons/config/win64-mingw-config.py
+++ b/build_files/scons/config/win64-mingw-config.py
@@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw64'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
-BF_PYTHON_DLL = 'python33'
+BF_PYTHON_DLL = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True
@@ -144,7 +144,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
@@ -169,8 +169,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-mmmx', '-msse', '-msse2']
-#May produce errors with unsupported MinGW-w64 builds
-WITH_BF_OPENMP = False
+WITH_BF_OPENMP = True
#Freestyle
WITH_BF_FREESTYLE = True
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 10994d3843c..87af137814f 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -27,18 +27,20 @@ if VC_VERSION == '11.0':
BF_FFMPEG_LIB = 'avformat-54.lib avcodec-54.lib avdevice-54.lib avutil-52.lib avfilter-3.lib swscale-2.lib swresample-0.lib'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-54.dll ${BF_FFMPEG_LIBPATH}/avcodec-54.dll ${BF_FFMPEG_LIBPATH}/avdevice-54.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/avfilter-3.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll'
else:
- BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
- BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
+ BF_FFMPEG_LIB = 'avformat-55.lib avcodec-55.lib avdevice-55.lib avutil-52.lib swscale-2.lib'
+ BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-55.dll ${BF_FFMPEG_LIBPATH}/avcodec-55.dll ${BF_FFMPEG_LIBPATH}/avdevice-55.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.3'
+BF_PYTHON_VERSION = '3.4'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python33'
+BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
+WITH_BF_PYTHON_INSTALL_NUMPY = False
+
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
@@ -224,7 +226,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
@@ -245,7 +247,12 @@ CC = 'cl.exe'
CXX = 'cl.exe'
CFLAGS = []
-CCFLAGS = ['/nologo', '/J', '/W1', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
+CCFLAGS = ['/nologo', '/J', '/W3', '/Gd', '/w34062', '/wd4018', '/wd4065', '/wd4127', '/wd4181', '/wd4200', '/wd4244', '/wd4267', '/wd4305', '/wd4800', '/we4013', '/we4431']
+
+# We want to support Vista level ABI for x64
+if VC_VERSION == '12.0':
+ CCFLAGS.append('/D_WIN32_WINNT=0x600')
+
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/Ob2', '/EHsc', '/GR', '/fp:fast']
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 94346b9e9b0..496f90d0bea 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -263,11 +263,9 @@ def setup_syslibs(lenv):
if lenv['WITH_BF_OPENAL']:
if not lenv['WITH_BF_STATICOPENAL']:
syslibs += Split(lenv['BF_OPENAL_LIB'])
- if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc' and not lenv['WITH_BF_STATICOPENMP']:
+ if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc' and lenv['C_COMPILER_ID'] != 'clang' and not lenv['WITH_BF_STATICOPENMP']:
if lenv['CC'] == 'cl.exe':
syslibs += ['vcomp']
- elif lenv['OURPLATFORM']=='darwin' and lenv['C_COMPILER_ID'] == 'clang' and lenv['CCVERSION'] >= '3.4': # clang-omp-3.4 !
- syslibs += ['iomp5']
else:
syslibs += ['gomp']
if lenv['WITH_BF_ICONV']:
@@ -428,9 +426,23 @@ def buildinfo(lenv, build_type):
build_hash = build_hash.strip()
build_branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
+ if build_branch == 'HEAD':
+ master_check = os.popen('git branch --list master --contains ' + build_hash).read().strip()
+ if master_check == 'master':
+ build_branch = 'master'
+ else:
+ head_hash = os.popen('git rev-parse HEAD').read().strip()
+ tag_hashes = os.popen('git show-ref --tags -d').read()
+ if tag_hashes.find(head_hash) != -1:
+ build_branch = 'master'
+
if build_hash == '':
build_hash = os.popen('git rev-parse --short HEAD').read().strip()
no_upstream = True
+ else:
+ older_commits = os.popen('git log --oneline HEAD..@{u}').read().strip()
+ if older_commits:
+ build_hash = os.popen('git rev-parse --short HEAD').read().strip()
# ## Check for local modifications
has_local_changes = False
@@ -442,7 +454,7 @@ def buildinfo(lenv, build_type):
if changed_files:
has_local_changes = True
elif no_upstream == False:
- unpushed_log = os.popen('git log @{u}..').read().strip()
+ unpushed_log = os.popen('git log --oneline @{u}..').read().strip()
has_local_changes = unpushed_log != ''
if has_local_changes:
@@ -588,17 +600,13 @@ def my_winpybundle_print(target, source, env):
def WinPyBundle(target=None, source=None, env=None):
import re
- py_tar= env.subst( env['LCGDIR'] )
- if py_tar[0]=='#':
- py_tar= py_tar[1:]
+ py_tar = env.subst(env['LCGDIR']).lstrip("#")
if env['BF_DEBUG']:
py_tar+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_d.tar.gz'
else:
py_tar+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '.tar.gz'
- py_target = env.subst( env['BF_INSTALLDIR'] )
- if py_target[0]=='#':
- py_target=py_target[1:]
+ py_target = env.subst(env['BF_INSTALLDIR']).lstrip("#")
py_target = os.path.join(py_target, VERSION, 'python', 'lib')
def printexception(func,path,ex):
if os.path.exists(path): #do not report if path does not exist. eg on a fresh build.
@@ -619,6 +627,34 @@ def WinPyBundle(target=None, source=None, env=None):
print "Unpacking '" + py_tar + "' to '" + py_target + "'"
untar_pybundle(py_tar,py_target,exclude_re)
+ # -------------
+ # Extract Numpy
+ if env['WITH_BF_PYTHON_INSTALL_NUMPY']:
+ py_tar = env.subst(env['LCGDIR']).lstrip("#")
+ py_tar += '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_numpy_1.8.tar.gz'
+
+ py_target = env.subst(env['BF_INSTALLDIR']).lstrip("#")
+ py_target = os.path.join(py_target, VERSION, 'python', 'lib', 'site-packages')
+ # rmtree handled above
+ # files are cleaned up in their archive
+ exclude_re = []
+ print("Unpacking '" + py_tar + "' to '" + py_target + "'")
+ untar_pybundle(py_tar, py_target, exclude_re)
+
+ # --------------------
+ # Copy 'site-packages'
+ py_dir = env.subst(env['LCGDIR']).lstrip("#")
+ py_dir += '/release/site-packages'
+ # grr, we have to do one by one because the dir exists
+ for f in os.listdir(py_dir):
+ fn_src = os.path.join(py_dir, f)
+ fn_dst = os.path.join(py_target, f)
+
+ shutil.rmtree(fn_dst, False, printexception)
+ shutil.copytree(fn_src, fn_dst)
+
+
+
def my_appit_print(target, source, env):
a = '%s' % (target[0])
d, f = os.path.split(a)
@@ -669,12 +705,12 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'cp -R %s/release/datafiles/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
- cmd = 'cp -R %s/release/datafiles/locale/languages %s/%s.app/Contents/MacOS/%s/datafiles/locale/'%(bldroot, installdir, binary, VERSION)
- commands.getoutput(cmd)
mo_dir = os.path.join(builddir[:-4], "locale")
for f in os.listdir(mo_dir):
cmd = 'ditto %s/%s %s/%s.app/Contents/MacOS/%s/datafiles/locale/%s/LC_MESSAGES/blender.mo'%(mo_dir, f, installdir, binary, VERSION, f[:-3])
commands.getoutput(cmd)
+ cmd = 'cp %s/release/datafiles/locale/languages %s/%s.app/Contents/MacOS/%s/datafiles/locale/'%(bldroot, installdir, binary, VERSION)
+ commands.getoutput(cmd)
if env['WITH_BF_OCIO']:
cmd = 'cp -R %s/release/datafiles/colormanagement %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
@@ -703,7 +739,7 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'cp -R %s/kernel/*.h %s/kernel/*.cl %s/kernel/*.cu %s/kernel/' % (croot, croot, croot, cinstalldir)
commands.getoutput(cmd)
- cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_transform.h %s/util/util_types.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, cinstalldir)
+ cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/kernel/geom %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_transform.h %s/util/util_types.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, croot, cinstalldir)
commands.getoutput(cmd)
cmd = 'cp -R %s/../intern/cycles/kernel/*.cubin %s/lib/' % (builddir, cinstalldir)
commands.getoutput(cmd)
@@ -721,6 +757,8 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
commands.getoutput(cmd)
+ cmd = 'cp -R %s/release/site-packages/ %s/%s.app/Contents/MacOS/%s/python/lib/python%s/site-packages/'%(libdir,installdir,binary,VERSION,env['BF_PYTHON_VERSION'])
+ commands.getoutput(cmd)
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
commands.getoutput(cmd)
@@ -730,32 +768,33 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
commands.getoutput(cmd)
- if env['C_COMPILER_ID'] == 'gcc' and env['CCVERSION'] >= '4.6.1': # for correct errorhandling with gcc >= 4.6.1 we need the gcc.dylib and gomp.dylib to link, thus distribute in app-bundle
- print "Bundling libgcc and libgomp"
- instname = env['BF_CXX']
- cmd = 'ditto --arch %s %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgcc
- commands.getoutput(cmd)
- cmd = 'install_name_tool -id @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgcc_s.1.dylib'%(installdir, binary) # change id of libgcc
- commands.getoutput(cmd)
- cmd = 'ditto --arch %s %s/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgomp
- commands.getoutput(cmd)
- cmd = 'install_name_tool -id @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(installdir, binary) # change id of libgomp
- commands.getoutput(cmd)
- cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(instname, installdir, binary) # change ref to libgcc
- commands.getoutput(cmd)
- cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgcc ( blender )
- commands.getoutput(cmd)
- cmd = 'install_name_tool -change %s/lib/libgomp.1.dylib @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgomp ( blender )
- commands.getoutput(cmd)
- if env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4':
- print "Bundling libiomp5"
- instname = env['BF_CXX']
- cmd = 'ditto --arch %s %s/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libiomp5
- commands.getoutput(cmd)
- cmd = 'install_name_tool -id @executable_path/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/lib/libiomp5.dylib'%(installdir, binary) # change id of libiomp5
- commands.getoutput(cmd)
- cmd = 'install_name_tool -change %s/lib/libiomp5.dylib @executable_path/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libiomp5 ( blender )
- commands.getoutput(cmd)
+ if env['WITH_BF_OPENMP']:
+ if env['C_COMPILER_ID'] == 'gcc' and env['CCVERSION'] >= '4.6.1': # for correct errorhandling with gcc >= 4.6.1 we need the gcc.dylib and gomp.dylib to link, thus distribute in app-bundle
+ print "Bundling libgcc and libgomp"
+ instname = env['BF_CXX']
+ cmd = 'ditto --arch %s %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgcc
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -id @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgcc_s.1.dylib'%(installdir, binary) # change id of libgcc
+ commands.getoutput(cmd)
+ cmd = 'ditto --arch %s %s/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgomp
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -id @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(installdir, binary) # change id of libgomp
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(instname, installdir, binary) # change ref to libgcc
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgcc ( blender )
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgomp.1.dylib @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgomp ( blender )
+ commands.getoutput(cmd)
+ if env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4':
+ print "Bundling libiomp5"
+ instname = env['LCGDIR'][1:] # made libiomp5 part of blender libs
+ cmd = 'ditto --arch %s %s/openmp/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libiomp5
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -id @loader_path/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/lib/libiomp5.dylib'%(installdir, binary) # change id of libiomp5
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change @loader_path/libiomp5.dylib @loader_path/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/%s'%(installdir, binary, binary) # change ref to libiomp5 ( blender )
+ commands.getoutput(cmd)
# extract copy system python, be sure to update other build systems
# when making changes to the files that are copied.
@@ -835,6 +874,17 @@ def UnixPyBundle(target=None, source=None, env=None):
run("find '%s' -type d -name '*.a' -prune -exec rm -rf {} ';'" % numpy_target)
else:
print 'Failed to find numpy at %s, skipping copying' % numpy_src
+ del numpy_src, numpy_target
+
+ if env['WITH_BF_PYTHON_INSTALL_REQUESTS']:
+ requests_src = py_src + "/site-packages/requests"
+ requests_target = py_target + "/site-packages/requests"
+ if os.path.exists(requests_src):
+ run("cp -R '%s' '%s'" % (requests_src, os.path.dirname(requests_target)))
+ run("find '%s' -type d -name '*.pem -prune -exec rm -rf {} ';'" % requests_target)
+ else:
+ print('Failed to find requests at %s, skipping copying' % requests_src)
+ del requests_src, requests_target
run("find '%s' -type d -name 'test' -prune -exec rm -rf {} ';'" % py_target)
run("find '%s' -type d -name '__pycache__' -exec rm -rf {} ';'" % py_target)
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 744896cef2d..3450f292668 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -124,7 +124,8 @@ def validate_arguments(args, bc):
'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
'WITHOUT_BF_INSTALL',
- 'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK', 'WITH_BF_PYTHON_INSTALL_NUMPY',
+ 'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK',
+ 'WITH_BF_PYTHON_INSTALL_NUMPY', 'WITH_BF_PYTHON_INSTALL_REQUESTS',
'WITHOUT_BF_OVERWRITE_INSTALL',
'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH', 'WITH_BF_STATICOPENMP', 'BF_OPENMP_STATIC_STATIC',
'WITH_GHOST_SDL',
@@ -520,7 +521,8 @@ def read_opts(env, cfg, args):
(BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
(BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
(BoolVariable('WITHOUT_BF_PYTHON_INSTALL', 'dont install Python modules if true', False)),
- (BoolVariable('WITH_BF_PYTHON_INSTALL_NUMPY', 'install Python mumpy module', False)),
+ (BoolVariable('WITH_BF_PYTHON_INSTALL_NUMPY', 'install Python numpy module', False)),
+ (BoolVariable('WITH_BF_PYTHON_INSTALL_REQUESTS', 'install Python requests module', False)),
(BoolVariable('WITHOUT_BF_PYTHON_UNPACK', 'dont remove and unpack Python modules everytime if true', False)),
(BoolVariable('WITHOUT_BF_OVERWRITE_INSTALL', 'dont remove existing files before breating the new install directory (set to False when making packages for others)', False)),
(BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
diff --git a/build_files/scons/tools/unordered_map.py b/build_files/scons/tools/unordered_map.py
new file mode 100644
index 00000000000..d314a777b0c
--- /dev/null
+++ b/build_files/scons/tools/unordered_map.py
@@ -0,0 +1,32 @@
+def test_unordered_map(conf):
+ """
+ Detect unordered_map availability
+
+ Returns (True/False, namespace, include prefix)
+ """
+
+ if conf.CheckCXXHeader("unordered_map"):
+ # Even so we've found unordered_map header file it doesn't
+ # mean unordered_map and unordered_set will be declared in
+ # std namespace.
+ #
+ # Namely, MSVC 2008 have unordered_map header which declares
+ # unordered_map class in std::tr1 namespace. In order to support
+ # this, we do extra check to see which exactly namespace is
+ # to be used.
+
+ if conf.CheckType('std::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
+ print("-- Found unordered_map/set in std namespace.")
+ return True, 'std', ''
+ elif conf.CheckType('std::tr1::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
+ print("-- Found unordered_map/set in std::tr1 namespace.")
+ return True, 'std::tr1', ''
+ else:
+ print("-- Found <unordered_map> but can not find neither std::unordered_map nor std::tr1::unordered_map.")
+ return False, '', ''
+ elif conf.CheckCXXHeader("tr1/unordered_map"):
+ print("-- Found unordered_map/set in std::tr1 namespace.")
+ return True, 'std::tr1', 'tr1/'
+ else:
+ print("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
+ return False, '', ''
diff --git a/doc/blender_file_format/BlendFileDnaExporter_25.py b/doc/blender_file_format/BlendFileDnaExporter_25.py
index 837b67c6eed..837b67c6eed 100755..100644
--- a/doc/blender_file_format/BlendFileDnaExporter_25.py
+++ b/doc/blender_file_format/BlendFileDnaExporter_25.py
diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1
index 9cefe7a2b24..b7d96dcbb3b 100644
--- a/doc/manpage/blender.1
+++ b/doc/manpage/blender.1
@@ -1,4 +1,4 @@
-.TH "BLENDER" "1" "February 14, 2013" "Blender Blender 2\&.66"
+.TH "BLENDER" "1" "March 6, 2014" "Blender Blender 2\&.70"
.SH NAME
blender \- a 3D modelling and rendering package
diff --git a/doc/manpage/blender.1.py b/doc/manpage/blender.1.py
index f5a5148f132..646b2aa374b 100644
--- a/doc/manpage/blender.1.py
+++ b/doc/manpage/blender.1.py
@@ -69,9 +69,9 @@ fw('''
.SH DESCRIPTION
.PP
.B blender
-is a 3D modelling and rendering package. It is the in-house software of a high quality animation studio, Blender has proven to be an extremely fast and versatile design instrument. The software has a personal touch, offering a unique approach to the world of Three Dimensions.
+is a 3D modelling and rendering package. Originating as the in-house software of a high quality animation studio, Blender has proven to be an extremely fast and versatile design instrument. The software has a personal touch, offering a unique approach to the world of Three Dimensions.
-Use Blender to create TV commercials, to make technical visualizations, business graphics, to do some morphing, or design user interfaces. You can easy build and manage complex environments. The renderer is versatile and extremely fast. All basic animation principles (curves & keys) are well implemented.
+Use Blender to create TV commercials, to make technical visualizations, business graphics, to create content for games, or design user interfaces. You can easy build and manage complex environments. The renderer is versatile and extremely fast. All basic animation principles (curves & keys) are well implemented.
http://www.blender.org''')
@@ -119,7 +119,7 @@ while lines:
fw('''
.br
.SH SEE ALSO
-.B yafaray(1)
+.B luxrender(1)
.br
.SH AUTHORS
diff --git a/doc/python_api/rst/bge.constraints.rst b/doc/python_api/rst/bge.constraints.rst
index 7757e11d41f..4d3e4ce880f 100644
--- a/doc/python_api/rst/bge.constraints.rst
+++ b/doc/python_api/rst/bge.constraints.rst
@@ -78,7 +78,7 @@ Physics Constraints (bge.constraints)
:return: a vehicle constraint object.
:rtype: :class:`bge.types.KX_VehicleWrapper`
-
+
.. function:: getCharacter(gameobj)
:arg gameobj: The game object with the character physics.
@@ -237,101 +237,101 @@ Physics Constraints (bge.constraints)
Not implemented.
.. data:: DBG_NODEBUG
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
No debug.
.. data:: DBG_DRAWWIREFRAME
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw wireframe in debug.
.. data:: DBG_DRAWAABB
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw Axis Aligned Bounding Box in debug.
.. data:: DBG_DRAWFREATURESTEXT
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw freatures text in debug.
.. data:: DBG_DRAWCONTACTPOINTS
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw contact points in debug.
.. data:: DBG_NOHELPTEXT
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Debug without help text.
.. data:: DBG_DRAWTEXT
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw text in debug.
.. data:: DBG_PROFILETIMINGS
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw profile timings in debug.
.. data:: DBG_ENABLESATCOMPARISION
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Enable sat comparision in debug.
.. data:: DBG_DISABLEBULLETLCP
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Disable Bullet LCP.
.. data:: DBG_ENABLECCD
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Enable Continous Colision Detection in debug.
.. data:: DBG_DRAWCONSTRAINTS
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw constraints in debug.
.. data:: DBG_DRAWCONSTRAINTLIMITS
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw constraint limits in debug.
.. data:: DBG_FASTWIREFRAME
-
+
.. note::
Debug mode to be used with function :class:`setDebugMode`
-
+
Draw a fast wireframe in debug.
.. data:: POINTTOPOINT_CONSTRAINT
diff --git a/doc/python_api/rst/bge.events.rst b/doc/python_api/rst/bge.events.rst
index 2238faea242..8dbded6a3fe 100644
--- a/doc/python_api/rst/bge.events.rst
+++ b/doc/python_api/rst/bge.events.rst
@@ -14,7 +14,7 @@ This module holds key constants for the SCA_KeyboardSensor.
# Set a connected keyboard sensor to accept F1
import bge
-
+
co = bge.logic.getCurrentController()
# 'Keyboard' is a keyboard sensor
sensor = co.sensors["Keyboard"]
@@ -24,7 +24,7 @@ This module holds key constants for the SCA_KeyboardSensor.
# Do the all keys thing
import bge
-
+
co = bge.logic.getCurrentController()
# 'Keyboard' is a keyboard sensor
sensor = co.sensors["Keyboard"]
@@ -46,20 +46,20 @@ This module holds key constants for the SCA_KeyboardSensor.
# The all keys thing without a keyboard sensor (but you will
# need an always sensor with pulse mode on)
import bge
-
+
# Just shortening names here
keyboard = bge.logic.keyboard
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
-
+
if keyboard.events[bge.events.WKEY] == JUST_ACTIVATED:
print("Activate Forward!")
if keyboard.events[bge.events.SKEY] == JUST_ACTIVATED:
- print("Activate Backward!")
+ print("Activate Backward!")
if keyboard.events[bge.events.AKEY] == JUST_ACTIVATED:
- print("Activate Left!")
+ print("Activate Left!")
if keyboard.events[bge.events.DKEY] == JUST_ACTIVATED:
print("Activate Right!")
-
+
*********
Functions
@@ -72,11 +72,11 @@ Functions
:arg event: key event constant from :mod:`bge.events` or the keyboard sensor.
:type event: int
:rtype: string
-
+
.. function:: EventToCharacter(event, shift)
Return the string name of a key event. Returns an empty string if the event cant be represented as a character.
-
+
:type event: int
:arg event: key event constant from :mod:`bge.events` or the keyboard sensor.
:type shift: bool
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst b/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
index 32e5c3eaad8..4d9dd5b5c34 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
@@ -34,7 +34,7 @@ base class --- :class:`PyObjectPlus`
:type: int
.. attribute:: walkDirection
-
+
The speed and direction the character is traveling in using world coordinates. This should be used instead of applyMovement() to properly move the character.
:type: list [x, y, z]
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
index a4c02ee6fec..b314a47c8e9 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
@@ -12,7 +12,7 @@ base class --- :class:`SCA_IObject`
Properties assigned to game objects are accessible as attributes of this class.
.. note::
-
+
Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError,
if an object may have been removed since last accessing it use the :data:`invalid` attribute to check.
@@ -75,25 +75,25 @@ base class --- :class:`SCA_IObject`
:type: float
.. note::
-
+
The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0.
-
+
.. attribute:: linVelocityMin
Enforces the object keeps moving at a minimum velocity.
:type: float
-
+
.. note::
-
+
Applies to dynamic and rigid body objects only.
.. note::
-
+
A value of 0.0 disables this option.
.. note::
-
+
While objects are stationary the minimum velocity will not be applied.
.. attribute:: linVelocityMax
@@ -101,9 +101,9 @@ base class --- :class:`SCA_IObject`
Clamp the maximum linear velocity to prevent objects moving beyond a set speed.
:type: float
-
+
.. note::
-
+
Applies to dynamic and rigid body objects only.
.. note::
@@ -247,25 +247,25 @@ base class --- :class:`SCA_IObject`
:type: :class:`mathutils.Matrix`
.. attribute:: localLinearVelocity
-
+
The object's local linear velocity. [x, y, z]
:type: :class:`mathutils.Vector`
.. attribute:: worldLinearVelocity
-
+
The object's world linear velocity. [x, y, z]
:type: :class:`mathutils.Vector`
.. attribute:: localAngularVelocity
-
+
The object's local angular velocity. [x, y, z]
:type: :class:`mathutils.Vector`
.. attribute:: worldAngularVelocity
-
+
The object's world angular velocity. [x, y, z]
:type: :class:`mathutils.Vector`
@@ -287,13 +287,13 @@ base class --- :class:`SCA_IObject`
a list meshes for this object.
:type: list of :class:`KX_MeshProxy`
-
+
.. note::
-
+
Most objects use only 1 mesh.
.. note::
-
+
Changes to this list will not update the KX_GameObject.
.. attribute:: sensors
@@ -301,13 +301,13 @@ base class --- :class:`SCA_IObject`
a sequence of :class:`SCA_ISensor` objects with string/index lookups and iterator support.
:type: list
-
+
.. note::
-
+
This attribute is experemental and may be removed (but probably wont be).
.. note::
-
+
Changes to this list will not update the KX_GameObject.
.. attribute:: controllers
@@ -315,13 +315,13 @@ base class --- :class:`SCA_IObject`
a sequence of :class:`SCA_IController` objects with string/index lookups and iterator support.
:type: list of :class:`SCA_ISensor`
-
+
.. note::
-
+
This attribute is experemental and may be removed (but probably wont be).
.. note::
-
+
Changes to this list will not update the KX_GameObject.
.. attribute:: actuators
@@ -329,7 +329,7 @@ base class --- :class:`SCA_IObject`
a list of :class:`SCA_IActuator` with string/index lookups and iterator support.
:type: list
-
+
.. note::
This attribute is experemental and may be removed (but probably wont be).
@@ -490,7 +490,7 @@ base class --- :class:`SCA_IObject`
Sets the game object's linear velocity.
- This method sets game object's velocity through it's centre of mass,
+ This method sets game object's velocity through it's centre of mass,
ie no angular velocity component.
This requires a dynamic object.
@@ -571,7 +571,7 @@ base class --- :class:`SCA_IObject`
Resumes physics for this object.
.. note::
-
+
The objects linear velocity will be applied from when the dynamics were suspended.
.. method:: enableRigidBody()
@@ -607,7 +607,7 @@ base class --- :class:`SCA_IObject`
:type ghost: boolean
.. note::
-
+
If the object type is sensor, it stays ghost regardless of ghost parameter
.. method:: removeParent()
@@ -724,7 +724,7 @@ base class --- :class:`SCA_IObject`
* or 5-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz), :class:`KX_PolyProxy`, 2-tuple (u, v))
.. note::
-
+
The ray ignores the object on which the method is called. It is casted from/to object center or explicit [x, y, z] points.
.. method:: setCollisionMargin(margin)
@@ -735,7 +735,7 @@ base class --- :class:`SCA_IObject`
:type margin: float
.. note::
-
+
If this object has no physics controller (a physics ID of zero), this function will raise RuntimeError.
.. method:: sendMessage(subject, body="", to="")
@@ -766,11 +766,11 @@ base class --- :class:`SCA_IObject`
.. note::
If this object has instances the other instances will be updated too.
-
+
.. note::
The gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as subsurf).
-
+
.. warning::
Only triangle mesh type objects are supported currently (not convex hull)
@@ -791,7 +791,7 @@ base class --- :class:`SCA_IObject`
.. method:: playAction(name, start_frame, end_frame, layer=0, priority=0, blendin=0, play_mode=KX_ACTION_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0, blend_mode=KX_ACTION_BLEND_BLEND)
Plays an action.
-
+
:arg name: the name of the action
:type name: string
:arg start: the start frame of the action
@@ -812,42 +812,42 @@ base class --- :class:`SCA_IObject`
:type ipo_flags: int bitfield
:arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
:type speed: float
- :arg blend_mode: how to blend this layer with previous layers
- :type blend_mode: one of :ref:`these constants <gameobject-playaction-blend>`
+ :arg blend_mode: how to blend this layer with previous layers
+ :type blend_mode: one of :ref:`these constants <gameobject-playaction-blend>`
.. method:: stopAction(layer=0)
-
+
Stop playing the action on the given layer.
-
+
:arg layer: The layer to stop playing.
:type layer: integer
-
+
.. method:: getActionFrame(layer=0)
-
+
Gets the current frame of the action playing in the supplied layer.
-
+
:arg layer: The layer that you want to get the frame from.
:type layer: integer
-
+
:return: The current frame of the action
:rtype: float
-
+
.. method:: setActionFrame(frame, layer=0)
-
+
Set the current frame of the action playing in the supplied layer.
-
+
:arg layer: The layer where you want to set the frame
:type layer: integer
:arg frame: The frame to set the action to
:type frame: float
.. method:: isPlayingAction(layer=0)
-
- Checks to see if there is an action playing in the given layer.
-
- :arg layer: The layer to check for a playing action.
- :type layer: integer
-
- :return: Whether or not the action is playing
- :rtype: boolean
+
+ Checks to see if there is an action playing in the given layer.
+
+ :arg layer: The layer to check for a playing action.
+ :type layer: integer
+
+ :return: Whether or not the action is playing
+ :rtype: boolean
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst
index a00e9c29ad4..7b5619106ed 100644
--- a/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst
@@ -10,6 +10,12 @@ base class --- :class:`SCA_IController`
A Python controller uses a Python script to activate it's actuators,
based on it's sensors.
+ .. attribute:: owner
+
+ The object the controller is attached to.
+
+ :type: :class:`KX_GameObject`
+
.. attribute:: script
The value of this variable depends on the execution methid.
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst
index 6cfef2f80f1..7511f6724d8 100644
--- a/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst
@@ -22,13 +22,13 @@ base class --- :class:`PyObjectPlus`
:type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
- .. function:: getClipboard()
+ .. method:: getClipboard()
Gets the clipboard text.
:rtype: string
- .. function:: setClipboard(text)
+ .. method:: setClipboard(text)
Sets the clipboard text.
diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py
index cf0420c3830..32afe335089 100644
--- a/doc/python_api/rst_from_bmesh_opdefines.py
+++ b/doc/python_api/rst_from_bmesh_opdefines.py
@@ -75,7 +75,7 @@ def main():
for l in fsrc:
l = l[:-1]
# weak but ok
- if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and not "bmo_opdefines[]" in l:
+ if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and "bmo_opdefines[]" not in l:
is_block = True
block_ctx = []
blocks.append((comment_ctx, block_ctx))
@@ -113,7 +113,7 @@ def main():
fsrc.close()
del fsrc
- # namespace hack
+ # namespace hack
vars = (
"BMO_OP_SLOT_ELEMENT_BUF",
"BMO_OP_SLOT_BOOL",
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 4cea81d5cf0..98bf6bf2eed 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -62,7 +62,7 @@ Sphinx: PDF generation
try:
import bpy # blender module
-except:
+except ImportError:
print("\nERROR: this script must run from inside Blender")
print(SCRIPT_HELP_MSG)
import sys
@@ -982,6 +982,7 @@ context_type_map = {
"image_paint_object": ("Object", False),
"lamp": ("Lamp", False),
"lattice": ("Lattice", False),
+ "line_style": ("FreestyleLineStyle", False),
"material": ("Material", False),
"material_slot": ("MaterialSlot", False),
"mesh": ("Mesh", False),
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index e6ff02a4b6f..e6ff02a4b6f 100755..100644
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
diff --git a/extern/Eigen3/Eigen/Core b/extern/Eigen3/Eigen/Core
index d4801702261..9131cc3fc9d 100644
--- a/extern/Eigen3/Eigen/Core
+++ b/extern/Eigen3/Eigen/Core
@@ -19,6 +19,12 @@
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
#include "src/Core/util/Macros.h"
+// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
+// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
+#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6)
+ #pragma GCC optimize ("-fno-ipa-cp-clone")
+#endif
+
#include <complex>
// this include file manages BLAS and MKL related macros
@@ -44,7 +50,7 @@
#endif
#else
// Remember that usage of defined() in a #define is undefined by the standard
- #if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
+ #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
#endif
#endif
@@ -87,19 +93,25 @@
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
extern "C" {
- #include <emmintrin.h>
- #include <xmmintrin.h>
- #ifdef EIGEN_VECTORIZE_SSE3
- #include <pmmintrin.h>
- #endif
- #ifdef EIGEN_VECTORIZE_SSSE3
- #include <tmmintrin.h>
- #endif
- #ifdef EIGEN_VECTORIZE_SSE4_1
- #include <smmintrin.h>
- #endif
- #ifdef EIGEN_VECTORIZE_SSE4_2
- #include <nmmintrin.h>
+ // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
+ // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
+ #ifdef __INTEL_COMPILER
+ #include <immintrin.h>
+ #else
+ #include <emmintrin.h>
+ #include <xmmintrin.h>
+ #ifdef EIGEN_VECTORIZE_SSE3
+ #include <pmmintrin.h>
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSSE3
+ #include <tmmintrin.h>
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSE4_1
+ #include <smmintrin.h>
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSE4_2
+ #include <nmmintrin.h>
+ #endif
#endif
} // end extern "C"
#elif defined __ALTIVEC__
@@ -236,15 +248,11 @@ using std::ptrdiff_t;
* \endcode
*/
-/** \defgroup Support_modules Support modules [category]
- * Category of modules which add support for external libraries.
- */
-
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
-#include "src/Core/util/XprHelper.h"
#include "src/Core/util/StaticAssert.h"
+#include "src/Core/util/XprHelper.h"
#include "src/Core/util/Memory.h"
#include "src/Core/NumTraits.h"
@@ -297,6 +305,7 @@ using std::ptrdiff_t;
#include "src/Core/Map.h"
#include "src/Core/Block.h"
#include "src/Core/VectorBlock.h"
+#include "src/Core/Ref.h"
#include "src/Core/Transpose.h"
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/Diagonal.h"
@@ -330,6 +339,7 @@ using std::ptrdiff_t;
#include "src/Core/products/TriangularSolverMatrix.h"
#include "src/Core/products/TriangularSolverVector.h"
#include "src/Core/BandMatrix.h"
+#include "src/Core/CoreIterators.h"
#include "src/Core/BooleanRedux.h"
#include "src/Core/Select.h"
diff --git a/extern/Eigen3/Eigen/Eigen2Support b/extern/Eigen3/Eigen/Eigen2Support
index 36156d29a92..6aa009d2093 100644
--- a/extern/Eigen3/Eigen/Eigen2Support
+++ b/extern/Eigen3/Eigen/Eigen2Support
@@ -14,12 +14,25 @@
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
#endif
+#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
+#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)"
+#else
+#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)")
+#endif
+
+#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING
+
#include "src/Core/util/DisableStupidWarnings.h"
/** \ingroup Support_modules
* \defgroup Eigen2Support_Module Eigen2 support module
- * This module provides a couple of deprecated functions improving the compatibility with Eigen2.
*
+ * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.
+ *
+ * This module provides a couple of deprecated functions improving the compatibility with Eigen2.
+ *
* To use it, define EIGEN2_SUPPORT before including any Eigen header
* \code
* #define EIGEN2_SUPPORT
diff --git a/extern/Eigen3/Eigen/Eigenvalues b/extern/Eigen3/Eigen/Eigenvalues
index af99ccd1fab..53c5a73a278 100644
--- a/extern/Eigen3/Eigen/Eigenvalues
+++ b/extern/Eigen3/Eigen/Eigenvalues
@@ -33,6 +33,8 @@
#include "src/Eigenvalues/HessenbergDecomposition.h"
#include "src/Eigenvalues/ComplexSchur.h"
#include "src/Eigenvalues/ComplexEigenSolver.h"
+#include "src/Eigenvalues/RealQZ.h"
+#include "src/Eigenvalues/GeneralizedEigenSolver.h"
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
#ifdef EIGEN_USE_LAPACKE
#include "src/Eigenvalues/RealSchur_MKL.h"
diff --git a/extern/Eigen3/Eigen/IterativeLinearSolvers b/extern/Eigen3/Eigen/IterativeLinearSolvers
index 315c2dd1ee7..0f4159dc19f 100644
--- a/extern/Eigen3/Eigen/IterativeLinearSolvers
+++ b/extern/Eigen3/Eigen/IterativeLinearSolvers
@@ -6,7 +6,7 @@
#include "src/Core/util/DisableStupidWarnings.h"
-/** \ingroup Sparse_modules
+/**
* \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module
*
* This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse.
diff --git a/extern/Eigen3/Eigen/MetisSupport b/extern/Eigen3/Eigen/MetisSupport
new file mode 100644
index 00000000000..6a113f7a878
--- /dev/null
+++ b/extern/Eigen3/Eigen/MetisSupport
@@ -0,0 +1,28 @@
+#ifndef EIGEN_METISSUPPORT_MODULE_H
+#define EIGEN_METISSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+extern "C" {
+#include <metis.h>
+}
+
+
+/** \ingroup Support_modules
+ * \defgroup MetisSupport_Module MetisSupport module
+ *
+ * \code
+ * #include <Eigen/MetisSupport>
+ * \endcode
+ * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis).
+ * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink
+ */
+
+
+#include "src/MetisSupport/MetisSupport.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_METISSUPPORT_MODULE_H
diff --git a/extern/Eigen3/Eigen/OrderingMethods b/extern/Eigen3/Eigen/OrderingMethods
index 1e2d87452e5..7c0f1fffff6 100644
--- a/extern/Eigen3/Eigen/OrderingMethods
+++ b/extern/Eigen3/Eigen/OrderingMethods
@@ -5,19 +5,62 @@
#include "src/Core/util/DisableStupidWarnings.h"
-/** \ingroup Sparse_modules
+/**
* \defgroup OrderingMethods_Module OrderingMethods module
*
- * This module is currently for internal use only.
- *
- *
+ * This module is currently for internal use only
+ *
+ * It defines various built-in and external ordering methods for sparse matrices.
+ * They are typically used to reduce the number of elements during
+ * the sparse matrix decomposition (LLT, LU, QR).
+ * Precisely, in a preprocessing step, a permutation matrix P is computed using
+ * those ordering methods and applied to the columns of the matrix.
+ * Using for instance the sparse Cholesky decomposition, it is expected that
+ * the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A).
+ *
+ *
+ * Usage :
* \code
* #include <Eigen/OrderingMethods>
* \endcode
+ *
+ * A simple usage is as a template parameter in the sparse decomposition classes :
+ *
+ * \code
+ * SparseLU<MatrixType, COLAMDOrdering<int> > solver;
+ * \endcode
+ *
+ * \code
+ * SparseQR<MatrixType, COLAMDOrdering<int> > solver;
+ * \endcode
+ *
+ * It is possible as well to call directly a particular ordering method for your own purpose,
+ * \code
+ * AMDOrdering<int> ordering;
+ * PermutationMatrix<Dynamic, Dynamic, int> perm;
+ * SparseMatrix<double> A;
+ * //Fill the matrix ...
+ *
+ * ordering(A, perm); // Call AMD
+ * \endcode
+ *
+ * \note Some of these methods (like AMD or METIS), need the sparsity pattern
+ * of the input matrix to be symmetric. When the matrix is structurally unsymmetric,
+ * Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method.
+ * If your matrix is already symmetric (at leat in structure), you can avoid that
+ * by calling the method with a SelfAdjointView type.
+ *
+ * \code
+ * // Call the ordering on the pattern of the lower triangular matrix A
+ * ordering(A.selfadjointView<Lower>(), perm);
+ * \endcode
*/
+#ifndef EIGEN_MPL2_ONLY
#include "src/OrderingMethods/Amd.h"
+#endif
+#include "src/OrderingMethods/Ordering.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_ORDERINGMETHODS_MODULE_H
diff --git a/extern/Eigen3/Eigen/SPQRSupport b/extern/Eigen3/Eigen/SPQRSupport
new file mode 100644
index 00000000000..77016442ee7
--- /dev/null
+++ b/extern/Eigen3/Eigen/SPQRSupport
@@ -0,0 +1,29 @@
+#ifndef EIGEN_SPQRSUPPORT_MODULE_H
+#define EIGEN_SPQRSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "SuiteSparseQR.hpp"
+
+/** \ingroup Support_modules
+ * \defgroup SPQRSupport_Module SuiteSparseQR module
+ *
+ * This module provides an interface to the SPQR library, which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package.
+ *
+ * \code
+ * #include <Eigen/SPQRSupport>
+ * \endcode
+ *
+ * In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...).
+ * For a cmake based project, you can use our FindSPQR.cmake and FindCholmod.Cmake modules
+ *
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+#include "src/CholmodSupport/CholmodSupport.h"
+#include "src/SPQRSupport/SuiteSparseQRSupport.h"
+
+#endif
diff --git a/extern/Eigen3/Eigen/Sparse b/extern/Eigen3/Eigen/Sparse
index 2d1757172eb..7cc9c09133a 100644
--- a/extern/Eigen3/Eigen/Sparse
+++ b/extern/Eigen3/Eigen/Sparse
@@ -1,13 +1,15 @@
#ifndef EIGEN_SPARSE_MODULE_H
#define EIGEN_SPARSE_MODULE_H
-/** \defgroup Sparse_modules Sparse modules
+/** \defgroup Sparse_Module Sparse meta-module
*
* Meta-module including all related modules:
- * - SparseCore
- * - OrderingMethods
- * - SparseCholesky
- * - IterativeLinearSolvers
+ * - \ref SparseCore_Module
+ * - \ref OrderingMethods_Module
+ * - \ref SparseCholesky_Module
+ * - \ref SparseLU_Module
+ * - \ref SparseQR_Module
+ * - \ref IterativeLinearSolvers_Module
*
* \code
* #include <Eigen/Sparse>
@@ -17,6 +19,8 @@
#include "SparseCore"
#include "OrderingMethods"
#include "SparseCholesky"
+#include "SparseLU"
+#include "SparseQR"
#include "IterativeLinearSolvers"
#endif // EIGEN_SPARSE_MODULE_H
diff --git a/extern/Eigen3/Eigen/SparseCholesky b/extern/Eigen3/Eigen/SparseCholesky
index 5f82742f7d8..9f5056aa1a1 100644
--- a/extern/Eigen3/Eigen/SparseCholesky
+++ b/extern/Eigen3/Eigen/SparseCholesky
@@ -1,11 +1,21 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2013 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
#ifndef EIGEN_SPARSECHOLESKY_MODULE_H
#define EIGEN_SPARSECHOLESKY_MODULE_H
#include "SparseCore"
+#include "OrderingMethods"
#include "src/Core/util/DisableStupidWarnings.h"
-/** \ingroup Sparse_modules
+/**
* \defgroup SparseCholesky_Module SparseCholesky module
*
* This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices.
@@ -20,11 +30,18 @@
* \endcode
*/
+#ifdef EIGEN_MPL2_ONLY
+#error The SparseCholesky module has nothing to offer in MPL2 only mode
+#endif
+
#include "src/misc/Solve.h"
#include "src/misc/SparseSolve.h"
-
#include "src/SparseCholesky/SimplicialCholesky.h"
+#ifndef EIGEN_MPL2_ONLY
+#include "src/SparseCholesky/SimplicialCholesky_impl.h"
+#endif
+
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
diff --git a/extern/Eigen3/Eigen/SparseCore b/extern/Eigen3/Eigen/SparseCore
index 41d28c92824..9b5be5e15a9 100644
--- a/extern/Eigen3/Eigen/SparseCore
+++ b/extern/Eigen3/Eigen/SparseCore
@@ -11,7 +11,7 @@
#include <cstring>
#include <algorithm>
-/** \ingroup Sparse_modules
+/**
* \defgroup SparseCore_Module SparseCore module
*
* This module provides a sparse matrix representation, and basic associatd matrix manipulations
@@ -40,14 +40,12 @@ struct Sparse {};
#include "src/SparseCore/SparseMatrix.h"
#include "src/SparseCore/MappedSparseMatrix.h"
#include "src/SparseCore/SparseVector.h"
-#include "src/SparseCore/CoreIterators.h"
#include "src/SparseCore/SparseBlock.h"
#include "src/SparseCore/SparseTranspose.h"
#include "src/SparseCore/SparseCwiseUnaryOp.h"
#include "src/SparseCore/SparseCwiseBinaryOp.h"
#include "src/SparseCore/SparseDot.h"
#include "src/SparseCore/SparsePermutation.h"
-#include "src/SparseCore/SparseAssign.h"
#include "src/SparseCore/SparseRedux.h"
#include "src/SparseCore/SparseFuzzy.h"
#include "src/SparseCore/ConservativeSparseSparseProduct.h"
diff --git a/extern/Eigen3/Eigen/SparseLU b/extern/Eigen3/Eigen/SparseLU
new file mode 100644
index 00000000000..8527a49bd86
--- /dev/null
+++ b/extern/Eigen3/Eigen/SparseLU
@@ -0,0 +1,49 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSELU_MODULE_H
+#define EIGEN_SPARSELU_MODULE_H
+
+#include "SparseCore"
+
+/**
+ * \defgroup SparseLU_Module SparseLU module
+ * This module defines a supernodal factorization of general sparse matrices.
+ * The code is fully optimized for supernode-panel updates with specialized kernels.
+ * Please, see the documentation of the SparseLU class for more details.
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
+// Ordering interface
+#include "OrderingMethods"
+
+#include "src/SparseLU/SparseLU_gemm_kernel.h"
+
+#include "src/SparseLU/SparseLU_Structs.h"
+#include "src/SparseLU/SparseLU_SupernodalMatrix.h"
+#include "src/SparseLU/SparseLUImpl.h"
+#include "src/SparseCore/SparseColEtree.h"
+#include "src/SparseLU/SparseLU_Memory.h"
+#include "src/SparseLU/SparseLU_heap_relax_snode.h"
+#include "src/SparseLU/SparseLU_relax_snode.h"
+#include "src/SparseLU/SparseLU_pivotL.h"
+#include "src/SparseLU/SparseLU_panel_dfs.h"
+#include "src/SparseLU/SparseLU_kernel_bmod.h"
+#include "src/SparseLU/SparseLU_panel_bmod.h"
+#include "src/SparseLU/SparseLU_column_dfs.h"
+#include "src/SparseLU/SparseLU_column_bmod.h"
+#include "src/SparseLU/SparseLU_copy_to_ucol.h"
+#include "src/SparseLU/SparseLU_pruneL.h"
+#include "src/SparseLU/SparseLU_Utils.h"
+#include "src/SparseLU/SparseLU.h"
+
+#endif // EIGEN_SPARSELU_MODULE_H
diff --git a/extern/Eigen3/Eigen/SparseQR b/extern/Eigen3/Eigen/SparseQR
new file mode 100644
index 00000000000..4ee42065eed
--- /dev/null
+++ b/extern/Eigen3/Eigen/SparseQR
@@ -0,0 +1,33 @@
+#ifndef EIGEN_SPARSEQR_MODULE_H
+#define EIGEN_SPARSEQR_MODULE_H
+
+#include "SparseCore"
+#include "OrderingMethods"
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup SparseQR_Module SparseQR module
+ * \brief Provides QR decomposition for sparse matrices
+ *
+ * This module provides a simplicial version of the left-looking Sparse QR decomposition.
+ * The columns of the input matrix should be reordered to limit the fill-in during the
+ * decomposition. Built-in methods (COLAMD, AMD) or external methods (METIS) can be used to this end.
+ * See the \link OrderingMethods_Module OrderingMethods\endlink module for the list
+ * of built-in and external ordering methods.
+ *
+ * \code
+ * #include <Eigen/SparseQR>
+ * \endcode
+ *
+ *
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
+#include "OrderingMethods"
+#include "src/SparseCore/SparseColEtree.h"
+#include "src/SparseQR/SparseQR.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h
index 68e54b1d4ad..d026418f8a9 100644
--- a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h
+++ b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h
@@ -16,7 +16,10 @@
namespace Eigen {
namespace internal {
-template<typename MatrixType, int UpLo> struct LDLT_Traits;
+ template<typename MatrixType, int UpLo> struct LDLT_Traits;
+
+ // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
+ enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite };
}
/** \ingroup Cholesky_Module
@@ -69,7 +72,12 @@ template<typename _MatrixType, int _UpLo> class LDLT
* The default constructor is useful in cases in which the user intends to
* perform decompositions via LDLT::compute(const MatrixType&).
*/
- LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {}
+ LDLT()
+ : m_matrix(),
+ m_transpositions(),
+ m_sign(internal::ZeroSign),
+ m_isInitialized(false)
+ {}
/** \brief Default Constructor with memory preallocation
*
@@ -81,6 +89,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
: m_matrix(size, size),
m_transpositions(size),
m_temporary(size),
+ m_sign(internal::ZeroSign),
m_isInitialized(false)
{}
@@ -93,6 +102,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
: m_matrix(matrix.rows(), matrix.cols()),
m_transpositions(matrix.rows()),
m_temporary(matrix.rows()),
+ m_sign(internal::ZeroSign),
m_isInitialized(false)
{
compute(matrix);
@@ -139,7 +149,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
inline bool isPositive() const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
- return m_sign == 1;
+ return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign;
}
#ifdef EIGEN2_SUPPORT
@@ -153,7 +163,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
inline bool isNegative(void) const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
- return m_sign == -1;
+ return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
}
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
@@ -196,7 +206,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
LDLT& compute(const MatrixType& matrix);
template <typename Derived>
- LDLT& rankUpdate(const MatrixBase<Derived>& w,RealScalar alpha=1);
+ LDLT& rankUpdate(const MatrixBase<Derived>& w, const RealScalar& alpha=1);
/** \returns the internal LDLT decomposition matrix
*
@@ -235,7 +245,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
MatrixType m_matrix;
TranspositionType m_transpositions;
TmpMatrixType m_temporary;
- int m_sign;
+ internal::SignMatrix m_sign;
bool m_isInitialized;
};
@@ -246,8 +256,9 @@ template<int UpLo> struct ldlt_inplace;
template<> struct ldlt_inplace<Lower>
{
template<typename MatrixType, typename TranspositionType, typename Workspace>
- static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
+ static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
{
+ using std::abs;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::Index Index;
@@ -257,8 +268,9 @@ template<> struct ldlt_inplace<Lower>
if (size <= 1)
{
transpositions.setIdentity();
- if(sign)
- *sign = real(mat.coeff(0,0))>0 ? 1:-1;
+ if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef;
+ else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef;
+ else sign = ZeroSign;
return true;
}
@@ -277,9 +289,6 @@ template<> struct ldlt_inplace<Lower>
// are compared; if any diagonal is negligible compared
// to the largest overall, the algorithm bails.
cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
-
- if(sign)
- *sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
}
// Finish early if the matrix is not full rank.
@@ -301,11 +310,11 @@ template<> struct ldlt_inplace<Lower>
for(int i=k+1;i<index_of_biggest_in_corner;++i)
{
Scalar tmp = mat.coeffRef(i,k);
- mat.coeffRef(i,k) = conj(mat.coeffRef(index_of_biggest_in_corner,i));
- mat.coeffRef(index_of_biggest_in_corner,i) = conj(tmp);
+ mat.coeffRef(i,k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner,i));
+ mat.coeffRef(index_of_biggest_in_corner,i) = numext::conj(tmp);
}
if(NumTraits<Scalar>::IsComplex)
- mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k));
+ mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k));
}
// partition the matrix:
@@ -326,6 +335,16 @@ template<> struct ldlt_inplace<Lower>
}
if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff))
A21 /= mat.coeffRef(k,k);
+
+ RealScalar realAkk = numext::real(mat.coeffRef(k,k));
+ if (sign == PositiveSemiDef) {
+ if (realAkk < 0) sign = Indefinite;
+ } else if (sign == NegativeSemiDef) {
+ if (realAkk > 0) sign = Indefinite;
+ } else if (sign == ZeroSign) {
+ if (realAkk > 0) sign = PositiveSemiDef;
+ else if (realAkk < 0) sign = NegativeSemiDef;
+ }
}
return true;
@@ -339,9 +358,9 @@ template<> struct ldlt_inplace<Lower>
// Here only rank-1 updates are implemented, to reduce the
// requirement for intermediate storage and improve accuracy
template<typename MatrixType, typename WDerived>
- static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, typename MatrixType::RealScalar sigma=1)
+ static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, const typename MatrixType::RealScalar& sigma=1)
{
- using internal::isfinite;
+ using numext::isfinite;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::Index Index;
@@ -359,9 +378,9 @@ template<> struct ldlt_inplace<Lower>
break;
// Update the diagonal terms
- RealScalar dj = real(mat.coeff(j,j));
+ RealScalar dj = numext::real(mat.coeff(j,j));
Scalar wj = w.coeff(j);
- RealScalar swj2 = sigma*abs2(wj);
+ RealScalar swj2 = sigma*numext::abs2(wj);
RealScalar gamma = dj*alpha + swj2;
mat.coeffRef(j,j) += swj2/alpha;
@@ -372,13 +391,13 @@ template<> struct ldlt_inplace<Lower>
Index rs = size-j-1;
w.tail(rs) -= wj * mat.col(j).tail(rs);
if(gamma != 0)
- mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs);
+ mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs);
}
return true;
}
template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
- static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, typename MatrixType::RealScalar sigma=1)
+ static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, const typename MatrixType::RealScalar& sigma=1)
{
// Apply the permutation to the input w
tmp = transpositions * w;
@@ -390,14 +409,14 @@ template<> struct ldlt_inplace<Lower>
template<> struct ldlt_inplace<Upper>
{
template<typename MatrixType, typename TranspositionType, typename Workspace>
- static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
+ static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
{
Transpose<MatrixType> matt(mat);
return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
}
template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
- static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, typename MatrixType::RealScalar sigma=1)
+ static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, const typename MatrixType::RealScalar& sigma=1)
{
Transpose<MatrixType> matt(mat);
return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma);
@@ -436,7 +455,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
m_isInitialized = false;
m_temporary.resize(size);
- internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign);
+ internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign);
m_isInitialized = true;
return *this;
@@ -449,7 +468,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
*/
template<typename MatrixType, int _UpLo>
template<typename Derived>
-LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w,typename NumTraits<typename MatrixType::Scalar>::Real sigma)
+LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename NumTraits<typename MatrixType::Scalar>::Real& sigma)
{
const Index size = w.rows();
if (m_isInitialized)
@@ -464,7 +483,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Deri
for (Index i = 0; i < size; i++)
m_transpositions.coeffRef(i) = i;
m_temporary.resize(size);
- m_sign = sigma>=0 ? 1 : -1;
+ m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef;
m_isInitialized = true;
}
@@ -534,8 +553,7 @@ template<typename Derived>
bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
- const Index size = m_matrix.rows();
- eigen_assert(size == bAndX.rows());
+ eigen_assert(m_matrix.rows() == bAndX.rows());
bAndX = this->solve(bAndX);
diff --git a/extern/Eigen3/Eigen/src/Cholesky/LLT.h b/extern/Eigen3/Eigen/src/Cholesky/LLT.h
index 41d14e532f1..2e6189f7dab 100644
--- a/extern/Eigen3/Eigen/src/Cholesky/LLT.h
+++ b/extern/Eigen3/Eigen/src/Cholesky/LLT.h
@@ -190,6 +190,7 @@ template<typename Scalar, int UpLo> struct llt_inplace;
template<typename MatrixType, typename VectorType>
static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
{
+ using std::sqrt;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::Index Index;
@@ -199,7 +200,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
typedef Matrix<Scalar,Dynamic,1> TempVectorType;
typedef typename TempVectorType::SegmentReturnType TempVecSegment;
- int n = mat.cols();
+ Index n = mat.cols();
eigen_assert(mat.rows()==n && vec.size()==n);
TempVectorType temp;
@@ -211,12 +212,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
// i.e., for sigma > 0
temp = sqrt(sigma) * vec;
- for(int i=0; i<n; ++i)
+ for(Index i=0; i<n; ++i)
{
JacobiRotation<Scalar> g;
g.makeGivens(mat(i,i), -temp(i), &mat(i,i));
- int rs = n-i-1;
+ Index rs = n-i-1;
if(rs>0)
{
ColXprSegment x(mat.col(i).tail(rs));
@@ -229,12 +230,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
{
temp = vec;
RealScalar beta = 1;
- for(int j=0; j<n; ++j)
+ for(Index j=0; j<n; ++j)
{
- RealScalar Ljj = real(mat.coeff(j,j));
- RealScalar dj = abs2(Ljj);
+ RealScalar Ljj = numext::real(mat.coeff(j,j));
+ RealScalar dj = numext::abs2(Ljj);
Scalar wj = temp.coeff(j);
- RealScalar swj2 = sigma*abs2(wj);
+ RealScalar swj2 = sigma*numext::abs2(wj);
RealScalar gamma = dj*beta + swj2;
RealScalar x = dj + swj2/beta;
@@ -250,7 +251,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
{
temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs);
if(gamma != 0)
- mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*conj(wj)/gamma)*temp.tail(rs);
+ mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*numext::conj(wj)/gamma)*temp.tail(rs);
}
}
}
@@ -263,6 +264,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
template<typename MatrixType>
static typename MatrixType::Index unblocked(MatrixType& mat)
{
+ using std::sqrt;
typedef typename MatrixType::Index Index;
eigen_assert(mat.rows()==mat.cols());
@@ -275,7 +277,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
- RealScalar x = real(mat.coeff(k,k));
+ RealScalar x = numext::real(mat.coeff(k,k));
if (k>0) x -= A10.squaredNorm();
if (x<=RealScalar(0))
return k;
diff --git a/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h
index 37f142150ff..c449960de4a 100644
--- a/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h
+++ b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h
@@ -51,7 +51,6 @@ void cholmod_configure_matrix(CholmodType& mat)
template<typename _Scalar, int _Options, typename _Index>
cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
{
- typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType;
cholmod_sparse res;
res.nzmax = mat.nonZeros();
res.nrow = mat.rows();;
@@ -59,10 +58,12 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
res.p = mat.outerIndexPtr();
res.i = mat.innerIndexPtr();
res.x = mat.valuePtr();
+ res.z = 0;
res.sorted = 1;
if(mat.isCompressed())
{
res.packed = 1;
+ res.nz = 0;
}
else
{
@@ -77,9 +78,13 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
{
res.itype = CHOLMOD_INT;
}
+ else if (internal::is_same<_Index,UF_long>::value)
+ {
+ res.itype = CHOLMOD_LONG;
+ }
else
{
- eigen_assert(false && "Index type different than int is not supported yet");
+ eigen_assert(false && "Index type not supported yet");
}
// setup res.xtype
@@ -123,7 +128,7 @@ cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat)
res.ncol = mat.cols();
res.nzmax = res.nrow * res.ncol;
res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
- res.x = mat.derived().data();
+ res.x = (void*)(mat.derived().data());
res.z = 0;
internal::cholmod_configure_matrix<Scalar>(res);
@@ -137,8 +142,8 @@ template<typename Scalar, int Flags, typename Index>
MappedSparseMatrix<Scalar,Flags,Index> viewAsEigen(cholmod_sparse& cm)
{
return MappedSparseMatrix<Scalar,Flags,Index>
- (cm.nrow, cm.ncol, reinterpret_cast<Index*>(cm.p)[cm.ncol],
- reinterpret_cast<Index*>(cm.p), reinterpret_cast<Index*>(cm.i),reinterpret_cast<Scalar*>(cm.x) );
+ (cm.nrow, cm.ncol, static_cast<Index*>(cm.p)[cm.ncol],
+ static_cast<Index*>(cm.p), static_cast<Index*>(cm.i),static_cast<Scalar*>(cm.x) );
}
enum CholmodMode {
@@ -167,12 +172,14 @@ class CholmodBase : internal::noncopyable
CholmodBase()
: m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
{
+ m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0);
cholmod_start(&m_cholmod);
}
CholmodBase(const MatrixType& matrix)
: m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
{
+ m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0);
cholmod_start(&m_cholmod);
compute(matrix);
}
@@ -237,7 +244,7 @@ class CholmodBase : internal::noncopyable
return internal::sparse_solve_retval<CholmodBase, Rhs>(*this, b.derived());
}
- /** Performs a symbolic decomposition on the sparcity of \a matrix.
+ /** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
*
* This function is particularly useful when solving for several problems having the same structure.
*
@@ -261,7 +268,7 @@ class CholmodBase : internal::noncopyable
/** Performs a numeric decomposition of \a matrix
*
- * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed.
+ * The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed.
*
* \sa analyzePattern()
*/
@@ -269,9 +276,10 @@ class CholmodBase : internal::noncopyable
{
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
- cholmod_factorize(&A, m_cholmodFactor, &m_cholmod);
+ cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
- this->m_info = Success;
+ // If the factorization failed, minor is the column at which it did. On success minor == n.
+ this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
m_factorizationIsOk = true;
}
@@ -286,16 +294,18 @@ class CholmodBase : internal::noncopyable
{
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
const Index size = m_cholmodFactor->n;
+ EIGEN_UNUSED_VARIABLE(size);
eigen_assert(size==b.rows());
// note: cd stands for Cholmod Dense
- cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived());
+ Rhs& b_ref(b.const_cast_derived());
+ cholmod_dense b_cd = viewAsCholmod(b_ref);
cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
if(!x_cd)
{
this->m_info = NumericalIssue;
}
- // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
+ // TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
cholmod_free_dense(&x_cd, &m_cholmod);
}
@@ -306,6 +316,7 @@ class CholmodBase : internal::noncopyable
{
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
const Index size = m_cholmodFactor->n;
+ EIGEN_UNUSED_VARIABLE(size);
eigen_assert(size==b.rows());
// note: cs stands for Cholmod Sparse
@@ -315,19 +326,36 @@ class CholmodBase : internal::noncopyable
{
this->m_info = NumericalIssue;
}
- // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
+ // TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs);
cholmod_free_sparse(&x_cs, &m_cholmod);
}
#endif // EIGEN_PARSED_BY_DOXYGEN
+
+ /** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization.
+ *
+ * During the numerical factorization, an offset term is added to the diagonal coefficients:\n
+ * \c d_ii = \a offset + \c d_ii
+ *
+ * The default is \a offset=0.
+ *
+ * \returns a reference to \c *this.
+ */
+ Derived& setShift(const RealScalar& offset)
+ {
+ m_shiftOffset[0] = offset;
+ return derived();
+ }
+
template<typename Stream>
- void dumpMemory(Stream& s)
+ void dumpMemory(Stream& /*s*/)
{}
protected:
mutable cholmod_common m_cholmod;
cholmod_factor* m_cholmodFactor;
+ RealScalar m_shiftOffset[2];
mutable ComputationInfo m_info;
bool m_isInitialized;
int m_factorizationIsOk;
@@ -340,8 +368,8 @@ class CholmodBase : internal::noncopyable
*
* This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization
* using the Cholmod library.
- * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest.
- * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
+ * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest.
+ * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
* X and B can be either dense or sparse.
*
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
@@ -387,8 +415,8 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl
*
* This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization
* using the Cholmod library.
- * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest.
- * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
+ * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest.
+ * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
* X and B can be either dense or sparse.
*
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
@@ -433,7 +461,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp
* This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization
* using the Cholmod library.
* This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM.
- * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
+ * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
* X and B can be either dense or sparse.
*
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
@@ -476,7 +504,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper
* \brief A general Cholesky factorization and solver based on Cholmod
*
* This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization
- * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
+ * using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
* X and B can be either dense or sparse.
*
* This variant permits to change the underlying Cholesky method at runtime.
diff --git a/extern/Eigen3/Eigen/src/Core/Array.h b/extern/Eigen3/Eigen/src/Core/Array.h
index aaa38997838..0ab03eff0f0 100644
--- a/extern/Eigen3/Eigen/src/Core/Array.h
+++ b/extern/Eigen3/Eigen/src/Core/Array.h
@@ -107,10 +107,10 @@ class Array
*
* \sa resize(Index,Index)
*/
- EIGEN_STRONG_INLINE explicit Array() : Base()
+ EIGEN_STRONG_INLINE Array() : Base()
{
Base::_check_template_params();
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -120,7 +120,7 @@ class Array
: Base(internal::constructor_without_unaligned_array_assert())
{
Base::_check_template_params();
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#endif
@@ -137,15 +137,15 @@ class Array
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array)
eigen_assert(dim >= 0);
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename T0, typename T1>
- EIGEN_STRONG_INLINE Array(const T0& x, const T1& y)
+ EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1)
{
Base::_check_template_params();
- this->template _init2<T0,T1>(x, y);
+ this->template _init2<T0,T1>(val0, val1);
}
#else
/** constructs an uninitialized matrix with \a rows rows and \a cols columns.
@@ -155,27 +155,27 @@ class Array
* Matrix() instead. */
Array(Index rows, Index cols);
/** constructs an initialized 2D vector with given coefficients */
- Array(const Scalar& x, const Scalar& y);
+ Array(const Scalar& val0, const Scalar& val1);
#endif
/** constructs an initialized 3D vector with given coefficients */
- EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z)
+ EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
{
Base::_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
- m_storage.data()[0] = x;
- m_storage.data()[1] = y;
- m_storage.data()[2] = z;
+ m_storage.data()[0] = val0;
+ m_storage.data()[1] = val1;
+ m_storage.data()[2] = val2;
}
/** constructs an initialized 4D vector with given coefficients */
- EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
+ EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
{
Base::_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
- m_storage.data()[0] = x;
- m_storage.data()[1] = y;
- m_storage.data()[2] = z;
- m_storage.data()[3] = w;
+ m_storage.data()[0] = val0;
+ m_storage.data()[1] = val1;
+ m_storage.data()[2] = val2;
+ m_storage.data()[3] = val3;
}
explicit Array(const Scalar *data);
@@ -210,7 +210,7 @@ class Array
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
Base::_check_template_params();
- Base::resize(other.rows(), other.cols());
+ Base::_resize_to_match(other);
*this = other;
}
diff --git a/extern/Eigen3/Eigen/src/Core/ArrayBase.h b/extern/Eigen3/Eigen/src/Core/ArrayBase.h
index 004b117c933..38852600dc2 100644
--- a/extern/Eigen3/Eigen/src/Core/ArrayBase.h
+++ b/extern/Eigen3/Eigen/src/Core/ArrayBase.h
@@ -143,7 +143,7 @@ template<typename Derived> class ArrayBase
ArrayBase<Derived>& array() { return *this; }
const ArrayBase<Derived>& array() const { return *this; }
- /** \returns an \link MatrixBase Matrix \endlink expression of this array
+ /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array
* \sa MatrixBase::array() */
MatrixWrapper<Derived> matrix() { return derived(); }
const MatrixWrapper<const Derived> matrix() const { return derived(); }
diff --git a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h
index 87af7fda937..a791bc3581a 100644
--- a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h
+++ b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h
@@ -55,22 +55,22 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
- inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
+ inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
- inline CoeffReturnType coeff(Index row, Index col) const
+ inline CoeffReturnType coeff(Index rowId, Index colId) const
{
- return m_expression.coeff(row, col);
+ return m_expression.coeff(rowId, colId);
}
- inline Scalar& coeffRef(Index row, Index col)
+ inline Scalar& coeffRef(Index rowId, Index colId)
{
- return m_expression.const_cast_derived().coeffRef(row, col);
+ return m_expression.const_cast_derived().coeffRef(rowId, colId);
}
- inline const Scalar& coeffRef(Index row, Index col) const
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
{
- return m_expression.const_cast_derived().coeffRef(row, col);
+ return m_expression.const_cast_derived().coeffRef(rowId, colId);
}
inline CoeffReturnType coeff(Index index) const
@@ -89,15 +89,15 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
}
template<int LoadMode>
- inline const PacketScalar packet(Index row, Index col) const
+ inline const PacketScalar packet(Index rowId, Index colId) const
{
- return m_expression.template packet<LoadMode>(row, col);
+ return m_expression.template packet<LoadMode>(rowId, colId);
}
template<int LoadMode>
- inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
{
- m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
+ m_expression.const_cast_derived().template writePacket<LoadMode>(rowId, colId, val);
}
template<int LoadMode>
@@ -107,9 +107,9 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
}
template<int LoadMode>
- inline void writePacket(Index index, const PacketScalar& x)
+ inline void writePacket(Index index, const PacketScalar& val)
{
- m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
+ m_expression.const_cast_derived().template writePacket<LoadMode>(index, val);
}
template<typename Dest>
@@ -121,6 +121,13 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
return m_expression;
}
+ /** Forwards the resizing request to the nested expression
+ * \sa DenseBase::resize(Index) */
+ void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
+ /** Forwards the resizing request to the nested expression
+ * \sa DenseBase::resize(Index,Index)*/
+ void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }
+
protected:
NestedExpressionType m_expression;
};
@@ -161,29 +168,29 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
- inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
+ inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {}
inline Index rows() const { return m_expression.rows(); }
inline Index cols() const { return m_expression.cols(); }
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
- inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
+ inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
- inline CoeffReturnType coeff(Index row, Index col) const
+ inline CoeffReturnType coeff(Index rowId, Index colId) const
{
- return m_expression.coeff(row, col);
+ return m_expression.coeff(rowId, colId);
}
- inline Scalar& coeffRef(Index row, Index col)
+ inline Scalar& coeffRef(Index rowId, Index colId)
{
- return m_expression.const_cast_derived().coeffRef(row, col);
+ return m_expression.const_cast_derived().coeffRef(rowId, colId);
}
- inline const Scalar& coeffRef(Index row, Index col) const
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
{
- return m_expression.derived().coeffRef(row, col);
+ return m_expression.derived().coeffRef(rowId, colId);
}
inline CoeffReturnType coeff(Index index) const
@@ -202,15 +209,15 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
}
template<int LoadMode>
- inline const PacketScalar packet(Index row, Index col) const
+ inline const PacketScalar packet(Index rowId, Index colId) const
{
- return m_expression.template packet<LoadMode>(row, col);
+ return m_expression.template packet<LoadMode>(rowId, colId);
}
template<int LoadMode>
- inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
{
- m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
+ m_expression.const_cast_derived().template writePacket<LoadMode>(rowId, colId, val);
}
template<int LoadMode>
@@ -220,9 +227,9 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
}
template<int LoadMode>
- inline void writePacket(Index index, const PacketScalar& x)
+ inline void writePacket(Index index, const PacketScalar& val)
{
- m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
+ m_expression.const_cast_derived().template writePacket<LoadMode>(index, val);
}
const typename internal::remove_all<NestedExpressionType>::type&
@@ -231,6 +238,13 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
return m_expression;
}
+ /** Forwards the resizing request to the nested expression
+ * \sa DenseBase::resize(Index) */
+ void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
+ /** Forwards the resizing request to the nested expression
+ * \sa DenseBase::resize(Index,Index)*/
+ void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }
+
protected:
NestedExpressionType m_expression;
};
diff --git a/extern/Eigen3/Eigen/src/Core/Assign.h b/extern/Eigen3/Eigen/src/Core/Assign.h
index cd29a88f0da..1dccc2f4212 100644
--- a/extern/Eigen3/Eigen/src/Core/Assign.h
+++ b/extern/Eigen3/Eigen/src/Core/Assign.h
@@ -155,7 +155,7 @@ struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
template<typename Derived1, typename Derived2, int Index, int Stop>
struct assign_DefaultTraversal_InnerUnrolling
{
- static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
+ static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
{
dst.copyCoeffByOuterInner(outer, Index, src);
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
@@ -165,7 +165,7 @@ struct assign_DefaultTraversal_InnerUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
- static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
+ static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
};
/***********************
@@ -218,7 +218,7 @@ struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
template<typename Derived1, typename Derived2, int Index, int Stop>
struct assign_innervec_InnerUnrolling
{
- static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
+ static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
{
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
assign_innervec_InnerUnrolling<Derived1, Derived2,
@@ -229,7 +229,7 @@ struct assign_innervec_InnerUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
- static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
+ static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
};
/***************************************************************************
@@ -507,19 +507,19 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
namespace internal {
template<typename Derived, typename OtherDerived,
- bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0,
- bool NeedToTranspose = Derived::IsVectorAtCompileTime
- && OtherDerived::IsVectorAtCompileTime
- && ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
- | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
- // revert to || as soon as not needed anymore.
- (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
- && int(Derived::SizeAtCompileTime) != 1>
+ bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
+ bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
+ | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
+ // revert to || as soon as not needed anymore.
+ (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
+ && int(Derived::SizeAtCompileTime) != 1>
struct assign_selector;
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,false,false> {
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
+ template<typename ActualDerived, typename ActualOtherDerived>
+ static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
};
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,true,false> {
@@ -528,6 +528,8 @@ struct assign_selector<Derived,OtherDerived,true,false> {
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,false,true> {
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
+ template<typename ActualDerived, typename ActualOtherDerived>
+ static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
};
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,true,true> {
@@ -566,16 +568,14 @@ template<typename Derived>
template <typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
{
- other.derived().evalTo(derived());
- return derived();
+ return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
}
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
{
- other.evalTo(derived());
- return derived();
+ return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
}
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/Core/Assign_MKL.h b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h
index 428c6367b92..7772951b915 100644
--- a/extern/Eigen3/Eigen/src/Core/Assign_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h
@@ -210,7 +210,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr)
// The vm*powx functions are not avaibale in the windows version of MKL.
-#ifdef _WIN32
+#ifndef _WIN32
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float)
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double)
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8)
diff --git a/extern/Eigen3/Eigen/src/Core/Block.h b/extern/Eigen3/Eigen/src/Core/Block.h
index 5f29cb3d1b3..358b3188b38 100644
--- a/extern/Eigen3/Eigen/src/Core/Block.h
+++ b/extern/Eigen3/Eigen/src/Core/Block.h
@@ -21,7 +21,6 @@ namespace Eigen {
* \param XprType the type of the expression in which we are taking a block
* \param BlockRows the number of rows of the block we are taking at compile time (optional)
* \param BlockCols the number of columns of the block we are taking at compile time (optional)
- * \param _DirectAccessStatus \internal used for partial specialization
*
* This class represents an expression of either a fixed-size or dynamic-size block. It is the return
* type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
@@ -47,8 +46,8 @@ namespace Eigen {
*/
namespace internal {
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
-struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> > : traits<XprType>
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
+struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType>
{
typedef typename traits<XprType>::Scalar Scalar;
typedef typename traits<XprType>::StorageKind StorageKind;
@@ -92,30 +91,27 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess>
Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
};
};
-}
-
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class Block
- : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> >::type
-{
- public:
- typedef typename internal::dense_xpr_base<Block>::type Base;
- EIGEN_DENSE_PUBLIC_INTERFACE(Block)
+template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
+ bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
+
+} // end namespace internal
- class InnerIterator;
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
+ : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
+{
+ typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
+ public:
+ //typedef typename Impl::Base Base;
+ typedef Impl Base;
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
+
/** Column or Row constructor
*/
- inline Block(XprType& xpr, Index i)
- : m_xpr(xpr),
- // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
- // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
- // all other cases are invalid.
- // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
- m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
- m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
- m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
- m_blockCols(BlockCols==1 ? 1 : xpr.cols())
+ inline Block(XprType& xpr, Index i) : Impl(xpr,i)
{
eigen_assert( (i>=0) && (
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
@@ -124,50 +120,109 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
/** Fixed-size constructor
*/
- inline Block(XprType& xpr, Index startRow, Index startCol)
- : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
- m_blockRows(BlockRows), m_blockCols(BlockCols)
+ inline Block(XprType& xpr, Index a_startRow, Index a_startCol)
+ : Impl(xpr, a_startRow, a_startCol)
{
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
- eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
- && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
+ eigen_assert(a_startRow >= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows()
+ && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols());
}
/** Dynamic-size constructor
*/
inline Block(XprType& xpr,
- Index startRow, Index startCol,
+ Index a_startRow, Index a_startCol,
Index blockRows, Index blockCols)
- : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
- m_blockRows(blockRows), m_blockCols(blockCols)
+ : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols)
{
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
- eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
- && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
+ eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows
+ && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols);
}
+};
+
+// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
+// that must be specialized for direct and non-direct access...
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
+class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
+ : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
+{
+ typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
+ typedef typename XprType::Index Index;
+ public:
+ typedef Impl Base;
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
+ inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
+ inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {}
+ inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols)
+ : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {}
+};
- EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
+namespace internal {
+
+/** \internal Internal implementation of dense Blocks in the general case. */
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
+ : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
+{
+ typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
+ public:
+
+ typedef typename internal::dense_xpr_base<BlockType>::type Base;
+ EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
+
+ class InnerIterator;
+
+ /** Column or Row constructor
+ */
+ inline BlockImpl_dense(XprType& xpr, Index i)
+ : m_xpr(xpr),
+ // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
+ // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
+ // all other cases are invalid.
+ // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
+ m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
+ m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
+ m_blockCols(BlockCols==1 ? 1 : xpr.cols())
+ {}
+
+ /** Fixed-size constructor
+ */
+ inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol)
+ : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
+ m_blockRows(BlockRows), m_blockCols(BlockCols)
+ {}
+
+ /** Dynamic-size constructor
+ */
+ inline BlockImpl_dense(XprType& xpr,
+ Index a_startRow, Index a_startCol,
+ Index blockRows, Index blockCols)
+ : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
+ m_blockRows(blockRows), m_blockCols(blockCols)
+ {}
inline Index rows() const { return m_blockRows.value(); }
inline Index cols() const { return m_blockCols.value(); }
- inline Scalar& coeffRef(Index row, Index col)
+ inline Scalar& coeffRef(Index rowId, Index colId)
{
EIGEN_STATIC_ASSERT_LVALUE(XprType)
return m_xpr.const_cast_derived()
- .coeffRef(row + m_startRow.value(), col + m_startCol.value());
+ .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
}
- inline const Scalar& coeffRef(Index row, Index col) const
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
{
return m_xpr.derived()
- .coeffRef(row + m_startRow.value(), col + m_startCol.value());
+ .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
}
- EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
{
- return m_xpr.coeff(row + m_startRow.value(), col + m_startCol.value());
+ return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
}
inline Scalar& coeffRef(Index index)
@@ -193,17 +248,17 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
}
template<int LoadMode>
- inline PacketScalar packet(Index row, Index col) const
+ inline PacketScalar packet(Index rowId, Index colId) const
{
return m_xpr.template packet<Unaligned>
- (row + m_startRow.value(), col + m_startCol.value());
+ (rowId + m_startRow.value(), colId + m_startCol.value());
}
template<int LoadMode>
- inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
{
m_xpr.const_cast_derived().template writePacket<Unaligned>
- (row + m_startRow.value(), col + m_startCol.value(), x);
+ (rowId + m_startRow.value(), colId + m_startCol.value(), val);
}
template<int LoadMode>
@@ -215,11 +270,11 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
}
template<int LoadMode>
- inline void writePacket(Index index, const PacketScalar& x)
+ inline void writePacket(Index index, const PacketScalar& val)
{
m_xpr.const_cast_derived().template writePacket<Unaligned>
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
- m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x);
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
}
#ifdef EIGEN_PARSED_BY_DOXYGEN
@@ -253,21 +308,21 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
};
-/** \internal */
+/** \internal Internal implementation of dense Blocks in the direct access case.*/
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
-class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
- : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel, true> >
+class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
+ : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
{
+ typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
public:
- typedef MapBase<Block> Base;
- EIGEN_DENSE_PUBLIC_INTERFACE(Block)
-
- EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
+ typedef MapBase<BlockType> Base;
+ EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
/** Column or Row constructor
*/
- inline Block(XprType& xpr, Index i)
+ inline BlockImpl_dense(XprType& xpr, Index i)
: Base(internal::const_cast_ptr(&xpr.coeffRef(
(BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
(BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
@@ -275,34 +330,25 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
BlockCols==1 ? 1 : xpr.cols()),
m_xpr(xpr)
{
- eigen_assert( (i>=0) && (
- ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
- ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
init();
}
/** Fixed-size constructor
*/
- inline Block(XprType& xpr, Index startRow, Index startCol)
+ inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
{
- eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
- && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
init();
}
/** Dynamic-size constructor
*/
- inline Block(XprType& xpr,
+ inline BlockImpl_dense(XprType& xpr,
Index startRow, Index startCol,
Index blockRows, Index blockCols)
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
m_xpr(xpr)
{
- eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
- && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
- eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
- && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
init();
}
@@ -314,7 +360,7 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
/** \sa MapBase::innerStride() */
inline Index innerStride() const
{
- return internal::traits<Block>::HasSameStorageOrderAsXprType
+ return internal::traits<BlockType>::HasSameStorageOrderAsXprType
? m_xpr.innerStride()
: m_xpr.outerStride();
}
@@ -333,7 +379,7 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal used by allowAligned() */
- inline Block(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
+ inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
: Base(data, blockRows, blockCols), m_xpr(xpr)
{
init();
@@ -343,7 +389,7 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
protected:
void init()
{
- m_outerStride = internal::traits<Block>::HasSameStorageOrderAsXprType
+ m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
? m_xpr.outerStride()
: m_xpr.innerStride();
}
@@ -352,6 +398,8 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
Index m_outerStride;
};
+} // end namespace internal
+
} // end namespace Eigen
#endif // EIGEN_BLOCK_H
diff --git a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h
index 57efd8e6953..be9f48a8c71 100644
--- a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h
+++ b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h
@@ -29,9 +29,9 @@ struct all_unroller
};
template<typename Derived>
-struct all_unroller<Derived, 1>
+struct all_unroller<Derived, 0>
{
- static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
+ static inline bool run(const Derived &/*mat*/) { return true; }
};
template<typename Derived>
@@ -55,9 +55,9 @@ struct any_unroller
};
template<typename Derived>
-struct any_unroller<Derived, 1>
+struct any_unroller<Derived, 0>
{
- static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
+ static inline bool run(const Derived & /*mat*/) { return false; }
};
template<typename Derived>
@@ -85,9 +85,7 @@ inline bool DenseBase<Derived>::all() const
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
};
if(unroll)
- return internal::all_unroller<Derived,
- unroll ? int(SizeAtCompileTime) : Dynamic
- >::run(derived());
+ return internal::all_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
else
{
for(Index j = 0; j < cols(); ++j)
@@ -111,9 +109,7 @@ inline bool DenseBase<Derived>::any() const
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
};
if(unroll)
- return internal::any_unroller<Derived,
- unroll ? int(SizeAtCompileTime) : Dynamic
- >::run(derived());
+ return internal::any_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
else
{
for(Index j = 0; j < cols(); ++j)
@@ -133,6 +129,26 @@ inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
return derived().template cast<bool>().template cast<Index>().sum();
}
+/** \returns true is \c *this contains at least one Not A Number (NaN).
+ *
+ * \sa allFinite()
+ */
+template<typename Derived>
+inline bool DenseBase<Derived>::hasNaN() const
+{
+ return !((derived().array()==derived().array()).all());
+}
+
+/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
+ *
+ * \sa hasNaN()
+ */
+template<typename Derived>
+inline bool DenseBase<Derived>::allFinite() const
+{
+ return !((derived()-derived()).hasNaN());
+}
+
} // end namespace Eigen
#endif // EIGEN_ALLANDANY_H
diff --git a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h
index 4adce64143c..a96867af4d5 100644
--- a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h
+++ b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h
@@ -65,6 +65,8 @@ struct CommaInitializer
template<typename OtherDerived>
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
{
+ if(other.cols()==0 || other.rows()==0)
+ return *this;
if (m_col==m_xpr.cols())
{
m_row+=m_currentBlockRows;
@@ -116,6 +118,8 @@ struct CommaInitializer
*
* Example: \include MatrixBase_set.cpp
* Output: \verbinclude MatrixBase_set.out
+ *
+ * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order.
*
* \sa CommaInitializer::finished(), class CommaInitializer
*/
diff --git a/extern/Eigen3/Eigen/src/Core/CoreIterators.h b/extern/Eigen3/Eigen/src/Core/CoreIterators.h
new file mode 100644
index 00000000000..6da4683d2c2
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/Core/CoreIterators.h
@@ -0,0 +1,61 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_COREITERATORS_H
+#define EIGEN_COREITERATORS_H
+
+namespace Eigen {
+
+/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
+ */
+
+/** \ingroup SparseCore_Module
+ * \class InnerIterator
+ * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression
+ *
+ * todo
+ */
+
+// generic version for dense matrix and expressions
+template<typename Derived> class DenseBase<Derived>::InnerIterator
+{
+ protected:
+ typedef typename Derived::Scalar Scalar;
+ typedef typename Derived::Index Index;
+
+ enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit };
+ public:
+ EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer)
+ : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize())
+ {}
+
+ EIGEN_STRONG_INLINE Scalar value() const
+ {
+ return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner)
+ : m_expression.coeff(m_inner, m_outer);
+ }
+
+ EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; }
+
+ EIGEN_STRONG_INLINE Index index() const { return m_inner; }
+ inline Index row() const { return IsRowMajor ? m_outer : index(); }
+ inline Index col() const { return IsRowMajor ? index() : m_outer; }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
+
+ protected:
+ const Derived& m_expression;
+ Index m_inner;
+ const Index m_outer;
+ const Index m_end;
+};
+
+} // end namespace Eigen
+
+#endif // EIGEN_COREITERATORS_H
diff --git a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h
index 1b93af31b60..586f77aaf32 100644
--- a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h
+++ b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h
@@ -94,8 +94,8 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
// add together a float matrix and a double matrix.
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
- EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \
- ? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \
+ EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
+ ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
: int(internal::is_same<LHS, RHS>::value)), \
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
@@ -122,13 +122,13 @@ class CwiseBinaryOp : internal::no_assignment_operator,
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
- EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
- : m_lhs(lhs), m_rhs(rhs), m_functor(func)
+ EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
+ : m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
{
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
// require the sizes to match
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
- eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
+ eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
}
EIGEN_STRONG_INLINE Index rows() const {
@@ -169,17 +169,17 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
- EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
{
- return derived().functor()(derived().lhs().coeff(row, col),
- derived().rhs().coeff(row, col));
+ return derived().functor()(derived().lhs().coeff(rowId, colId),
+ derived().rhs().coeff(rowId, colId));
}
template<int LoadMode>
- EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
+ EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
{
- return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(row, col),
- derived().rhs().template packet<LoadMode>(row, col));
+ return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(rowId, colId),
+ derived().rhs().template packet<LoadMode>(rowId, colId));
}
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
diff --git a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h
index 2635a62b07b..a93bab2d0f9 100644
--- a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h
+++ b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h
@@ -54,27 +54,27 @@ class CwiseNullaryOp : internal::no_assignment_operator,
typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
- CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
- : m_rows(rows), m_cols(cols), m_functor(func)
+ CwiseNullaryOp(Index nbRows, Index nbCols, const NullaryOp& func = NullaryOp())
+ : m_rows(nbRows), m_cols(nbCols), m_functor(func)
{
- eigen_assert(rows >= 0
- && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
- && cols >= 0
- && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
+ eigen_assert(nbRows >= 0
+ && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows)
+ && nbCols >= 0
+ && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols));
}
EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
- EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const
+ EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
{
- return m_functor(rows, cols);
+ return m_functor(rowId, colId);
}
template<int LoadMode>
- EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
+ EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
{
- return m_functor.packetOp(row, col);
+ return m_functor.packetOp(rowId, colId);
}
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
@@ -163,11 +163,11 @@ DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
/** \returns an expression of a constant matrix of value \a value
*
- * The parameters \a rows and \a cols are the number of rows and of columns of
+ * The parameters \a nbRows and \a nbCols are the number of rows and of columns of
* the returned matrix. Must be compatible with this DenseBase type.
*
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
- * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
+ * it is redundant to pass \a nbRows and \a nbCols as arguments, so Zero() should be used
* instead.
*
* The template parameter \a CustomNullaryOp is the type of the functor.
@@ -176,9 +176,9 @@ DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
+DenseBase<Derived>::Constant(Index nbRows, Index nbCols, const Scalar& value)
{
- return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
+ return DenseBase<Derived>::NullaryExpr(nbRows, nbCols, internal::scalar_constant_op<Scalar>(value));
}
/** \returns an expression of a constant matrix of value \a value
@@ -292,14 +292,14 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
}
-/** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
+/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
template<typename Derived>
bool DenseBase<Derived>::isApproxToConstant
-(const Scalar& value, RealScalar prec) const
+(const Scalar& val, const RealScalar& prec) const
{
for(Index j = 0; j < cols(); ++j)
for(Index i = 0; i < rows(); ++i)
- if(!internal::isApprox(this->coeff(i, j), value, prec))
+ if(!internal::isApprox(this->coeff(i, j), val, prec))
return false;
return true;
}
@@ -309,19 +309,19 @@ bool DenseBase<Derived>::isApproxToConstant
* \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
template<typename Derived>
bool DenseBase<Derived>::isConstant
-(const Scalar& value, RealScalar prec) const
+(const Scalar& val, const RealScalar& prec) const
{
- return isApproxToConstant(value, prec);
+ return isApproxToConstant(val, prec);
}
-/** Alias for setConstant(): sets all coefficients in this expression to \a value.
+/** Alias for setConstant(): sets all coefficients in this expression to \a val.
*
* \sa setConstant(), Constant(), class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value)
+EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
{
- setConstant(value);
+ setConstant(val);
}
/** Sets all coefficients in this expression to \a value.
@@ -329,9 +329,9 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value)
* \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value)
+EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
{
- return derived() = Constant(rows(), cols(), value);
+ return derived() = Constant(rows(), cols(), val);
}
/** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value.
@@ -345,17 +345,17 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setConstant(Index size, const Scalar& value)
+PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
{
resize(size);
- return setConstant(value);
+ return setConstant(val);
}
/** Resizes to the given size, and sets all coefficients in this expression to the given \a value.
*
- * \param rows the new number of rows
- * \param cols the new number of columns
- * \param value the value to which all coefficients are set
+ * \param nbRows the new number of rows
+ * \param nbCols the new number of columns
+ * \param val the value to which all coefficients are set
*
* Example: \include Matrix_setConstant_int_int.cpp
* Output: \verbinclude Matrix_setConstant_int_int.out
@@ -364,10 +364,10 @@ PlainObjectBase<Derived>::setConstant(Index size, const Scalar& value)
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& value)
+PlainObjectBase<Derived>::setConstant(Index nbRows, Index nbCols, const Scalar& val)
{
- resize(rows, cols);
- return setConstant(value);
+ resize(nbRows, nbCols);
+ return setConstant(val);
}
/**
@@ -384,10 +384,10 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& valu
* \sa CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const Scalar& low, const Scalar& high)
+EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
+ return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,false>(low,high,newSize));
}
/**
@@ -425,9 +425,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low,
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Zero(Index rows, Index cols)
+DenseBase<Derived>::Zero(Index nbRows, Index nbCols)
{
- return Constant(rows, cols, Scalar(0));
+ return Constant(nbRows, nbCols, Scalar(0));
}
/** \returns an expression of a zero vector.
@@ -479,7 +479,7 @@ DenseBase<Derived>::Zero()
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
-bool DenseBase<Derived>::isZero(RealScalar prec) const
+bool DenseBase<Derived>::isZero(const RealScalar& prec) const
{
for(Index j = 0; j < cols(); ++j)
for(Index i = 0; i < rows(); ++i)
@@ -512,16 +512,16 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setZero(Index size)
+PlainObjectBase<Derived>::setZero(Index newSize)
{
- resize(size);
+ resize(newSize);
return setConstant(Scalar(0));
}
/** Resizes to the given size, and sets all coefficients in this expression to zero.
*
- * \param rows the new number of rows
- * \param cols the new number of columns
+ * \param nbRows the new number of rows
+ * \param nbCols the new number of columns
*
* Example: \include Matrix_setZero_int_int.cpp
* Output: \verbinclude Matrix_setZero_int_int.out
@@ -530,9 +530,9 @@ PlainObjectBase<Derived>::setZero(Index size)
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setZero(Index rows, Index cols)
+PlainObjectBase<Derived>::setZero(Index nbRows, Index nbCols)
{
- resize(rows, cols);
+ resize(nbRows, nbCols);
return setConstant(Scalar(0));
}
@@ -540,7 +540,7 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
/** \returns an expression of a matrix where all coefficients equal one.
*
- * The parameters \a rows and \a cols are the number of rows and of columns of
+ * The parameters \a nbRows and \a nbCols are the number of rows and of columns of
* the returned matrix. Must be compatible with this MatrixBase type.
*
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
@@ -554,14 +554,14 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Ones(Index rows, Index cols)
+DenseBase<Derived>::Ones(Index nbRows, Index nbCols)
{
- return Constant(rows, cols, Scalar(1));
+ return Constant(nbRows, nbCols, Scalar(1));
}
/** \returns an expression of a vector where all coefficients equal one.
*
- * The parameter \a size is the size of the returned vector.
+ * The parameter \a newSize is the size of the returned vector.
* Must be compatible with this MatrixBase type.
*
* \only_for_vectors
@@ -577,9 +577,9 @@ DenseBase<Derived>::Ones(Index rows, Index cols)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Ones(Index size)
+DenseBase<Derived>::Ones(Index newSize)
{
- return Constant(size, Scalar(1));
+ return Constant(newSize, Scalar(1));
}
/** \returns an expression of a fixed-size matrix or vector where all coefficients equal one.
@@ -609,7 +609,7 @@ DenseBase<Derived>::Ones()
*/
template<typename Derived>
bool DenseBase<Derived>::isOnes
-(RealScalar prec) const
+(const RealScalar& prec) const
{
return isApproxToConstant(Scalar(1), prec);
}
@@ -627,7 +627,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
return setConstant(Scalar(1));
}
-/** Resizes to the given \a size, and sets all coefficients in this expression to one.
+/** Resizes to the given \a newSize, and sets all coefficients in this expression to one.
*
* \only_for_vectors
*
@@ -638,16 +638,16 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setOnes(Index size)
+PlainObjectBase<Derived>::setOnes(Index newSize)
{
- resize(size);
+ resize(newSize);
return setConstant(Scalar(1));
}
/** Resizes to the given size, and sets all coefficients in this expression to one.
*
- * \param rows the new number of rows
- * \param cols the new number of columns
+ * \param nbRows the new number of rows
+ * \param nbCols the new number of columns
*
* Example: \include Matrix_setOnes_int_int.cpp
* Output: \verbinclude Matrix_setOnes_int_int.out
@@ -656,9 +656,9 @@ PlainObjectBase<Derived>::setOnes(Index size)
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
+PlainObjectBase<Derived>::setOnes(Index nbRows, Index nbCols)
{
- resize(rows, cols);
+ resize(nbRows, nbCols);
return setConstant(Scalar(1));
}
@@ -666,7 +666,7 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
/** \returns an expression of the identity matrix (not necessarily square).
*
- * The parameters \a rows and \a cols are the number of rows and of columns of
+ * The parameters \a nbRows and \a nbCols are the number of rows and of columns of
* the returned matrix. Must be compatible with this MatrixBase type.
*
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
@@ -680,9 +680,9 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
-MatrixBase<Derived>::Identity(Index rows, Index cols)
+MatrixBase<Derived>::Identity(Index nbRows, Index nbCols)
{
- return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
+ return DenseBase<Derived>::NullaryExpr(nbRows, nbCols, internal::scalar_identity_op<Scalar>());
}
/** \returns an expression of the identity matrix (not necessarily square).
@@ -714,7 +714,7 @@ MatrixBase<Derived>::Identity()
*/
template<typename Derived>
bool MatrixBase<Derived>::isIdentity
-(RealScalar prec) const
+(const RealScalar& prec) const
{
for(Index j = 0; j < cols(); ++j)
{
@@ -776,8 +776,8 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
/** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this.
*
- * \param rows the new number of rows
- * \param cols the new number of columns
+ * \param nbRows the new number of rows
+ * \param nbCols the new number of columns
*
* Example: \include Matrix_setIdentity_int_int.cpp
* Output: \verbinclude Matrix_setIdentity_int_int.out
@@ -785,9 +785,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
+EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index nbRows, Index nbCols)
{
- derived().resize(rows, cols);
+ derived().resize(nbRows, nbCols);
return setIdentity();
}
@@ -798,10 +798,10 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index
* \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index size, Index i)
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return BasisReturnType(SquareMatrixType::Identity(size,size), i);
+ return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i);
}
/** \returns an expression of the i-th unit (basis) vector.
diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h
index 063355ae521..f2de749f92b 100644
--- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h
+++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h
@@ -98,15 +98,15 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
- EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
{
- return derived().functor()(derived().nestedExpression().coeff(row, col));
+ return derived().functor()(derived().nestedExpression().coeff(rowId, colId));
}
template<int LoadMode>
- EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
+ EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
{
- return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(row, col));
+ return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(rowId, colId));
}
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h
index 66f73a9505b..b2638d3265b 100644
--- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h
+++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h
@@ -44,9 +44,10 @@ struct traits<CwiseUnaryView<ViewOp, MatrixType> >
// "error: no integral type can represent all of the enumerator values
InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic
? int(Dynamic)
- : int(MatrixTypeInnerStride)
- * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
- OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
+ : int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
+ OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret == Dynamic
+ ? int(Dynamic)
+ : outer_stride_at_compile_time<MatrixType>::ret * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar))
};
};
}
@@ -55,8 +56,7 @@ template<typename ViewOp, typename MatrixType, typename StorageKind>
class CwiseUnaryViewImpl;
template<typename ViewOp, typename MatrixType>
-class CwiseUnaryView : internal::no_assignment_operator,
- public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
+class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
{
public:
@@ -98,6 +98,10 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
+
+ inline Scalar* data() { return &coeffRef(0); }
+ inline const Scalar* data() const { return &coeff(0); }
inline Index innerStride() const
{
@@ -106,7 +110,7 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
inline Index outerStride() const
{
- return derived().nestedExpression().outerStride();
+ return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
}
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
diff --git a/extern/Eigen3/Eigen/src/Core/DenseBase.h b/extern/Eigen3/Eigen/src/Core/DenseBase.h
index 1cc0314ef0b..c5800f6c8c8 100644
--- a/extern/Eigen3/Eigen/src/Core/DenseBase.h
+++ b/extern/Eigen3/Eigen/src/Core/DenseBase.h
@@ -13,6 +13,16 @@
namespace Eigen {
+namespace internal {
+
+// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
+// This dummy function simply aims at checking that at compile time.
+static inline void check_DenseIndex_is_signed() {
+ EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+}
+
+} // end namespace internal
+
/** \class DenseBase
* \ingroup Core_Module
*
@@ -204,21 +214,21 @@ template<typename Derived> class DenseBase
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
* nothing else.
*/
- void resize(Index size)
+ void resize(Index newSize)
{
- EIGEN_ONLY_USED_FOR_DEBUG(size);
- eigen_assert(size == this->size()
+ EIGEN_ONLY_USED_FOR_DEBUG(newSize);
+ eigen_assert(newSize == this->size()
&& "DenseBase::resize() does not actually allow to resize.");
}
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
* nothing else.
*/
- void resize(Index rows, Index cols)
+ void resize(Index nbRows, Index nbCols)
{
- EIGEN_ONLY_USED_FOR_DEBUG(rows);
- EIGEN_ONLY_USED_FOR_DEBUG(cols);
- eigen_assert(rows == this->rows() && cols == this->cols()
+ EIGEN_ONLY_USED_FOR_DEBUG(nbRows);
+ EIGEN_ONLY_USED_FOR_DEBUG(nbCols);
+ eigen_assert(nbRows == this->rows() && nbCols == this->cols()
&& "DenseBase::resize() does not actually allow to resize.");
}
@@ -271,7 +281,7 @@ template<typename Derived> class DenseBase
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
Eigen::Transpose<Derived> transpose();
- typedef const Transpose<const Derived> ConstTransposeReturnType;
+ typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
ConstTransposeReturnType transpose() const;
void transposeInPlace();
#ifndef EIGEN_NO_DEBUG
@@ -281,29 +291,6 @@ template<typename Derived> class DenseBase
public:
#endif
- typedef VectorBlock<Derived> SegmentReturnType;
- typedef const VectorBlock<const Derived> ConstSegmentReturnType;
- template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
- template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
-
- // Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
- SegmentReturnType segment(Index start, Index size);
- typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const;
-
- SegmentReturnType head(Index size);
- typename DenseBase::ConstSegmentReturnType head(Index size) const;
-
- SegmentReturnType tail(Index size);
- typename DenseBase::ConstSegmentReturnType tail(Index size) const;
-
- template<int Size> typename FixedSegmentReturnType<Size>::Type head();
- template<int Size> typename ConstFixedSegmentReturnType<Size>::Type head() const;
-
- template<int Size> typename FixedSegmentReturnType<Size>::Type tail();
- template<int Size> typename ConstFixedSegmentReturnType<Size>::Type tail() const;
-
- template<int Size> typename FixedSegmentReturnType<Size>::Type segment(Index start);
- template<int Size> typename ConstFixedSegmentReturnType<Size>::Type segment(Index start) const;
static const ConstantReturnType
Constant(Index rows, Index cols, const Scalar& value);
@@ -348,17 +335,20 @@ template<typename Derived> class DenseBase
template<typename OtherDerived>
bool isApprox(const DenseBase<OtherDerived>& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
bool isMuchSmallerThan(const RealScalar& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
template<typename OtherDerived>
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+
+ inline bool hasNaN() const;
+ inline bool allFinite() const;
inline Derived& operator*=(const Scalar& other);
inline Derived& operator/=(const Scalar& other);
@@ -438,8 +428,6 @@ template<typename Derived> class DenseBase
return derived().coeff(0,0);
}
-/////////// Array module ///////////
-
bool all(void) const;
bool any(void) const;
Index count() const;
@@ -465,11 +453,11 @@ template<typename Derived> class DenseBase
template<typename ThenDerived>
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
- select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
+ select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
template<typename ElseDerived>
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
- select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
+ select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
template<int p> RealScalar lpNorm() const;
diff --git a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h
index 72704c2d79f..3c890f21590 100644
--- a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h
+++ b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h
@@ -427,22 +427,22 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
template<int StoreMode>
EIGEN_STRONG_INLINE void writePacket
- (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
+ (Index row, Index col, const typename internal::packet_traits<Scalar>::type& val)
{
eigen_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
- derived().template writePacket<StoreMode>(row,col,x);
+ derived().template writePacket<StoreMode>(row,col,val);
}
/** \internal */
template<int StoreMode>
EIGEN_STRONG_INLINE void writePacketByOuterInner
- (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
+ (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& val)
{
writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner),
- x);
+ val);
}
/** \internal
@@ -456,10 +456,10 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
*/
template<int StoreMode>
EIGEN_STRONG_INLINE void writePacket
- (Index index, const typename internal::packet_traits<Scalar>::type& x)
+ (Index index, const typename internal::packet_traits<Scalar>::type& val)
{
eigen_internal_assert(index >= 0 && index < size());
- derived().template writePacket<StoreMode>(index,x);
+ derived().template writePacket<StoreMode>(index,val);
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
diff --git a/extern/Eigen3/Eigen/src/Core/DenseStorage.h b/extern/Eigen3/Eigen/src/Core/DenseStorage.h
index 1fc2daf2c40..3e7f9c1b7a7 100644
--- a/extern/Eigen3/Eigen/src/Core/DenseStorage.h
+++ b/extern/Eigen3/Eigen/src/Core/DenseStorage.h
@@ -35,17 +35,36 @@ template <typename T, int Size, int MatrixOrArrayOptions,
struct plain_array
{
T array[Size];
- plain_array() {}
- plain_array(constructor_without_unaligned_array_assert) {}
+
+ plain_array()
+ {
+ EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
+ }
+
+ plain_array(constructor_without_unaligned_array_assert)
+ {
+ EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
+ }
};
-#ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
+#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
+#elif EIGEN_GNUC_AT_LEAST(4,7)
+ // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
+ // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
+ // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
+ template<typename PtrType>
+ EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
+ #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
+ eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \
+ && "this assertion is explained here: " \
+ "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
+ " **** READ THIS WEB PAGE !!! ****");
#else
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
&& "this assertion is explained here: " \
- "http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \
+ "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
" **** READ THIS WEB PAGE !!! ****");
#endif
@@ -53,8 +72,17 @@ template <typename T, int Size, int MatrixOrArrayOptions>
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
{
EIGEN_USER_ALIGN16 T array[Size];
- plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
- plain_array(constructor_without_unaligned_array_assert) {}
+
+ plain_array()
+ {
+ EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf);
+ EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
+ }
+
+ plain_array(constructor_without_unaligned_array_assert)
+ {
+ EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
+ }
};
template <typename T, int MatrixOrArrayOptions, int Alignment>
@@ -86,7 +114,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
{
internal::plain_array<T,Size,_Options> m_data;
public:
- inline explicit DenseStorage() {}
+ inline DenseStorage() {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()) {}
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
@@ -103,7 +131,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
{
public:
- inline explicit DenseStorage() {}
+ inline DenseStorage() {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
inline void swap(DenseStorage& ) {}
@@ -132,16 +160,16 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_rows(0), m_cols(0) {}
+ inline DenseStorage() : m_rows(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
- inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex cols) : m_rows(rows), m_cols(cols) {}
+ inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
inline void swap(DenseStorage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
- inline DenseIndex rows(void) const {return m_rows;}
- inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
- inline void resize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
+ inline DenseIndex rows() const {return m_rows;}
+ inline DenseIndex cols() const {return m_cols;}
+ inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
+ inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
inline const T *data() const { return m_data.array; }
inline T *data() { return m_data.array; }
};
@@ -152,15 +180,15 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_rows;
public:
- inline explicit DenseStorage() : m_rows(0) {}
+ inline DenseStorage() : m_rows(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
- inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex) : m_rows(rows) {}
+ inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline DenseIndex rows(void) const {return m_rows;}
inline DenseIndex cols(void) const {return _Cols;}
- inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
- inline void resize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
+ inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
+ inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
inline const T *data() const { return m_data.array; }
inline T *data() { return m_data.array; }
};
@@ -171,15 +199,15 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_cols(0) {}
+ inline DenseStorage() : m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
- inline DenseStorage(DenseIndex, DenseIndex, DenseIndex cols) : m_cols(cols) {}
+ inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
inline DenseIndex rows(void) const {return _Rows;}
inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
- inline void resize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
+ inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
+ inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
inline const T *data() const { return m_data.array; }
inline T *data() { return m_data.array; }
};
@@ -191,24 +219,24 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
+ inline DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(0), m_rows(0), m_cols(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex cols)
- : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
+ inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
+ : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
inline void swap(DenseStorage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
inline DenseIndex rows(void) const {return m_rows;}
inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex cols)
+ inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
- m_rows = rows;
- m_cols = cols;
+ m_rows = nbRows;
+ m_cols = nbCols;
}
- void resize(DenseIndex size, DenseIndex rows, DenseIndex cols)
+ void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
{
if(size != m_rows*m_cols)
{
@@ -219,8 +247,8 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
- m_rows = rows;
- m_cols = cols;
+ m_rows = nbRows;
+ m_cols = nbCols;
}
inline const T *data() const { return m_data; }
inline T *data() { return m_data; }
@@ -232,20 +260,20 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
T *m_data;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_data(0), m_cols(0) {}
+ inline DenseStorage() : m_data(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
+ inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
static inline DenseIndex rows(void) {return _Rows;}
inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols)
+ inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
- m_cols = cols;
+ m_cols = nbCols;
}
- EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols)
+ EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols)
{
if(size != _Rows*m_cols)
{
@@ -256,7 +284,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
- m_cols = cols;
+ m_cols = nbCols;
}
inline const T *data() const { return m_data; }
inline T *data() { return m_data; }
@@ -268,20 +296,20 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
T *m_data;
DenseIndex m_rows;
public:
- inline explicit DenseStorage() : m_data(0), m_rows(0) {}
+ inline DenseStorage() : m_data(0), m_rows(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
+ inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline DenseIndex rows(void) const {return m_rows;}
static inline DenseIndex cols(void) {return _Cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex)
+ inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
- m_rows = rows;
+ m_rows = nbRows;
}
- EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex)
+ EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex)
{
if(size != m_rows*_Cols)
{
@@ -292,7 +320,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
- m_rows = rows;
+ m_rows = nbRows;
}
inline const T *data() const { return m_data; }
inline T *data() { return m_data; }
diff --git a/extern/Eigen3/Eigen/src/Core/Diagonal.h b/extern/Eigen3/Eigen/src/Core/Diagonal.h
index 16261968a0f..aab8007b3fc 100644
--- a/extern/Eigen3/Eigen/src/Core/Diagonal.h
+++ b/extern/Eigen3/Eigen/src/Core/Diagonal.h
@@ -41,12 +41,12 @@ struct traits<Diagonal<MatrixType,DiagIndex> >
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
typedef typename MatrixType::StorageKind StorageKind;
enum {
- RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
- : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
- MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
+ RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
+ : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
+ MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
ColsAtCompileTime = 1,
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
- : DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
+ : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
MatrixType::MaxColsAtCompileTime)
: (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
@@ -61,20 +61,21 @@ struct traits<Diagonal<MatrixType,DiagIndex> >
};
}
-template<typename MatrixType, int DiagIndex> class Diagonal
- : public internal::dense_xpr_base< Diagonal<MatrixType,DiagIndex> >::type
+template<typename MatrixType, int _DiagIndex> class Diagonal
+ : public internal::dense_xpr_base< Diagonal<MatrixType,_DiagIndex> >::type
{
public:
+ enum { DiagIndex = _DiagIndex };
typedef typename internal::dense_xpr_base<Diagonal>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
- inline Diagonal(MatrixType& matrix, Index index = DiagIndex) : m_matrix(matrix), m_index(index) {}
+ inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
inline Index rows() const
- { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
+ { return m_index.value()<0 ? (std::min<Index>)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min<Index>)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
inline Index cols() const { return 1; }
@@ -113,20 +114,20 @@ template<typename MatrixType, int DiagIndex> class Diagonal
return m_matrix.coeff(row+rowOffset(), row+colOffset());
}
- inline Scalar& coeffRef(Index index)
+ inline Scalar& coeffRef(Index idx)
{
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
- return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset());
+ return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset());
}
- inline const Scalar& coeffRef(Index index) const
+ inline const Scalar& coeffRef(Index idx) const
{
- return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset());
+ return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset());
}
- inline CoeffReturnType coeff(Index index) const
+ inline CoeffReturnType coeff(Index idx) const
{
- return m_matrix.coeff(index+rowOffset(), index+colOffset());
+ return m_matrix.coeff(idx+rowOffset(), idx+colOffset());
}
const typename internal::remove_all<typename MatrixType::Nested>::type&
@@ -142,7 +143,7 @@ template<typename MatrixType, int DiagIndex> class Diagonal
protected:
typename MatrixType::Nested m_matrix;
- const internal::variable_if_dynamic<Index, DiagIndex> m_index;
+ const internal::variable_if_dynamicindex<Index, DiagIndex> m_index;
private:
// some compilers may fail to optimize std::max etc in case of compile-time constants...
@@ -171,7 +172,7 @@ MatrixBase<Derived>::diagonal()
/** This is the const version of diagonal(). */
template<typename Derived>
-inline const typename MatrixBase<Derived>::ConstDiagonalReturnType
+inline typename MatrixBase<Derived>::ConstDiagonalReturnType
MatrixBase<Derived>::diagonal() const
{
return ConstDiagonalReturnType(derived());
@@ -189,18 +190,18 @@ MatrixBase<Derived>::diagonal() const
*
* \sa MatrixBase::diagonal(), class Diagonal */
template<typename Derived>
-inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Dynamic>::Type
+inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<DynamicIndex>::Type
MatrixBase<Derived>::diagonal(Index index)
{
- return typename DiagonalIndexReturnType<Dynamic>::Type(derived(), index);
+ return typename DiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
}
/** This is the const version of diagonal(Index). */
template<typename Derived>
-inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Dynamic>::Type
+inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<DynamicIndex>::Type
MatrixBase<Derived>::diagonal(Index index) const
{
- return typename ConstDiagonalIndexReturnType<Dynamic>::Type(derived(), index);
+ return typename ConstDiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
}
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h
index 88190da684d..e6c220f4195 100644
--- a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h
@@ -20,6 +20,7 @@ class DiagonalBase : public EigenBase<Derived>
public:
typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
typedef typename DiagonalVectorType::Scalar Scalar;
+ typedef typename DiagonalVectorType::RealScalar RealScalar;
typedef typename internal::traits<Derived>::StorageKind StorageKind;
typedef typename internal::traits<Derived>::Index Index;
@@ -55,9 +56,14 @@ class DiagonalBase : public EigenBase<Derived>
inline Index rows() const { return diagonal().size(); }
inline Index cols() const { return diagonal().size(); }
+ /** \returns the diagonal matrix product of \c *this by the matrix \a matrix.
+ */
template<typename MatrixDerived>
const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
- operator*(const MatrixBase<MatrixDerived> &matrix) const;
+ operator*(const MatrixBase<MatrixDerived> &matrix) const
+ {
+ return DiagonalProduct<MatrixDerived, Derived, OnTheLeft>(matrix.derived(), derived());
+ }
inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
inverse() const
@@ -65,6 +71,17 @@ class DiagonalBase : public EigenBase<Derived>
return diagonal().cwiseInverse();
}
+ inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
+ operator*(const Scalar& scalar) const
+ {
+ return diagonal() * scalar;
+ }
+ friend inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
+ operator*(const Scalar& scalar, const DiagonalBase& other)
+ {
+ return other.diagonal() * scalar;
+ }
+
#ifdef EIGEN2_SUPPORT
template<typename OtherDerived>
bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
@@ -238,7 +255,7 @@ class DiagonalWrapper
#endif
/** Constructor from expression of diagonal coefficients to wrap. */
- inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
+ inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {}
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
const DiagonalVectorType& diagonal() const { return m_diagonal; }
@@ -272,13 +289,14 @@ MatrixBase<Derived>::asDiagonal() const
* \sa asDiagonal()
*/
template<typename Derived>
-bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const
+bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
{
+ using std::abs;
if(cols() != rows()) return false;
RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
for(Index j = 0; j < cols(); ++j)
{
- RealScalar absOnDiagonal = internal::abs(coeff(j,j));
+ RealScalar absOnDiagonal = abs(coeff(j,j));
if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
}
for(Index j = 0; j < cols(); ++j)
diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h
index 598c6b3e19a..c03a0c2e12b 100644
--- a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h
+++ b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h
@@ -26,14 +26,15 @@ struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
_StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
- _PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
- ||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)),
+ _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
+ ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
// FIXME currently we need same types, but in the future the next rule should be the one
- //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))),
- _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))),
+ //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
+ _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
+ _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
- Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),
+ Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
};
};
@@ -54,13 +55,21 @@ class DiagonalProduct : internal::no_assignment_operator,
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
}
- inline Index rows() const { return m_matrix.rows(); }
- inline Index cols() const { return m_matrix.cols(); }
+ EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
+ EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
- const Scalar coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
{
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
}
+
+ EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
+ {
+ enum {
+ StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
+ };
+ return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
+ }
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
@@ -69,11 +78,19 @@ class DiagonalProduct : internal::no_assignment_operator,
StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
};
const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
-
return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
}
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const
+ {
+ enum {
+ StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
+ };
+ return packet<LoadMode>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
+ }
protected:
template<int LoadMode>
@@ -88,7 +105,7 @@ class DiagonalProduct : internal::no_assignment_operator,
{
enum {
InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
- DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned
+ DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned)
};
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
@@ -103,19 +120,9 @@ class DiagonalProduct : internal::no_assignment_operator,
template<typename Derived>
template<typename DiagonalDerived>
inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
-MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &diagonal) const
-{
- return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), diagonal.derived());
-}
-
-/** \returns the diagonal matrix product of \c *this by the matrix \a matrix.
- */
-template<typename DiagonalDerived>
-template<typename MatrixDerived>
-inline const DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>
-DiagonalBase<DiagonalDerived>::operator*(const MatrixBase<MatrixDerived> &matrix) const
+MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
{
- return DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>(matrix.derived(), derived());
+ return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), a_diagonal.derived());
}
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/Core/Dot.h b/extern/Eigen3/Eigen/src/Core/Dot.h
index ae9274e36dd..9d7651f1fd4 100644
--- a/extern/Eigen3/Eigen/src/Core/Dot.h
+++ b/extern/Eigen3/Eigen/src/Core/Dot.h
@@ -112,7 +112,7 @@ MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
template<typename Derived>
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
{
- return internal::real((*this).cwiseAbs2().sum());
+ return numext::real((*this).cwiseAbs2().sum());
}
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
@@ -124,7 +124,8 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
template<typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
{
- return internal::sqrt(squaredNorm());
+ using std::sqrt;
+ return sqrt(squaredNorm());
}
/** \returns an expression of the quotient of *this by its own norm.
@@ -165,6 +166,7 @@ struct lpNorm_selector
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
static inline RealScalar run(const MatrixBase<Derived>& m)
{
+ using std::pow;
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
}
};
@@ -223,11 +225,11 @@ MatrixBase<Derived>::lpNorm() const
template<typename Derived>
template<typename OtherDerived>
bool MatrixBase<Derived>::isOrthogonal
-(const MatrixBase<OtherDerived>& other, RealScalar prec) const
+(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
{
typename internal::nested<Derived,2>::type nested(derived());
typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
- return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
+ return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
}
/** \returns true if *this is approximately an unitary matrix,
@@ -242,7 +244,7 @@ bool MatrixBase<Derived>::isOrthogonal
* Output: \verbinclude MatrixBase_isUnitary.out
*/
template<typename Derived>
-bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
+bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
{
typename Derived::Nested nested(derived());
for(Index i = 0; i < cols(); ++i)
diff --git a/extern/Eigen3/Eigen/src/Core/EigenBase.h b/extern/Eigen3/Eigen/src/Core/EigenBase.h
index 0bbd28bec21..fadb45852f6 100644
--- a/extern/Eigen3/Eigen/src/Core/EigenBase.h
+++ b/extern/Eigen3/Eigen/src/Core/EigenBase.h
@@ -126,35 +126,6 @@ Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
return derived();
}
-/** replaces \c *this by \c *this * \a other.
- *
- * \returns a reference to \c *this
- */
-template<typename Derived>
-template<typename OtherDerived>
-inline Derived&
-MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
-{
- other.derived().applyThisOnTheRight(derived());
- return derived();
-}
-
-/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
-template<typename Derived>
-template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
-{
- other.derived().applyThisOnTheRight(derived());
-}
-
-/** replaces \c *this by \c *this * \a other. */
-template<typename Derived>
-template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
-{
- other.derived().applyThisOnTheLeft(derived());
-}
-
} // end namespace Eigen
#endif // EIGEN_EIGENBASE_H
diff --git a/extern/Eigen3/Eigen/src/Core/Functors.h b/extern/Eigen3/Eigen/src/Core/Functors.h
index 278c46c6b61..04fb217323d 100644
--- a/extern/Eigen3/Eigen/src/Core/Functors.h
+++ b/extern/Eigen3/Eigen/src/Core/Functors.h
@@ -154,6 +154,7 @@ template<typename Scalar> struct scalar_hypot_op {
{
using std::max;
using std::min;
+ using std::sqrt;
Scalar p = (max)(_x, _y);
Scalar q = (min)(_x, _y);
Scalar qp = q/p;
@@ -170,7 +171,7 @@ struct functor_traits<scalar_hypot_op<Scalar> > {
*/
template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
- inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); }
+ inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); }
};
template<typename Scalar, typename OtherScalar>
struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
@@ -204,21 +205,28 @@ struct functor_traits<scalar_difference_op<Scalar> > {
*
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
-template<typename Scalar> struct scalar_quotient_op {
+template<typename LhsScalar,typename RhsScalar> struct scalar_quotient_op {
+ enum {
+ // TODO vectorize mixed product
+ Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv
+ };
+ typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
- EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
+ EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pdiv(a,b); }
};
-template<typename Scalar>
-struct functor_traits<scalar_quotient_op<Scalar> > {
+template<typename LhsScalar,typename RhsScalar>
+struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
enum {
- Cost = 2 * NumTraits<Scalar>::MulCost,
- PacketAccess = packet_traits<Scalar>::HasDiv
+ Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost), // rough estimate!
+ PacketAccess = scalar_quotient_op<LhsScalar,RhsScalar>::Vectorizable
};
};
+
+
/** \internal
* \brief Template functor to compute the and of two booleans
*
@@ -280,7 +288,7 @@ struct functor_traits<scalar_opposite_op<Scalar> >
template<typename Scalar> struct scalar_abs_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); }
+ EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
{ return internal::pabs(a); }
@@ -302,7 +310,7 @@ struct functor_traits<scalar_abs_op<Scalar> >
template<typename Scalar> struct scalar_abs2_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); }
+ EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
{ return internal::pmul(a,a); }
@@ -318,7 +326,7 @@ struct functor_traits<scalar_abs2_op<Scalar> >
*/
template<typename Scalar> struct scalar_conjugate_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
- EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return internal::conj(a); }
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
};
@@ -355,7 +363,7 @@ template<typename Scalar>
struct scalar_real_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); }
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
};
template<typename Scalar>
struct functor_traits<scalar_real_op<Scalar> >
@@ -370,7 +378,7 @@ template<typename Scalar>
struct scalar_imag_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); }
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
};
template<typename Scalar>
struct functor_traits<scalar_imag_op<Scalar> >
@@ -385,7 +393,7 @@ template<typename Scalar>
struct scalar_real_ref_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); }
+ EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
};
template<typename Scalar>
struct functor_traits<scalar_real_ref_op<Scalar> >
@@ -400,7 +408,7 @@ template<typename Scalar>
struct scalar_imag_ref_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); }
+ EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
};
template<typename Scalar>
struct functor_traits<scalar_imag_ref_op<Scalar> >
@@ -414,7 +422,7 @@ struct functor_traits<scalar_imag_ref_op<Scalar> >
*/
template<typename Scalar> struct scalar_exp_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
};
@@ -430,7 +438,7 @@ struct functor_traits<scalar_exp_op<Scalar> >
*/
template<typename Scalar> struct scalar_log_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::log(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
};
@@ -447,7 +455,7 @@ struct functor_traits<scalar_log_op<Scalar> >
* indeed it seems better to declare m_other as a Packet and do the pset1() once
* in the constructor. However, in practice:
* - GCC does not like m_other as a Packet and generate a load every time it needs it
- * - on the other hand GCC is able to moves the pset1() away the loop :)
+ * - on the other hand GCC is able to moves the pset1() outside the loop :)
* - simpler code ;)
* (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
*/
@@ -478,33 +486,6 @@ template<typename Scalar1,typename Scalar2>
struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
{ enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
-template<typename Scalar, bool IsInteger>
-struct scalar_quotient1_impl {
- typedef typename packet_traits<Scalar>::type Packet;
- // FIXME default copy constructors seems bugged with std::complex<>
- EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
- EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
- EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
- EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
- { return internal::pmul(a, pset1<Packet>(m_other)); }
- const Scalar m_other;
-};
-template<typename Scalar>
-struct functor_traits<scalar_quotient1_impl<Scalar,false> >
-{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
-
-template<typename Scalar>
-struct scalar_quotient1_impl<Scalar,true> {
- // FIXME default copy constructors seems bugged with std::complex<>
- EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
- EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
- EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
- typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
-};
-template<typename Scalar>
-struct functor_traits<scalar_quotient1_impl<Scalar,true> >
-{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
-
/** \internal
* \brief Template functor to divide a scalar by a fixed other one
*
@@ -514,14 +495,19 @@ struct functor_traits<scalar_quotient1_impl<Scalar,true> >
* \sa class CwiseUnaryOp, MatrixBase::operator/
*/
template<typename Scalar>
-struct scalar_quotient1_op : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger > {
- EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other)
- : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger >(other) {}
+struct scalar_quotient1_op {
+ typedef typename packet_traits<Scalar>::type Packet;
+ // FIXME default copy constructors seems bugged with std::complex<>
+ EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { }
+ EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {}
+ EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
+ EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
+ { return internal::pdiv(a, pset1<Packet>(m_other)); }
+ typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
};
template<typename Scalar>
struct functor_traits<scalar_quotient1_op<Scalar> >
-: functor_traits<scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger> >
-{};
+{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
// nullary functors
@@ -555,20 +541,28 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
// linear access for packet ops:
// 1) initialization
// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
-// 2) each step
+// 2) each step (where size is 1 for coeff access or PacketSize for packet access)
// base += [size*step, ..., size*step]
+//
+// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp)
+// in order to avoid the padd() in operator() ?
template <typename Scalar>
struct linspaced_op_impl<Scalar,false>
{
typedef typename packet_traits<Scalar>::type Packet;
- linspaced_op_impl(Scalar low, Scalar step) :
+ linspaced_op_impl(const Scalar& low, const Scalar& step) :
m_low(low), m_step(step),
m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
- m_base(padd(pset1<Packet>(low),pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
+ m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
template<typename Index>
- EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
+ EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
+ {
+ m_base = padd(m_base, pset1<Packet>(m_step));
+ return m_low+Scalar(i)*m_step;
+ }
+
template<typename Index>
EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
@@ -586,7 +580,7 @@ struct linspaced_op_impl<Scalar,true>
{
typedef typename packet_traits<Scalar>::type Packet;
- linspaced_op_impl(Scalar low, Scalar step) :
+ linspaced_op_impl(const Scalar& low, const Scalar& step) :
m_low(low), m_step(step),
m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
@@ -615,7 +609,7 @@ template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_o
template <typename Scalar, bool RandomAccess> struct linspaced_op
{
typedef typename packet_traits<Scalar>::type Packet;
- linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
+ linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
template<typename Index>
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
@@ -654,12 +648,14 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op
template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
-// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication
-// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>.
+// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication
+// where the mixing of different types is handled by scalar_product_traits
+// In particular, real * complex<real> is allowed.
// FIXME move this to functor_traits adding a functor_default
-template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
-template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
-template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
+template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; };
+template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
+template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
+template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
/** \internal
@@ -688,7 +684,7 @@ struct functor_traits<scalar_add_op<Scalar> >
*/
template<typename Scalar> struct scalar_sqrt_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
};
@@ -706,7 +702,7 @@ struct functor_traits<scalar_sqrt_op<Scalar> >
*/
template<typename Scalar> struct scalar_cos_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
- inline Scalar operator() (const Scalar& a) const { return internal::cos(a); }
+ inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
};
@@ -725,7 +721,7 @@ struct functor_traits<scalar_cos_op<Scalar> >
*/
template<typename Scalar> struct scalar_sin_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
};
@@ -745,7 +741,7 @@ struct functor_traits<scalar_sin_op<Scalar> >
*/
template<typename Scalar> struct scalar_tan_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
};
@@ -764,7 +760,7 @@ struct functor_traits<scalar_tan_op<Scalar> >
*/
template<typename Scalar> struct scalar_acos_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
};
@@ -783,7 +779,7 @@ struct functor_traits<scalar_acos_op<Scalar> >
*/
template<typename Scalar> struct scalar_asin_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
- inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); }
+ inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); }
typedef typename packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
};
@@ -805,7 +801,7 @@ struct scalar_pow_op {
// FIXME default copy constructors seems bugged with std::complex<>
inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
- inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
+ inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
const Scalar m_exponent;
};
template<typename Scalar>
diff --git a/extern/Eigen3/Eigen/src/Core/Fuzzy.h b/extern/Eigen3/Eigen/src/Core/Fuzzy.h
index d74edcfdb9d..fe63bd2984d 100644
--- a/extern/Eigen3/Eigen/src/Core/Fuzzy.h
+++ b/extern/Eigen3/Eigen/src/Core/Fuzzy.h
@@ -19,7 +19,7 @@ namespace internal
template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isApprox_selector
{
- static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
+ static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
{
using std::min;
typename internal::nested<Derived,2>::type nested(x);
@@ -31,7 +31,7 @@ struct isApprox_selector
template<typename Derived, typename OtherDerived>
struct isApprox_selector<Derived, OtherDerived, true>
{
- static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar)
+ static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&)
{
return x.matrix() == y.matrix();
}
@@ -40,16 +40,16 @@ struct isApprox_selector<Derived, OtherDerived, true>
template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isMuchSmallerThan_object_selector
{
- static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
+ static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
{
- return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum();
+ return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum();
}
};
template<typename Derived, typename OtherDerived>
struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
{
- static bool run(const Derived& x, const OtherDerived&, typename Derived::RealScalar)
+ static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&)
{
return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
}
@@ -58,16 +58,16 @@ struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isMuchSmallerThan_scalar_selector
{
- static bool run(const Derived& x, const typename Derived::RealScalar& y, typename Derived::RealScalar prec)
+ static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec)
{
- return x.cwiseAbs2().sum() <= abs2(prec * y);
+ return x.cwiseAbs2().sum() <= numext::abs2(prec * y);
}
};
template<typename Derived>
struct isMuchSmallerThan_scalar_selector<Derived, true>
{
- static bool run(const Derived& x, const typename Derived::RealScalar&, typename Derived::RealScalar)
+ static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&)
{
return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
}
@@ -97,7 +97,7 @@ template<typename Derived>
template<typename OtherDerived>
bool DenseBase<Derived>::isApprox(
const DenseBase<OtherDerived>& other,
- RealScalar prec
+ const RealScalar& prec
) const
{
return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
@@ -119,7 +119,7 @@ bool DenseBase<Derived>::isApprox(
template<typename Derived>
bool DenseBase<Derived>::isMuchSmallerThan(
const typename NumTraits<Scalar>::Real& other,
- RealScalar prec
+ const RealScalar& prec
) const
{
return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec);
@@ -139,7 +139,7 @@ template<typename Derived>
template<typename OtherDerived>
bool DenseBase<Derived>::isMuchSmallerThan(
const DenseBase<OtherDerived>& other,
- RealScalar prec
+ const RealScalar& prec
) const
{
return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
diff --git a/extern/Eigen3/Eigen/src/Core/GeneralProduct.h b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h
index bfc2a67b12f..2a59d94645e 100644
--- a/extern/Eigen3/Eigen/src/Core/GeneralProduct.h
+++ b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h
@@ -222,7 +222,29 @@ class GeneralProduct<Lhs, Rhs, InnerProduct>
***********************************************************************/
namespace internal {
-template<int StorageOrder> struct outer_product_selector;
+
+// Column major
+template<typename ProductType, typename Dest, typename Func>
+EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&)
+{
+ typedef typename Dest::Index Index;
+ // FIXME make sure lhs is sequentially stored
+ // FIXME not very good if rhs is real and lhs complex while alpha is real too
+ const Index cols = dest.cols();
+ for (Index j=0; j<cols; ++j)
+ func(dest.col(j), prod.rhs().coeff(j) * prod.lhs());
+}
+
+// Row major
+template<typename ProductType, typename Dest, typename Func>
+EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) {
+ typedef typename Dest::Index Index;
+ // FIXME make sure rhs is sequentially stored
+ // FIXME not very good if lhs is real and rhs complex while alpha is real too
+ const Index rows = dest.rows();
+ for (Index i=0; i<rows; ++i)
+ func(dest.row(i), prod.lhs().coeff(i) * prod.rhs());
+}
template<typename Lhs, typename Rhs>
struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> >
@@ -235,6 +257,8 @@ template<typename Lhs, typename Rhs>
class GeneralProduct<Lhs, Rhs, OuterProduct>
: public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs>
{
+ template<typename T> struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
+
public:
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
@@ -243,41 +267,39 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
}
-
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
- {
- internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha);
+
+ struct set { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
+ struct add { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
+ struct sub { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
+ struct adds {
+ Scalar m_scale;
+ adds(const Scalar& s) : m_scale(s) {}
+ template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
+ dst.const_cast_derived() += m_scale * src;
+ }
+ };
+
+ template<typename Dest>
+ inline void evalTo(Dest& dest) const {
+ internal::outer_product_selector_run(*this, dest, set(), IsRowMajor<Dest>());
+ }
+
+ template<typename Dest>
+ inline void addTo(Dest& dest) const {
+ internal::outer_product_selector_run(*this, dest, add(), IsRowMajor<Dest>());
}
-};
-
-namespace internal {
-template<> struct outer_product_selector<ColMajor> {
- template<typename ProductType, typename Dest>
- static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) {
- typedef typename Dest::Index Index;
- // FIXME make sure lhs is sequentially stored
- // FIXME not very good if rhs is real and lhs complex while alpha is real too
- const Index cols = dest.cols();
- for (Index j=0; j<cols; ++j)
- dest.col(j) += (alpha * prod.rhs().coeff(j)) * prod.lhs();
- }
-};
+ template<typename Dest>
+ inline void subTo(Dest& dest) const {
+ internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor<Dest>());
+ }
-template<> struct outer_product_selector<RowMajor> {
- template<typename ProductType, typename Dest>
- static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) {
- typedef typename Dest::Index Index;
- // FIXME make sure rhs is sequentially stored
- // FIXME not very good if lhs is real and rhs complex while alpha is real too
- const Index rows = dest.rows();
- for (Index i=0; i<rows; ++i)
- dest.row(i) += (alpha * prod.lhs().coeff(i)) * prod.rhs();
- }
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
+ {
+ internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor<Dest>());
+ }
};
-} // end namespace internal
-
/***********************************************************************
* Implementation of General Matrix Vector Product
***********************************************************************/
@@ -311,7 +333,7 @@ class GeneralProduct<Lhs, Rhs, GemvProduct>
typedef typename Lhs::Scalar LhsScalar;
typedef typename Rhs::Scalar RhsScalar;
- GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
+ GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs)
{
// EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value),
// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
@@ -320,7 +342,7 @@ class GeneralProduct<Lhs, Rhs, GemvProduct>
enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType;
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols());
internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
@@ -335,7 +357,7 @@ template<int StorageOrder, bool BlasCompatible>
struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible>
{
template<typename ProductType, typename Dest>
- static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha)
+ static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
{
Transpose<Dest> destT(dest);
enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor };
@@ -384,7 +406,7 @@ struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
template<> struct gemv_selector<OnTheRight,ColMajor,true>
{
template<typename ProductType, typename Dest>
- static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha)
+ static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
{
typedef typename ProductType::Index Index;
typedef typename ProductType::LhsScalar LhsScalar;
@@ -413,7 +435,7 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
- bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0));
+ bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
@@ -457,7 +479,7 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
template<> struct gemv_selector<OnTheRight,RowMajor,true>
{
template<typename ProductType, typename Dest>
- static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha)
+ static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
{
typedef typename ProductType::LhsScalar LhsScalar;
typedef typename ProductType::RhsScalar RhsScalar;
@@ -508,7 +530,7 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
template<> struct gemv_selector<OnTheRight,ColMajor,false>
{
template<typename ProductType, typename Dest>
- static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha)
+ static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
{
typedef typename Dest::Index Index;
// TODO makes sure dest is sequentially stored in memory, otherwise use a temp
@@ -521,7 +543,7 @@ template<> struct gemv_selector<OnTheRight,ColMajor,false>
template<> struct gemv_selector<OnTheRight,RowMajor,false>
{
template<typename ProductType, typename Dest>
- static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha)
+ static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
{
typedef typename Dest::Index Index;
// TODO makes sure rhs is sequentially stored in memory, otherwise use a temp
diff --git a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h
index 858fb243ec8..5f783ebeee8 100644
--- a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h
+++ b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h
@@ -106,7 +106,7 @@ pnegate(const Packet& a) { return -a; }
/** \internal \returns conj(a) (coeff-wise) */
template<typename Packet> inline Packet
-pconj(const Packet& a) { return conj(a); }
+pconj(const Packet& a) { return numext::conj(a); }
/** \internal \returns a * b (coeff-wise) */
template<typename Packet> inline Packet
@@ -130,7 +130,7 @@ pmax(const Packet& a,
/** \internal \returns the absolute value of \a a */
template<typename Packet> inline Packet
-pabs(const Packet& a) { return abs(a); }
+pabs(const Packet& a) { using std::abs; return abs(a); }
/** \internal \returns the bitwise and of \a a and \a b */
template<typename Packet> inline Packet
@@ -156,7 +156,11 @@ pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
template<typename Packet> inline Packet
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
-/** \internal \returns a packet with elements of \a *from duplicated, e.g.: (from[0],from[0],from[1],from[1]) */
+/** \internal \returns a packet with elements of \a *from duplicated.
+ * For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and
+ * duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]}
+ * Currently, this function is only used for scalar * complex products.
+ */
template<typename Packet> inline Packet
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
@@ -215,7 +219,12 @@ template<typename Packet> inline Packet preverse(const Packet& a)
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
template<typename Packet> inline Packet pcplxflip(const Packet& a)
-{ return Packet(imag(a),real(a)); }
+{
+ // FIXME: uncomment the following in case we drop the internal imag and real functions.
+// using std::imag;
+// using std::real;
+ return Packet(imag(a),real(a));
+}
/**************************
* Special math functions
@@ -223,35 +232,35 @@ template<typename Packet> inline Packet pcplxflip(const Packet& a)
/** \internal \returns the sine of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet psin(const Packet& a) { return sin(a); }
+Packet psin(const Packet& a) { using std::sin; return sin(a); }
/** \internal \returns the cosine of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pcos(const Packet& a) { return cos(a); }
+Packet pcos(const Packet& a) { using std::cos; return cos(a); }
/** \internal \returns the tan of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet ptan(const Packet& a) { return tan(a); }
+Packet ptan(const Packet& a) { using std::tan; return tan(a); }
/** \internal \returns the arc sine of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pasin(const Packet& a) { return asin(a); }
+Packet pasin(const Packet& a) { using std::asin; return asin(a); }
/** \internal \returns the arc cosine of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pacos(const Packet& a) { return acos(a); }
+Packet pacos(const Packet& a) { using std::acos; return acos(a); }
/** \internal \returns the exp of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pexp(const Packet& a) { return exp(a); }
+Packet pexp(const Packet& a) { using std::exp; return exp(a); }
/** \internal \returns the log of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet plog(const Packet& a) { return log(a); }
+Packet plog(const Packet& a) { using std::log; return log(a); }
/** \internal \returns the square-root of \a a (coeff-wise) */
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet psqrt(const Packet& a) { return sqrt(a); }
+Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
/***************************************************************************
* The following functions might not have to be overwritten for vectorized types
@@ -302,8 +311,21 @@ struct palign_impl
static inline void run(PacketType&, const PacketType&) {}
};
-/** \internal update \a first using the concatenation of the \a Offset last elements
- * of \a first and packet_size minus \a Offset first elements of \a second */
+/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
+ * of \a first and \a Offset first elements of \a second.
+ *
+ * This function is currently only used to optimize matrix-vector products on unligned matrices.
+ * It takes 2 packets that represent a contiguous memory array, and returns a packet starting
+ * at the position \a Offset. For instance, for packets of 4 elements, we have:
+ * Input:
+ * - first = {f0,f1,f2,f3}
+ * - second = {s0,s1,s2,s3}
+ * Output:
+ * - if Offset==0 then {f0,f1,f2,f3}
+ * - if Offset==1 then {f1,f2,f3,s0}
+ * - if Offset==2 then {f2,f3,s0,s1}
+ * - if Offset==3 then {f3,s0,s1,s3}
+ */
template<int Offset,typename PacketType>
inline void palign(PacketType& first, const PacketType& second)
{
diff --git a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h
index e63726c4735..2acf9772334 100644
--- a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h
+++ b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2010-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
@@ -11,7 +11,7 @@
#ifndef EIGEN_GLOBAL_FUNCTIONS_H
#define EIGEN_GLOBAL_FUNCTIONS_H
-#define EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(NAME,FUNCTOR) \
+#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \
template<typename Derived> \
inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
NAME(const Eigen::ArrayBase<Derived>& x) { \
@@ -35,20 +35,21 @@
};
-namespace std
+namespace Eigen
{
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(real,scalar_real_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(abs,scalar_abs_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sqrt,scalar_sqrt_op)
-
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op)
+
template<typename Derived>
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived>
pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
@@ -64,16 +65,13 @@ namespace std
exponents.derived()
);
}
-}
-
-namespace Eigen
-{
+
/**
* \brief Component-wise division of a scalar by array elements.
**/
template <typename Derived>
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>
- operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a)
+ operator/(const typename Derived::Scalar& s, const Eigen::ArrayBase<Derived>& a)
{
return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>(
a.derived(),
@@ -85,19 +83,10 @@ namespace Eigen
{
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op)
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs,scalar_abs_op)
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op)
- EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sqrt,scalar_sqrt_op)
}
}
-// TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...)
+// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...)
#endif // EIGEN_GLOBAL_FUNCTIONS_H
diff --git a/extern/Eigen3/Eigen/src/Core/IO.h b/extern/Eigen3/Eigen/src/Core/IO.h
index cc8e18a0076..8d4bc59e9dd 100644
--- a/extern/Eigen3/Eigen/src/Core/IO.h
+++ b/extern/Eigen3/Eigen/src/Core/IO.h
@@ -55,9 +55,8 @@ struct IOFormat
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
const std::string& _matPrefix="", const std::string& _matSuffix="")
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
- coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
+ rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
{
- rowSpacer = "";
int i = int(matSuffix.length())-1;
while (i>=0 && matSuffix[i]!='\n')
{
@@ -129,6 +128,7 @@ struct significant_decimals_default_impl
static inline int run()
{
using std::ceil;
+ using std::log;
return cast<RealScalar,int>(ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10))));
}
};
@@ -185,21 +185,22 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
explicit_precision = fmt.precision;
}
+ std::streamsize old_precision = 0;
+ if(explicit_precision) old_precision = s.precision(explicit_precision);
+
bool align_cols = !(fmt.flags & DontAlignCols);
if(align_cols)
{
// compute the largest width
- for(Index j = 1; j < m.cols(); ++j)
+ for(Index j = 0; j < m.cols(); ++j)
for(Index i = 0; i < m.rows(); ++i)
{
std::stringstream sstr;
- if(explicit_precision) sstr.precision(explicit_precision);
+ sstr.copyfmt(s);
sstr << m.coeff(i,j);
width = std::max<Index>(width, Index(sstr.str().length()));
}
}
- std::streamsize old_precision = 0;
- if(explicit_precision) old_precision = s.precision(explicit_precision);
s << fmt.matPrefix;
for(Index i = 0; i < m.rows(); ++i)
{
diff --git a/extern/Eigen3/Eigen/src/Core/Map.h b/extern/Eigen3/Eigen/src/Core/Map.h
index 15a19226e29..f804c89d63e 100644
--- a/extern/Eigen3/Eigen/src/Core/Map.h
+++ b/extern/Eigen3/Eigen/src/Core/Map.h
@@ -133,36 +133,36 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
/** Constructor in the fixed-size case.
*
- * \param data pointer to the array to map
- * \param stride optional Stride object, passing the strides.
+ * \param dataPtr pointer to the array to map
+ * \param a_stride optional Stride object, passing the strides.
*/
- inline Map(PointerArgType data, const StrideType& stride = StrideType())
- : Base(cast_to_pointer_type(data)), m_stride(stride)
+ inline Map(PointerArgType dataPtr, const StrideType& a_stride = StrideType())
+ : Base(cast_to_pointer_type(dataPtr)), m_stride(a_stride)
{
PlainObjectType::Base::_check_template_params();
}
/** Constructor in the dynamic-size vector case.
*
- * \param data pointer to the array to map
- * \param size the size of the vector expression
- * \param stride optional Stride object, passing the strides.
+ * \param dataPtr pointer to the array to map
+ * \param a_size the size of the vector expression
+ * \param a_stride optional Stride object, passing the strides.
*/
- inline Map(PointerArgType data, Index size, const StrideType& stride = StrideType())
- : Base(cast_to_pointer_type(data), size), m_stride(stride)
+ inline Map(PointerArgType dataPtr, Index a_size, const StrideType& a_stride = StrideType())
+ : Base(cast_to_pointer_type(dataPtr), a_size), m_stride(a_stride)
{
PlainObjectType::Base::_check_template_params();
}
/** Constructor in the dynamic-size matrix case.
*
- * \param data pointer to the array to map
- * \param rows the number of rows of the matrix expression
- * \param cols the number of columns of the matrix expression
- * \param stride optional Stride object, passing the strides.
+ * \param dataPtr pointer to the array to map
+ * \param nbRows the number of rows of the matrix expression
+ * \param nbCols the number of columns of the matrix expression
+ * \param a_stride optional Stride object, passing the strides.
*/
- inline Map(PointerArgType data, Index rows, Index cols, const StrideType& stride = StrideType())
- : Base(cast_to_pointer_type(data), rows, cols), m_stride(stride)
+ inline Map(PointerArgType dataPtr, Index nbRows, Index nbCols, const StrideType& a_stride = StrideType())
+ : Base(cast_to_pointer_type(dataPtr), nbRows, nbCols), m_stride(a_stride)
{
PlainObjectType::Base::_check_template_params();
}
diff --git a/extern/Eigen3/Eigen/src/Core/MapBase.h b/extern/Eigen3/Eigen/src/Core/MapBase.h
index a388d61ea92..6876de588c0 100644
--- a/extern/Eigen3/Eigen/src/Core/MapBase.h
+++ b/extern/Eigen3/Eigen/src/Core/MapBase.h
@@ -87,9 +87,9 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
*/
inline const Scalar* data() const { return m_data; }
- inline const Scalar& coeff(Index row, Index col) const
+ inline const Scalar& coeff(Index rowId, Index colId) const
{
- return m_data[col * colStride() + row * rowStride()];
+ return m_data[colId * colStride() + rowId * rowStride()];
}
inline const Scalar& coeff(Index index) const
@@ -98,9 +98,9 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
return m_data[index * innerStride()];
}
- inline const Scalar& coeffRef(Index row, Index col) const
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
{
- return this->m_data[col * colStride() + row * rowStride()];
+ return this->m_data[colId * colStride() + rowId * rowStride()];
}
inline const Scalar& coeffRef(Index index) const
@@ -110,10 +110,10 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
}
template<int LoadMode>
- inline PacketScalar packet(Index row, Index col) const
+ inline PacketScalar packet(Index rowId, Index colId) const
{
return internal::ploadt<PacketScalar, LoadMode>
- (m_data + (col * colStride() + row * rowStride()));
+ (m_data + (colId * colStride() + rowId * rowStride()));
}
template<int LoadMode>
@@ -123,29 +123,29 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
}
- inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
+ inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
checkSanity();
}
- inline MapBase(PointerType data, Index size)
- : m_data(data),
- m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
- m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime))
+ inline MapBase(PointerType dataPtr, Index vecSize)
+ : m_data(dataPtr),
+ m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
+ m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime))
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- eigen_assert(size >= 0);
- eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
+ eigen_assert(vecSize >= 0);
+ eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
checkSanity();
}
- inline MapBase(PointerType data, Index rows, Index cols)
- : m_data(data), m_rows(rows), m_cols(cols)
+ inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols)
+ : m_data(dataPtr), m_rows(nbRows), m_cols(nbCols)
{
- eigen_assert( (data == 0)
- || ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
- && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
+ eigen_assert( (dataPtr == 0)
+ || ( nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows)
+ && nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)));
checkSanity();
}
@@ -210,23 +210,23 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
}
template<int StoreMode>
- inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index row, Index col, const PacketScalar& val)
{
internal::pstoret<Scalar, PacketScalar, StoreMode>
- (this->m_data + (col * colStride() + row * rowStride()), x);
+ (this->m_data + (col * colStride() + row * rowStride()), val);
}
template<int StoreMode>
- inline void writePacket(Index index, const PacketScalar& x)
+ inline void writePacket(Index index, const PacketScalar& val)
{
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
internal::pstoret<Scalar, PacketScalar, StoreMode>
- (this->m_data + index * innerStride(), x);
+ (this->m_data + index * innerStride(), val);
}
- explicit inline MapBase(PointerType data) : Base(data) {}
- inline MapBase(PointerType data, Index size) : Base(data, size) {}
- inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
+ explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
+ inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
+ inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) : Base(dataPtr, nbRows, nbCols) {}
Derived& operator=(const MapBase& other)
{
diff --git a/extern/Eigen3/Eigen/src/Core/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/MathFunctions.h
index 05e913f2fec..2bfc5ebd98a 100644
--- a/extern/Eigen3/Eigen/src/Core/MathFunctions.h
+++ b/extern/Eigen3/Eigen/src/Core/MathFunctions.h
@@ -51,16 +51,15 @@ struct global_math_functions_filtering_base
typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
};
-#define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
-#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
-
+#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
+#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
/****************************************************************************
* Implementation of real *
****************************************************************************/
-template<typename Scalar>
-struct real_impl
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
+struct real_default_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
static inline RealScalar run(const Scalar& x)
@@ -69,34 +68,32 @@ struct real_impl
}
};
-template<typename RealScalar>
-struct real_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct real_default_impl<Scalar,true>
{
- static inline RealScalar run(const std::complex<RealScalar>& x)
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ static inline RealScalar run(const Scalar& x)
{
using std::real;
return real(x);
}
};
+template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
+
template<typename Scalar>
struct real_retval
{
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
-}
/****************************************************************************
* Implementation of imag *
****************************************************************************/
-template<typename Scalar>
-struct imag_impl
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
+struct imag_default_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
static inline RealScalar run(const Scalar&)
@@ -105,28 +102,25 @@ struct imag_impl
}
};
-template<typename RealScalar>
-struct imag_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct imag_default_impl<Scalar,true>
{
- static inline RealScalar run(const std::complex<RealScalar>& x)
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ static inline RealScalar run(const Scalar& x)
{
using std::imag;
return imag(x);
}
};
+template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
+
template<typename Scalar>
struct imag_retval
{
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of real_ref *
****************************************************************************/
@@ -151,18 +145,6 @@ struct real_ref_retval
typedef typename NumTraits<Scalar>::Real & type;
};
-template<typename Scalar>
-inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
-{
- return real_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of imag_ref *
****************************************************************************/
@@ -203,23 +185,11 @@ struct imag_ref_retval
typedef typename NumTraits<Scalar>::Real & type;
};
-template<typename Scalar>
-inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
-{
- return imag_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of conj *
****************************************************************************/
-template<typename Scalar>
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
struct conj_impl
{
static inline Scalar run(const Scalar& x)
@@ -228,10 +198,10 @@ struct conj_impl
}
};
-template<typename RealScalar>
-struct conj_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct conj_impl<Scalar,true>
{
- static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
+ static inline Scalar run(const Scalar& x)
{
using std::conj;
return conj(x);
@@ -244,39 +214,6 @@ struct conj_retval
typedef Scalar type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
-}
-
-/****************************************************************************
-* Implementation of abs *
-****************************************************************************/
-
-template<typename Scalar>
-struct abs_impl
-{
- typedef typename NumTraits<Scalar>::Real RealScalar;
- static inline RealScalar run(const Scalar& x)
- {
- using std::abs;
- return abs(x);
- }
-};
-
-template<typename Scalar>
-struct abs_retval
-{
- typedef typename NumTraits<Scalar>::Real type;
-};
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of abs2 *
****************************************************************************/
@@ -306,12 +243,6 @@ struct abs2_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of norm1 *
****************************************************************************/
@@ -322,6 +253,7 @@ struct norm1_default_impl
typedef typename NumTraits<Scalar>::Real RealScalar;
static inline RealScalar run(const Scalar& x)
{
+ using std::abs;
return abs(real(x)) + abs(imag(x));
}
};
@@ -331,6 +263,7 @@ struct norm1_default_impl<Scalar, false>
{
static inline Scalar run(const Scalar& x)
{
+ using std::abs;
return abs(x);
}
};
@@ -344,12 +277,6 @@ struct norm1_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of hypot *
****************************************************************************/
@@ -362,9 +289,12 @@ struct hypot_impl
{
using std::max;
using std::min;
+ using std::abs;
+ using std::sqrt;
RealScalar _x = abs(x);
RealScalar _y = abs(y);
RealScalar p = (max)(_x, _y);
+ if(p==RealScalar(0)) return 0;
RealScalar q = (min)(_x, _y);
RealScalar qp = q/p;
return p * sqrt(RealScalar(1) + qp*qp);
@@ -377,12 +307,6 @@ struct hypot_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of cast *
****************************************************************************/
@@ -405,97 +329,29 @@ inline NewType cast(const OldType& x)
}
/****************************************************************************
-* Implementation of sqrt *
+* Implementation of atanh2 *
****************************************************************************/
template<typename Scalar, bool IsInteger>
-struct sqrt_default_impl
-{
- static inline Scalar run(const Scalar& x)
- {
- using std::sqrt;
- return sqrt(x);
- }
-};
-
-template<typename Scalar>
-struct sqrt_default_impl<Scalar, true>
-{
- static inline Scalar run(const Scalar&)
- {
-#ifdef EIGEN2_SUPPORT
- eigen_assert(!NumTraits<Scalar>::IsInteger);
-#else
- EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
-#endif
- return Scalar(0);
- }
-};
-
-template<typename Scalar>
-struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
-
-template<typename Scalar>
-struct sqrt_retval
-{
- typedef Scalar type;
-};
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
-}
-
-/****************************************************************************
-* Implementation of standard unary real functions (exp, log, sin, cos, ... *
-****************************************************************************/
-
-// This macro instanciate all the necessary template mechanism which is common to all unary real functions.
-#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
- template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
- static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \
- }; \
- template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
- static inline Scalar run(const Scalar&) { \
- EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
- return Scalar(0); \
- } \
- }; \
- template<typename Scalar> struct NAME##_impl \
- : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
- {}; \
- template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
- template<typename Scalar> \
- inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
- return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
- }
-
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
-EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
-
-/****************************************************************************
-* Implementation of atan2 *
-****************************************************************************/
-
-template<typename Scalar, bool IsInteger>
-struct atan2_default_impl
+struct atanh2_default_impl
{
typedef Scalar retval;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
static inline Scalar run(const Scalar& x, const Scalar& y)
{
- using std::atan2;
- return atan2(x, y);
+ using std::abs;
+ using std::log;
+ using std::sqrt;
+ Scalar z = x / y;
+ if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
+ return RealScalar(0.5) * log((y + x) / (y - x));
+ else
+ return z + z*z*z / RealScalar(3);
}
};
template<typename Scalar>
-struct atan2_default_impl<Scalar, true>
+struct atanh2_default_impl<Scalar, true>
{
static inline Scalar run(const Scalar&, const Scalar&)
{
@@ -505,20 +361,14 @@ struct atan2_default_impl<Scalar, true>
};
template<typename Scalar>
-struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
+struct atanh2_impl : atanh2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
template<typename Scalar>
-struct atan2_retval
+struct atanh2_retval
{
typedef Scalar type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of pow *
****************************************************************************/
@@ -562,12 +412,6 @@ struct pow_retval
typedef Scalar type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of random *
****************************************************************************/
@@ -666,11 +510,10 @@ struct random_default_impl<Scalar, false, true>
#else
enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
scalar_bits = sizeof(Scalar) * CHAR_BIT,
- shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits))
+ shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
+ offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
};
- Scalar x = Scalar(std::rand() >> shift);
- Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
- return x - offset;
+ return Scalar((std::rand() >> shift) - offset);
#endif
}
};
@@ -702,6 +545,97 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
}
+} // end namespace internal
+
+/****************************************************************************
+* Generic math function *
+****************************************************************************/
+
+namespace numext {
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
+{
+ return internal::real_ref_impl<Scalar>::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
+{
+ return internal::imag_ref_impl<Scalar>::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
+}
+
+template<typename Scalar>
+inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
+}
+
+// std::isfinite is non standard, so let's define our own version,
+// even though it is not very efficient.
+template<typename T> bool (isfinite)(const T& x)
+{
+ return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
+}
+
+} // end namespace numext
+
+namespace internal {
+
/****************************************************************************
* Implementation of fuzzy comparisons *
****************************************************************************/
@@ -718,11 +652,13 @@ struct scalar_fuzzy_default_impl<Scalar, false, false>
template<typename OtherScalar>
static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
{
+ using std::abs;
return abs(x) <= abs(y) * prec;
}
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
{
using std::min;
+ using std::abs;
return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
}
static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
@@ -757,12 +693,12 @@ struct scalar_fuzzy_default_impl<Scalar, true, false>
template<typename OtherScalar>
static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
{
- return abs2(x) <= abs2(y) * prec * prec;
+ return numext::abs2(x) <= numext::abs2(y) * prec * prec;
}
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
{
using std::min;
- return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
+ return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
}
};
@@ -824,17 +760,7 @@ template<> struct scalar_fuzzy_impl<bool>
};
-/****************************************************************************
-* Special functions *
-****************************************************************************/
-
-// std::isfinite is non standard, so let's define our own version,
-// even though it is not very efficient.
-template<typename T> bool (isfinite)(const T& x)
-{
- return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
-}
-
+
} // end namespace internal
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/Core/Matrix.h b/extern/Eigen3/Eigen/src/Core/Matrix.h
index 99160b591b0..d7d0b5b9a4f 100644
--- a/extern/Eigen3/Eigen/src/Core/Matrix.h
+++ b/extern/Eigen3/Eigen/src/Core/Matrix.h
@@ -200,16 +200,16 @@ class Matrix
*
* \sa resize(Index,Index)
*/
- EIGEN_STRONG_INLINE explicit Matrix() : Base()
+ EIGEN_STRONG_INLINE Matrix() : Base()
{
Base::_check_template_params();
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
// FIXME is it still needed
Matrix(internal::constructor_without_unaligned_array_assert)
: Base(internal::constructor_without_unaligned_array_assert())
- { Base::_check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED }
+ { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
*
@@ -224,7 +224,7 @@ class Matrix
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
eigen_assert(dim >= 0);
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -304,7 +304,7 @@ class Matrix
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
Base::_check_template_params();
- Base::resize(other.rows(), other.cols());
+ Base::_resize_to_match(other);
// FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to
// go for pure _set() implementations, right?
*this = other;
diff --git a/extern/Eigen3/Eigen/src/Core/MatrixBase.h b/extern/Eigen3/Eigen/src/Core/MatrixBase.h
index c1e0ed132cc..344b38f2fc7 100644
--- a/extern/Eigen3/Eigen/src/Core/MatrixBase.h
+++ b/extern/Eigen3/Eigen/src/Core/MatrixBase.h
@@ -162,6 +162,9 @@ template<typename Derived> class MatrixBase
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
+
+ template<typename MatrixPower, typename Lhs, typename Rhs>
+ Derived& lazyAssign(const MatrixPowerProduct<MatrixPower, Lhs,Rhs>& other);
#endif // not EIGEN_PARSED_BY_DOXYGEN
template<typename OtherDerived>
@@ -212,8 +215,8 @@ template<typename Derived> class MatrixBase
typedef Diagonal<Derived> DiagonalReturnType;
DiagonalReturnType diagonal();
- typedef const Diagonal<const Derived> ConstDiagonalReturnType;
- const ConstDiagonalReturnType diagonal() const;
+ typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
+ ConstDiagonalReturnType diagonal() const;
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
@@ -224,11 +227,11 @@ template<typename Derived> class MatrixBase
// Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
// On the other hand they confuse MSVC8...
#if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
- typename MatrixBase::template DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index);
- typename MatrixBase::template ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const;
+ typename MatrixBase::template DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
+ typename MatrixBase::template ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
#else
- typename DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index);
- typename ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const;
+ typename DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
+ typename ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
#endif
#ifdef EIGEN2_SUPPORT
@@ -237,7 +240,7 @@ template<typename Derived> class MatrixBase
// huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead
// of an integer constant. Solution: overload the part() method template wrt template parameters list.
- template<template<typename T, int n> class U>
+ template<template<typename T, int N> class U>
const DiagonalWrapper<ConstDiagonalReturnType> part() const
{ return diagonal().asDiagonal(); }
#endif // EIGEN2_SUPPORT
@@ -255,7 +258,7 @@ template<typename Derived> class MatrixBase
template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
- typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
+ const typename NumTraits<Scalar>::Real& m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
static const IdentityReturnType Identity();
static const IdentityReturnType Identity(Index rows, Index cols);
static const BasisReturnType Unit(Index size, Index i);
@@ -271,16 +274,16 @@ template<typename Derived> class MatrixBase
Derived& setIdentity();
Derived& setIdentity(Index rows, Index cols);
- bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isUpperTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isLowerTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isUpperTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isLowerTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
- bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isUnitary(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
/** \returns true if each coefficients of \c *this and \a other are all exactly equal.
* \warning When using floating point scalar values you probably should rather use a
@@ -314,7 +317,7 @@ template<typename Derived> class MatrixBase
MatrixBase<Derived>& matrix() { return *this; }
const MatrixBase<Derived>& matrix() const { return *this; }
- /** \returns an \link ArrayBase Array \endlink expression of this matrix
+ /** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix
* \sa ArrayBase::matrix() */
ArrayWrapper<Derived> array() { return derived(); }
const ArrayWrapper<const Derived> array() const { return derived(); }
@@ -454,6 +457,7 @@ template<typename Derived> class MatrixBase
const MatrixFunctionReturnValue<Derived> sin() const;
const MatrixSquareRootReturnValue<Derived> sqrt() const;
const MatrixLogarithmReturnValue<Derived> log() const;
+ const MatrixPowerReturnValue<Derived> pow(const RealScalar& p) const;
#ifdef EIGEN2_SUPPORT
template<typename ProductDerived, typename Lhs, typename Rhs>
@@ -506,6 +510,51 @@ template<typename Derived> class MatrixBase
{EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
};
+
+/***************************************************************************
+* Implementation of matrix base methods
+***************************************************************************/
+
+/** replaces \c *this by \c *this * \a other.
+ *
+ * \returns a reference to \c *this
+ *
+ * Example: \include MatrixBase_applyOnTheRight.cpp
+ * Output: \verbinclude MatrixBase_applyOnTheRight.out
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline Derived&
+MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
+{
+ other.derived().applyThisOnTheRight(derived());
+ return derived();
+}
+
+/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=().
+ *
+ * Example: \include MatrixBase_applyOnTheRight.cpp
+ * Output: \verbinclude MatrixBase_applyOnTheRight.out
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
+{
+ other.derived().applyThisOnTheRight(derived());
+}
+
+/** replaces \c *this by \a other * \c *this.
+ *
+ * Example: \include MatrixBase_applyOnTheLeft.cpp
+ * Output: \verbinclude MatrixBase_applyOnTheLeft.out
+ */
+template<typename Derived>
+template<typename OtherDerived>
+inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
+{
+ other.derived().applyThisOnTheLeft(derived());
+}
+
} // end namespace Eigen
#endif // EIGEN_MATRIXBASE_H
diff --git a/extern/Eigen3/Eigen/src/Core/NoAlias.h b/extern/Eigen3/Eigen/src/Core/NoAlias.h
index ecb3fa2850e..768bfb18ca4 100644
--- a/extern/Eigen3/Eigen/src/Core/NoAlias.h
+++ b/extern/Eigen3/Eigen/src/Core/NoAlias.h
@@ -80,8 +80,17 @@ class NoAlias
template<typename Lhs, typename Rhs, int NestingFlags>
EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
{ return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
+
+ template<typename OtherDerived>
+ ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
+ { return m_expression = func; }
#endif
+ ExpressionType& expression() const
+ {
+ return m_expression;
+ }
+
protected:
ExpressionType& m_expression;
};
diff --git a/extern/Eigen3/Eigen/src/Core/NumTraits.h b/extern/Eigen3/Eigen/src/Core/NumTraits.h
index c94ef026b42..bac9e50b857 100644
--- a/extern/Eigen3/Eigen/src/Core/NumTraits.h
+++ b/extern/Eigen3/Eigen/src/Core/NumTraits.h
@@ -140,6 +140,9 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
};
+
+ static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
+ static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
};
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h
index bc29f814205..1297b8413fb 100644
--- a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h
@@ -105,13 +105,13 @@ class PermutationBase : public EigenBase<Derived>
#endif
/** \returns the number of rows */
- inline Index rows() const { return indices().size(); }
+ inline Index rows() const { return Index(indices().size()); }
/** \returns the number of columns */
- inline Index cols() const { return indices().size(); }
+ inline Index cols() const { return Index(indices().size()); }
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
- inline Index size() const { return indices().size(); }
+ inline Index size() const { return Index(indices().size()); }
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename DenseDerived>
@@ -139,9 +139,9 @@ class PermutationBase : public EigenBase<Derived>
/** Resizes to given size.
*/
- inline void resize(Index size)
+ inline void resize(Index newSize)
{
- indices().resize(size);
+ indices().resize(newSize);
}
/** Sets *this to be the identity permutation matrix */
@@ -153,9 +153,9 @@ class PermutationBase : public EigenBase<Derived>
/** Sets *this to be the identity permutation matrix of given size.
*/
- void setIdentity(Index size)
+ void setIdentity(Index newSize)
{
- resize(size);
+ resize(newSize);
setIdentity();
}
@@ -317,7 +317,7 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
* array's size.
*/
template<typename Other>
- explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices)
+ explicit inline PermutationMatrix(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
{}
/** Convert the Transpositions \a tr to a permutation matrix */
@@ -406,12 +406,12 @@ class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,
typedef typename IndicesType::Scalar Index;
#endif
- inline Map(const Index* indices)
- : m_indices(indices)
+ inline Map(const Index* indicesPtr)
+ : m_indices(indicesPtr)
{}
- inline Map(const Index* indices, Index size)
- : m_indices(indices,size)
+ inline Map(const Index* indicesPtr, Index size)
+ : m_indices(indicesPtr,size)
{}
/** Copies the other permutation into *this */
@@ -490,8 +490,8 @@ class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesTyp
typedef typename Traits::IndicesType IndicesType;
#endif
- inline PermutationWrapper(const IndicesType& indices)
- : m_indices(indices)
+ inline PermutationWrapper(const IndicesType& a_indices)
+ : m_indices(a_indices)
{}
/** const version of indices(). */
@@ -541,24 +541,26 @@ struct permut_matrix_product_retval
: public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
{
typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
+ typedef typename MatrixType::Index Index;
permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix)
: m_permutation(perm), m_matrix(matrix)
{}
- inline int rows() const { return m_matrix.rows(); }
- inline int cols() const { return m_matrix.cols(); }
+ inline Index rows() const { return m_matrix.rows(); }
+ inline Index cols() const { return m_matrix.cols(); }
template<typename Dest> inline void evalTo(Dest& dst) const
{
- const int n = Side==OnTheLeft ? rows() : cols();
-
+ const Index n = Side==OnTheLeft ? rows() : cols();
+ // FIXME we need an is_same for expression that is not sensitive to constness. For instance
+ // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
if(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))
{
// apply the permutation inplace
Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
mask.fill(false);
- int r = 0;
+ Index r = 0;
while(r < m_permutation.size())
{
// search for the next seed
@@ -566,10 +568,10 @@ struct permut_matrix_product_retval
if(r>=m_permutation.size())
break;
// we got one, let's follow it until we are back to the seed
- int k0 = r++;
- int kPrev = k0;
+ Index k0 = r++;
+ Index kPrev = k0;
mask.coeffRef(k0) = true;
- for(int k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
+ for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
{
Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
.swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
diff --git a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h
index 71c74309acc..dd34b59e541 100644
--- a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h
+++ b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h
@@ -11,30 +11,46 @@
#ifndef EIGEN_DENSESTORAGEBASE_H
#define EIGEN_DENSESTORAGEBASE_H
-#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
-# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
+#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
+# define EIGEN_INITIALIZE_COEFFS
+# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
+#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
+# define EIGEN_INITIALIZE_COEFFS
+# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
#else
-# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+# undef EIGEN_INITIALIZE_COEFFS
+# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#endif
namespace Eigen {
namespace internal {
-template<typename Index>
-EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols)
-{
- // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
- // we assume Index is signed
- Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
- bool error = (rows < 0 || cols < 0) ? true
- : (rows == 0 || cols == 0) ? false
- : (rows > max_index / cols);
- if (error)
- throw_std_bad_alloc();
-}
-
-template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
+template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
+ template<typename Index>
+ static EIGEN_ALWAYS_INLINE void run(Index, Index)
+ {
+ }
+};
+
+template<> struct check_rows_cols_for_overflow<Dynamic> {
+ template<typename Index>
+ static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
+ {
+ // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
+ // we assume Index is signed
+ Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
+ bool error = (rows == 0 || cols == 0) ? false
+ : (rows > max_index / cols);
+ if (error)
+ throw_std_bad_alloc();
+ }
+};
+
+template <typename Derived,
+ typename OtherDerived = Derived,
+ bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
+struct conservative_resize_like_impl;
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
@@ -119,12 +135,12 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
- EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
{
if(Flags & RowMajorBit)
- return m_storage.data()[col + row * m_storage.cols()];
+ return m_storage.data()[colId + rowId * m_storage.cols()];
else // column-major
- return m_storage.data()[row + col * m_storage.rows()];
+ return m_storage.data()[rowId + colId * m_storage.rows()];
}
EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
@@ -132,12 +148,12 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
return m_storage.data()[index];
}
- EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
+ EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
{
if(Flags & RowMajorBit)
- return m_storage.data()[col + row * m_storage.cols()];
+ return m_storage.data()[colId + rowId * m_storage.cols()];
else // column-major
- return m_storage.data()[row + col * m_storage.rows()];
+ return m_storage.data()[rowId + colId * m_storage.rows()];
}
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
@@ -145,12 +161,12 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
return m_storage.data()[index];
}
- EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
{
if(Flags & RowMajorBit)
- return m_storage.data()[col + row * m_storage.cols()];
+ return m_storage.data()[colId + rowId * m_storage.cols()];
else // column-major
- return m_storage.data()[row + col * m_storage.rows()];
+ return m_storage.data()[rowId + colId * m_storage.rows()];
}
EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
@@ -160,12 +176,12 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
/** \internal */
template<int LoadMode>
- EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
+ EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
{
return internal::ploadt<PacketScalar, LoadMode>
(m_storage.data() + (Flags & RowMajorBit
- ? col + row * m_storage.cols()
- : row + col * m_storage.rows()));
+ ? colId + rowId * m_storage.cols()
+ : rowId + colId * m_storage.rows()));
}
/** \internal */
@@ -177,19 +193,19 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
/** \internal */
template<int StoreMode>
- EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
+ EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
{
internal::pstoret<Scalar, PacketScalar, StoreMode>
(m_storage.data() + (Flags & RowMajorBit
- ? col + row * m_storage.cols()
- : row + col * m_storage.rows()), x);
+ ? colId + rowId * m_storage.cols()
+ : rowId + colId * m_storage.rows()), val);
}
/** \internal */
template<int StoreMode>
- EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
+ EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
{
- internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
+ internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
}
/** \returns a const pointer to the data array of this matrix */
@@ -216,17 +232,22 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
*
* \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
*/
- EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
- {
- #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
- internal::check_rows_cols_for_overflow(rows, cols);
- Index size = rows*cols;
+ EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
+ {
+ eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime)
+ && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime)
+ && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime)
+ && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime)
+ && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array.");
+ internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
+ #ifdef EIGEN_INITIALIZE_COEFFS
+ Index size = nbRows*nbCols;
bool size_changed = size != this->size();
- m_storage.resize(size, rows, cols);
- if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ m_storage.resize(size, nbRows, nbCols);
+ if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#else
- internal::check_rows_cols_for_overflow(rows, cols);
- m_storage.resize(rows*cols, rows, cols);
+ internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
+ m_storage.resize(nbRows*nbCols, nbRows, nbCols);
#endif
}
@@ -244,16 +265,16 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
inline void resize(Index size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
- eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
- #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
+ eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
+ #ifdef EIGEN_INITIALIZE_COEFFS
bool size_changed = size != this->size();
#endif
if(RowsAtCompileTime == 1)
m_storage.resize(size, 1, size);
else
m_storage.resize(size, size, 1);
- #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
- if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ #ifdef EIGEN_INITIALIZE_COEFFS
+ if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#endif
}
@@ -265,9 +286,9 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
*
* \sa resize(Index,Index)
*/
- inline void resize(NoChange_t, Index cols)
+ inline void resize(NoChange_t, Index nbCols)
{
- resize(rows(), cols);
+ resize(rows(), nbCols);
}
/** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
@@ -278,9 +299,9 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
*
* \sa resize(Index,Index)
*/
- inline void resize(Index rows, NoChange_t)
+ inline void resize(Index nbRows, NoChange_t)
{
- resize(rows, cols());
+ resize(nbRows, cols());
}
/** Resizes \c *this to have the same dimensions as \a other.
@@ -294,7 +315,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
{
const OtherDerived& other = _other.derived();
- internal::check_rows_cols_for_overflow(other.rows(), other.cols());
+ internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
const Index othersize = other.rows()*other.cols();
if(RowsAtCompileTime == 1)
{
@@ -318,9 +339,9 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
* Matrices are resized relative to the top-left element. In case values need to be
* appended to the matrix they will be uninitialized.
*/
- EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
+ EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols)
{
- internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
+ internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols);
}
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
@@ -330,10 +351,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
*
* In case the matrix is growing, new rows will be uninitialized.
*/
- EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
+ EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t)
{
// Note: see the comment in conservativeResize(Index,Index)
- conservativeResize(rows, cols());
+ conservativeResize(nbRows, cols());
}
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
@@ -343,10 +364,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
*
* In case the matrix is growing, new columns will be uninitialized.
*/
- EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
+ EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
{
// Note: see the comment in conservativeResize(Index,Index)
- conservativeResize(rows(), cols);
+ conservativeResize(rows(), nbCols);
}
/** Resizes the vector to \a size while retaining old values.
@@ -400,10 +421,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
return Base::operator=(func);
}
- EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
+ EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
{
// _check_template_params();
-// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -412,15 +433,15 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
PlainObjectBase(internal::constructor_without_unaligned_array_assert)
: m_storage(internal::constructor_without_unaligned_array_assert())
{
-// _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
#endif
- EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
- : m_storage(size, rows, cols)
+ EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
+ : m_storage(a_size, nbRows, nbCols)
{
// _check_template_params();
-// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
}
/** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&)
@@ -439,7 +460,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
_check_template_params();
- internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols());
+ internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
Base::operator=(other.derived());
}
@@ -551,6 +572,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
: (rows() == other.rows() && cols() == other.cols())))
&& "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
+ EIGEN_ONLY_USED_FOR_DEBUG(other);
#else
resizeLike(other);
#endif
@@ -600,23 +622,19 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
}
template<typename T0, typename T1>
- EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
+ EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
{
EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
bool(NumTraits<T1>::IsInteger),
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
- eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
- && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
- internal::check_rows_cols_for_overflow(rows, cols);
- m_storage.resize(rows*cols,rows,cols);
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ resize(nbRows,nbCols);
}
template<typename T0, typename T1>
- EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
+ EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
- m_storage.data()[0] = x;
- m_storage.data()[1] = y;
+ m_storage.data()[0] = val0;
+ m_storage.data()[1] = val1;
}
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
@@ -653,8 +671,10 @@ private:
enum { ThisConstantIsPrivateInPlainObjectBase };
};
+namespace internal {
+
template <typename Derived, typename OtherDerived, bool IsVector>
-struct internal::conservative_resize_like_impl
+struct conservative_resize_like_impl
{
typedef typename Derived::Index Index;
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
@@ -665,7 +685,7 @@ struct internal::conservative_resize_like_impl
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
{
- internal::check_rows_cols_for_overflow(rows, cols);
+ internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
}
else
@@ -714,11 +734,14 @@ struct internal::conservative_resize_like_impl
}
};
-namespace internal {
-
+// Here, the specialization for vectors inherits from the general matrix case
+// to allow calling .conservativeResize(rows,cols) on vectors.
template <typename Derived, typename OtherDerived>
struct conservative_resize_like_impl<Derived,OtherDerived,true>
+ : conservative_resize_like_impl<Derived,OtherDerived,false>
{
+ using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
+
typedef typename Derived::Index Index;
static void run(DenseBase<Derived>& _this, Index size)
{
diff --git a/extern/Eigen3/Eigen/src/Core/ProductBase.h b/extern/Eigen3/Eigen/src/Core/ProductBase.h
index ec12e5c9f6b..a494b5f8703 100644
--- a/extern/Eigen3/Eigen/src/Core/ProductBase.h
+++ b/extern/Eigen3/Eigen/src/Core/ProductBase.h
@@ -87,10 +87,10 @@ class ProductBase : public MatrixBase<Derived>
typedef typename Base::PlainObject PlainObject;
- ProductBase(const Lhs& lhs, const Rhs& rhs)
- : m_lhs(lhs), m_rhs(rhs)
+ ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
+ : m_lhs(a_lhs), m_rhs(a_rhs)
{
- eigen_assert(lhs.cols() == rhs.rows()
+ eigen_assert(a_lhs.cols() == a_rhs.rows()
&& "invalid matrix product"
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
}
@@ -108,7 +108,7 @@ class ProductBase : public MatrixBase<Derived>
inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); }
template<typename Dest>
- inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
+ inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); }
const _LhsNested& lhs() const { return m_lhs; }
const _RhsNested& rhs() const { return m_rhs; }
@@ -195,25 +195,25 @@ class ScaledProduct;
// Also note that here we accept any compatible scalar types
template<typename Derived,typename Lhs,typename Rhs>
const ScaledProduct<Derived>
-operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::Scalar x)
+operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Scalar& x)
{ return ScaledProduct<Derived>(prod.derived(), x); }
template<typename Derived,typename Lhs,typename Rhs>
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
const ScaledProduct<Derived> >::type
-operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::RealScalar x)
+operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::RealScalar& x)
{ return ScaledProduct<Derived>(prod.derived(), x); }
template<typename Derived,typename Lhs,typename Rhs>
const ScaledProduct<Derived>
-operator*(typename Derived::Scalar x,const ProductBase<Derived,Lhs,Rhs>& prod)
+operator*(const typename Derived::Scalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
{ return ScaledProduct<Derived>(prod.derived(), x); }
template<typename Derived,typename Lhs,typename Rhs>
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
const ScaledProduct<Derived> >::type
-operator*(typename Derived::RealScalar x,const ProductBase<Derived,Lhs,Rhs>& prod)
+operator*(const typename Derived::RealScalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
{ return ScaledProduct<Derived>(prod.derived(), x); }
namespace internal {
@@ -241,7 +241,7 @@ class ScaledProduct
typedef typename Base::PlainObject PlainObject;
// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct)
- ScaledProduct(const NestedProduct& prod, Scalar x)
+ ScaledProduct(const NestedProduct& prod, const Scalar& x)
: Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {}
template<typename Dest>
@@ -254,7 +254,7 @@ class ScaledProduct
inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); }
template<typename Dest>
- inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { m_prod.derived().scaleAndAddTo(dst,alpha * m_alpha); }
+ inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); }
const Scalar& alpha() const { return m_alpha; }
diff --git a/extern/Eigen3/Eigen/src/Core/Random.h b/extern/Eigen3/Eigen/src/Core/Random.h
index a9f7f434666..480fea408d0 100644
--- a/extern/Eigen3/Eigen/src/Core/Random.h
+++ b/extern/Eigen3/Eigen/src/Core/Random.h
@@ -112,7 +112,7 @@ inline Derived& DenseBase<Derived>::setRandom()
return *this = Random(rows(), cols());
}
-/** Resizes to the given \a size, and sets all coefficients in this expression to random values.
+/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values.
*
* \only_for_vectors
*
@@ -123,16 +123,16 @@ inline Derived& DenseBase<Derived>::setRandom()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setRandom(Index size)
+PlainObjectBase<Derived>::setRandom(Index newSize)
{
- resize(size);
+ resize(newSize);
return setRandom();
}
/** Resizes to the given size, and sets all coefficients in this expression to random values.
*
- * \param rows the new number of rows
- * \param cols the new number of columns
+ * \param nbRows the new number of rows
+ * \param nbCols the new number of columns
*
* Example: \include Matrix_setRandom_int_int.cpp
* Output: \verbinclude Matrix_setRandom_int_int.out
@@ -141,9 +141,9 @@ PlainObjectBase<Derived>::setRandom(Index size)
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setRandom(Index rows, Index cols)
+PlainObjectBase<Derived>::setRandom(Index nbRows, Index nbCols)
{
- resize(rows, cols);
+ resize(nbRows, nbCols);
return setRandom();
}
diff --git a/extern/Eigen3/Eigen/src/Core/Redux.h b/extern/Eigen3/Eigen/src/Core/Redux.h
index b7ce7c658a2..50548fa9a0e 100644
--- a/extern/Eigen3/Eigen/src/Core/Redux.h
+++ b/extern/Eigen3/Eigen/src/Core/Redux.h
@@ -330,7 +330,8 @@ DenseBase<Derived>::redux(const Func& func) const
::run(derived(), func);
}
-/** \returns the minimum of all coefficients of *this
+/** \returns the minimum of all coefficients of \c *this.
+ * \warning the result is undefined if \c *this contains NaN.
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
@@ -339,7 +340,8 @@ DenseBase<Derived>::minCoeff() const
return this->redux(Eigen::internal::scalar_min_op<Scalar>());
}
-/** \returns the maximum of all coefficients of *this
+/** \returns the maximum of all coefficients of \c *this.
+ * \warning the result is undefined if \c *this contains NaN.
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
diff --git a/extern/Eigen3/Eigen/src/Core/Ref.h b/extern/Eigen3/Eigen/src/Core/Ref.h
new file mode 100644
index 00000000000..00d9e6d2b41
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/Core/Ref.h
@@ -0,0 +1,256 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_REF_H
+#define EIGEN_REF_H
+
+namespace Eigen {
+
+template<typename Derived> class RefBase;
+template<typename PlainObjectType, int Options = 0,
+ typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
+
+/** \class Ref
+ * \ingroup Core_Module
+ *
+ * \brief A matrix or vector expression mapping an existing expressions
+ *
+ * \tparam PlainObjectType the equivalent matrix type of the mapped data
+ * \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned.
+ * The default is \c #Unaligned.
+ * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1),
+ * but accept a variable outer stride (leading dimension).
+ * This can be overridden by specifying strides.
+ * The type passed here must be a specialization of the Stride template, see examples below.
+ *
+ * This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies.
+ * A Ref<> object can represent either a const expression or a l-value:
+ * \code
+ * // in-out argument:
+ * void foo1(Ref<VectorXf> x);
+ *
+ * // read-only const argument:
+ * void foo2(const Ref<const VectorXf>& x);
+ * \endcode
+ *
+ * In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered.
+ * By default, a Ref<VectorXf> can reference any dense vector expression of float having a contiguous memory layout.
+ * Likewise, a Ref<MatrixXf> can reference any column major dense matrix expression of float whose column's elements are contiguously stored with
+ * the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension),
+ * can be greater than the number of rows.
+ *
+ * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function.
+ * Here are some examples:
+ * \code
+ * MatrixXf A;
+ * VectorXf a;
+ * foo1(a.head()); // OK
+ * foo1(A.col()); // OK
+ * foo1(A.row()); // compilation error because here innerstride!=1
+ * foo2(A.row()); // The row is copied into a contiguous temporary
+ * foo2(2*a); // The expression is evaluated into a temporary
+ * foo2(A.col().segment(2,4)); // No temporary
+ * \endcode
+ *
+ * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter.
+ * Here is an example accepting an innerstride!=1:
+ * \code
+ * // in-out argument:
+ * void foo3(Ref<VectorXf,0,InnerStride<> > x);
+ * foo3(A.row()); // OK
+ * \endcode
+ * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more
+ * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a
+ * template function, e.g.:
+ * \code
+ * // in the .h:
+ * void foo(const Ref<MatrixXf>& A);
+ * void foo(const Ref<MatrixXf,0,Stride<> >& A);
+ *
+ * // in the .cpp:
+ * template<typename TypeOfA> void foo_impl(const TypeOfA& A) {
+ * ... // crazy code goes here
+ * }
+ * void foo(const Ref<MatrixXf>& A) { foo_impl(A); }
+ * void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
+ * \endcode
+ *
+ *
+ * \sa PlainObjectBase::Map(), \ref TopicStorageOrders
+ */
+
+namespace internal {
+
+template<typename _PlainObjectType, int _Options, typename _StrideType>
+struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
+ : public traits<Map<_PlainObjectType, _Options, _StrideType> >
+{
+ typedef _PlainObjectType PlainObjectType;
+ typedef _StrideType StrideType;
+ enum {
+ Options = _Options,
+ Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit
+ };
+
+ template<typename Derived> struct match {
+ enum {
+ HasDirectAccess = internal::has_direct_access<Derived>::ret,
+ StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
+ InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
+ || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
+ || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
+ OuterStrideMatch = Derived::IsVectorAtCompileTime
+ || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
+ AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),
+ MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch
+ };
+ typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
+ };
+
+};
+
+template<typename Derived>
+struct traits<RefBase<Derived> > : public traits<Derived> {};
+
+}
+
+template<typename Derived> class RefBase
+ : public MapBase<Derived>
+{
+ typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
+ typedef typename internal::traits<Derived>::StrideType StrideType;
+
+public:
+
+ typedef MapBase<Derived> Base;
+ EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
+
+ inline Index innerStride() const
+ {
+ return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
+ }
+
+ inline Index outerStride() const
+ {
+ return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
+ : IsVectorAtCompileTime ? this->size()
+ : int(Flags)&RowMajorBit ? this->cols()
+ : this->rows();
+ }
+
+ RefBase()
+ : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
+ // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
+ m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
+ StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
+ {}
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
+
+protected:
+
+ typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
+
+ template<typename Expression>
+ void construct(Expression& expr)
+ {
+ if(PlainObjectType::RowsAtCompileTime==1)
+ {
+ eigen_assert(expr.rows()==1 || expr.cols()==1);
+ ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
+ }
+ else if(PlainObjectType::ColsAtCompileTime==1)
+ {
+ eigen_assert(expr.rows()==1 || expr.cols()==1);
+ ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
+ }
+ else
+ ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
+ ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
+ StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
+ }
+
+ StrideBase m_stride;
+};
+
+
+template<typename PlainObjectType, int Options, typename StrideType> class Ref
+ : public RefBase<Ref<PlainObjectType, Options, StrideType> >
+{
+ typedef internal::traits<Ref> Traits;
+ public:
+
+ typedef RefBase<Ref> Base;
+ EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
+
+
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ template<typename Derived>
+ inline Ref(PlainObjectBase<Derived>& expr,
+ typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
+ {
+ Base::construct(expr);
+ }
+ template<typename Derived>
+ inline Ref(const DenseBase<Derived>& expr,
+ typename internal::enable_if<bool(internal::is_lvalue<Derived>::value&&bool(Traits::template match<Derived>::MatchAtCompileTime)),Derived>::type* = 0,
+ int = Derived::ThisConstantIsPrivateInPlainObjectBase)
+ #else
+ template<typename Derived>
+ inline Ref(DenseBase<Derived>& expr)
+ #endif
+ {
+ Base::construct(expr.const_cast_derived());
+ }
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
+
+};
+
+// this is the const ref version
+template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
+ : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
+{
+ typedef internal::traits<Ref> Traits;
+ public:
+
+ typedef RefBase<Ref> Base;
+ EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
+
+ template<typename Derived>
+ inline Ref(const DenseBase<Derived>& expr)
+ {
+// std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
+// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
+// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
+ construct(expr.derived(), typename Traits::template match<Derived>::type());
+ }
+
+ protected:
+
+ template<typename Expression>
+ void construct(const Expression& expr,internal::true_type)
+ {
+ Base::construct(expr);
+ }
+
+ template<typename Expression>
+ void construct(const Expression& expr, internal::false_type)
+ {
+ m_object.lazyAssign(expr);
+ Base::construct(m_object);
+ }
+
+ protected:
+ TPlainObjectType m_object;
+};
+
+} // end namespace Eigen
+
+#endif // EIGEN_REF_H
diff --git a/extern/Eigen3/Eigen/src/Core/Replicate.h b/extern/Eigen3/Eigen/src/Core/Replicate.h
index b61fdc29e2f..dde86a8349b 100644
--- a/extern/Eigen3/Eigen/src/Core/Replicate.h
+++ b/extern/Eigen3/Eigen/src/Core/Replicate.h
@@ -70,8 +70,8 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
template<typename OriginalMatrixType>
- inline explicit Replicate(const OriginalMatrixType& matrix)
- : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
+ inline explicit Replicate(const OriginalMatrixType& a_matrix)
+ : m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
{
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
@@ -79,8 +79,8 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
}
template<typename OriginalMatrixType>
- inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor)
- : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
+ inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor)
+ : m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
{
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
@@ -89,27 +89,27 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
- inline Scalar coeff(Index row, Index col) const
+ inline Scalar coeff(Index rowId, Index colId) const
{
// try to avoid using modulo; this is a pure optimization strategy
const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
- : RowFactor==1 ? row
- : row%m_matrix.rows();
+ : RowFactor==1 ? rowId
+ : rowId%m_matrix.rows();
const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
- : ColFactor==1 ? col
- : col%m_matrix.cols();
+ : ColFactor==1 ? colId
+ : colId%m_matrix.cols();
return m_matrix.coeff(actual_row, actual_col);
}
template<int LoadMode>
- inline PacketScalar packet(Index row, Index col) const
+ inline PacketScalar packet(Index rowId, Index colId) const
{
const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
- : RowFactor==1 ? row
- : row%m_matrix.rows();
+ : RowFactor==1 ? rowId
+ : rowId%m_matrix.rows();
const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
- : ColFactor==1 ? col
- : col%m_matrix.cols();
+ : ColFactor==1 ? colId
+ : colId%m_matrix.cols();
return m_matrix.template packet<LoadMode>(actual_row, actual_col);
}
diff --git a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h
index 613912ffa8c..d66c24ba0f8 100644
--- a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h
+++ b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h
@@ -48,7 +48,7 @@ struct nested<ReturnByValue<Derived>, n, PlainObject>
} // end namespace internal
template<typename Derived> class ReturnByValue
- : public internal::dense_xpr_base< ReturnByValue<Derived> >::type
+ : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue<Derived> >::type
{
public:
typedef typename internal::traits<Derived>::ReturnType ReturnType;
diff --git a/extern/Eigen3/Eigen/src/Core/Select.h b/extern/Eigen3/Eigen/src/Core/Select.h
index 2bf6e91d0aa..87993bbb553 100644
--- a/extern/Eigen3/Eigen/src/Core/Select.h
+++ b/extern/Eigen3/Eigen/src/Core/Select.h
@@ -60,10 +60,10 @@ class Select : internal::no_assignment_operator,
typedef typename internal::dense_xpr_base<Select>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Select)
- Select(const ConditionMatrixType& conditionMatrix,
- const ThenMatrixType& thenMatrix,
- const ElseMatrixType& elseMatrix)
- : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix)
+ Select(const ConditionMatrixType& a_conditionMatrix,
+ const ThenMatrixType& a_thenMatrix,
+ const ElseMatrixType& a_elseMatrix)
+ : m_condition(a_conditionMatrix), m_then(a_thenMatrix), m_else(a_elseMatrix)
{
eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
@@ -136,7 +136,7 @@ template<typename Derived>
template<typename ThenDerived>
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
- typename ThenDerived::Scalar elseScalar) const
+ const typename ThenDerived::Scalar& elseScalar) const
{
return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
@@ -150,8 +150,8 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
template<typename Derived>
template<typename ElseDerived>
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
-DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
- const DenseBase<ElseDerived>& elseMatrix) const
+DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
+ const DenseBase<ElseDerived>& elseMatrix) const
{
return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
diff --git a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h
index 82cc4da736a..6fa7cd15e6f 100644
--- a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h
+++ b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h
@@ -132,7 +132,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
* \sa rankUpdate(const MatrixBase<DerivedU>&, Scalar)
*/
template<typename DerivedU, typename DerivedV>
- SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha = Scalar(1));
+ SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha = Scalar(1));
/** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
* \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix.
@@ -145,7 +145,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
* \sa rankUpdate(const MatrixBase<DerivedU>&, const MatrixBase<DerivedV>&, Scalar)
*/
template<typename DerivedU>
- SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha = Scalar(1));
+ SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
/////////// Cholesky module ///////////
@@ -214,9 +214,9 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), U
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src);
if(row == col)
- dst.coeffRef(row, col) = real(src.coeff(row, col));
+ dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
else if(row < col)
- dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col));
+ dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
}
};
@@ -239,9 +239,9 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), U
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src);
if(row == col)
- dst.coeffRef(row, col) = real(src.coeff(row, col));
+ dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
else if(row > col)
- dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col));
+ dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
}
};
@@ -262,7 +262,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dyn
for(Index i = 0; i < j; ++i)
{
dst.copyCoeff(i, j, src);
- dst.coeffRef(j,i) = conj(dst.coeff(i,j));
+ dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
}
dst.copyCoeff(j, j, src);
}
@@ -280,7 +280,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dyn
for(Index j = 0; j < i; ++j)
{
dst.copyCoeff(i, j, src);
- dst.coeffRef(j,i) = conj(dst.coeff(i,j));
+ dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
}
dst.copyCoeff(i, i, src);
}
diff --git a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h
index 0caf2bab1d8..22f3047b43f 100644
--- a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h
+++ b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h
@@ -185,7 +185,10 @@ inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
internal::scalar_product_op<Scalar> >::type BinOp;
typedef typename Derived::PlainObject PlainObject;
SelfCwiseBinaryOp<BinOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
- tmp = PlainObject::Constant(rows(),cols(), NumTraits<Scalar>::IsInteger ? other : Scalar(1)/other);
+ Scalar actual_other;
+ if(NumTraits<Scalar>::IsInteger) actual_other = other;
+ else actual_other = Scalar(1)/other;
+ tmp = PlainObject::Constant(rows(),cols(), actual_other);
return derived();
}
diff --git a/extern/Eigen3/Eigen/src/Core/StableNorm.h b/extern/Eigen3/Eigen/src/Core/StableNorm.h
index d8bf7db70e4..389d9427539 100644
--- a/extern/Eigen3/Eigen/src/Core/StableNorm.h
+++ b/extern/Eigen3/Eigen/src/Core/StableNorm.h
@@ -13,131 +13,105 @@
namespace Eigen {
namespace internal {
+
template<typename ExpressionType, typename Scalar>
inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
{
- Scalar max = bl.cwiseAbs().maxCoeff();
- if (max>scale)
+ using std::max;
+ Scalar maxCoeff = bl.cwiseAbs().maxCoeff();
+
+ if (maxCoeff>scale)
{
- ssq = ssq * abs2(scale/max);
- scale = max;
- invScale = Scalar(1)/scale;
+ ssq = ssq * numext::abs2(scale/maxCoeff);
+ Scalar tmp = Scalar(1)/maxCoeff;
+ if(tmp > NumTraits<Scalar>::highest())
+ {
+ invScale = NumTraits<Scalar>::highest();
+ scale = Scalar(1)/invScale;
+ }
+ else
+ {
+ scale = maxCoeff;
+ invScale = tmp;
+ }
}
- // TODO if the max is much much smaller than the current scale,
+
+ // TODO if the maxCoeff is much much smaller than the current scale,
// then we can neglect this sub vector
- ssq += (bl*invScale).squaredNorm();
-}
-}
-
-/** \returns the \em l2 norm of \c *this avoiding underflow and overflow.
- * This version use a blockwise two passes algorithm:
- * 1 - find the absolute largest coefficient \c s
- * 2 - compute \f$ s \Vert \frac{*this}{s} \Vert \f$ in a standard way
- *
- * For architecture/scalar types supporting vectorization, this version
- * is faster than blueNorm(). Otherwise the blueNorm() is much faster.
- *
- * \sa norm(), blueNorm(), hypotNorm()
- */
-template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-MatrixBase<Derived>::stableNorm() const
-{
- using std::min;
- const Index blockSize = 4096;
- RealScalar scale(0);
- RealScalar invScale(1);
- RealScalar ssq(0); // sum of square
- enum {
- Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0
- };
- Index n = size();
- Index bi = internal::first_aligned(derived());
- if (bi>0)
- internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
- for (; bi<n; bi+=blockSize)
- internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
- return scale * internal::sqrt(ssq);
+ if(scale>Scalar(0)) // if scale==0, then bl is 0
+ ssq += (bl*invScale).squaredNorm();
}
-/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
- * A Portable Fortran Program to Find the Euclidean Norm of a Vector,
- * ACM TOMS, Vol 4, Issue 1, 1978.
- *
- * For architecture/scalar types without vectorization, this version
- * is much faster than stableNorm(). Otherwise the stableNorm() is faster.
- *
- * \sa norm(), stableNorm(), hypotNorm()
- */
template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-MatrixBase<Derived>::blueNorm() const
+inline typename NumTraits<typename traits<Derived>::Scalar>::Real
+blueNorm_impl(const EigenBase<Derived>& _vec)
{
+ typedef typename Derived::RealScalar RealScalar;
+ typedef typename Derived::Index Index;
using std::pow;
using std::min;
using std::max;
- static Index nmax = -1;
+ using std::sqrt;
+ using std::abs;
+ const Derived& vec(_vec.derived());
+ static bool initialized = false;
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
- if(nmax <= 0)
+ if(!initialized)
{
- int nbig, ibeta, it, iemin, iemax, iexp;
- RealScalar abig, eps;
+ int ibeta, it, iemin, iemax, iexp;
+ RealScalar eps;
// This program calculates the machine-dependent constants
- // bl, b2, slm, s2m, relerr overfl, nmax
+ // bl, b2, slm, s2m, relerr overfl
// from the "basic" machine-dependent numbers
// nbig, ibeta, it, iemin, iemax, rbig.
// The following define the basic machine-dependent constants.
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
// are used. For any specific computer, each of the assignment
// statements can be replaced
- nbig = (std::numeric_limits<Index>::max)(); // largest integer
- ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
- it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
- iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
- iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
- rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
+ ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
+ it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
+ iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
+ iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
+ rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
iexp = -((1-iemin)/2);
- b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
+ b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
iexp = (iemax + 1 - it)/2;
- b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
+ b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
iexp = (2-iemin)/2;
- s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
+ s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
iexp = - ((iemax+it)/2);
- s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
+ s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
- overfl = rbig*s2m; // overflow boundary for abig
+ overfl = rbig*s2m; // overflow boundary for abig
eps = RealScalar(pow(double(ibeta), 1-it));
- relerr = internal::sqrt(eps); // tolerance for neglecting asml
- abig = RealScalar(1.0/eps - 1.0);
- if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
- else nmax = nbig;
+ relerr = sqrt(eps); // tolerance for neglecting asml
+ initialized = true;
}
- Index n = size();
+ Index n = vec.size();
RealScalar ab2 = b2 / RealScalar(n);
RealScalar asml = RealScalar(0);
RealScalar amed = RealScalar(0);
RealScalar abig = RealScalar(0);
- for(Index j=0; j<n; ++j)
+ for(typename Derived::InnerIterator it(vec, 0); it; ++it)
{
- RealScalar ax = internal::abs(coeff(j));
- if(ax > ab2) abig += internal::abs2(ax*s2m);
- else if(ax < b1) asml += internal::abs2(ax*s1m);
- else amed += internal::abs2(ax);
+ RealScalar ax = abs(it.value());
+ if(ax > ab2) abig += numext::abs2(ax*s2m);
+ else if(ax < b1) asml += numext::abs2(ax*s1m);
+ else amed += numext::abs2(ax);
}
if(abig > RealScalar(0))
{
- abig = internal::sqrt(abig);
+ abig = sqrt(abig);
if(abig > overfl)
{
- eigen_assert(false && "overflow");
return rbig;
}
if(amed > RealScalar(0))
{
abig = abig/s2m;
- amed = internal::sqrt(amed);
+ amed = sqrt(amed);
}
else
return abig/s2m;
@@ -146,20 +120,70 @@ MatrixBase<Derived>::blueNorm() const
{
if (amed > RealScalar(0))
{
- abig = internal::sqrt(amed);
- amed = internal::sqrt(asml) / s1m;
+ abig = sqrt(amed);
+ amed = sqrt(asml) / s1m;
}
else
- return internal::sqrt(asml)/s1m;
+ return sqrt(asml)/s1m;
}
else
- return internal::sqrt(amed);
+ return sqrt(amed);
asml = (min)(abig, amed);
abig = (max)(abig, amed);
if(asml <= abig*relerr)
return abig;
else
- return abig * internal::sqrt(RealScalar(1) + internal::abs2(asml/abig));
+ return abig * sqrt(RealScalar(1) + numext::abs2(asml/abig));
+}
+
+} // end namespace internal
+
+/** \returns the \em l2 norm of \c *this avoiding underflow and overflow.
+ * This version use a blockwise two passes algorithm:
+ * 1 - find the absolute largest coefficient \c s
+ * 2 - compute \f$ s \Vert \frac{*this}{s} \Vert \f$ in a standard way
+ *
+ * For architecture/scalar types supporting vectorization, this version
+ * is faster than blueNorm(). Otherwise the blueNorm() is much faster.
+ *
+ * \sa norm(), blueNorm(), hypotNorm()
+ */
+template<typename Derived>
+inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
+MatrixBase<Derived>::stableNorm() const
+{
+ using std::min;
+ using std::sqrt;
+ const Index blockSize = 4096;
+ RealScalar scale(0);
+ RealScalar invScale(1);
+ RealScalar ssq(0); // sum of square
+ enum {
+ Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0
+ };
+ Index n = size();
+ Index bi = internal::first_aligned(derived());
+ if (bi>0)
+ internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
+ for (; bi<n; bi+=blockSize)
+ internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
+ return scale * sqrt(ssq);
+}
+
+/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
+ * A Portable Fortran Program to Find the Euclidean Norm of a Vector,
+ * ACM TOMS, Vol 4, Issue 1, 1978.
+ *
+ * For architecture/scalar types without vectorization, this version
+ * is much faster than stableNorm(). Otherwise the stableNorm() is faster.
+ *
+ * \sa norm(), stableNorm(), hypotNorm()
+ */
+template<typename Derived>
+inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
+MatrixBase<Derived>::blueNorm() const
+{
+ return internal::blueNorm_impl(*this);
}
/** \returns the \em l2 norm of \c *this avoiding undeflow and overflow.
diff --git a/extern/Eigen3/Eigen/src/Core/Swap.h b/extern/Eigen3/Eigen/src/Core/Swap.h
index fd73cf3ad7e..bf58bd5997d 100644
--- a/extern/Eigen3/Eigen/src/Core/Swap.h
+++ b/extern/Eigen3/Eigen/src/Core/Swap.h
@@ -49,9 +49,9 @@ template<typename ExpressionType> class SwapWrapper
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
inline const Scalar* data() const { return m_expression.data(); }
- inline Scalar& coeffRef(Index row, Index col)
+ inline Scalar& coeffRef(Index rowId, Index colId)
{
- return m_expression.const_cast_derived().coeffRef(row, col);
+ return m_expression.const_cast_derived().coeffRef(rowId, colId);
}
inline Scalar& coeffRef(Index index)
@@ -59,9 +59,9 @@ template<typename ExpressionType> class SwapWrapper
return m_expression.const_cast_derived().coeffRef(index);
}
- inline Scalar& coeffRef(Index row, Index col) const
+ inline Scalar& coeffRef(Index rowId, Index colId) const
{
- return m_expression.coeffRef(row, col);
+ return m_expression.coeffRef(rowId, colId);
}
inline Scalar& coeffRef(Index index) const
@@ -70,14 +70,14 @@ template<typename ExpressionType> class SwapWrapper
}
template<typename OtherDerived>
- void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
+ void copyCoeff(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
- eigen_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
- Scalar tmp = m_expression.coeff(row, col);
- m_expression.coeffRef(row, col) = _other.coeff(row, col);
- _other.coeffRef(row, col) = tmp;
+ eigen_internal_assert(rowId >= 0 && rowId < rows()
+ && colId >= 0 && colId < cols());
+ Scalar tmp = m_expression.coeff(rowId, colId);
+ m_expression.coeffRef(rowId, colId) = _other.coeff(rowId, colId);
+ _other.coeffRef(rowId, colId) = tmp;
}
template<typename OtherDerived>
@@ -91,16 +91,16 @@ template<typename ExpressionType> class SwapWrapper
}
template<typename OtherDerived, int StoreMode, int LoadMode>
- void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
+ void copyPacket(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
- eigen_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
- Packet tmp = m_expression.template packet<StoreMode>(row, col);
- m_expression.template writePacket<StoreMode>(row, col,
- _other.template packet<LoadMode>(row, col)
+ eigen_internal_assert(rowId >= 0 && rowId < rows()
+ && colId >= 0 && colId < cols());
+ Packet tmp = m_expression.template packet<StoreMode>(rowId, colId);
+ m_expression.template writePacket<StoreMode>(rowId, colId,
+ _other.template packet<LoadMode>(rowId, colId)
);
- _other.template writePacket<LoadMode>(row, col, tmp);
+ _other.template writePacket<LoadMode>(rowId, colId, tmp);
}
template<typename OtherDerived, int StoreMode, int LoadMode>
diff --git a/extern/Eigen3/Eigen/src/Core/Transpose.h b/extern/Eigen3/Eigen/src/Core/Transpose.h
index 045a1cce671..22096ea2fde 100644
--- a/extern/Eigen3/Eigen/src/Core/Transpose.h
+++ b/extern/Eigen3/Eigen/src/Core/Transpose.h
@@ -62,7 +62,7 @@ template<typename MatrixType> class Transpose
typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
- inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
+ inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
@@ -104,6 +104,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
@@ -117,10 +118,10 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
inline const Scalar* data() const { return derived().nestedExpression().data(); }
- inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
+ inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId)
{
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
- return derived().nestedExpression().const_cast_derived().coeffRef(col, row);
+ return derived().nestedExpression().const_cast_derived().coeffRef(colId, rowId);
}
inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
@@ -129,9 +130,9 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
return derived().nestedExpression().const_cast_derived().coeffRef(index);
}
- inline const Scalar& coeffRef(Index row, Index col) const
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
{
- return derived().nestedExpression().coeffRef(col, row);
+ return derived().nestedExpression().coeffRef(colId, rowId);
}
inline const Scalar& coeffRef(Index index) const
@@ -139,9 +140,9 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
return derived().nestedExpression().coeffRef(index);
}
- inline CoeffReturnType coeff(Index row, Index col) const
+ inline CoeffReturnType coeff(Index rowId, Index colId) const
{
- return derived().nestedExpression().coeff(col, row);
+ return derived().nestedExpression().coeff(colId, rowId);
}
inline CoeffReturnType coeff(Index index) const
@@ -150,15 +151,15 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
}
template<int LoadMode>
- inline const PacketScalar packet(Index row, Index col) const
+ inline const PacketScalar packet(Index rowId, Index colId) const
{
- return derived().nestedExpression().template packet<LoadMode>(col, row);
+ return derived().nestedExpression().template packet<LoadMode>(colId, rowId);
}
template<int LoadMode>
- inline void writePacket(Index row, Index col, const PacketScalar& x)
+ inline void writePacket(Index rowId, Index colId, const PacketScalar& x)
{
- derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(col, row, x);
+ derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(colId, rowId, x);
}
template<int LoadMode>
@@ -206,7 +207,7 @@ DenseBase<Derived>::transpose()
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-inline const typename DenseBase<Derived>::ConstTransposeReturnType
+inline typename DenseBase<Derived>::ConstTransposeReturnType
DenseBase<Derived>::transpose() const
{
return ConstTransposeReturnType(derived());
@@ -252,7 +253,7 @@ struct inplace_transpose_selector;
template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,true> { // square matrix
static void run(MatrixType& m) {
- m.template triangularView<StrictlyUpper>().swap(m.transpose());
+ m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
}
};
@@ -260,7 +261,7 @@ template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,false> { // non square matrix
static void run(MatrixType& m) {
if (m.rows()==m.cols())
- m.template triangularView<StrictlyUpper>().swap(m.transpose());
+ m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
else
m = m.transpose().eval();
}
@@ -278,17 +279,20 @@ struct inplace_transpose_selector<MatrixType,false> { // non square matrix
* m = m.transpose().eval();
* \endcode
* and is faster and also safer because in the latter line of code, forgetting the eval() results
- * in a bug caused by aliasing.
+ * in a bug caused by \ref TopicAliasing "aliasing".
*
* Notice however that this method is only useful if you want to replace a matrix by its own transpose.
* If you just need the transpose of a matrix, use transpose().
*
- * \note if the matrix is not square, then \c *this must be a resizable matrix.
+ * \note if the matrix is not square, then \c *this must be a resizable matrix.
+ * This excludes (non-square) fixed-size matrices, block-expressions and maps.
*
* \sa transpose(), adjoint(), adjointInPlace() */
template<typename Derived>
inline void DenseBase<Derived>::transposeInPlace()
{
+ eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
+ && "transposeInPlace() called on a non-square non-resizable matrix");
internal::inplace_transpose_selector<Derived>::run(derived());
}
@@ -312,6 +316,7 @@ inline void DenseBase<Derived>::transposeInPlace()
* If you just need the adjoint of a matrix, use adjoint().
*
* \note if the matrix is not square, then \c *this must be a resizable matrix.
+ * This excludes (non-square) fixed-size matrices, block-expressions and maps.
*
* \sa transpose(), adjoint(), transposeInPlace() */
template<typename Derived>
@@ -353,7 +358,7 @@ struct check_transpose_aliasing_run_time_selector
{
static bool run(const Scalar* dest, const OtherDerived& src)
{
- return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
+ return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src));
}
};
@@ -362,8 +367,8 @@ struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseB
{
static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
{
- return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.lhs())))
- || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.rhs())));
+ return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs())))
+ || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs())));
}
};
@@ -385,7 +390,7 @@ struct checkTransposeAliasing_impl
eigen_assert((!check_transpose_aliasing_run_time_selector
<typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
::run(extract_data(dst), other))
- && "aliasing detected during tranposition, use transposeInPlace() "
+ && "aliasing detected during transposition, use transposeInPlace() "
"or evaluate the rhs into a temporary using .eval()");
}
diff --git a/extern/Eigen3/Eigen/src/Core/Transpositions.h b/extern/Eigen3/Eigen/src/Core/Transpositions.h
index 2cd268a5fa0..e4ba0756fa6 100644
--- a/extern/Eigen3/Eigen/src/Core/Transpositions.h
+++ b/extern/Eigen3/Eigen/src/Core/Transpositions.h
@@ -99,9 +99,9 @@ class TranspositionsBase
IndicesType& indices() { return derived().indices(); }
/** Resizes to given size. */
- inline void resize(int size)
+ inline void resize(int newSize)
{
- indices().resize(size);
+ indices().resize(newSize);
}
/** Sets \c *this to represents an identity transformation */
@@ -177,7 +177,7 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
/** Generic constructor from expression of the transposition indices. */
template<typename Other>
- explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
+ explicit inline Transpositions(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
{}
/** Copies the \a other transpositions into \c *this */
@@ -234,12 +234,12 @@ class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,Packe
typedef typename Traits::IndicesType IndicesType;
typedef typename IndicesType::Scalar Index;
- inline Map(const Index* indices)
- : m_indices(indices)
+ inline Map(const Index* indicesPtr)
+ : m_indices(indicesPtr)
{}
- inline Map(const Index* indices, Index size)
- : m_indices(indices,size)
+ inline Map(const Index* indicesPtr, Index size)
+ : m_indices(indicesPtr,size)
{}
/** Copies the \a other transpositions into \c *this */
@@ -291,8 +291,8 @@ class TranspositionsWrapper
typedef typename Traits::IndicesType IndicesType;
typedef typename IndicesType::Scalar Index;
- inline TranspositionsWrapper(IndicesType& indices)
- : m_indices(indices)
+ inline TranspositionsWrapper(IndicesType& a_indices)
+ : m_indices(a_indices)
{}
/** Copies the \a other transpositions into \c *this */
diff --git a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h
index de9540063c2..fba07365f6f 100644
--- a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h
@@ -511,6 +511,7 @@ template<typename Derived1, typename Derived2, bool ClearOpposite>
struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
{
typedef typename Derived1::Index Index;
+ typedef typename Derived1::Scalar Scalar;
static inline void run(Derived1 &dst, const Derived2 &src)
{
for(Index j = 0; j < dst.cols(); ++j)
@@ -520,7 +521,7 @@ struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic
dst.copyCoeff(i, j, src);
if (ClearOpposite)
for(Index i = maxi; i < dst.rows(); ++i)
- dst.coeffRef(i, j) = 0;
+ dst.coeffRef(i, j) = Scalar(0);
}
}
};
@@ -778,22 +779,23 @@ MatrixBase<Derived>::triangularView() const
* \sa isLowerTriangular()
*/
template<typename Derived>
-bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
+bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
{
+ using std::abs;
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
for(Index j = 0; j < cols(); ++j)
{
Index maxi = (std::min)(j, rows()-1);
for(Index i = 0; i <= maxi; ++i)
{
- RealScalar absValue = internal::abs(coeff(i,j));
+ RealScalar absValue = abs(coeff(i,j));
if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
}
}
RealScalar threshold = maxAbsOnUpperPart * prec;
for(Index j = 0; j < cols(); ++j)
for(Index i = j+1; i < rows(); ++i)
- if(internal::abs(coeff(i, j)) > threshold) return false;
+ if(abs(coeff(i, j)) > threshold) return false;
return true;
}
@@ -803,13 +805,14 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
* \sa isUpperTriangular()
*/
template<typename Derived>
-bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
+bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
{
+ using std::abs;
RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
for(Index j = 0; j < cols(); ++j)
for(Index i = j; i < rows(); ++i)
{
- RealScalar absValue = internal::abs(coeff(i,j));
+ RealScalar absValue = abs(coeff(i,j));
if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
}
RealScalar threshold = maxAbsOnLowerPart * prec;
@@ -817,7 +820,7 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
{
Index maxi = (std::min)(j, rows()-1);
for(Index i = 0; i < maxi; ++i)
- if(internal::abs(coeff(i, j)) > threshold) return false;
+ if(abs(coeff(i, j)) > threshold) return false;
}
return true;
}
diff --git a/extern/Eigen3/Eigen/src/Core/VectorBlock.h b/extern/Eigen3/Eigen/src/Core/VectorBlock.h
index 6f4effca055..1a7330f3cfc 100644
--- a/extern/Eigen3/Eigen/src/Core/VectorBlock.h
+++ b/extern/Eigen3/Eigen/src/Core/VectorBlock.h
@@ -90,195 +90,6 @@ template<typename VectorType, int Size> class VectorBlock
};
-/** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
- *
- * \only_for_vectors
- *
- * \param start the first coefficient in the segment
- * \param size the number of coefficients in the segment
- *
- * Example: \include MatrixBase_segment_int_int.cpp
- * Output: \verbinclude MatrixBase_segment_int_int.out
- *
- * \note Even though the returned expression has dynamic size, in the case
- * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
- * which means that evaluating it does not cause a dynamic memory allocation.
- *
- * \sa class Block, segment(Index)
- */
-template<typename Derived>
-inline typename DenseBase<Derived>::SegmentReturnType
-DenseBase<Derived>::segment(Index start, Index size)
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return SegmentReturnType(derived(), start, size);
-}
-
-/** This is the const version of segment(Index,Index).*/
-template<typename Derived>
-inline typename DenseBase<Derived>::ConstSegmentReturnType
-DenseBase<Derived>::segment(Index start, Index size) const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return ConstSegmentReturnType(derived(), start, size);
-}
-
-/** \returns a dynamic-size expression of the first coefficients of *this.
- *
- * \only_for_vectors
- *
- * \param size the number of coefficients in the block
- *
- * Example: \include MatrixBase_start_int.cpp
- * Output: \verbinclude MatrixBase_start_int.out
- *
- * \note Even though the returned expression has dynamic size, in the case
- * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
- * which means that evaluating it does not cause a dynamic memory allocation.
- *
- * \sa class Block, block(Index,Index)
- */
-template<typename Derived>
-inline typename DenseBase<Derived>::SegmentReturnType
-DenseBase<Derived>::head(Index size)
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return SegmentReturnType(derived(), 0, size);
-}
-
-/** This is the const version of head(Index).*/
-template<typename Derived>
-inline typename DenseBase<Derived>::ConstSegmentReturnType
-DenseBase<Derived>::head(Index size) const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return ConstSegmentReturnType(derived(), 0, size);
-}
-
-/** \returns a dynamic-size expression of the last coefficients of *this.
- *
- * \only_for_vectors
- *
- * \param size the number of coefficients in the block
- *
- * Example: \include MatrixBase_end_int.cpp
- * Output: \verbinclude MatrixBase_end_int.out
- *
- * \note Even though the returned expression has dynamic size, in the case
- * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
- * which means that evaluating it does not cause a dynamic memory allocation.
- *
- * \sa class Block, block(Index,Index)
- */
-template<typename Derived>
-inline typename DenseBase<Derived>::SegmentReturnType
-DenseBase<Derived>::tail(Index size)
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return SegmentReturnType(derived(), this->size() - size, size);
-}
-
-/** This is the const version of tail(Index).*/
-template<typename Derived>
-inline typename DenseBase<Derived>::ConstSegmentReturnType
-DenseBase<Derived>::tail(Index size) const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return ConstSegmentReturnType(derived(), this->size() - size, size);
-}
-
-/** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this
- *
- * \only_for_vectors
- *
- * The template parameter \a Size is the number of coefficients in the block
- *
- * \param start the index of the first element of the sub-vector
- *
- * Example: \include MatrixBase_template_int_segment.cpp
- * Output: \verbinclude MatrixBase_template_int_segment.out
- *
- * \sa class Block
- */
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::segment(Index start)
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<Size>::Type(derived(), start);
-}
-
-/** This is the const version of segment<int>(Index).*/
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::segment(Index start) const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<Size>::Type(derived(), start);
-}
-
-/** \returns a fixed-size expression of the first coefficients of *this.
- *
- * \only_for_vectors
- *
- * The template parameter \a Size is the number of coefficients in the block
- *
- * Example: \include MatrixBase_template_int_start.cpp
- * Output: \verbinclude MatrixBase_template_int_start.out
- *
- * \sa class Block
- */
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::head()
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<Size>::Type(derived(), 0);
-}
-
-/** This is the const version of head<int>().*/
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::head() const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<Size>::Type(derived(), 0);
-}
-
-/** \returns a fixed-size expression of the last coefficients of *this.
- *
- * \only_for_vectors
- *
- * The template parameter \a Size is the number of coefficients in the block
- *
- * Example: \include MatrixBase_template_int_end.cpp
- * Output: \verbinclude MatrixBase_template_int_end.out
- *
- * \sa class Block
- */
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::tail()
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename FixedSegmentReturnType<Size>::Type(derived(), size() - Size);
-}
-
-/** This is the const version of tail<int>.*/
-template<typename Derived>
-template<int Size>
-inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type
-DenseBase<Derived>::tail() const
-{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
- return typename ConstFixedSegmentReturnType<Size>::Type(derived(), size() - Size);
-}
-
} // end namespace Eigen
#endif // EIGEN_VECTORBLOCK_H
diff --git a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h
index 862c0f33608..d5ab036647e 100644
--- a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h
+++ b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h
@@ -50,7 +50,7 @@ struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0),
- TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime
+ TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
};
#if EIGEN_GNUC_AT_LEAST(3,4)
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
@@ -58,7 +58,8 @@ struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
#endif
enum {
- CoeffReadCost = TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
+ CoeffReadCost = TraversalSize==Dynamic ? Dynamic
+ : TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
};
};
}
@@ -103,8 +104,8 @@ class PartialReduxExpr : internal::no_assignment_operator,
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
template <typename ResultType> \
- struct member_##MEMBER { \
- EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
+ struct member_##MEMBER { \
+ EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
typedef ResultType result_type; \
template<typename Scalar, int Size> struct Cost \
{ enum { value = COST }; }; \
@@ -233,6 +234,28 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
Direction==Vertical ? 1 : m_matrix.rows(),
Direction==Horizontal ? 1 : m_matrix.cols());
}
+
+ template<typename OtherDerived> struct OppositeExtendedType {
+ typedef Replicate<OtherDerived,
+ Direction==Horizontal ? 1 : ExpressionType::RowsAtCompileTime,
+ Direction==Vertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
+ };
+
+ /** \internal
+ * Replicates a vector in the opposite direction to match the size of \c *this */
+ template<typename OtherDerived>
+ typename OppositeExtendedType<OtherDerived>::Type
+ extendedToOpposite(const DenseBase<OtherDerived>& other) const
+ {
+ EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxColsAtCompileTime==1),
+ YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
+ EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxRowsAtCompileTime==1),
+ YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
+ return typename OppositeExtendedType<OtherDerived>::Type
+ (other.derived(),
+ Direction==Horizontal ? 1 : m_matrix.rows(),
+ Direction==Vertical ? 1 : m_matrix.cols());
+ }
public:
@@ -255,6 +278,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
/** \returns a row (or column) vector expression of the smallest coefficient
* of each column (or row) of the referenced expression.
+ *
+ * \warning the result is undefined if \c *this contains NaN.
*
* Example: \include PartialRedux_minCoeff.cpp
* Output: \verbinclude PartialRedux_minCoeff.out
@@ -265,6 +290,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
/** \returns a row (or column) vector expression of the largest coefficient
* of each column (or row) of the referenced expression.
+ *
+ * \warning the result is undefined if \c *this contains NaN.
*
* Example: \include PartialRedux_maxCoeff.cpp
* Output: \verbinclude PartialRedux_maxCoeff.out
@@ -504,6 +531,23 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
return m_matrix / extendedTo(other.derived());
}
+
+ /** \returns an expression where each column of row of the referenced matrix are normalized.
+ * The referenced matrix is \b not modified.
+ * \sa MatrixBase::normalized(), normalize()
+ */
+ CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
+ const ExpressionTypeNestedCleaned,
+ const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
+ normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
+
+
+ /** Normalize in-place each row or columns of the referenced matrix.
+ * \sa MatrixBase::normalize(), normalized()
+ */
+ void normalize() {
+ m_matrix = this->normalized();
+ }
/////////// Geometry module ///////////
diff --git a/extern/Eigen3/Eigen/src/Core/Visitor.h b/extern/Eigen3/Eigen/src/Core/Visitor.h
index 916bfd096a9..64867b7a2cb 100644
--- a/extern/Eigen3/Eigen/src/Core/Visitor.h
+++ b/extern/Eigen3/Eigen/src/Core/Visitor.h
@@ -164,25 +164,25 @@ struct functor_traits<max_coeff_visitor<Scalar> > {
} // end namespace internal
-/** \returns the minimum of all coefficients of *this
- * and puts in *row and *col its location.
+/** \returns the minimum of all coefficients of *this and puts in *row and *col its location.
+ * \warning the result is undefined if \c *this contains NaN.
*
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
*/
template<typename Derived>
template<typename IndexType>
typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::minCoeff(IndexType* row, IndexType* col) const
+DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
{
internal::min_coeff_visitor<Derived> minVisitor;
this->visit(minVisitor);
- *row = minVisitor.row;
- if (col) *col = minVisitor.col;
+ *rowId = minVisitor.row;
+ if (colId) *colId = minVisitor.col;
return minVisitor.res;
}
-/** \returns the minimum of all coefficients of *this
- * and puts in *index its location.
+/** \returns the minimum of all coefficients of *this and puts in *index its location.
+ * \warning the result is undefined if \c *this contains NaN.
*
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff()
*/
@@ -198,25 +198,25 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
return minVisitor.res;
}
-/** \returns the maximum of all coefficients of *this
- * and puts in *row and *col its location.
+/** \returns the maximum of all coefficients of *this and puts in *row and *col its location.
+ * \warning the result is undefined if \c *this contains NaN.
*
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
*/
template<typename Derived>
template<typename IndexType>
typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::maxCoeff(IndexType* row, IndexType* col) const
+DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
{
internal::max_coeff_visitor<Derived> maxVisitor;
this->visit(maxVisitor);
- *row = maxVisitor.row;
- if (col) *col = maxVisitor.col;
+ *rowPtr = maxVisitor.row;
+ if (colPtr) *colPtr = maxVisitor.col;
return maxVisitor.res;
}
-/** \returns the maximum of all coefficients of *this
- * and puts in *index its location.
+/** \returns the maximum of all coefficients of *this and puts in *index its location.
+ * \warning the result is undefined if \c *this contains NaN.
*
* \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
*/
diff --git a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 75de1931198..e4089962dea 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -173,6 +173,9 @@ template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const
template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return psub<Packet4f>(p4f_ZERO, a); }
template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return psub<Packet4i>(p4i_ZERO, a); }
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b,p4f_ZERO); }
/* Commented out: it's actually slower than processing it scalar
*
diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h
index 795b4be7303..f183d31de2a 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h
@@ -68,7 +68,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a)
template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
Packet4f v1, v2;
- float32x2_t a_lo, a_hi;
// Get the real values of a | a1_re | a1_re | a2_re | a2_re |
v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0));
@@ -81,9 +80,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, con
// Conjugate v2
v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR));
// Swap real/imag elements in v2.
- a_lo = vrev64_f32(vget_low_f32(v2));
- a_hi = vrev64_f32(vget_high_f32(v2));
- v2 = vcombine_f32(a_lo, a_hi);
+ v2 = vrev64q_f32(v2);
// Add and return the result
return Packet2cf(vaddq_f32(v1, v2));
}
@@ -241,13 +238,10 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, con
// TODO optimize it for AltiVec
Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
Packet4f s, rev_s;
- float32x2_t a_lo, a_hi;
// this computes the norm
s = vmulq_f32(b.v, b.v);
- a_lo = vrev64_f32(vget_low_f32(s));
- a_hi = vrev64_f32(vget_high_f32(s));
- rev_s = vcombine_f32(a_lo, a_hi);
+ rev_s = vrev64q_f32(s);
return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s)));
}
diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h
index a20250f7c65..163bac215e6 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -115,6 +115,9 @@ template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const
template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return vnegq_f32(a); }
template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return vnegq_s32(a); }
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmulq_f32(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmulq_s32(a,b); }
@@ -188,15 +191,15 @@ template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) { EI
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
{
float32x2_t lo, hi;
- lo = vdup_n_f32(*from);
- hi = vdup_n_f32(*(from+1));
+ lo = vld1_dup_f32(from);
+ hi = vld1_dup_f32(from+1);
return vcombine_f32(lo, hi);
}
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
{
int32x2_t lo, hi;
- lo = vdup_n_s32(*from);
- hi = vdup_n_s32(*(from+1));
+ lo = vld1_dup_s32(from);
+ hi = vld1_dup_s32(from+1);
return vcombine_s32(lo, hi);
}
@@ -237,15 +240,12 @@ template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vabsq_s
template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
{
float32x2_t a_lo, a_hi, sum;
- float s[2];
a_lo = vget_low_f32(a);
a_hi = vget_high_f32(a);
sum = vpadd_f32(a_lo, a_hi);
sum = vpadd_f32(sum, sum);
- vst1_f32(s, sum);
-
- return s[0];
+ return vget_lane_f32(sum, 0);
}
template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
@@ -271,15 +271,12 @@ template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a)
{
int32x2_t a_lo, a_hi, sum;
- int32_t s[2];
a_lo = vget_low_s32(a);
a_hi = vget_high_s32(a);
sum = vpadd_s32(a_lo, a_hi);
sum = vpadd_s32(sum, sum);
- vst1_s32(s, sum);
-
- return s[0];
+ return vget_lane_s32(sum, 0);
}
template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
@@ -307,7 +304,6 @@ template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a)
{
float32x2_t a_lo, a_hi, prod;
- float s[2];
// Get a_lo = |a1|a2| and a_hi = |a3|a4|
a_lo = vget_low_f32(a);
@@ -316,14 +312,12 @@ template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a)
prod = vmul_f32(a_lo, a_hi);
// Multiply prod with its swapped value |a2*a4|a1*a3|
prod = vmul_f32(prod, vrev64_f32(prod));
- vst1_f32(s, prod);
- return s[0];
+ return vget_lane_f32(prod, 0);
}
template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a)
{
int32x2_t a_lo, a_hi, prod;
- int32_t s[2];
// Get a_lo = |a1|a2| and a_hi = |a3|a4|
a_lo = vget_low_s32(a);
@@ -332,65 +326,57 @@ template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a)
prod = vmul_s32(a_lo, a_hi);
// Multiply prod with its swapped value |a2*a4|a1*a3|
prod = vmul_s32(prod, vrev64_s32(prod));
- vst1_s32(s, prod);
- return s[0];
+ return vget_lane_s32(prod, 0);
}
// min
template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a)
{
float32x2_t a_lo, a_hi, min;
- float s[2];
a_lo = vget_low_f32(a);
a_hi = vget_high_f32(a);
min = vpmin_f32(a_lo, a_hi);
min = vpmin_f32(min, min);
- vst1_f32(s, min);
- return s[0];
+ return vget_lane_f32(min, 0);
}
+
template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a)
{
int32x2_t a_lo, a_hi, min;
- int32_t s[2];
a_lo = vget_low_s32(a);
a_hi = vget_high_s32(a);
min = vpmin_s32(a_lo, a_hi);
min = vpmin_s32(min, min);
- vst1_s32(s, min);
-
- return s[0];
+
+ return vget_lane_s32(min, 0);
}
// max
template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a)
{
float32x2_t a_lo, a_hi, max;
- float s[2];
a_lo = vget_low_f32(a);
a_hi = vget_high_f32(a);
max = vpmax_f32(a_lo, a_hi);
max = vpmax_f32(max, max);
- vst1_f32(s, max);
- return s[0];
+ return vget_lane_f32(max, 0);
}
+
template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
{
int32x2_t a_lo, a_hi, max;
- int32_t s[2];
a_lo = vget_low_s32(a);
a_hi = vget_high_s32(a);
max = vpmax_s32(a_lo, a_hi);
- max = vpmax_s32(max, max);
- vst1_s32(s, max);
- return s[0];
+ return vget_lane_s32(max, 0);
}
// this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors,
diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h
index 12df987754c..91bba5e38fe 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h
@@ -81,25 +81,31 @@ template<> EIGEN_STRONG_INLINE Packet2cf por <Packet2cf>(const Packet2cf& a,
template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_xor_ps(a.v,b.v)); }
template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_andnot_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&real_ref(*from))); }
-template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&real_ref(*from))); }
+template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&numext::real_ref(*from))); }
+template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&numext::real_ref(*from))); }
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
{
Packet2cf res;
- #if EIGEN_GNUC_AT_MOST(4,2)
- // workaround annoying "may be used uninitialized in this function" warning with gcc 4.2
+#if EIGEN_GNUC_AT_MOST(4,2)
+ // Workaround annoying "may be used uninitialized in this function" warning with gcc 4.2
res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), reinterpret_cast<const __m64*>(&from));
- #else
+#elif EIGEN_GNUC_AT_LEAST(4,6)
+ // Suppress annoying "may be used uninitialized in this function" warning with gcc >= 4.6
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wuninitialized"
res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
- #endif
+ #pragma GCC diagnostic pop
+#else
+ res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
+#endif
return Packet2cf(_mm_movelh_ps(res.v,res.v));
}
template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&real_ref(*to), from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&real_ref(*to), from.v); }
+template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), from.v); }
+template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), from.v); }
template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h
index 3f41a4e2600..99cbd0d95be 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -31,7 +31,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
/* the smallest non denormalized float number */
_EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos, 0x00800000);
-
+ _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf, 0xff800000);//-1.f/0.f);
+
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
@@ -51,7 +52,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
Packet4i emm0;
- Packet4f invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps());
+ Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps());
+ Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */
emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
@@ -96,7 +98,9 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
y2 = pmul(e, p4f_cephes_log_q2);
x = padd(x, y);
x = padd(x, y2);
- return _mm_or_ps(x, invalid_mask); // negative arg will be NAN
+ // negative arg will be NAN, 0 will be -INF
+ return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)),
+ _mm_and_ps(iszero_mask, p4f_minus_inf));
}
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
@@ -131,13 +135,16 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
/* express exp(x) as exp(g + n*log(2)) */
fx = pmadd(x, p4f_cephes_LOG2EF, p4f_half);
- /* how to perform a floorf with SSE: just below */
+#ifdef EIGEN_VECTORIZE_SSE4_1
+ fx = _mm_floor_ps(fx);
+#else
emm0 = _mm_cvttps_epi32(fx);
tmp = _mm_cvtepi32_ps(emm0);
/* if greater, substract 1 */
Packet4f mask = _mm_cmpgt_ps(tmp, fx);
mask = _mm_and_ps(mask, p4f_1);
fx = psub(tmp, mask);
+#endif
tmp = pmul(fx, p4f_cephes_exp_C1);
Packet4f z = pmul(fx, p4f_cephes_exp_C2);
@@ -161,6 +168,79 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
emm0 = _mm_slli_epi32(emm0, 23);
return pmul(y, _mm_castsi128_ps(emm0));
}
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
+Packet2d pexp<Packet2d>(const Packet2d& _x)
+{
+ Packet2d x = _x;
+
+ _EIGEN_DECLARE_CONST_Packet2d(1 , 1.0);
+ _EIGEN_DECLARE_CONST_Packet2d(2 , 2.0);
+ _EIGEN_DECLARE_CONST_Packet2d(half, 0.5);
+
+ _EIGEN_DECLARE_CONST_Packet2d(exp_hi, 709.437);
+ _EIGEN_DECLARE_CONST_Packet2d(exp_lo, -709.436139303);
+
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_LOG2EF, 1.4426950408889634073599);
+
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p0, 1.26177193074810590878e-4);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p1, 3.02994407707441961300e-2);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p2, 9.99999999999999999910e-1);
+
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q0, 3.00198505138664455042e-6);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q1, 2.52448340349684104192e-3);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q2, 2.27265548208155028766e-1);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q3, 2.00000000000000000009e0);
+
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C1, 0.693145751953125);
+ _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6);
+ static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0);
+
+ Packet2d tmp = _mm_setzero_pd(), fx;
+ Packet4i emm0;
+
+ // clamp x
+ x = pmax(pmin(x, p2d_exp_hi), p2d_exp_lo);
+ /* express exp(x) as exp(g + n*log(2)) */
+ fx = pmadd(p2d_cephes_LOG2EF, x, p2d_half);
+
+#ifdef EIGEN_VECTORIZE_SSE4_1
+ fx = _mm_floor_pd(fx);
+#else
+ emm0 = _mm_cvttpd_epi32(fx);
+ tmp = _mm_cvtepi32_pd(emm0);
+ /* if greater, substract 1 */
+ Packet2d mask = _mm_cmpgt_pd(tmp, fx);
+ mask = _mm_and_pd(mask, p2d_1);
+ fx = psub(tmp, mask);
+#endif
+
+ tmp = pmul(fx, p2d_cephes_exp_C1);
+ Packet2d z = pmul(fx, p2d_cephes_exp_C2);
+ x = psub(x, tmp);
+ x = psub(x, z);
+
+ Packet2d x2 = pmul(x,x);
+
+ Packet2d px = p2d_cephes_exp_p0;
+ px = pmadd(px, x2, p2d_cephes_exp_p1);
+ px = pmadd(px, x2, p2d_cephes_exp_p2);
+ px = pmul (px, x);
+
+ Packet2d qx = p2d_cephes_exp_q0;
+ qx = pmadd(qx, x2, p2d_cephes_exp_q1);
+ qx = pmadd(qx, x2, p2d_cephes_exp_q2);
+ qx = pmadd(qx, x2, p2d_cephes_exp_q3);
+
+ x = pdiv(px,psub(qx,px));
+ x = pmadd(p2d_2,x,p2d_1);
+
+ // build 2^n
+ emm0 = _mm_cvttpd_epi32(fx);
+ emm0 = _mm_add_epi32(emm0, p4i_1023_0);
+ emm0 = _mm_slli_epi32(emm0, 20);
+ emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3));
+ return pmul(x, _mm_castsi128_pd(emm0));
+}
/* evaluation of 4 sines at onces, using SSE2 intrinsics.
@@ -362,21 +442,32 @@ Packet4f pcos<Packet4f>(const Packet4f& _x)
return _mm_xor_ps(y, sign_bit);
}
+#if EIGEN_FAST_MATH
+
// This is based on Quake3's fast inverse square root.
// For detail see here: http://www.beyond3d.com/content/articles/8/
+// It lacks 1 (or 2 bits in some rare cases) of precision, and does not handle negative, +inf, or denormalized numbers correctly.
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
Packet4f psqrt<Packet4f>(const Packet4f& _x)
{
Packet4f half = pmul(_x, pset1<Packet4f>(.5f));
/* select only the inverse sqrt of non-zero inputs */
- Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>(std::numeric_limits<float>::epsilon()));
+ Packet4f non_zero_mask = _mm_cmpge_ps(_x, pset1<Packet4f>((std::numeric_limits<float>::min)()));
Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x));
x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x))));
return pmul(_x,x);
}
+#else
+
+template<> EIGEN_STRONG_INLINE Packet4f psqrt<Packet4f>(const Packet4f& x) { return _mm_sqrt_ps(x); }
+
+#endif
+
+template<> EIGEN_STRONG_INLINE Packet2d psqrt<Packet2d>(const Packet2d& x) { return _mm_sqrt_pd(x); }
+
} // end namespace internal
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h
index 10d9182190f..fc8ae50fed7 100644
--- a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -48,6 +48,9 @@ template<> struct is_arithmetic<__m128d> { enum { value = true }; };
#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
const Packet4f p4f_##NAME = pset1<Packet4f>(X)
+#define _EIGEN_DECLARE_CONST_Packet2d(NAME,X) \
+ const Packet2d p2d_##NAME = pset1<Packet2d>(X)
+
#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \
const Packet4f p4f_##NAME = _mm_castsi128_ps(pset1<Packet4i>(X))
@@ -63,7 +66,7 @@ template<> struct packet_traits<float> : default_packet_traits
AlignedOnScalar = 1,
size=4,
- HasDiv = 1,
+ HasDiv = 1,
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
HasLog = 1,
@@ -79,7 +82,9 @@ template<> struct packet_traits<double> : default_packet_traits
AlignedOnScalar = 1,
size=2,
- HasDiv = 1
+ HasDiv = 1,
+ HasExp = 1,
+ HasSqrt = 1
};
};
template<> struct packet_traits<int> : default_packet_traits
@@ -137,6 +142,10 @@ template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a)
return psub(_mm_setr_epi32(0,0,0,0), a);
}
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_mul_ps(a,b); }
template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
@@ -169,18 +178,26 @@ template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const
template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b)
{
+#ifdef EIGEN_VECTORIZE_SSE4_1
+ return _mm_min_epi32(a,b);
+#else
// after some bench, this version *is* faster than a scalar implementation
Packet4i mask = _mm_cmplt_epi32(a,b);
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
+#endif
}
template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); }
template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b)
{
+#ifdef EIGEN_VECTORIZE_SSE4_1
+ return _mm_max_epi32(a,b);
+#else
// after some bench, this version *is* faster than a scalar implementation
Packet4i mask = _mm_cmpgt_epi32(a,b);
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
+#endif
}
template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_and_ps(a,b); }
@@ -491,8 +508,8 @@ template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a)
// for GCC (eg., it does not like using std::min after the pstore !!)
EIGEN_ALIGN16 int aux[4];
pstore(aux, a);
- register int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
- register int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
+ int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
+ int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
return aux0<aux2 ? aux0 : aux2;
}
@@ -512,8 +529,8 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
// for GCC (eg., it does not like using std::min after the pstore !!)
EIGEN_ALIGN16 int aux[4];
pstore(aux, a);
- register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
- register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];
+ int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
+ int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];
return aux0>aux2 ? aux0 : aux2;
}
diff --git a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h
index 403d25fa9eb..c06a0df1c21 100644
--- a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h
+++ b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h
@@ -150,7 +150,7 @@ class CoeffBasedProduct
{
// we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
// We still allow to mix T and complex<T>.
- EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
+ EIGEN_STATIC_ASSERT((internal::scalar_product_traits<typename Lhs::RealScalar, typename Rhs::RealScalar>::Defined),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
eigen_assert(lhs.cols() == rhs.rows()
&& "invalid matrix product"
diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h
index 5eb03c98ccf..bcdca5b0d23 100644
--- a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h
+++ b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h
@@ -69,8 +69,8 @@ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdi
* - the number of scalars that fit into a packet (when vectorization is enabled).
*
* \sa setCpuCacheSizes */
-template<typename LhsScalar, typename RhsScalar, int KcFactor>
-void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
+template<typename LhsScalar, typename RhsScalar, int KcFactor, typename SizeType>
+void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n)
{
EIGEN_UNUSED_VARIABLE(n);
// Explanations:
@@ -91,13 +91,13 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd
};
manage_caching_sizes(GetAction, &l1, &l2);
- k = std::min<std::ptrdiff_t>(k, l1/kdiv);
- std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
+ k = std::min<SizeType>(k, l1/kdiv);
+ SizeType _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
if(_m<m) m = _m & mr_mask;
}
-template<typename LhsScalar, typename RhsScalar>
-inline void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
+template<typename LhsScalar, typename RhsScalar, typename SizeType>
+inline void computeProductBlockingSizes(SizeType& k, SizeType& m, SizeType& n)
{
computeProductBlockingSizes<LhsScalar,RhsScalar,1>(k, m, n);
}
@@ -527,9 +527,16 @@ struct gebp_kernel
ResPacketSize = Traits::ResPacketSize
};
- EIGEN_DONT_INLINE EIGEN_FLATTEN_ATTRIB
+ EIGEN_DONT_INLINE
void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha,
- Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, RhsScalar* unpackedB = 0)
+ Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, RhsScalar* unpackedB=0);
+};
+
+template<typename LhsScalar, typename RhsScalar, typename Index, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
+EIGEN_DONT_INLINE
+void gebp_kernel<LhsScalar,RhsScalar,Index,mr,nr,ConjugateLhs,ConjugateRhs>
+ ::operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha,
+ Index strideA, Index strideB, Index offsetA, Index offsetB, RhsScalar* unpackedB)
{
Traits traits;
@@ -1089,7 +1096,7 @@ EIGEN_ASM_COMMENT("mybegin4");
}
}
}
-};
+
#undef CJMADD
@@ -1110,80 +1117,85 @@ EIGEN_ASM_COMMENT("mybegin4");
template<typename Scalar, typename Index, int Pack1, int Pack2, int StorageOrder, bool Conjugate, bool PanelMode>
struct gemm_pack_lhs
{
- EIGEN_DONT_INLINE void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows,
- Index stride=0, Index offset=0)
+ EIGEN_DONT_INLINE void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride=0, Index offset=0);
+};
+
+template<typename Scalar, typename Index, int Pack1, int Pack2, int StorageOrder, bool Conjugate, bool PanelMode>
+EIGEN_DONT_INLINE void gemm_pack_lhs<Scalar, Index, Pack1, Pack2, StorageOrder, Conjugate, PanelMode>
+ ::operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride, Index offset)
+{
+ typedef typename packet_traits<Scalar>::type Packet;
+ enum { PacketSize = packet_traits<Scalar>::size };
+
+ EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS");
+ EIGEN_UNUSED_VARIABLE(stride)
+ EIGEN_UNUSED_VARIABLE(offset)
+ eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
+ eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) );
+ conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
+ const_blas_data_mapper<Scalar, Index, StorageOrder> lhs(_lhs,lhsStride);
+ Index count = 0;
+ Index peeled_mc = (rows/Pack1)*Pack1;
+ for(Index i=0; i<peeled_mc; i+=Pack1)
{
- typedef typename packet_traits<Scalar>::type Packet;
- enum { PacketSize = packet_traits<Scalar>::size };
-
- EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS");
- eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
- eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) );
- conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
- const_blas_data_mapper<Scalar, Index, StorageOrder> lhs(_lhs,lhsStride);
- Index count = 0;
- Index peeled_mc = (rows/Pack1)*Pack1;
- for(Index i=0; i<peeled_mc; i+=Pack1)
- {
- if(PanelMode) count += Pack1 * offset;
+ if(PanelMode) count += Pack1 * offset;
- if(StorageOrder==ColMajor)
+ if(StorageOrder==ColMajor)
+ {
+ for(Index k=0; k<depth; k++)
{
- for(Index k=0; k<depth; k++)
- {
- Packet A, B, C, D;
- if(Pack1>=1*PacketSize) A = ploadu<Packet>(&lhs(i+0*PacketSize, k));
- if(Pack1>=2*PacketSize) B = ploadu<Packet>(&lhs(i+1*PacketSize, k));
- if(Pack1>=3*PacketSize) C = ploadu<Packet>(&lhs(i+2*PacketSize, k));
- if(Pack1>=4*PacketSize) D = ploadu<Packet>(&lhs(i+3*PacketSize, k));
- if(Pack1>=1*PacketSize) { pstore(blockA+count, cj.pconj(A)); count+=PacketSize; }
- if(Pack1>=2*PacketSize) { pstore(blockA+count, cj.pconj(B)); count+=PacketSize; }
- if(Pack1>=3*PacketSize) { pstore(blockA+count, cj.pconj(C)); count+=PacketSize; }
- if(Pack1>=4*PacketSize) { pstore(blockA+count, cj.pconj(D)); count+=PacketSize; }
- }
+ Packet A, B, C, D;
+ if(Pack1>=1*PacketSize) A = ploadu<Packet>(&lhs(i+0*PacketSize, k));
+ if(Pack1>=2*PacketSize) B = ploadu<Packet>(&lhs(i+1*PacketSize, k));
+ if(Pack1>=3*PacketSize) C = ploadu<Packet>(&lhs(i+2*PacketSize, k));
+ if(Pack1>=4*PacketSize) D = ploadu<Packet>(&lhs(i+3*PacketSize, k));
+ if(Pack1>=1*PacketSize) { pstore(blockA+count, cj.pconj(A)); count+=PacketSize; }
+ if(Pack1>=2*PacketSize) { pstore(blockA+count, cj.pconj(B)); count+=PacketSize; }
+ if(Pack1>=3*PacketSize) { pstore(blockA+count, cj.pconj(C)); count+=PacketSize; }
+ if(Pack1>=4*PacketSize) { pstore(blockA+count, cj.pconj(D)); count+=PacketSize; }
}
- else
+ }
+ else
+ {
+ for(Index k=0; k<depth; k++)
{
- for(Index k=0; k<depth; k++)
+ // TODO add a vectorized transpose here
+ Index w=0;
+ for(; w<Pack1-3; w+=4)
{
- // TODO add a vectorized transpose here
- Index w=0;
- for(; w<Pack1-3; w+=4)
- {
- Scalar a(cj(lhs(i+w+0, k))),
- b(cj(lhs(i+w+1, k))),
- c(cj(lhs(i+w+2, k))),
- d(cj(lhs(i+w+3, k)));
- blockA[count++] = a;
- blockA[count++] = b;
- blockA[count++] = c;
- blockA[count++] = d;
- }
- if(Pack1%4)
- for(;w<Pack1;++w)
- blockA[count++] = cj(lhs(i+w, k));
+ Scalar a(cj(lhs(i+w+0, k))),
+ b(cj(lhs(i+w+1, k))),
+ c(cj(lhs(i+w+2, k))),
+ d(cj(lhs(i+w+3, k)));
+ blockA[count++] = a;
+ blockA[count++] = b;
+ blockA[count++] = c;
+ blockA[count++] = d;
}
+ if(Pack1%4)
+ for(;w<Pack1;++w)
+ blockA[count++] = cj(lhs(i+w, k));
}
- if(PanelMode) count += Pack1 * (stride-offset-depth);
- }
- if(rows-peeled_mc>=Pack2)
- {
- if(PanelMode) count += Pack2*offset;
- for(Index k=0; k<depth; k++)
- for(Index w=0; w<Pack2; w++)
- blockA[count++] = cj(lhs(peeled_mc+w, k));
- if(PanelMode) count += Pack2 * (stride-offset-depth);
- peeled_mc += Pack2;
- }
- for(Index i=peeled_mc; i<rows; i++)
- {
- if(PanelMode) count += offset;
- for(Index k=0; k<depth; k++)
- blockA[count++] = cj(lhs(i, k));
- if(PanelMode) count += (stride-offset-depth);
}
+ if(PanelMode) count += Pack1 * (stride-offset-depth);
}
-};
+ if(rows-peeled_mc>=Pack2)
+ {
+ if(PanelMode) count += Pack2*offset;
+ for(Index k=0; k<depth; k++)
+ for(Index w=0; w<Pack2; w++)
+ blockA[count++] = cj(lhs(peeled_mc+w, k));
+ if(PanelMode) count += Pack2 * (stride-offset-depth);
+ peeled_mc += Pack2;
+ }
+ for(Index i=peeled_mc; i<rows; i++)
+ {
+ if(PanelMode) count += offset;
+ for(Index k=0; k<depth; k++)
+ blockA[count++] = cj(lhs(i, k));
+ if(PanelMode) count += (stride-offset-depth);
+ }
+}
// copy a complete panel of the rhs
// this version is optimized for column major matrices
@@ -1197,92 +1209,102 @@ struct gemm_pack_rhs<Scalar, Index, nr, ColMajor, Conjugate, PanelMode>
{
typedef typename packet_traits<Scalar>::type Packet;
enum { PacketSize = packet_traits<Scalar>::size };
- EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols,
- Index stride=0, Index offset=0)
+ EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0);
+};
+
+template<typename Scalar, typename Index, int nr, bool Conjugate, bool PanelMode>
+EIGEN_DONT_INLINE void gemm_pack_rhs<Scalar, Index, nr, ColMajor, Conjugate, PanelMode>
+ ::operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride, Index offset)
+{
+ EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR");
+ EIGEN_UNUSED_VARIABLE(stride)
+ EIGEN_UNUSED_VARIABLE(offset)
+ eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
+ conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
+ Index packet_cols = (cols/nr) * nr;
+ Index count = 0;
+ for(Index j2=0; j2<packet_cols; j2+=nr)
{
- EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR");
- eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
- conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
- Index packet_cols = (cols/nr) * nr;
- Index count = 0;
- for(Index j2=0; j2<packet_cols; j2+=nr)
+ // skip what we have before
+ if(PanelMode) count += nr * offset;
+ const Scalar* b0 = &rhs[(j2+0)*rhsStride];
+ const Scalar* b1 = &rhs[(j2+1)*rhsStride];
+ const Scalar* b2 = &rhs[(j2+2)*rhsStride];
+ const Scalar* b3 = &rhs[(j2+3)*rhsStride];
+ for(Index k=0; k<depth; k++)
{
- // skip what we have before
- if(PanelMode) count += nr * offset;
- const Scalar* b0 = &rhs[(j2+0)*rhsStride];
- const Scalar* b1 = &rhs[(j2+1)*rhsStride];
- const Scalar* b2 = &rhs[(j2+2)*rhsStride];
- const Scalar* b3 = &rhs[(j2+3)*rhsStride];
- for(Index k=0; k<depth; k++)
- {
- blockB[count+0] = cj(b0[k]);
- blockB[count+1] = cj(b1[k]);
- if(nr==4) blockB[count+2] = cj(b2[k]);
- if(nr==4) blockB[count+3] = cj(b3[k]);
- count += nr;
- }
- // skip what we have after
- if(PanelMode) count += nr * (stride-offset-depth);
+ blockB[count+0] = cj(b0[k]);
+ blockB[count+1] = cj(b1[k]);
+ if(nr==4) blockB[count+2] = cj(b2[k]);
+ if(nr==4) blockB[count+3] = cj(b3[k]);
+ count += nr;
}
+ // skip what we have after
+ if(PanelMode) count += nr * (stride-offset-depth);
+ }
- // copy the remaining columns one at a time (nr==1)
- for(Index j2=packet_cols; j2<cols; ++j2)
+ // copy the remaining columns one at a time (nr==1)
+ for(Index j2=packet_cols; j2<cols; ++j2)
+ {
+ if(PanelMode) count += offset;
+ const Scalar* b0 = &rhs[(j2+0)*rhsStride];
+ for(Index k=0; k<depth; k++)
{
- if(PanelMode) count += offset;
- const Scalar* b0 = &rhs[(j2+0)*rhsStride];
- for(Index k=0; k<depth; k++)
- {
- blockB[count] = cj(b0[k]);
- count += 1;
- }
- if(PanelMode) count += (stride-offset-depth);
+ blockB[count] = cj(b0[k]);
+ count += 1;
}
+ if(PanelMode) count += (stride-offset-depth);
}
-};
+}
// this version is optimized for row major matrices
template<typename Scalar, typename Index, int nr, bool Conjugate, bool PanelMode>
struct gemm_pack_rhs<Scalar, Index, nr, RowMajor, Conjugate, PanelMode>
{
enum { PacketSize = packet_traits<Scalar>::size };
- EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols,
- Index stride=0, Index offset=0)
+ EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0);
+};
+
+template<typename Scalar, typename Index, int nr, bool Conjugate, bool PanelMode>
+EIGEN_DONT_INLINE void gemm_pack_rhs<Scalar, Index, nr, RowMajor, Conjugate, PanelMode>
+ ::operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride, Index offset)
+{
+ EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR");
+ EIGEN_UNUSED_VARIABLE(stride)
+ EIGEN_UNUSED_VARIABLE(offset)
+ eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
+ conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
+ Index packet_cols = (cols/nr) * nr;
+ Index count = 0;
+ for(Index j2=0; j2<packet_cols; j2+=nr)
{
- EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR");
- eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
- conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
- Index packet_cols = (cols/nr) * nr;
- Index count = 0;
- for(Index j2=0; j2<packet_cols; j2+=nr)
+ // skip what we have before
+ if(PanelMode) count += nr * offset;
+ for(Index k=0; k<depth; k++)
{
- // skip what we have before
- if(PanelMode) count += nr * offset;
- for(Index k=0; k<depth; k++)
- {
- const Scalar* b0 = &rhs[k*rhsStride + j2];
- blockB[count+0] = cj(b0[0]);
- blockB[count+1] = cj(b0[1]);
- if(nr==4) blockB[count+2] = cj(b0[2]);
- if(nr==4) blockB[count+3] = cj(b0[3]);
- count += nr;
- }
- // skip what we have after
- if(PanelMode) count += nr * (stride-offset-depth);
+ const Scalar* b0 = &rhs[k*rhsStride + j2];
+ blockB[count+0] = cj(b0[0]);
+ blockB[count+1] = cj(b0[1]);
+ if(nr==4) blockB[count+2] = cj(b0[2]);
+ if(nr==4) blockB[count+3] = cj(b0[3]);
+ count += nr;
}
- // copy the remaining columns one at a time (nr==1)
- for(Index j2=packet_cols; j2<cols; ++j2)
+ // skip what we have after
+ if(PanelMode) count += nr * (stride-offset-depth);
+ }
+ // copy the remaining columns one at a time (nr==1)
+ for(Index j2=packet_cols; j2<cols; ++j2)
+ {
+ if(PanelMode) count += offset;
+ const Scalar* b0 = &rhs[j2];
+ for(Index k=0; k<depth; k++)
{
- if(PanelMode) count += offset;
- const Scalar* b0 = &rhs[j2];
- for(Index k=0; k<depth; k++)
- {
- blockB[count] = cj(b0[k*rhsStride]);
- count += 1;
- }
- if(PanelMode) count += stride-offset-depth;
+ blockB[count] = cj(b0[k*rhsStride]);
+ count += 1;
}
+ if(PanelMode) count += stride-offset-depth;
}
-};
+}
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h
index 73a465ec5ee..3f5ffcf51c7 100644
--- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h
@@ -50,6 +50,7 @@ template<
typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs>
struct general_matrix_matrix_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,ColMajor>
{
+
typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;
static void run(Index rows, Index cols, Index depth,
const LhsScalar* _lhs, Index lhsStride,
@@ -169,7 +170,6 @@ static void run(Index rows, Index cols, Index depth,
// vertical panel which is, in practice, a very low number.
pack_rhs(blockB, &rhs(k2,0), rhsStride, actual_kc, cols);
-
// For each mc x kc block of the lhs's vertical panel...
// (==GEPP_VAR1)
for(Index i2=0; i2<rows; i2+=mc)
@@ -183,7 +183,6 @@ static void run(Index rows, Index cols, Index depth,
// Everything is packed, we can now call the block * panel kernel:
gebp(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha, -1, -1, 0, 0, blockW);
-
}
}
}
@@ -204,7 +203,7 @@ struct traits<GeneralProduct<Lhs,Rhs,GemmProduct> >
template<typename Scalar, typename Index, typename Gemm, typename Lhs, typename Rhs, typename Dest, typename BlockingType>
struct gemm_functor
{
- gemm_functor(const Lhs& lhs, const Rhs& rhs, Dest& dest, Scalar actualAlpha,
+ gemm_functor(const Lhs& lhs, const Rhs& rhs, Dest& dest, const Scalar& actualAlpha,
BlockingType& blocking)
: m_lhs(lhs), m_rhs(rhs), m_dest(dest), m_actualAlpha(actualAlpha), m_blocking(blocking)
{}
@@ -395,7 +394,7 @@ class GeneralProduct<Lhs, Rhs, GemmProduct>
EIGEN_CHECK_BINARY_COMPATIBILIY(BinOp,LhsScalar,RhsScalar);
}
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index 432d3a9dc84..5c37639091c 100644
--- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -12,6 +12,9 @@
namespace Eigen {
+template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>
+struct selfadjoint_rank1_update;
+
namespace internal {
/**********************************************************************
@@ -39,7 +42,7 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
{
typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;
static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride,
- const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, ResScalar alpha)
+ const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, const ResScalar& alpha)
{
general_matrix_matrix_triangular_product<Index,
RhsScalar, RhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateRhs,
@@ -55,7 +58,7 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
{
typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;
static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride,
- const RhsScalar* _rhs, Index rhsStride, ResScalar* res, Index resStride, ResScalar alpha)
+ const RhsScalar* _rhs, Index rhsStride, ResScalar* res, Index resStride, const ResScalar& alpha)
{
const_blas_data_mapper<LhsScalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride);
const_blas_data_mapper<RhsScalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride);
@@ -133,7 +136,7 @@ struct tribb_kernel
enum {
BlockSize = EIGEN_PLAIN_ENUM_MAX(mr,nr)
};
- void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, ResScalar alpha, RhsScalar* workspace)
+ void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, const ResScalar& alpha, RhsScalar* workspace)
{
gebp_kernel<LhsScalar, RhsScalar, Index, mr, nr, ConjLhs, ConjRhs> gebp_kernel;
Matrix<ResScalar,BlockSize,BlockSize,ColMajor> buffer;
@@ -180,31 +183,92 @@ struct tribb_kernel
// high level API
+template<typename MatrixType, typename ProductType, int UpLo, bool IsOuterProduct>
+struct general_product_to_triangular_selector;
+
+
+template<typename MatrixType, typename ProductType, int UpLo>
+struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,true>
+{
+ static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha)
+ {
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::Index Index;
+
+ typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
+ typedef internal::blas_traits<Lhs> LhsBlasTraits;
+ typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs;
+ typedef typename internal::remove_all<ActualLhs>::type _ActualLhs;
+ typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
+
+ typedef typename internal::remove_all<typename ProductType::RhsNested>::type Rhs;
+ typedef internal::blas_traits<Rhs> RhsBlasTraits;
+ typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs;
+ typedef typename internal::remove_all<ActualRhs>::type _ActualRhs;
+ typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
+
+ Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
+
+ enum {
+ StorageOrder = (internal::traits<MatrixType>::Flags&RowMajorBit) ? RowMajor : ColMajor,
+ UseLhsDirectly = _ActualLhs::InnerStrideAtCompileTime==1,
+ UseRhsDirectly = _ActualRhs::InnerStrideAtCompileTime==1
+ };
+
+ internal::gemv_static_vector_if<Scalar,Lhs::SizeAtCompileTime,Lhs::MaxSizeAtCompileTime,!UseLhsDirectly> static_lhs;
+ ei_declare_aligned_stack_constructed_variable(Scalar, actualLhsPtr, actualLhs.size(),
+ (UseLhsDirectly ? const_cast<Scalar*>(actualLhs.data()) : static_lhs.data()));
+ if(!UseLhsDirectly) Map<typename _ActualLhs::PlainObject>(actualLhsPtr, actualLhs.size()) = actualLhs;
+
+ internal::gemv_static_vector_if<Scalar,Rhs::SizeAtCompileTime,Rhs::MaxSizeAtCompileTime,!UseRhsDirectly> static_rhs;
+ ei_declare_aligned_stack_constructed_variable(Scalar, actualRhsPtr, actualRhs.size(),
+ (UseRhsDirectly ? const_cast<Scalar*>(actualRhs.data()) : static_rhs.data()));
+ if(!UseRhsDirectly) Map<typename _ActualRhs::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
+
+
+ selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
+ LhsBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
+ RhsBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex>
+ ::run(actualLhs.size(), mat.data(), mat.outerStride(), actualLhsPtr, actualRhsPtr, actualAlpha);
+ }
+};
+
+template<typename MatrixType, typename ProductType, int UpLo>
+struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
+{
+ static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha)
+ {
+ typedef typename MatrixType::Index Index;
+
+ typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
+ typedef internal::blas_traits<Lhs> LhsBlasTraits;
+ typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs;
+ typedef typename internal::remove_all<ActualLhs>::type _ActualLhs;
+ typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
+
+ typedef typename internal::remove_all<typename ProductType::RhsNested>::type Rhs;
+ typedef internal::blas_traits<Rhs> RhsBlasTraits;
+ typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs;
+ typedef typename internal::remove_all<ActualRhs>::type _ActualRhs;
+ typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
+
+ typename ProductType::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
+
+ internal::general_matrix_matrix_triangular_product<Index,
+ typename Lhs::Scalar, _ActualLhs::Flags&RowMajorBit ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
+ typename Rhs::Scalar, _ActualRhs::Flags&RowMajorBit ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
+ MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor, UpLo>
+ ::run(mat.cols(), actualLhs.cols(),
+ &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(),
+ mat.data(), mat.outerStride(), actualAlpha);
+ }
+};
+
template<typename MatrixType, unsigned int UpLo>
template<typename ProductDerived, typename _Lhs, typename _Rhs>
TriangularView<MatrixType,UpLo>& TriangularView<MatrixType,UpLo>::assignProduct(const ProductBase<ProductDerived, _Lhs,_Rhs>& prod, const Scalar& alpha)
{
- typedef typename internal::remove_all<typename ProductDerived::LhsNested>::type Lhs;
- typedef internal::blas_traits<Lhs> LhsBlasTraits;
- typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs;
- typedef typename internal::remove_all<ActualLhs>::type _ActualLhs;
- typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
-
- typedef typename internal::remove_all<typename ProductDerived::RhsNested>::type Rhs;
- typedef internal::blas_traits<Rhs> RhsBlasTraits;
- typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs;
- typedef typename internal::remove_all<ActualRhs>::type _ActualRhs;
- typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
-
- typename ProductDerived::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
-
- internal::general_matrix_matrix_triangular_product<Index,
- typename Lhs::Scalar, _ActualLhs::Flags&RowMajorBit ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
- typename Rhs::Scalar, _ActualRhs::Flags&RowMajorBit ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
- MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor, UpLo>
- ::run(m_matrix.cols(), actualLhs.cols(),
- &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(),
- const_cast<Scalar*>(m_matrix.data()), m_matrix.outerStride(), actualAlpha);
+ general_product_to_triangular_selector<MatrixType, ProductDerived, UpLo, (_Lhs::ColsAtCompileTime==1) || (_Rhs::RowsAtCompileTime==1)>::run(m_matrix.const_cast_derived(), prod.derived(), alpha);
return *this;
}
diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h
index ba1f73957db..09387703efa 100644
--- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -52,12 +52,17 @@ EIGEN_DONT_INLINE static void run(
Index rows, Index cols,
const LhsScalar* lhs, Index lhsStride,
const RhsScalar* rhs, Index rhsIncr,
- ResScalar* res, Index
- #ifdef EIGEN_INTERNAL_DEBUGGING
- resIncr
- #endif
- , RhsScalar alpha)
+ ResScalar* res, Index resIncr, RhsScalar alpha);
+};
+
+template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version>
+EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjugateLhs,RhsScalar,ConjugateRhs,Version>::run(
+ Index rows, Index cols,
+ const LhsScalar* lhs, Index lhsStride,
+ const RhsScalar* rhs, Index rhsIncr,
+ ResScalar* res, Index resIncr, RhsScalar alpha)
{
+ EIGEN_UNUSED_VARIABLE(resIncr)
eigen_internal_assert(resIncr==1);
#ifdef _EIGEN_ACCUMULATE_PACKETS
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
@@ -74,21 +79,21 @@ EIGEN_DONT_INLINE static void run(
conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
if(ConjugateRhs)
- alpha = conj(alpha);
+ alpha = numext::conj(alpha);
enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
const Index columnsAtOnce = 4;
const Index peels = 2;
const Index LhsPacketAlignedMask = LhsPacketSize-1;
const Index ResPacketAlignedMask = ResPacketSize-1;
- const Index PeelAlignedMask = ResPacketSize*peels-1;
+// const Index PeelAlignedMask = ResPacketSize*peels-1;
const Index size = rows;
// How many coeffs of the result do we have to skip to be aligned.
// Here we assume data are at least aligned on the base scalar type.
Index alignedStart = internal::first_aligned(res,size);
Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0;
- const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
+ const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
Index alignmentPattern = alignmentStep==0 ? AllAligned
@@ -177,6 +182,8 @@ EIGEN_DONT_INLINE static void run(
_EIGEN_ACCUMULATE_PACKETS(d,du,d);
break;
case FirstAligned:
+ {
+ Index j = alignedStart;
if(peels>1)
{
LhsPacket A00, A01, A02, A03, A10, A11, A12, A13;
@@ -186,7 +193,7 @@ EIGEN_DONT_INLINE static void run(
A02 = pload<LhsPacket>(&lhs2[alignedStart-2]);
A03 = pload<LhsPacket>(&lhs3[alignedStart-3]);
- for (Index j = alignedStart; j<peeledSize; j+=peels*ResPacketSize)
+ for (; j<peeledSize; j+=peels*ResPacketSize)
{
A11 = pload<LhsPacket>(&lhs1[j-1+LhsPacketSize]); palign<1>(A01,A11);
A12 = pload<LhsPacket>(&lhs2[j-2+LhsPacketSize]); palign<2>(A02,A12);
@@ -210,9 +217,10 @@ EIGEN_DONT_INLINE static void run(
pstore(&res[j+ResPacketSize],T1);
}
}
- for (Index j = peeledSize; j<alignedSize; j+=ResPacketSize)
+ for (; j<alignedSize; j+=ResPacketSize)
_EIGEN_ACCUMULATE_PACKETS(d,du,du);
break;
+ }
default:
for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
_EIGEN_ACCUMULATE_PACKETS(du,du,du);
@@ -250,7 +258,7 @@ EIGEN_DONT_INLINE static void run(
// process aligned result's coeffs
if ((size_t(lhs0+alignedStart)%sizeof(LhsPacket))==0)
for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
- pstore(&res[i], pcj.pmadd(ploadu<LhsPacket>(&lhs0[i]), ptmp0, pload<ResPacket>(&res[i])));
+ pstore(&res[i], pcj.pmadd(pload<LhsPacket>(&lhs0[i]), ptmp0, pload<ResPacket>(&res[i])));
else
for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
pstore(&res[i], pcj.pmadd(ploadu<LhsPacket>(&lhs0[i]), ptmp0, pload<ResPacket>(&res[i])));
@@ -271,7 +279,6 @@ EIGEN_DONT_INLINE static void run(
} while(Vectorizable);
#undef _EIGEN_ACCUMULATE_PACKETS
}
-};
/* Optimized row-major matrix * vector product:
* This algorithm processes 4 rows at onces that allows to both reduce
@@ -309,6 +316,15 @@ EIGEN_DONT_INLINE static void run(
const LhsScalar* lhs, Index lhsStride,
const RhsScalar* rhs, Index rhsIncr,
ResScalar* res, Index resIncr,
+ ResScalar alpha);
+};
+
+template<typename Index, typename LhsScalar, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version>
+EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjugateLhs,RhsScalar,ConjugateRhs,Version>::run(
+ Index rows, Index cols,
+ const LhsScalar* lhs, Index lhsStride,
+ const RhsScalar* rhs, Index rhsIncr,
+ ResScalar* res, Index resIncr,
ResScalar alpha)
{
EIGEN_UNUSED_VARIABLE(rhsIncr);
@@ -332,7 +348,7 @@ EIGEN_DONT_INLINE static void run(
const Index peels = 2;
const Index RhsPacketAlignedMask = RhsPacketSize-1;
const Index LhsPacketAlignedMask = LhsPacketSize-1;
- const Index PeelAlignedMask = RhsPacketSize*peels-1;
+// const Index PeelAlignedMask = RhsPacketSize*peels-1;
const Index depth = cols;
// How many coeffs of the result do we have to skip to be aligned.
@@ -340,7 +356,7 @@ EIGEN_DONT_INLINE static void run(
// if that's not the case then vectorization is discarded, see below.
Index alignedStart = internal::first_aligned(rhs, depth);
Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0;
- const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
+ const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
Index alignmentPattern = alignmentStep==0 ? AllAligned
@@ -430,10 +446,12 @@ EIGEN_DONT_INLINE static void run(
_EIGEN_ACCUMULATE_PACKETS(d,du,d);
break;
case FirstAligned:
+ {
+ Index j = alignedStart;
if (peels>1)
{
/* Here we proccess 4 rows with with two peeled iterations to hide
- * tghe overhead of unaligned loads. Moreover unaligned loads are handled
+ * the overhead of unaligned loads. Moreover unaligned loads are handled
* using special shift/move operations between the two aligned packets
* overlaping the desired unaligned packet. This is *much* more efficient
* than basic unaligned loads.
@@ -443,7 +461,7 @@ EIGEN_DONT_INLINE static void run(
A02 = pload<LhsPacket>(&lhs2[alignedStart-2]);
A03 = pload<LhsPacket>(&lhs3[alignedStart-3]);
- for (Index j = alignedStart; j<peeledSize; j+=peels*RhsPacketSize)
+ for (; j<peeledSize; j+=peels*RhsPacketSize)
{
RhsPacket b = pload<RhsPacket>(&rhs[j]);
A11 = pload<LhsPacket>(&lhs1[j-1+LhsPacketSize]); palign<1>(A01,A11);
@@ -465,9 +483,10 @@ EIGEN_DONT_INLINE static void run(
ptmp3 = pcj.pmadd(A13, b, ptmp3);
}
}
- for (Index j = peeledSize; j<alignedSize; j+=RhsPacketSize)
+ for (; j<alignedSize; j+=RhsPacketSize)
_EIGEN_ACCUMULATE_PACKETS(d,du,du);
break;
+ }
default:
for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
_EIGEN_ACCUMULATE_PACKETS(du,du,du);
@@ -539,7 +558,6 @@ EIGEN_DONT_INLINE static void run(
#undef _EIGEN_ACCUMULATE_PACKETS
}
-};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h
index e9de6af3ed1..1cb9fe6b5a7 100644
--- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h
@@ -53,7 +53,7 @@ struct general_matrix_vector_product_gemv :
#define EIGEN_MKL_GEMV_SPECIALIZE(Scalar) \
template<typename Index, bool ConjugateLhs, bool ConjugateRhs> \
struct general_matrix_vector_product<Index,Scalar,ColMajor,ConjugateLhs,Scalar,ConjugateRhs,Specialized> { \
-static EIGEN_DONT_INLINE void run( \
+static void run( \
Index rows, Index cols, \
const Scalar* lhs, Index lhsStride, \
const Scalar* rhs, Index rhsIncr, \
@@ -70,7 +70,7 @@ static EIGEN_DONT_INLINE void run( \
}; \
template<typename Index, bool ConjugateLhs, bool ConjugateRhs> \
struct general_matrix_vector_product<Index,Scalar,RowMajor,ConjugateLhs,Scalar,ConjugateRhs,Specialized> { \
-static EIGEN_DONT_INLINE void run( \
+static void run( \
Index rows, Index cols, \
const Scalar* lhs, Index lhsStride, \
const Scalar* rhs, Index rhsIncr, \
@@ -92,7 +92,7 @@ struct general_matrix_vector_product_gemv<Index,EIGTYPE,LhsStorageOrder,Conjugat
{ \
typedef Matrix<EIGTYPE,Dynamic,1,ColMajor> GEMVVector;\
\
-static EIGEN_DONT_INLINE void run( \
+static void run( \
Index rows, Index cols, \
const EIGTYPE* lhs, Index lhsStride, \
const EIGTYPE* rhs, Index rhsIncr, \
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
index 48209636eed..99cf9e0ae27 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
@@ -30,9 +30,9 @@ struct symm_pack_lhs
for(Index k=i; k<i+BlockRows; k++)
{
for(Index w=0; w<h; w++)
- blockA[count++] = conj(lhs(k, i+w)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
- blockA[count++] = real(lhs(k,k)); // real (diagonal)
+ blockA[count++] = numext::real(lhs(k,k)); // real (diagonal)
for(Index w=h+1; w<BlockRows; w++)
blockA[count++] = lhs(i+w, k); // normal
@@ -41,7 +41,7 @@ struct symm_pack_lhs
// transposed copy
for(Index k=i+BlockRows; k<cols; k++)
for(Index w=0; w<BlockRows; w++)
- blockA[count++] = conj(lhs(k, i+w)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
}
void operator()(Scalar* blockA, const Scalar* _lhs, Index lhsStride, Index cols, Index rows)
{
@@ -65,10 +65,10 @@ struct symm_pack_lhs
for(Index k=0; k<i; k++)
blockA[count++] = lhs(i, k); // normal
- blockA[count++] = real(lhs(i, i)); // real (diagonal)
+ blockA[count++] = numext::real(lhs(i, i)); // real (diagonal)
for(Index k=i+1; k<cols; k++)
- blockA[count++] = conj(lhs(k, i)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i)); // transposed
}
}
};
@@ -107,12 +107,12 @@ struct symm_pack_rhs
// transpose
for(Index k=k2; k<j2; k++)
{
- blockB[count+0] = conj(rhs(j2+0,k));
- blockB[count+1] = conj(rhs(j2+1,k));
+ blockB[count+0] = numext::conj(rhs(j2+0,k));
+ blockB[count+1] = numext::conj(rhs(j2+1,k));
if (nr==4)
{
- blockB[count+2] = conj(rhs(j2+2,k));
- blockB[count+3] = conj(rhs(j2+3,k));
+ blockB[count+2] = numext::conj(rhs(j2+2,k));
+ blockB[count+3] = numext::conj(rhs(j2+3,k));
}
count += nr;
}
@@ -124,11 +124,11 @@ struct symm_pack_rhs
for (Index w=0 ; w<h; ++w)
blockB[count+w] = rhs(k,j2+w);
- blockB[count+h] = real(rhs(k,k));
+ blockB[count+h] = numext::real(rhs(k,k));
// transpose
for (Index w=h+1 ; w<nr; ++w)
- blockB[count+w] = conj(rhs(j2+w,k));
+ blockB[count+w] = numext::conj(rhs(j2+w,k));
count += nr;
++h;
}
@@ -151,12 +151,12 @@ struct symm_pack_rhs
{
for(Index k=k2; k<end_k; k++)
{
- blockB[count+0] = conj(rhs(j2+0,k));
- blockB[count+1] = conj(rhs(j2+1,k));
+ blockB[count+0] = numext::conj(rhs(j2+0,k));
+ blockB[count+1] = numext::conj(rhs(j2+1,k));
if (nr==4)
{
- blockB[count+2] = conj(rhs(j2+2,k));
- blockB[count+3] = conj(rhs(j2+3,k));
+ blockB[count+2] = numext::conj(rhs(j2+2,k));
+ blockB[count+3] = numext::conj(rhs(j2+3,k));
}
count += nr;
}
@@ -169,13 +169,13 @@ struct symm_pack_rhs
Index half = (std::min)(end_k,j2);
for(Index k=k2; k<half; k++)
{
- blockB[count] = conj(rhs(j2,k));
+ blockB[count] = numext::conj(rhs(j2,k));
count += 1;
}
if(half==j2 && half<k2+rows)
{
- blockB[count] = real(rhs(j2,j2));
+ blockB[count] = numext::real(rhs(j2,j2));
count += 1;
}
else
@@ -211,7 +211,7 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,LhsSelfAdjoint,Co
const Scalar* lhs, Index lhsStride,
const Scalar* rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha)
+ const Scalar& alpha)
{
product_selfadjoint_matrix<Scalar, Index,
EIGEN_LOGICAL_XOR(RhsSelfAdjoint,RhsStorageOrder==RowMajor) ? ColMajor : RowMajor,
@@ -234,7 +234,18 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
const Scalar* _lhs, Index lhsStride,
const Scalar* _rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha)
+ const Scalar& alpha);
+};
+
+template <typename Scalar, typename Index,
+ int LhsStorageOrder, bool ConjugateLhs,
+ int RhsStorageOrder, bool ConjugateRhs>
+EIGEN_DONT_INLINE void product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs, RhsStorageOrder,false,ConjugateRhs,ColMajor>::run(
+ Index rows, Index cols,
+ const Scalar* _lhs, Index lhsStride,
+ const Scalar* _rhs, Index rhsStride,
+ Scalar* res, Index resStride,
+ const Scalar& alpha)
{
Index size = rows;
@@ -301,7 +312,6 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
}
}
}
-};
// matrix * selfadjoint product
template <typename Scalar, typename Index,
@@ -315,7 +325,18 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
const Scalar* _lhs, Index lhsStride,
const Scalar* _rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha)
+ const Scalar& alpha);
+};
+
+template <typename Scalar, typename Index,
+ int LhsStorageOrder, bool ConjugateLhs,
+ int RhsStorageOrder, bool ConjugateRhs>
+EIGEN_DONT_INLINE void product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLhs, RhsStorageOrder,true,ConjugateRhs,ColMajor>::run(
+ Index rows, Index cols,
+ const Scalar* _lhs, Index lhsStride,
+ const Scalar* _rhs, Index rhsStride,
+ Scalar* res, Index resStride,
+ const Scalar& alpha)
{
Index size = cols;
@@ -353,7 +374,6 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
}
}
}
-};
} // end namespace internal
@@ -383,7 +403,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>
RhsIsSelfAdjoint = (RhsMode&SelfAdjoint)==SelfAdjoint
};
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
index 4e5c4125c01..dfa687fefe6 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
@@ -23,7 +23,7 @@
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.
-
+//
********************************************************************************
* Content : Eigen bindings to Intel(R) MKL
* Self adjoint matrix * matrix product functionality based on ?SYMM/?HEMM.
@@ -47,7 +47,7 @@ template <typename Index, \
struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLhs,RhsStorageOrder,false,ConjugateRhs,ColMajor> \
{\
\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index rows, Index cols, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
@@ -98,7 +98,7 @@ template <typename Index, \
int RhsStorageOrder, bool ConjugateRhs> \
struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLhs,RhsStorageOrder,false,ConjugateRhs,ColMajor> \
{\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index rows, Index cols, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
@@ -174,7 +174,7 @@ template <typename Index, \
struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateLhs,RhsStorageOrder,true,ConjugateRhs,ColMajor> \
{\
\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index rows, Index cols, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
@@ -224,7 +224,7 @@ template <typename Index, \
int RhsStorageOrder, bool ConjugateRhs> \
struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateLhs,RhsStorageOrder,true,ConjugateRhs,ColMajor> \
{\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index rows, Index cols, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h
index c3145c69a5f..f698f67f9b0 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h
@@ -32,10 +32,18 @@ static EIGEN_DONT_INLINE void run(
const Scalar* lhs, Index lhsStride,
const Scalar* _rhs, Index rhsIncr,
Scalar* res,
+ Scalar alpha);
+};
+
+template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version>
+EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,Version>::run(
+ Index size,
+ const Scalar* lhs, Index lhsStride,
+ const Scalar* _rhs, Index rhsIncr,
+ Scalar* res,
Scalar alpha)
{
typedef typename packet_traits<Scalar>::type Packet;
- typedef typename NumTraits<Scalar>::Real RealScalar;
const Index PacketSize = sizeof(Packet)/sizeof(Scalar);
enum {
@@ -51,7 +59,7 @@ static EIGEN_DONT_INLINE void run(
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, IsRowMajor), ConjugateRhs> pcj0;
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> pcj1;
- Scalar cjAlpha = ConjugateRhs ? conj(alpha) : alpha;
+ Scalar cjAlpha = ConjugateRhs ? numext::conj(alpha) : alpha;
// FIXME this copy is now handled outside product_selfadjoint_vector, so it could probably be removed.
// if the rhs is not sequentially stored in memory we copy it to a temporary buffer,
@@ -71,8 +79,8 @@ static EIGEN_DONT_INLINE void run(
for (Index j=FirstTriangular ? bound : 0;
j<(FirstTriangular ? size : bound);j+=2)
{
- register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
- register const Scalar* EIGEN_RESTRICT A1 = lhs + (j+1)*lhsStride;
+ const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
+ const Scalar* EIGEN_RESTRICT A1 = lhs + (j+1)*lhsStride;
Scalar t0 = cjAlpha * rhs[j];
Packet ptmp0 = pset1<Packet>(t0);
@@ -90,8 +98,8 @@ static EIGEN_DONT_INLINE void run(
size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize);
// TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed
- res[j] += cjd.pmul(internal::real(A0[j]), t0);
- res[j+1] += cjd.pmul(internal::real(A1[j+1]), t1);
+ res[j] += cjd.pmul(numext::real(A0[j]), t0);
+ res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1);
if(FirstTriangular)
{
res[j] += cj0.pmul(A1[j], t1);
@@ -106,8 +114,8 @@ static EIGEN_DONT_INLINE void run(
for (size_t i=starti; i<alignedStart; ++i)
{
res[i] += t0 * A0[i] + t1 * A1[i];
- t2 += conj(A0[i]) * rhs[i];
- t3 += conj(A1[i]) * rhs[i];
+ t2 += numext::conj(A0[i]) * rhs[i];
+ t3 += numext::conj(A1[i]) * rhs[i];
}
// Yes this an optimization for gcc 4.3 and 4.4 (=> huge speed up)
// gcc 4.2 does this optimization automatically.
@@ -139,12 +147,12 @@ static EIGEN_DONT_INLINE void run(
}
for (Index j=FirstTriangular ? 0 : bound;j<(FirstTriangular ? bound : size);j++)
{
- register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
+ const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
Scalar t1 = cjAlpha * rhs[j];
Scalar t2(0);
// TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed
- res[j] += cjd.pmul(internal::real(A0[j]), t1);
+ res[j] += cjd.pmul(numext::real(A0[j]), t1);
for (Index i=FirstTriangular ? 0 : j+1; i<(FirstTriangular ? j : size); i++)
{
res[i] += cj0.pmul(A0[i], t1);
@@ -153,7 +161,6 @@ static EIGEN_DONT_INLINE void run(
res[j] += alpha * t2;
}
}
-};
} // end namespace internal
@@ -180,7 +187,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
typedef typename Dest::Scalar ResScalar;
typedef typename Base::RhsScalar RhsScalar;
@@ -260,7 +267,7 @@ struct SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false>
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
// let's simply transpose the product
Transpose<Dest> destT(dest);
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
index f88d483b653..86684b66d94 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
@@ -50,7 +50,7 @@ struct selfadjoint_matrix_vector_product_symv :
#define EIGEN_MKL_SYMV_SPECIALIZE(Scalar) \
template<typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs> \
struct selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,Specialized> { \
-static EIGEN_DONT_INLINE void run( \
+static void run( \
Index size, const Scalar* lhs, Index lhsStride, \
const Scalar* _rhs, Index rhsIncr, Scalar* res, Scalar alpha) { \
enum {\
@@ -77,7 +77,7 @@ struct selfadjoint_matrix_vector_product_symv<EIGTYPE,Index,StorageOrder,UpLo,Co
{ \
typedef Matrix<EIGTYPE,Dynamic,1,ColMajor> SYMVVector;\
\
-static EIGEN_DONT_INLINE void run( \
+static void run( \
Index size, const EIGTYPE* lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* res, EIGTYPE alpha) \
{ \
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h
index 6a55f3d7715..6ca4ae6c0fe 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h
@@ -18,21 +18,19 @@
namespace Eigen {
-template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>
-struct selfadjoint_rank1_update;
template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
struct selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRhs>
{
- static void run(Index size, Scalar* mat, Index stride, const Scalar* vec, Scalar alpha)
+ static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha)
{
internal::conj_if<ConjRhs> cj;
typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;
- typedef typename internal::conditional<ConjLhs,typename OtherMap::ConjugateReturnType,const OtherMap&>::type ConjRhsType;
+ typedef typename internal::conditional<ConjLhs,typename OtherMap::ConjugateReturnType,const OtherMap&>::type ConjLhsType;
for (Index i=0; i<size; ++i)
{
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+(UpLo==Lower ? i : 0), (UpLo==Lower ? size-i : (i+1)))
- += (alpha * cj(vec[i])) * ConjRhsType(OtherMap(vec+(UpLo==Lower ? i : 0),UpLo==Lower ? size-i : (i+1)));
+ += (alpha * cj(vecY[i])) * ConjLhsType(OtherMap(vecX+(UpLo==Lower ? i : 0),UpLo==Lower ? size-i : (i+1)));
}
}
};
@@ -40,9 +38,9 @@ struct selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRhs>
template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
struct selfadjoint_rank1_update<Scalar,Index,RowMajor,UpLo,ConjLhs,ConjRhs>
{
- static void run(Index size, Scalar* mat, Index stride, const Scalar* vec, Scalar alpha)
+ static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha)
{
- selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo==Lower?Upper:Lower,ConjRhs,ConjLhs>::run(size,mat,stride,vec,alpha);
+ selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo==Lower?Upper:Lower,ConjRhs,ConjLhs>::run(size,mat,stride,vecY,vecX,alpha);
}
};
@@ -52,7 +50,7 @@ struct selfadjoint_product_selector;
template<typename MatrixType, typename OtherType, int UpLo>
struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
{
- static void run(MatrixType& mat, const OtherType& other, typename MatrixType::Scalar alpha)
+ static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Index Index;
@@ -78,14 +76,14 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
(!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
- ::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualAlpha);
+ ::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualOtherPtr, actualAlpha);
}
};
template<typename MatrixType, typename OtherType, int UpLo>
struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
{
- static void run(MatrixType& mat, const OtherType& other, typename MatrixType::Scalar alpha)
+ static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Index Index;
@@ -113,7 +111,7 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
template<typename MatrixType, unsigned int UpLo>
template<typename DerivedU>
SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
-::rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha)
+::rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha)
{
selfadjoint_product_selector<MatrixType,DerivedU,UpLo>::run(_expression().const_cast_derived(), u.derived(), alpha);
diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h
index 57a98cc2de9..8594a97cea3 100644
--- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h
+++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h
@@ -24,14 +24,14 @@ struct selfadjoint_rank2_update_selector;
template<typename Scalar, typename Index, typename UType, typename VType>
struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
{
- static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
+ static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
{
const Index size = u.size();
for (Index i=0; i<size; ++i)
{
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
- (conj(alpha) * conj(u.coeff(i))) * v.tail(size-i)
- + (alpha * conj(v.coeff(i))) * u.tail(size-i);
+ (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.tail(size-i)
+ + (alpha * numext::conj(v.coeff(i))) * u.tail(size-i);
}
}
};
@@ -39,13 +39,13 @@ struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
template<typename Scalar, typename Index, typename UType, typename VType>
struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
{
- static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha)
+ static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
{
const Index size = u.size();
for (Index i=0; i<size; ++i)
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
- (conj(alpha) * conj(u.coeff(i))) * v.head(i+1)
- + (alpha * conj(v.coeff(i))) * u.head(i+1);
+ (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.head(i+1)
+ + (alpha * numext::conj(v.coeff(i))) * u.head(i+1);
}
};
@@ -58,7 +58,7 @@ template<bool Cond, typename T> struct conj_expr_if
template<typename MatrixType, unsigned int UpLo>
template<typename DerivedU, typename DerivedV>
SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
-::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha)
+::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha)
{
typedef internal::blas_traits<DerivedU> UBlasTraits;
typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
@@ -75,9 +75,9 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
- * internal::conj(VBlasTraits::extractScalarFactor(v.derived()));
+ * numext::conj(VBlasTraits::extractScalarFactor(v.derived()));
if (IsRowMajor)
- actualAlpha = internal::conj(actualAlpha);
+ actualAlpha = numext::conj(actualAlpha);
internal::selfadjoint_rank2_update_selector<Scalar, Index,
typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type,
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h
index 92cba66f615..8110507b50b 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -61,7 +61,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,LhsIsTriangular,
const Scalar* lhs, Index lhsStride,
const Scalar* rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha, level3_blocking<Scalar,Scalar>& blocking)
+ const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
{
product_triangular_matrix_matrix<Scalar, Index,
(Mode&(UnitDiag|ZeroDiag)) | ((Mode&Upper) ? Lower : Upper),
@@ -96,7 +96,20 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
const Scalar* _lhs, Index lhsStride,
const Scalar* _rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha, level3_blocking<Scalar,Scalar>& blocking)
+ const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
+};
+
+template <typename Scalar, typename Index, int Mode,
+ int LhsStorageOrder, bool ConjugateLhs,
+ int RhsStorageOrder, bool ConjugateRhs, int Version>
+EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,true,
+ LhsStorageOrder,ConjugateLhs,
+ RhsStorageOrder,ConjugateRhs,ColMajor,Version>::run(
+ Index _rows, Index _cols, Index _depth,
+ const Scalar* _lhs, Index lhsStride,
+ const Scalar* _rhs, Index rhsStride,
+ Scalar* res, Index resStride,
+ const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
{
// strip zeros
Index diagSize = (std::min)(_rows,_depth);
@@ -203,15 +216,14 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
}
}
}
-};
// implements col-major += alpha * op(general) * op(triangular)
template <typename Scalar, typename Index, int Mode,
int LhsStorageOrder, bool ConjugateLhs,
int RhsStorageOrder, bool ConjugateRhs, int Version>
struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
- LhsStorageOrder,ConjugateLhs,
- RhsStorageOrder,ConjugateRhs,ColMajor,Version>
+ LhsStorageOrder,ConjugateLhs,
+ RhsStorageOrder,ConjugateRhs,ColMajor,Version>
{
typedef gebp_traits<Scalar,Scalar> Traits;
enum {
@@ -225,7 +237,20 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
const Scalar* _lhs, Index lhsStride,
const Scalar* _rhs, Index rhsStride,
Scalar* res, Index resStride,
- Scalar alpha, level3_blocking<Scalar,Scalar>& blocking)
+ const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
+};
+
+template <typename Scalar, typename Index, int Mode,
+ int LhsStorageOrder, bool ConjugateLhs,
+ int RhsStorageOrder, bool ConjugateRhs, int Version>
+EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,false,
+ LhsStorageOrder,ConjugateLhs,
+ RhsStorageOrder,ConjugateRhs,ColMajor,Version>::run(
+ Index _rows, Index _cols, Index _depth,
+ const Scalar* _lhs, Index lhsStride,
+ const Scalar* _rhs, Index rhsStride,
+ Scalar* res, Index resStride,
+ const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
{
// strip zeros
Index diagSize = (std::min)(_cols,_depth);
@@ -343,7 +368,6 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
}
}
}
-};
/***************************************************************************
* Wrapper to product_triangular_matrix_matrix
@@ -364,7 +388,7 @@ struct TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs);
typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs);
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
index 8173da5bb6d..ba41a1c99f6 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
@@ -57,11 +57,11 @@ template <typename Index, int Mode, \
struct product_triangular_matrix_matrix<Scalar,Index, Mode, LhsIsTriangular, \
LhsStorageOrder,ConjugateLhs, RhsStorageOrder,ConjugateRhs,ColMajor,Specialized> { \
static inline void run(Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride,\
- const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) { \
+ const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking<Scalar,Scalar>& blocking) { \
product_triangular_matrix_matrix_trmm<Scalar,Index,Mode, \
LhsIsTriangular,LhsStorageOrder,ConjugateLhs, \
RhsStorageOrder, ConjugateRhs, ColMajor>::run( \
- _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \
+ _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \
} \
};
@@ -91,12 +91,12 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
conjA = ((LhsStorageOrder==ColMajor) && ConjugateLhs) ? 1 : 0 \
}; \
\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index _rows, Index _cols, Index _depth, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
EIGTYPE* res, Index resStride, \
- EIGTYPE alpha) \
+ EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \
{ \
Index diagSize = (std::min)(_rows,_depth); \
Index rows = IsLower ? _rows : diagSize; \
@@ -115,16 +115,16 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
product_triangular_matrix_matrix<EIGTYPE,Index,Mode,true, \
LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, BuiltIn>::run( \
- _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \
+ _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \
/*std::cout << "TRMM_L: A is not square! Go to Eigen TRMM implementation!\n";*/ \
} else { \
/* Make sense to call GEMM */ \
Map<const MatrixLhs, 0, OuterStride<> > lhsMap(_lhs,rows,depth,OuterStride<>(lhsStride)); \
MatrixLhs aa_tmp=lhsMap.template triangularView<Mode>(); \
MKL_INT aStride = aa_tmp.outerStride(); \
- gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> blocking(_rows,_cols,_depth); \
+ gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> gemm_blocking(_rows,_cols,_depth); \
general_matrix_matrix_product<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,RhsStorageOrder,ConjugateRhs,ColMajor>::run( \
- rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, blocking, 0); \
+ rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, gemm_blocking, 0); \
\
/*std::cout << "TRMM_L: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \
} \
@@ -205,12 +205,12 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
conjA = ((RhsStorageOrder==ColMajor) && ConjugateRhs) ? 1 : 0 \
}; \
\
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index _rows, Index _cols, Index _depth, \
const EIGTYPE* _lhs, Index lhsStride, \
const EIGTYPE* _rhs, Index rhsStride, \
EIGTYPE* res, Index resStride, \
- EIGTYPE alpha) \
+ EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \
{ \
Index diagSize = (std::min)(_cols,_depth); \
Index rows = _rows; \
@@ -229,16 +229,16 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
product_triangular_matrix_matrix<EIGTYPE,Index,Mode,false, \
LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, BuiltIn>::run( \
- _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \
+ _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \
/*std::cout << "TRMM_R: A is not square! Go to Eigen TRMM implementation!\n";*/ \
} else { \
/* Make sense to call GEMM */ \
Map<const MatrixRhs, 0, OuterStride<> > rhsMap(_rhs,depth,cols, OuterStride<>(rhsStride)); \
MatrixRhs aa_tmp=rhsMap.template triangularView<Mode>(); \
MKL_INT aStride = aa_tmp.outerStride(); \
- gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> blocking(_rows,_cols,_depth); \
+ gemm_blocking_space<ColMajor,EIGTYPE,EIGTYPE,Dynamic,Dynamic,Dynamic> gemm_blocking(_rows,_cols,_depth); \
general_matrix_matrix_product<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,RhsStorageOrder,ConjugateRhs,ColMajor>::run( \
- rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, blocking, 0); \
+ rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, gemm_blocking, 0); \
\
/*std::cout << "TRMM_R: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \
} \
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h
index b1c10c201c5..6117d5a8262 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -27,7 +27,13 @@ struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
};
static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
- const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
+ const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha);
+};
+
+template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version>
+EIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
+ ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
+ const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha)
{
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
Index size = (std::min)(_rows,_cols);
@@ -78,7 +84,6 @@ struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
_res, resIncr, alpha);
}
}
-};
template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
@@ -89,8 +94,14 @@ struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
HasUnitDiag = (Mode & UnitDiag)==UnitDiag,
HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
};
- static void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
- const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
+ static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
+ const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha);
+};
+
+template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
+EIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
+ ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
+ const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha)
{
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
Index diagSize = (std::min)(_rows,_cols);
@@ -141,7 +152,6 @@ struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
&res.coeffRef(diagSize), resIncr, alpha);
}
}
-};
/***************************************************************************
* Wrapper to product_triangular_vector
@@ -171,7 +181,7 @@ struct TriangularProduct<Mode,true,Lhs,false,Rhs,true>
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
@@ -187,7 +197,7 @@ struct TriangularProduct<Mode,false,Lhs,true,Rhs,false>
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
- template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
{
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
@@ -205,7 +215,7 @@ namespace internal {
template<> struct trmv_selector<ColMajor>
{
template<int Mode, typename Lhs, typename Rhs, typename Dest>
- static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar alpha)
+ static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, const typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar& alpha)
{
typedef TriangularProduct<Mode,true,Lhs,false,Rhs,true> ProductType;
typedef typename ProductType::Index Index;
@@ -235,7 +245,7 @@ template<> struct trmv_selector<ColMajor>
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
- bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0));
+ bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
@@ -246,7 +256,7 @@ template<> struct trmv_selector<ColMajor>
if(!evalToDest)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
- int size = dest.size();
+ Index size = dest.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
if(!alphaIsCompatible)
@@ -281,7 +291,7 @@ template<> struct trmv_selector<ColMajor>
template<> struct trmv_selector<RowMajor>
{
template<int Mode, typename Lhs, typename Rhs, typename Dest>
- static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar alpha)
+ static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, const typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar& alpha)
{
typedef TriangularProduct<Mode,true,Lhs,false,Rhs,true> ProductType;
typedef typename ProductType::LhsScalar LhsScalar;
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h
index 3589b8c5ef6..09f110da712 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h
@@ -50,7 +50,7 @@ struct triangular_matrix_vector_product_trmv :
#define EIGEN_MKL_TRMV_SPECIALIZE(Scalar) \
template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \
struct triangular_matrix_vector_product<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,ColMajor,Specialized> { \
- static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \
+ static void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \
const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \
triangular_matrix_vector_product_trmv<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,ColMajor>::run( \
_rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \
@@ -58,7 +58,7 @@ struct triangular_matrix_vector_product<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs
}; \
template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \
struct triangular_matrix_vector_product<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,RowMajor,Specialized> { \
- static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \
+ static void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \
const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \
triangular_matrix_vector_product_trmv<Index,Mode,Scalar,ConjLhs,Scalar,ConjRhs,RowMajor>::run( \
_rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \
@@ -81,12 +81,12 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \
LowUp = IsLower ? Lower : Upper \
}; \
- static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \
- const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \
+ static void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \
+ const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha) \
{ \
if (ConjLhs || IsZeroDiag) { \
triangular_matrix_vector_product<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,ColMajor,BuiltIn>::run( \
- _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \
+ _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \
return; \
}\
Index size = (std::min)(_rows,_cols); \
@@ -166,12 +166,12 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \
LowUp = IsLower ? Lower : Upper \
}; \
- static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \
- const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking<EIGTYPE,EIGTYPE>& blocking) \
+ static void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \
+ const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha) \
{ \
if (IsZeroDiag) { \
triangular_matrix_vector_product<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,RowMajor,BuiltIn>::run( \
- _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \
+ _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \
return; \
}\
Index size = (std::min)(_rows,_cols); \
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h
index a49ea318345..f103eae72c0 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h
@@ -18,7 +18,7 @@ namespace internal {
template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder>
struct triangular_solve_matrix<Scalar,Index,Side,Mode,Conjugate,TriStorageOrder,RowMajor>
{
- static EIGEN_DONT_INLINE void run(
+ static void run(
Index size, Index cols,
const Scalar* tri, Index triStride,
Scalar* _other, Index otherStride,
@@ -42,6 +42,13 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
Index size, Index otherSize,
const Scalar* _tri, Index triStride,
Scalar* _other, Index otherStride,
+ level3_blocking<Scalar,Scalar>& blocking);
+};
+template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
+EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageOrder,ColMajor>::run(
+ Index size, Index otherSize,
+ const Scalar* _tri, Index triStride,
+ Scalar* _other, Index otherStride,
level3_blocking<Scalar,Scalar>& blocking)
{
Index cols = otherSize;
@@ -173,7 +180,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
}
}
}
-};
/* Optimized triangular solver with multiple left hand sides and the trinagular matrix on the right
*/
@@ -184,6 +190,13 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
Index size, Index otherSize,
const Scalar* _tri, Index triStride,
Scalar* _other, Index otherStride,
+ level3_blocking<Scalar,Scalar>& blocking);
+};
+template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
+EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor>::run(
+ Index size, Index otherSize,
+ const Scalar* _tri, Index triStride,
+ Scalar* _other, Index otherStride,
level3_blocking<Scalar,Scalar>& blocking)
{
Index rows = otherSize;
@@ -308,7 +321,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
}
}
}
-};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
index a4f508b2e83..6a0bb833931 100644
--- a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
+++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
@@ -48,7 +48,7 @@ struct triangular_solve_matrix<EIGTYPE,Index,OnTheLeft,Mode,Conjugate,TriStorage
IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \
conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \
}; \
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index size, Index otherSize, \
const EIGTYPE* _tri, Index triStride, \
EIGTYPE* _other, Index otherStride, level3_blocking<EIGTYPE,EIGTYPE>& /*blocking*/) \
@@ -103,7 +103,7 @@ struct triangular_solve_matrix<EIGTYPE,Index,OnTheRight,Mode,Conjugate,TriStorag
IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \
conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \
}; \
- static EIGEN_DONT_INLINE void run( \
+ static void run( \
Index size, Index otherSize, \
const EIGTYPE* _tri, Index triStride, \
EIGTYPE* _other, Index otherStride, level3_blocking<EIGTYPE,EIGTYPE>& /*blocking*/) \
diff --git a/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h b/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h
index 91496651c82..a28f16fa04b 100644
--- a/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h
+++ b/extern/Eigen3/Eigen/src/Core/util/BlasUtil.h
@@ -42,7 +42,7 @@ template<bool Conjugate> struct conj_if;
template<> struct conj_if<true> {
template<typename T>
- inline T operator()(const T& x) { return conj(x); }
+ inline T operator()(const T& x) { return numext::conj(x); }
template<typename T>
inline T pconj(const T& x) { return internal::pconj(x); }
};
@@ -67,7 +67,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) + imag(x)*imag(y), imag(x)*real(y) - real(x)*imag(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); }
};
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
@@ -77,7 +77,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) + imag(x)*imag(y), real(x)*imag(y) - imag(x)*real(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
};
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
@@ -87,7 +87,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) - imag(x)*imag(y), - real(x)*imag(y) - imag(x)*real(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
};
template<typename RealScalar,bool Conj> struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
@@ -113,7 +113,7 @@ template<typename From,typename To> struct get_factor {
};
template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
- static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return real(x); }
+ static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
};
// Lightweight helper class to access matrix coefficients.
diff --git a/extern/Eigen3/Eigen/src/Core/util/Constants.h b/extern/Eigen3/Eigen/src/Core/util/Constants.h
index 3fd45e84f8e..14b9624e1d9 100644
--- a/extern/Eigen3/Eigen/src/Core/util/Constants.h
+++ b/extern/Eigen3/Eigen/src/Core/util/Constants.h
@@ -13,13 +13,18 @@
namespace Eigen {
-/** This value means that a quantity is not known at compile-time, and that instead the value is
+/** This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is
* stored in some runtime variable.
*
* Changing the value of Dynamic breaks the ABI, as Dynamic is often used as a template parameter for Matrix.
*/
const int Dynamic = -1;
+/** This value means that a signed quantity (e.g., a signed index) is not known at compile-time, and that instead its value
+ * has to be specified at runtime.
+ */
+const int DynamicIndex = 0xffffff;
+
/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
* The value Infinity there means the L-infinity norm.
*/
@@ -227,7 +232,9 @@ enum {
* scalar loops to handle the unaligned boundaries */
SliceVectorizedTraversal,
/** \internal Special case to properly handle incompatible scalar types or other defecting cases*/
- InvalidTraversal
+ InvalidTraversal,
+ /** \internal Evaluate all entries at once */
+ AllAtOnceTraversal
};
/** \internal \ingroup enums
@@ -257,9 +264,9 @@ enum {
ColMajor = 0,
/** Storage order is row major (see \ref TopicStorageOrders). */
RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
- /** \internal Align the matrix itself if it is vectorizable fixed-size */
+ /** Align the matrix itself if it is vectorizable fixed-size */
AutoAlign = 0,
- /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
+ /** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
DontAlign = 0x2
};
diff --git a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h
index bcdfe3914e3..d6a814586d3 100644
--- a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h
@@ -78,8 +78,7 @@ template<typename ExpressionType> class NestByValue;
template<typename ExpressionType> class ForceAlignedAccess;
template<typename ExpressionType> class SwapWrapper;
-template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
- bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class Block;
+template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
template<typename MatrixType, int Size=Dynamic> class VectorBlock;
template<typename MatrixType> class Transpose;
@@ -154,7 +153,6 @@ template<typename LhsScalar, typename RhsScalar, bool ConjLhs=false, bool ConjRh
template<typename Scalar> struct scalar_sum_op;
template<typename Scalar> struct scalar_difference_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op;
-template<typename Scalar> struct scalar_quotient_op;
template<typename Scalar> struct scalar_opposite_op;
template<typename Scalar> struct scalar_conjugate_op;
template<typename Scalar> struct scalar_real_op;
@@ -185,6 +183,7 @@ template<typename Scalar> struct scalar_identity_op;
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_multiple2_op;
+template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_quotient_op;
} // end namespace internal
@@ -271,6 +270,8 @@ template<typename Derived> struct MatrixExponentialReturnValue;
template<typename Derived> class MatrixFunctionReturnValue;
template<typename Derived> class MatrixSquareRootReturnValue;
template<typename Derived> class MatrixLogarithmReturnValue;
+template<typename Derived> class MatrixPowerReturnValue;
+template<typename Derived, typename Lhs, typename Rhs> class MatrixPowerProduct;
namespace internal {
template <typename Scalar>
diff --git a/extern/Eigen3/Eigen/src/Core/util/Macros.h b/extern/Eigen3/Eigen/src/Core/util/Macros.h
index d973a68372f..0088621acf7 100644
--- a/extern/Eigen3/Eigen/src/Core/util/Macros.h
+++ b/extern/Eigen3/Eigen/src/Core/util/Macros.h
@@ -12,7 +12,7 @@
#define EIGEN_MACROS_H
#define EIGEN_WORLD_VERSION 3
-#define EIGEN_MAJOR_VERSION 1
+#define EIGEN_MAJOR_VERSION 2
#define EIGEN_MINOR_VERSION 1
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
@@ -115,12 +115,6 @@
#define EIGEN_MAKESTRING2(a) #a
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
-#if EIGEN_GNUC_AT_LEAST(4,1) && !defined(__clang__) && !defined(__INTEL_COMPILER)
-#define EIGEN_FLATTEN_ATTRIB __attribute__((flatten))
-#else
-#define EIGEN_FLATTEN_ATTRIB
-#endif
-
// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
// but GCC is still doing fine with just inline.
@@ -151,6 +145,12 @@
#define EIGEN_DONT_INLINE
#endif
+#if (defined __GNUC__)
+#define EIGEN_PERMISSIVE_EXPR __extension__
+#else
+#define EIGEN_PERMISSIVE_EXPR
+#endif
+
// this macro allows to get rid of linking errors about multiply defined functions.
// - static is not very good because it prevents definitions from different object files to be merged.
// So static causes the resulting linked executable to be bloated with multiple copies of the same function.
@@ -238,12 +238,19 @@
#endif
// Suppresses 'unused variable' warnings.
-#define EIGEN_UNUSED_VARIABLE(var) (void)var;
+namespace Eigen {
+ namespace internal {
+ template<typename T> void ignore_unused_variable(const T&) {}
+ }
+}
+#define EIGEN_UNUSED_VARIABLE(var) Eigen::internal::ignore_unused_variable(var);
-#if !defined(EIGEN_ASM_COMMENT) && (defined __GNUC__)
-#define EIGEN_ASM_COMMENT(X) asm("#" X)
-#else
-#define EIGEN_ASM_COMMENT(X)
+#if !defined(EIGEN_ASM_COMMENT)
+ #if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+ #define EIGEN_ASM_COMMENT(X) asm("#" X)
+ #else
+ #define EIGEN_ASM_COMMENT(X)
+ #endif
#endif
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
@@ -301,6 +308,12 @@
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
using Base::operator =;
+#elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
+#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
+ using Base::operator =; \
+ EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
+ template <typename OtherDerived> \
+ EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
#else
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
using Base::operator =; \
diff --git a/extern/Eigen3/Eigen/src/Core/util/Memory.h b/extern/Eigen3/Eigen/src/Core/util/Memory.h
index 6e06ace44a0..cacbd02fd12 100644
--- a/extern/Eigen3/Eigen/src/Core/util/Memory.h
+++ b/extern/Eigen3/Eigen/src/Core/util/Memory.h
@@ -19,6 +19,10 @@
#ifndef EIGEN_MEMORY_H
#define EIGEN_MEMORY_H
+#ifndef EIGEN_MALLOC_ALREADY_ALIGNED
+
+// Try to determine automatically if malloc is already aligned.
+
// On 64-bit systems, glibc's malloc returns 16-byte-aligned pointers, see:
// http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html
// This is true at least since glibc 2.8.
@@ -27,7 +31,7 @@
// page 114, "[The] LP64 model [...] is used by all 64-bit UNIX ports" so it's indeed
// quite safe, at least within the context of glibc, to equate 64-bit with LP64.
#if defined(__GLIBC__) && ((__GLIBC__>=2 && __GLIBC_MINOR__ >= 8) || __GLIBC__>2) \
- && defined(__LP64__)
+ && defined(__LP64__) && ! defined( __SANITIZE_ADDRESS__ )
#define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 1
#else
#define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 0
@@ -52,10 +56,19 @@
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
#endif
-#if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) \
- && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
- #define EIGEN_HAS_POSIX_MEMALIGN 1
-#else
+#endif
+
+// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554)
+// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first.
+// Currently, let's include it only on unix systems:
+#if defined(__unix__) || defined(__unix)
+ #include <unistd.h>
+ #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
+ #define EIGEN_HAS_POSIX_MEMALIGN 1
+ #endif
+#endif
+
+#ifndef EIGEN_HAS_POSIX_MEMALIGN
#define EIGEN_HAS_POSIX_MEMALIGN 0
#endif
@@ -88,11 +101,11 @@ inline void throw_std_bad_alloc()
/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
* Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
*/
-inline void* handmade_aligned_malloc(size_t size)
+inline void* handmade_aligned_malloc(std::size_t size)
{
void *original = std::malloc(size+16);
if (original == 0) return 0;
- void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
+ void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -108,13 +121,18 @@ inline void handmade_aligned_free(void *ptr)
* Since we know that our handmade version is based on std::realloc
* we can use std::realloc to implement efficient reallocation.
*/
-inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
+inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
{
if (ptr == 0) return handmade_aligned_malloc(size);
void *original = *(reinterpret_cast<void**>(ptr) - 1);
+ std::ptrdiff_t previous_offset = static_cast<char *>(ptr)-static_cast<char *>(original);
original = std::realloc(original,size+16);
if (original == 0) return 0;
- void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
+ void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
+ void *previous_aligned = static_cast<char *>(original)+previous_offset;
+ if(aligned!=previous_aligned)
+ std::memmove(aligned, previous_aligned, size);
+
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -123,7 +141,7 @@ inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
*** Implementation of generic aligned realloc (when no realloc can be used)***
*****************************************************************************/
-void* aligned_malloc(size_t size);
+void* aligned_malloc(std::size_t size);
void aligned_free(void *ptr);
/** \internal
@@ -204,7 +222,7 @@ inline void* aligned_malloc(size_t size)
if(posix_memalign(&result, 16, size)) result = 0;
#elif EIGEN_HAS_MM_MALLOC
result = _mm_malloc(size, 16);
- #elif (defined _MSC_VER)
+ #elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
result = _aligned_malloc(size, 16);
#else
result = handmade_aligned_malloc(size);
@@ -227,7 +245,7 @@ inline void aligned_free(void *ptr)
std::free(ptr);
#elif EIGEN_HAS_MM_MALLOC
_mm_free(ptr);
- #elif defined(_MSC_VER)
+ #elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
_aligned_free(ptr);
#else
handmade_aligned_free(ptr);
@@ -446,7 +464,6 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T *
template<typename Scalar, typename Index>
static inline Index first_aligned(const Scalar* array, Index size)
{
- typedef typename packet_traits<Scalar>::type Packet;
enum { PacketSize = packet_traits<Scalar>::size,
PacketAlignedMask = PacketSize-1
};
@@ -470,6 +487,13 @@ static inline Index first_aligned(const Scalar* array, Index size)
}
}
+/** \internal Returns the smallest integer multiple of \a base and greater or equal to \a size
+ */
+template<typename Index>
+inline static Index first_multiple(Index size, Index base)
+{
+ return ((size+base-1)/base)*base;
+}
// std::copy is much slower than memcpy, so let's introduce a smart_copy which
// use memcpy on trivial types, i.e., on types that does not require an initialization ctor.
@@ -554,7 +578,7 @@ template<typename T> class aligned_stack_memory_handler
*/
#ifdef EIGEN_ALLOCA
- #ifdef __arm__
+ #if defined(__arm__) || defined(_WIN32)
#define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast<void*>((reinterpret_cast<size_t>(EIGEN_ALLOCA(SIZE+16)) & ~(size_t(15))) + 16)
#else
#define EIGEN_ALIGNED_ALLOCA EIGEN_ALLOCA
@@ -610,7 +634,9 @@ template<typename T> class aligned_stack_memory_handler
/* memory allocated we can safely let the default implementation handle */ \
/* this particular case. */ \
static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \
+ static void *operator new[](size_t size, void* ptr) { return ::operator new[](size,ptr); } \
void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \
+ void operator delete[](void * memory, void *ptr) throw() { return ::operator delete[](memory,ptr); } \
/* nothrow-new (returns zero instead of std::bad_alloc) */ \
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void operator delete(void *ptr, const std::nothrow_t&) throw() { \
@@ -705,15 +731,6 @@ public:
::new( p ) T( value );
}
- // Support for c++11
-#if (__cplusplus >= 201103L)
- template<typename... Args>
- void construct(pointer p, Args&&... args)
- {
- ::new(p) T(std::forward<Args>(args)...);
- }
-#endif
-
void destroy( pointer p )
{
p->~T();
@@ -738,14 +755,19 @@ public:
# if defined(__PIC__) && defined(__i386__)
// Case for x86 with PIC
# define EIGEN_CPUID(abcd,func,id) \
- __asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
+ __asm__ __volatile__ ("xchgl %%ebx, %k1;cpuid; xchgl %%ebx,%k1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
+# elif defined(__PIC__) && defined(__x86_64__)
+ // Case for x64 with PIC. In theory this is only a problem with recent gcc and with medium or large code model, not with the default small code model.
+ // However, we cannot detect which code model is used, and the xchg overhead is negligible anyway.
+# define EIGEN_CPUID(abcd,func,id) \
+ __asm__ __volatile__ ("xchg{q}\t{%%}rbx, %q1; cpuid; xchg{q}\t{%%}rbx, %q1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id));
# else
// Case for x86_64 or x86 w/o PIC
# define EIGEN_CPUID(abcd,func,id) \
- __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) );
+ __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id) );
# endif
# elif defined(_MSC_VER)
-# if (_MSC_VER > 1500)
+# if (_MSC_VER > 1500) && ( defined(_M_IX86) || defined(_M_X64) )
# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id)
# endif
# endif
diff --git a/extern/Eigen3/Eigen/src/Core/util/Meta.h b/extern/Eigen3/Eigen/src/Core/util/Meta.h
index a5f31164d15..71d58710871 100644
--- a/extern/Eigen3/Eigen/src/Core/util/Meta.h
+++ b/extern/Eigen3/Eigen/src/Core/util/Meta.h
@@ -186,23 +186,35 @@ template<int Y, int InfX, int SupX>
class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
-template<typename T, typename U> struct scalar_product_traits;
+template<typename T, typename U> struct scalar_product_traits
+{
+ enum { Defined = 0 };
+};
template<typename T> struct scalar_product_traits<T,T>
{
- //enum { Cost = NumTraits<T>::MulCost };
+ enum {
+ // Cost = NumTraits<T>::MulCost,
+ Defined = 1
+ };
typedef T ReturnType;
};
template<typename T> struct scalar_product_traits<T,std::complex<T> >
{
- //enum { Cost = 2*NumTraits<T>::MulCost };
+ enum {
+ // Cost = 2*NumTraits<T>::MulCost,
+ Defined = 1
+ };
typedef std::complex<T> ReturnType;
};
template<typename T> struct scalar_product_traits<std::complex<T>, T>
{
- //enum { Cost = 2*NumTraits<T>::MulCost };
+ enum {
+ // Cost = 2*NumTraits<T>::MulCost,
+ Defined = 1
+ };
typedef std::complex<T> ReturnType;
};
diff --git a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h
index b46a75b3783..8872c5b648e 100644
--- a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h
+++ b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h
@@ -89,7 +89,8 @@
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED,
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
- THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH
+ THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
+ OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
};
};
diff --git a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h
index 2a65c7cbfa4..3c4773054b4 100644
--- a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h
+++ b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h
@@ -65,12 +65,34 @@ template<typename T> class variable_if_dynamic<T, Dynamic>
void setValue(T value) { m_value = value; }
};
+/** \internal like variable_if_dynamic but for DynamicIndex
+ */
+template<typename T, int Value> class variable_if_dynamicindex
+{
+ public:
+ EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
+ explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); assert(v == T(Value)); }
+ static T value() { return T(Value); }
+ void setValue(T) {}
+};
+
+template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
+{
+ T m_value;
+ variable_if_dynamicindex() { assert(false); }
+ public:
+ explicit variable_if_dynamicindex(T value) : m_value(value) {}
+ T value() const { return m_value; }
+ void setValue(T value) { m_value = value; }
+};
+
template<typename T> struct functor_traits
{
enum
{
Cost = 10,
- PacketAccess = false
+ PacketAccess = false,
+ IsRepeatable = false
};
};
@@ -301,9 +323,9 @@ template<typename T, int n=1, typename PlainObject = typename eval<T>::type> str
// it's important that this value can still be squared without integer overflowing.
DynamicAsInteger = 10000,
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
- ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? DynamicAsInteger : ScalarReadCost,
+ ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost),
CoeffReadCost = traits<T>::CoeffReadCost,
- CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? DynamicAsInteger : CoeffReadCost,
+ CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost),
NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n,
CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger,
CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
index 5c928e8fc2d..2e4309dd945 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
@@ -34,7 +34,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
/** Default constructor initializing a null box. */
- inline explicit AlignedBox()
+ inline AlignedBox()
{ if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h
index 20f1fceeb19..af598a40313 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
index 19cc1bfd883..b95bf00ecff 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
@@ -44,7 +44,7 @@ public:
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
/** Default constructor without initialization */
- inline explicit Hyperplane() {}
+ inline Hyperplane() {}
/** Constructs a dynamic-size hyperplane with \a _dim the dimension
* of the ambient space */
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
index 6e4a168a8cd..9b57b7e0bb4 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
@@ -36,7 +36,7 @@ public:
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
/** Default constructor without initialization */
- inline explicit ParametrizedLine() {}
+ inline ParametrizedLine() {}
/** Constructs a dynamic-size line with \a _dim the dimension
* of the ambient space */
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h
index ec87da054d6..4b6390cf1de 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h
index 3e02b7a4fd1..19b8582a1b1 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h
index 78ad73b60ad..b1c8f38da93 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h
index a07c1c7c762..b8fa6cd3f64 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h
index dceb8020383..fab60b251df 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h
index 0fb9a9f9a5a..2b9859f6f4c 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h b/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h
index 7aff428dc45..0e6fdb4889d 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h
index 3a8a9ca8146..3544af2538d 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h
@@ -12,18 +12,18 @@
namespace Eigen {
-template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return internal::real(x); }
-template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return internal::imag(x); }
-template<typename T> inline T ei_conj(const T& x) { return internal::conj(x); }
-template<typename T> inline typename NumTraits<T>::Real ei_abs (const T& x) { return internal::abs(x); }
-template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return internal::abs2(x); }
-template<typename T> inline T ei_sqrt(const T& x) { return internal::sqrt(x); }
-template<typename T> inline T ei_exp (const T& x) { return internal::exp(x); }
-template<typename T> inline T ei_log (const T& x) { return internal::log(x); }
-template<typename T> inline T ei_sin (const T& x) { return internal::sin(x); }
-template<typename T> inline T ei_cos (const T& x) { return internal::cos(x); }
-template<typename T> inline T ei_atan2(const T& x,const T& y) { return internal::atan2(x,y); }
-template<typename T> inline T ei_pow (const T& x,const T& y) { return internal::pow(x,y); }
+template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return numext::real(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return numext::imag(x); }
+template<typename T> inline T ei_conj(const T& x) { return numext::conj(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_abs (const T& x) { using std::abs; return abs(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return numext::abs2(x); }
+template<typename T> inline T ei_sqrt(const T& x) { using std::sqrt; return sqrt(x); }
+template<typename T> inline T ei_exp (const T& x) { using std::exp; return exp(x); }
+template<typename T> inline T ei_log (const T& x) { using std::log; return log(x); }
+template<typename T> inline T ei_sin (const T& x) { using std::sin; return sin(x); }
+template<typename T> inline T ei_cos (const T& x) { using std::cos; return cos(x); }
+template<typename T> inline T ei_atan2(const T& x,const T& y) { using std::atan2; return atan2(x,y); }
+template<typename T> inline T ei_pow (const T& x,const T& y) { return numext::pow(x,y); }
template<typename T> inline T ei_random () { return internal::random<T>(); }
template<typename T> inline T ei_random (const T& x, const T& y) { return internal::random(x, y); }
diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h
index 3d2eeb44586..3d03d2288d8 100644
--- a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h
+++ b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h
@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
+// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
@@ -315,7 +315,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[p-2] = 0.0;
for (j = p-2; j >= k; --j)
{
- Scalar t(internal::hypot(m_sigma[j],f));
+ Scalar t(numext::hypot(m_sigma[j],f));
Scalar cs(m_sigma[j]/t);
Scalar sn(f/t);
m_sigma[j] = t;
@@ -344,7 +344,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[k-1] = 0.0;
for (j = k; j < p; ++j)
{
- Scalar t(internal::hypot(m_sigma[j],f));
+ Scalar t(numext::hypot(m_sigma[j],f));
Scalar cs( m_sigma[j]/t);
Scalar sn(f/t);
m_sigma[j] = t;
@@ -392,7 +392,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
for (j = k; j < p-1; ++j)
{
- Scalar t = internal::hypot(f,g);
+ Scalar t = numext::hypot(f,g);
Scalar cs = f/t;
Scalar sn = g/t;
if (j != k)
@@ -410,7 +410,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
m_matV(i,j) = t;
}
}
- t = internal::hypot(f,g);
+ t = numext::hypot(f,g);
cs = f/t;
sn = g/t;
m_sigma[j] = t;
@@ -512,8 +512,7 @@ template<typename MatrixType>
template<typename OtherDerived, typename ResultType>
bool SVD<MatrixType>::solve(const MatrixBase<OtherDerived> &b, ResultType* result) const
{
- const int rows = m_matU.rows();
- ei_assert(b.rows() == rows);
+ ei_assert(b.rows() == m_matU.rows());
Scalar maxVal = m_sigma.cwise().abs().maxCoeff();
for (int j=0; j<b.cols(); ++j)
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h
index c4b8a308cee..af434bc9bd6 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h
@@ -3,7 +3,7 @@
//
// Copyright (C) 2009 Claire Maurice
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -220,6 +220,19 @@ template<typename _MatrixType> class ComplexEigenSolver
return m_schur.info();
}
+ /** \brief Sets the maximum number of iterations allowed. */
+ ComplexEigenSolver& setMaxIterations(Index maxIters)
+ {
+ m_schur.setMaxIterations(maxIters);
+ return *this;
+ }
+
+ /** \brief Returns the maximum number of iterations. */
+ Index getMaxIterations()
+ {
+ return m_schur.getMaxIterations();
+ }
+
protected:
EigenvectorType m_eivec;
EigenvalueType m_eivalues;
@@ -229,16 +242,17 @@ template<typename _MatrixType> class ComplexEigenSolver
EigenvectorType m_matX;
private:
- void doComputeEigenvectors(RealScalar matrixnorm);
+ void doComputeEigenvectors(const RealScalar& matrixnorm);
void sortEigenvalues(bool computeEigenvectors);
};
template<typename MatrixType>
-ComplexEigenSolver<MatrixType>& ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
+ComplexEigenSolver<MatrixType>&
+ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
{
// this code is inspired from Jampack
- assert(matrix.cols() == matrix.rows());
+ eigen_assert(matrix.cols() == matrix.rows());
// Do a complex Schur decomposition, A = U T U^*
// The eigenvalues are on the diagonal of T.
@@ -259,7 +273,7 @@ ComplexEigenSolver<MatrixType>& ComplexEigenSolver<MatrixType>::compute(const Ma
template<typename MatrixType>
-void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm)
+void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(const RealScalar& matrixnorm)
{
const Index n = m_eivalues.size();
@@ -280,7 +294,7 @@ void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm
{
// If the i-th and k-th eigenvalue are equal, then z equals 0.
// Use a small value instead, to prevent division by zero.
- internal::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
+ numext::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
}
m_matX.coeffRef(i,k) = m_matX.coeff(i,k) / z;
}
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h
index 16a9a03d219..89e6cade334 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h
@@ -3,7 +3,7 @@
//
// Copyright (C) 2009 Claire Maurice
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -96,7 +96,8 @@ template<typename _MatrixType> class ComplexSchur
m_matU(size,size),
m_hess(size),
m_isInitialized(false),
- m_matUisUptodate(false)
+ m_matUisUptodate(false),
+ m_maxIters(-1)
{}
/** \brief Constructor; computes Schur decomposition of given matrix.
@@ -109,11 +110,12 @@ template<typename _MatrixType> class ComplexSchur
* \sa matrixT() and matrixU() for examples.
*/
ComplexSchur(const MatrixType& matrix, bool computeU = true)
- : m_matT(matrix.rows(),matrix.cols()),
- m_matU(matrix.rows(),matrix.cols()),
- m_hess(matrix.rows()),
- m_isInitialized(false),
- m_matUisUptodate(false)
+ : m_matT(matrix.rows(),matrix.cols()),
+ m_matU(matrix.rows(),matrix.cols()),
+ m_hess(matrix.rows()),
+ m_isInitialized(false),
+ m_matUisUptodate(false),
+ m_maxIters(-1)
{
compute(matrix, computeU);
}
@@ -166,6 +168,7 @@ template<typename _MatrixType> class ComplexSchur
*
* \param[in] matrix Square matrix whose Schur decomposition is to be computed.
* \param[in] computeU If true, both T and U are computed; if false, only T is computed.
+
* \returns Reference to \c *this
*
* The Schur decomposition is computed by first reducing the
@@ -180,8 +183,30 @@ template<typename _MatrixType> class ComplexSchur
*
* Example: \include ComplexSchur_compute.cpp
* Output: \verbinclude ComplexSchur_compute.out
+ *
+ * \sa compute(const MatrixType&, bool, Index)
*/
ComplexSchur& compute(const MatrixType& matrix, bool computeU = true);
+
+ /** \brief Compute Schur decomposition from a given Hessenberg matrix
+ * \param[in] matrixH Matrix in Hessenberg form H
+ * \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T
+ * \param computeU Computes the matriX U of the Schur vectors
+ * \return Reference to \c *this
+ *
+ * This routine assumes that the matrix is already reduced in Hessenberg form matrixH
+ * using either the class HessenbergDecomposition or another mean.
+ * It computes the upper quasi-triangular matrix T of the Schur decomposition of H
+ * When computeU is true, this routine computes the matrix U such that
+ * A = U T U^T = (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix
+ *
+ * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix
+ * is not available, the user should give an identity matrix (Q.setIdentity())
+ *
+ * \sa compute(const MatrixType&, bool)
+ */
+ template<typename HessMatrixType, typename OrthMatrixType>
+ ComplexSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU=true);
/** \brief Reports whether previous computation was successful.
*
@@ -189,15 +214,33 @@ template<typename _MatrixType> class ComplexSchur
*/
ComputationInfo info() const
{
- eigen_assert(m_isInitialized && "RealSchur is not initialized.");
+ eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
return m_info;
}
- /** \brief Maximum number of iterations.
+ /** \brief Sets the maximum number of iterations allowed.
*
- * Maximum number of iterations allowed for an eigenvalue to converge.
+ * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size
+ * of the matrix.
*/
- static const int m_maxIterations = 30;
+ ComplexSchur& setMaxIterations(Index maxIters)
+ {
+ m_maxIters = maxIters;
+ return *this;
+ }
+
+ /** \brief Returns the maximum number of iterations. */
+ Index getMaxIterations()
+ {
+ return m_maxIters;
+ }
+
+ /** \brief Maximum number of iterations per row.
+ *
+ * If not otherwise specified, the maximum number of iterations is this number times the size of the
+ * matrix. It is currently set to 30.
+ */
+ static const int m_maxIterationsPerRow = 30;
protected:
ComplexMatrixType m_matT, m_matU;
@@ -205,6 +248,7 @@ template<typename _MatrixType> class ComplexSchur
ComputationInfo m_info;
bool m_isInitialized;
bool m_matUisUptodate;
+ Index m_maxIters;
private:
bool subdiagonalEntryIsNeglegible(Index i);
@@ -219,8 +263,8 @@ template<typename _MatrixType> class ComplexSchur
template<typename MatrixType>
inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
{
- RealScalar d = internal::norm1(m_matT.coeff(i,i)) + internal::norm1(m_matT.coeff(i+1,i+1));
- RealScalar sd = internal::norm1(m_matT.coeff(i+1,i));
+ RealScalar d = numext::norm1(m_matT.coeff(i,i)) + numext::norm1(m_matT.coeff(i+1,i+1));
+ RealScalar sd = numext::norm1(m_matT.coeff(i+1,i));
if (internal::isMuchSmallerThan(sd, d, NumTraits<RealScalar>::epsilon()))
{
m_matT.coeffRef(i+1,i) = ComplexScalar(0);
@@ -234,10 +278,11 @@ inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
template<typename MatrixType>
typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
{
+ using std::abs;
if (iter == 10 || iter == 20)
{
// exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
- return internal::abs(internal::real(m_matT.coeff(iu,iu-1))) + internal::abs(internal::real(m_matT.coeff(iu-1,iu-2)));
+ return abs(numext::real(m_matT.coeff(iu,iu-1))) + abs(numext::real(m_matT.coeff(iu-1,iu-2)));
}
// compute the shift as one of the eigenvalues of t, the 2x2
@@ -254,13 +299,13 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu
ComplexScalar eival1 = (trace + disc) / RealScalar(2);
ComplexScalar eival2 = (trace - disc) / RealScalar(2);
- if(internal::norm1(eival1) > internal::norm1(eival2))
+ if(numext::norm1(eival1) > numext::norm1(eival2))
eival2 = det / eival1;
else
eival1 = det / eival2;
// choose the eigenvalue closest to the bottom entry of the diagonal
- if(internal::norm1(eival1-t.coeff(1,1)) < internal::norm1(eival2-t.coeff(1,1)))
+ if(numext::norm1(eival1-t.coeff(1,1)) < numext::norm1(eival2-t.coeff(1,1)))
return normt * eival1;
else
return normt * eival2;
@@ -284,10 +329,20 @@ ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const MatrixType& ma
}
internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix, computeU);
- reduceToTriangularForm(computeU);
+ computeFromHessenberg(m_matT, m_matU, computeU);
return *this;
}
+template<typename MatrixType>
+template<typename HessMatrixType, typename OrthMatrixType>
+ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU)
+{
+ m_matT = matrixH;
+ if(computeU)
+ m_matU = matrixQ;
+ reduceToTriangularForm(computeU);
+ return *this;
+}
namespace internal {
/* Reduce given matrix to Hessenberg form */
@@ -309,7 +364,6 @@ struct complex_schur_reduce_to_hessenberg<MatrixType, false>
static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
{
typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;
- typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType;
// Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar
_this.m_hess.compute(matrix);
@@ -329,6 +383,10 @@ struct complex_schur_reduce_to_hessenberg<MatrixType, false>
template<typename MatrixType>
void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
{
+ Index maxIters = m_maxIters;
+ if (maxIters == -1)
+ maxIters = m_maxIterationsPerRow * m_matT.rows();
+
// The matrix m_matT is divided in three parts.
// Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
// Rows il,...,iu is the part we are working on (the active submatrix).
@@ -336,6 +394,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
Index iu = m_matT.cols() - 1;
Index il;
Index iter = 0; // number of iterations we are working on the (iu,iu) element
+ Index totalIter = 0; // number of iterations for whole matrix
while(true)
{
@@ -350,9 +409,10 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
// if iu is zero then we are done; the whole matrix is triangularized
if(iu==0) break;
- // if we spent too many iterations on the current element, we give up
+ // if we spent too many iterations, we give up
iter++;
- if(iter > m_maxIterations * m_matT.cols()) break;
+ totalIter++;
+ if(totalIter > maxIters) break;
// find il, the top row of the active submatrix
il = iu-1;
@@ -382,7 +442,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
}
}
- if(iter <= m_maxIterations * m_matT.cols())
+ if(totalIter <= maxIters)
m_info = Success;
else
m_info = NoConvergence;
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h
index aa18e696352..91496ae5bdb 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h
@@ -40,7 +40,7 @@ namespace Eigen {
/** \internal Specialization for the data types supported by MKL */
#define EIGEN_MKL_SCHUR_COMPLEX(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \
-template<> inline\
+template<> inline \
ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \
ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, bool computeU) \
{ \
@@ -49,7 +49,7 @@ ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matri
typedef MatrixType::RealScalar RealScalar; \
typedef std::complex<RealScalar> ComplexScalar; \
\
- assert(matrix.cols() == matrix.rows()); \
+ eigen_assert(matrix.cols() == matrix.rows()); \
\
m_matUisUptodate = false; \
if(matrix.cols() == 1) \
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h
index c16ff2b74e2..6e7150685a2 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h
@@ -2,7 +2,7 @@
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -281,6 +281,19 @@ template<typename _MatrixType> class EigenSolver
return m_realSchur.info();
}
+ /** \brief Sets the maximum number of iterations allowed. */
+ EigenSolver& setMaxIterations(Index maxIters)
+ {
+ m_realSchur.setMaxIterations(maxIters);
+ return *this;
+ }
+
+ /** \brief Returns the maximum number of iterations. */
+ Index getMaxIterations()
+ {
+ return m_realSchur.getMaxIterations();
+ }
+
private:
void doComputeEigenvectors();
@@ -304,12 +317,12 @@ MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
MatrixType matD = MatrixType::Zero(n,n);
for (Index i=0; i<n; ++i)
{
- if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(i)), internal::real(m_eivalues.coeff(i))))
- matD.coeffRef(i,i) = internal::real(m_eivalues.coeff(i));
+ if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i))))
+ matD.coeffRef(i,i) = numext::real(m_eivalues.coeff(i));
else
{
- matD.template block<2,2>(i,i) << internal::real(m_eivalues.coeff(i)), internal::imag(m_eivalues.coeff(i)),
- -internal::imag(m_eivalues.coeff(i)), internal::real(m_eivalues.coeff(i));
+ matD.template block<2,2>(i,i) << numext::real(m_eivalues.coeff(i)), numext::imag(m_eivalues.coeff(i)),
+ -numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i));
++i;
}
}
@@ -325,7 +338,7 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
EigenvectorsType matV(n,n);
for (Index j=0; j<n; ++j)
{
- if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(j)), internal::real(m_eivalues.coeff(j))) || j+1==n)
+ if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(j)), numext::real(m_eivalues.coeff(j))) || j+1==n)
{
// we have a real eigen value
matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
@@ -348,12 +361,16 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
}
template<typename MatrixType>
-EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
+EigenSolver<MatrixType>&
+EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
{
- assert(matrix.cols() == matrix.rows());
+ using std::sqrt;
+ using std::abs;
+ eigen_assert(matrix.cols() == matrix.rows());
// Reduce to real Schur form.
m_realSchur.compute(matrix, computeEigenvectors);
+
if (m_realSchur.info() == Success)
{
m_matT = m_realSchur.matrixT();
@@ -373,7 +390,7 @@ EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matr
else
{
Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1));
- Scalar z = internal::sqrt(internal::abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
+ Scalar z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
i += 2;
@@ -393,10 +410,11 @@ EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matr
// Complex scalar division.
template<typename Scalar>
-std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
+std::complex<Scalar> cdiv(const Scalar& xr, const Scalar& xi, const Scalar& yr, const Scalar& yi)
{
+ using std::abs;
Scalar r,d;
- if (internal::abs(yr) > internal::abs(yi))
+ if (abs(yr) > abs(yi))
{
r = yi/yr;
d = yr + r*yi;
@@ -414,6 +432,7 @@ std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
template<typename MatrixType>
void EigenSolver<MatrixType>::doComputeEigenvectors()
{
+ using std::abs;
const Index size = m_eivec.cols();
const Scalar eps = NumTraits<Scalar>::epsilon();
@@ -469,14 +488,14 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
Scalar t = (x * lastr - lastw * r) / denom;
m_matT.coeffRef(i,n) = t;
- if (internal::abs(x) > internal::abs(lastw))
+ if (abs(x) > abs(lastw))
m_matT.coeffRef(i+1,n) = (-r - w * t) / x;
else
m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw;
}
// Overflow control
- Scalar t = internal::abs(m_matT.coeff(i,n));
+ Scalar t = abs(m_matT.coeff(i,n));
if ((eps * t) * t > Scalar(1))
m_matT.col(n).tail(size-i) /= t;
}
@@ -488,7 +507,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
Index l = n-1;
// Last vector component imaginary so matrix is triangular
- if (internal::abs(m_matT.coeff(n,n-1)) > internal::abs(m_matT.coeff(n-1,n)))
+ if (abs(m_matT.coeff(n,n-1)) > abs(m_matT.coeff(n-1,n)))
{
m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1);
m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1);
@@ -496,8 +515,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
else
{
std::complex<Scalar> cc = cdiv<Scalar>(0.0,-m_matT.coeff(n-1,n),m_matT.coeff(n-1,n-1)-p,q);
- m_matT.coeffRef(n-1,n-1) = internal::real(cc);
- m_matT.coeffRef(n-1,n) = internal::imag(cc);
+ m_matT.coeffRef(n-1,n-1) = numext::real(cc);
+ m_matT.coeffRef(n-1,n) = numext::imag(cc);
}
m_matT.coeffRef(n,n-1) = 0.0;
m_matT.coeffRef(n,n) = 1.0;
@@ -519,8 +538,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
if (m_eivalues.coeff(i).imag() == RealScalar(0))
{
std::complex<Scalar> cc = cdiv(-ra,-sa,w,q);
- m_matT.coeffRef(i,n-1) = internal::real(cc);
- m_matT.coeffRef(i,n) = internal::imag(cc);
+ m_matT.coeffRef(i,n-1) = numext::real(cc);
+ m_matT.coeffRef(i,n) = numext::imag(cc);
}
else
{
@@ -530,12 +549,12 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
if ((vr == 0.0) && (vi == 0.0))
- vr = eps * norm * (internal::abs(w) + internal::abs(q) + internal::abs(x) + internal::abs(y) + internal::abs(lastw));
+ vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));
- std::complex<Scalar> cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi);
- m_matT.coeffRef(i,n-1) = internal::real(cc);
- m_matT.coeffRef(i,n) = internal::imag(cc);
- if (internal::abs(x) > (internal::abs(lastw) + internal::abs(q)))
+ std::complex<Scalar> cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi);
+ m_matT.coeffRef(i,n-1) = numext::real(cc);
+ m_matT.coeffRef(i,n) = numext::imag(cc);
+ if (abs(x) > (abs(lastw) + abs(q)))
{
m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x;
@@ -543,14 +562,14 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
else
{
cc = cdiv(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n),lastw,q);
- m_matT.coeffRef(i+1,n-1) = internal::real(cc);
- m_matT.coeffRef(i+1,n) = internal::imag(cc);
+ m_matT.coeffRef(i+1,n-1) = numext::real(cc);
+ m_matT.coeffRef(i+1,n) = numext::imag(cc);
}
}
// Overflow control
using std::max;
- Scalar t = (max)(internal::abs(m_matT.coeff(i,n-1)),internal::abs(m_matT.coeff(i,n)));
+ Scalar t = (max)(abs(m_matT.coeff(i,n-1)),abs(m_matT.coeff(i,n)));
if ((eps * t) * t > Scalar(1))
m_matT.block(i, n-1, size-i, 2) /= t;
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
new file mode 100644
index 00000000000..dc240e13e13
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
@@ -0,0 +1,341 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_GENERALIZEDEIGENSOLVER_H
+#define EIGEN_GENERALIZEDEIGENSOLVER_H
+
+#include "./RealQZ.h"
+
+namespace Eigen {
+
+/** \eigenvalues_module \ingroup Eigenvalues_Module
+ *
+ *
+ * \class GeneralizedEigenSolver
+ *
+ * \brief Computes the generalized eigenvalues and eigenvectors of a pair of general matrices
+ *
+ * \tparam _MatrixType the type of the matrices of which we are computing the
+ * eigen-decomposition; this is expected to be an instantiation of the Matrix
+ * class template. Currently, only real matrices are supported.
+ *
+ * The generalized eigenvalues and eigenvectors of a matrix pair \f$ A \f$ and \f$ B \f$ are scalars
+ * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda Bv \f$. If
+ * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and
+ * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V =
+ * B V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we
+ * have \f$ A = B V D V^{-1} \f$. This is called the generalized eigen-decomposition.
+ *
+ * The generalized eigenvalues and eigenvectors of a matrix pair may be complex, even when the
+ * matrices are real. Moreover, the generalized eigenvalue might be infinite if the matrix B is
+ * singular. To workaround this difficulty, the eigenvalues are provided as a pair of complex \f$ \alpha \f$
+ * and real \f$ \beta \f$ such that: \f$ \lambda_i = \alpha_i / \beta_i \f$. If \f$ \beta_i \f$ is (nearly) zero,
+ * then one can consider the well defined left eigenvalue \f$ \mu = \beta_i / \alpha_i\f$ such that:
+ * \f$ \mu_i A v_i = B v_i \f$, or even \f$ \mu_i u_i^T A = u_i^T B \f$ where \f$ u_i \f$ is
+ * called the left eigenvector.
+ *
+ * Call the function compute() to compute the generalized eigenvalues and eigenvectors of
+ * a given matrix pair. Alternatively, you can use the
+ * GeneralizedEigenSolver(const MatrixType&, const MatrixType&, bool) constructor which computes the
+ * eigenvalues and eigenvectors at construction time. Once the eigenvalue and
+ * eigenvectors are computed, they can be retrieved with the eigenvalues() and
+ * eigenvectors() functions.
+ *
+ * Here is an usage example of this class:
+ * Example: \include GeneralizedEigenSolver.cpp
+ * Output: \verbinclude GeneralizedEigenSolver.out
+ *
+ * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver
+ */
+template<typename _MatrixType> class GeneralizedEigenSolver
+{
+ public:
+
+ /** \brief Synonym for the template parameter \p _MatrixType. */
+ typedef _MatrixType MatrixType;
+
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ Options = MatrixType::Options,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
+ };
+
+ /** \brief Scalar type for matrices of type #MatrixType. */
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef typename MatrixType::Index Index;
+
+ /** \brief Complex scalar type for #MatrixType.
+ *
+ * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
+ * \c float or \c double) and just \c Scalar if #Scalar is
+ * complex.
+ */
+ typedef std::complex<RealScalar> ComplexScalar;
+
+ /** \brief Type for vector of real scalar values eigenvalues as returned by betas().
+ *
+ * This is a column vector with entries of type #Scalar.
+ * The length of the vector is the size of #MatrixType.
+ */
+ typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> VectorType;
+
+ /** \brief Type for vector of complex scalar values eigenvalues as returned by betas().
+ *
+ * This is a column vector with entries of type #ComplexScalar.
+ * The length of the vector is the size of #MatrixType.
+ */
+ typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ComplexVectorType;
+
+ /** \brief Expression type for the eigenvalues as returned by eigenvalues().
+ */
+ typedef CwiseBinaryOp<internal::scalar_quotient_op<ComplexScalar,Scalar>,ComplexVectorType,VectorType> EigenvalueType;
+
+ /** \brief Type for matrix of eigenvectors as returned by eigenvectors().
+ *
+ * This is a square matrix with entries of type #ComplexScalar.
+ * The size is the same as the size of #MatrixType.
+ */
+ typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> EigenvectorsType;
+
+ /** \brief Default constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via EigenSolver::compute(const MatrixType&, bool).
+ *
+ * \sa compute() for an example.
+ */
+ GeneralizedEigenSolver() : m_eivec(), m_alphas(), m_betas(), m_isInitialized(false), m_realQZ(), m_matS(), m_tmp() {}
+
+ /** \brief Default constructor with memory preallocation
+ *
+ * Like the default constructor but with preallocation of the internal data
+ * according to the specified problem \a size.
+ * \sa GeneralizedEigenSolver()
+ */
+ GeneralizedEigenSolver(Index size)
+ : m_eivec(size, size),
+ m_alphas(size),
+ m_betas(size),
+ m_isInitialized(false),
+ m_eigenvectorsOk(false),
+ m_realQZ(size),
+ m_matS(size, size),
+ m_tmp(size)
+ {}
+
+ /** \brief Constructor; computes the generalized eigendecomposition of given matrix pair.
+ *
+ * \param[in] A Square matrix whose eigendecomposition is to be computed.
+ * \param[in] B Square matrix whose eigendecomposition is to be computed.
+ * \param[in] computeEigenvectors If true, both the eigenvectors and the
+ * eigenvalues are computed; if false, only the eigenvalues are computed.
+ *
+ * This constructor calls compute() to compute the generalized eigenvalues
+ * and eigenvectors.
+ *
+ * \sa compute()
+ */
+ GeneralizedEigenSolver(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true)
+ : m_eivec(A.rows(), A.cols()),
+ m_alphas(A.cols()),
+ m_betas(A.cols()),
+ m_isInitialized(false),
+ m_eigenvectorsOk(false),
+ m_realQZ(A.cols()),
+ m_matS(A.rows(), A.cols()),
+ m_tmp(A.cols())
+ {
+ compute(A, B, computeEigenvectors);
+ }
+
+ /* \brief Returns the computed generalized eigenvectors.
+ *
+ * \returns %Matrix whose columns are the (possibly complex) eigenvectors.
+ *
+ * \pre Either the constructor
+ * GeneralizedEigenSolver(const MatrixType&,const MatrixType&, bool) or the member function
+ * compute(const MatrixType&, const MatrixType& bool) has been called before, and
+ * \p computeEigenvectors was set to true (the default).
+ *
+ * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding
+ * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The
+ * eigenvectors are normalized to have (Euclidean) norm equal to one. The
+ * matrix returned by this function is the matrix \f$ V \f$ in the
+ * generalized eigendecomposition \f$ A = B V D V^{-1} \f$, if it exists.
+ *
+ * \sa eigenvalues()
+ */
+// EigenvectorsType eigenvectors() const;
+
+ /** \brief Returns an expression of the computed generalized eigenvalues.
+ *
+ * \returns An expression of the column vector containing the eigenvalues.
+ *
+ * It is a shortcut for \code this->alphas().cwiseQuotient(this->betas()); \endcode
+ * Not that betas might contain zeros. It is therefore not recommended to use this function,
+ * but rather directly deal with the alphas and betas vectors.
+ *
+ * \pre Either the constructor
+ * GeneralizedEigenSolver(const MatrixType&,const MatrixType&,bool) or the member function
+ * compute(const MatrixType&,const MatrixType&,bool) has been called before.
+ *
+ * The eigenvalues are repeated according to their algebraic multiplicity,
+ * so there are as many eigenvalues as rows in the matrix. The eigenvalues
+ * are not sorted in any particular order.
+ *
+ * \sa alphas(), betas(), eigenvectors()
+ */
+ EigenvalueType eigenvalues() const
+ {
+ eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized.");
+ return EigenvalueType(m_alphas,m_betas);
+ }
+
+ /** \returns A const reference to the vectors containing the alpha values
+ *
+ * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
+ *
+ * \sa betas(), eigenvalues() */
+ ComplexVectorType alphas() const
+ {
+ eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized.");
+ return m_alphas;
+ }
+
+ /** \returns A const reference to the vectors containing the beta values
+ *
+ * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
+ *
+ * \sa alphas(), eigenvalues() */
+ VectorType betas() const
+ {
+ eigen_assert(m_isInitialized && "GeneralizedEigenSolver is not initialized.");
+ return m_betas;
+ }
+
+ /** \brief Computes generalized eigendecomposition of given matrix.
+ *
+ * \param[in] A Square matrix whose eigendecomposition is to be computed.
+ * \param[in] B Square matrix whose eigendecomposition is to be computed.
+ * \param[in] computeEigenvectors If true, both the eigenvectors and the
+ * eigenvalues are computed; if false, only the eigenvalues are
+ * computed.
+ * \returns Reference to \c *this
+ *
+ * This function computes the eigenvalues of the real matrix \p matrix.
+ * The eigenvalues() function can be used to retrieve them. If
+ * \p computeEigenvectors is true, then the eigenvectors are also computed
+ * and can be retrieved by calling eigenvectors().
+ *
+ * The matrix is first reduced to real generalized Schur form using the RealQZ
+ * class. The generalized Schur decomposition is then used to compute the eigenvalues
+ * and eigenvectors.
+ *
+ * The cost of the computation is dominated by the cost of the
+ * generalized Schur decomposition.
+ *
+ * This method reuses of the allocated data in the GeneralizedEigenSolver object.
+ */
+ GeneralizedEigenSolver& compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true);
+
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
+ return m_realQZ.info();
+ }
+
+ /** Sets the maximal number of iterations allowed.
+ */
+ GeneralizedEigenSolver& setMaxIterations(Index maxIters)
+ {
+ m_realQZ.setMaxIterations(maxIters);
+ return *this;
+ }
+
+ protected:
+ MatrixType m_eivec;
+ ComplexVectorType m_alphas;
+ VectorType m_betas;
+ bool m_isInitialized;
+ bool m_eigenvectorsOk;
+ RealQZ<MatrixType> m_realQZ;
+ MatrixType m_matS;
+
+ typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
+ ColumnVectorType m_tmp;
+};
+
+//template<typename MatrixType>
+//typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType GeneralizedEigenSolver<MatrixType>::eigenvectors() const
+//{
+// eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
+// eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
+// Index n = m_eivec.cols();
+// EigenvectorsType matV(n,n);
+// // TODO
+// return matV;
+//}
+
+template<typename MatrixType>
+GeneralizedEigenSolver<MatrixType>&
+GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
+{
+ using std::sqrt;
+ using std::abs;
+ eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
+
+ // Reduce to generalized real Schur form:
+ // A = Q S Z and B = Q T Z
+ m_realQZ.compute(A, B, computeEigenvectors);
+
+ if (m_realQZ.info() == Success)
+ {
+ m_matS = m_realQZ.matrixS();
+ if (computeEigenvectors)
+ m_eivec = m_realQZ.matrixZ().transpose();
+
+ // Compute eigenvalues from matS
+ m_alphas.resize(A.cols());
+ m_betas.resize(A.cols());
+ Index i = 0;
+ while (i < A.cols())
+ {
+ if (i == A.cols() - 1 || m_matS.coeff(i+1, i) == Scalar(0))
+ {
+ m_alphas.coeffRef(i) = m_matS.coeff(i, i);
+ m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i);
+ ++i;
+ }
+ else
+ {
+ Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1));
+ Scalar z = sqrt(abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1)));
+ m_alphas.coeffRef(i) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z);
+ m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z);
+
+ m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i);
+ m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i);
+ i += 2;
+ }
+ }
+ }
+
+ m_isInitialized = true;
+ m_eigenvectorsOk = false;//computeEigenvectors;
+
+ return *this;
+}
+
+} // end namespace Eigen
+
+#endif // EIGEN_GENERALIZEDEIGENSOLVER_H
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h
index b8378b08a09..3db0c0106c9 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h
@@ -82,7 +82,7 @@ template<typename _MatrixType> class HessenbergDecomposition
typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
/** \brief Return type of matrixQ() */
- typedef typename HouseholderSequence<MatrixType,CoeffVectorType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
typedef internal::HessenbergDecompositionMatrixHReturnType<MatrixType> MatrixHReturnType;
@@ -291,7 +291,7 @@ template<typename _MatrixType> class HessenbergDecomposition
template<typename MatrixType>
void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp)
{
- assert(matA.rows()==matA.cols());
+ eigen_assert(matA.rows()==matA.cols());
Index n = matA.rows();
temp.resize(n);
for (Index i = 0; i<n-1; ++i)
@@ -313,7 +313,7 @@ void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVector
// A = A H'
matA.rightCols(remainingSize)
- .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), internal::conj(h), &temp.coeffRef(0));
+ .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), numext::conj(h), &temp.coeffRef(0));
}
}
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
index 6af481c75f6..4fec8af0a3e 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
@@ -121,10 +121,11 @@ template<typename Derived>
inline typename MatrixBase<Derived>::RealScalar
MatrixBase<Derived>::operatorNorm() const
{
+ using std::sqrt;
typename Derived::PlainObject m_eval(derived());
// FIXME if it is really guaranteed that the eigenvalues are already sorted,
// then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
- return internal::sqrt((m_eval*m_eval.adjoint())
+ return sqrt((m_eval*m_eval.adjoint())
.eval()
.template selfadjointView<Lower>()
.eigenvalues()
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealQZ.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealQZ.h
new file mode 100644
index 00000000000..5706eeebe91
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealQZ.h
@@ -0,0 +1,624 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Alexey Korepanov <kaikaikai@yandex.ru>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_REAL_QZ_H
+#define EIGEN_REAL_QZ_H
+
+namespace Eigen {
+
+ /** \eigenvalues_module \ingroup Eigenvalues_Module
+ *
+ *
+ * \class RealQZ
+ *
+ * \brief Performs a real QZ decomposition of a pair of square matrices
+ *
+ * \tparam _MatrixType the type of the matrix of which we are computing the
+ * real QZ decomposition; this is expected to be an instantiation of the
+ * Matrix class template.
+ *
+ * Given a real square matrices A and B, this class computes the real QZ
+ * decomposition: \f$ A = Q S Z \f$, \f$ B = Q T Z \f$ where Q and Z are
+ * real orthogonal matrixes, T is upper-triangular matrix, and S is upper
+ * quasi-triangular matrix. An orthogonal matrix is a matrix whose
+ * inverse is equal to its transpose, \f$ U^{-1} = U^T \f$. A quasi-triangular
+ * matrix is a block-triangular matrix whose diagonal consists of 1-by-1
+ * blocks and 2-by-2 blocks where further reduction is impossible due to
+ * complex eigenvalues.
+ *
+ * The eigenvalues of the pencil \f$ A - z B \f$ can be obtained from
+ * 1x1 and 2x2 blocks on the diagonals of S and T.
+ *
+ * Call the function compute() to compute the real QZ decomposition of a
+ * given pair of matrices. Alternatively, you can use the
+ * RealQZ(const MatrixType& B, const MatrixType& B, bool computeQZ)
+ * constructor which computes the real QZ decomposition at construction
+ * time. Once the decomposition is computed, you can use the matrixS(),
+ * matrixT(), matrixQ() and matrixZ() functions to retrieve the matrices
+ * S, T, Q and Z in the decomposition. If computeQZ==false, some time
+ * is saved by not computing matrices Q and Z.
+ *
+ * Example: \include RealQZ_compute.cpp
+ * Output: \include RealQZ_compute.out
+ *
+ * \note The implementation is based on the algorithm in "Matrix Computations"
+ * by Gene H. Golub and Charles F. Van Loan, and a paper "An algorithm for
+ * generalized eigenvalue problems" by C.B.Moler and G.W.Stewart.
+ *
+ * \sa class RealSchur, class ComplexSchur, class EigenSolver, class ComplexEigenSolver
+ */
+
+ template<typename _MatrixType> class RealQZ
+ {
+ public:
+ typedef _MatrixType MatrixType;
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ Options = MatrixType::Options,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
+ };
+ typedef typename MatrixType::Scalar Scalar;
+ typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
+ typedef typename MatrixType::Index Index;
+
+ typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> EigenvalueType;
+ typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
+
+ /** \brief Default constructor.
+ *
+ * \param [in] size Positive integer, size of the matrix whose QZ decomposition will be computed.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via compute(). The \p size parameter is only
+ * used as a hint. It is not an error to give a wrong \p size, but it may
+ * impair performance.
+ *
+ * \sa compute() for an example.
+ */
+ RealQZ(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime) :
+ m_S(size, size),
+ m_T(size, size),
+ m_Q(size, size),
+ m_Z(size, size),
+ m_workspace(size*2),
+ m_maxIters(400),
+ m_isInitialized(false)
+ { }
+
+ /** \brief Constructor; computes real QZ decomposition of given matrices
+ *
+ * \param[in] A Matrix A.
+ * \param[in] B Matrix B.
+ * \param[in] computeQZ If false, A and Z are not computed.
+ *
+ * This constructor calls compute() to compute the QZ decomposition.
+ */
+ RealQZ(const MatrixType& A, const MatrixType& B, bool computeQZ = true) :
+ m_S(A.rows(),A.cols()),
+ m_T(A.rows(),A.cols()),
+ m_Q(A.rows(),A.cols()),
+ m_Z(A.rows(),A.cols()),
+ m_workspace(A.rows()*2),
+ m_maxIters(400),
+ m_isInitialized(false) {
+ compute(A, B, computeQZ);
+ }
+
+ /** \brief Returns matrix Q in the QZ decomposition.
+ *
+ * \returns A const reference to the matrix Q.
+ */
+ const MatrixType& matrixQ() const {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
+ return m_Q;
+ }
+
+ /** \brief Returns matrix Z in the QZ decomposition.
+ *
+ * \returns A const reference to the matrix Z.
+ */
+ const MatrixType& matrixZ() const {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
+ return m_Z;
+ }
+
+ /** \brief Returns matrix S in the QZ decomposition.
+ *
+ * \returns A const reference to the matrix S.
+ */
+ const MatrixType& matrixS() const {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ return m_S;
+ }
+
+ /** \brief Returns matrix S in the QZ decomposition.
+ *
+ * \returns A const reference to the matrix S.
+ */
+ const MatrixType& matrixT() const {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ return m_T;
+ }
+
+ /** \brief Computes QZ decomposition of given matrix.
+ *
+ * \param[in] A Matrix A.
+ * \param[in] B Matrix B.
+ * \param[in] computeQZ If false, A and Z are not computed.
+ * \returns Reference to \c *this
+ */
+ RealQZ& compute(const MatrixType& A, const MatrixType& B, bool computeQZ = true);
+
+ /** \brief Reports whether previous computation was successful.
+ *
+ * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
+ */
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ return m_info;
+ }
+
+ /** \brief Returns number of performed QR-like iterations.
+ */
+ Index iterations() const
+ {
+ eigen_assert(m_isInitialized && "RealQZ is not initialized.");
+ return m_global_iter;
+ }
+
+ /** Sets the maximal number of iterations allowed to converge to one eigenvalue
+ * or decouple the problem.
+ */
+ RealQZ& setMaxIterations(Index maxIters)
+ {
+ m_maxIters = maxIters;
+ return *this;
+ }
+
+ private:
+
+ MatrixType m_S, m_T, m_Q, m_Z;
+ Matrix<Scalar,Dynamic,1> m_workspace;
+ ComputationInfo m_info;
+ Index m_maxIters;
+ bool m_isInitialized;
+ bool m_computeQZ;
+ Scalar m_normOfT, m_normOfS;
+ Index m_global_iter;
+
+ typedef Matrix<Scalar,3,1> Vector3s;
+ typedef Matrix<Scalar,2,1> Vector2s;
+ typedef Matrix<Scalar,2,2> Matrix2s;
+ typedef JacobiRotation<Scalar> JRs;
+
+ void hessenbergTriangular();
+ void computeNorms();
+ Index findSmallSubdiagEntry(Index iu);
+ Index findSmallDiagEntry(Index f, Index l);
+ void splitOffTwoRows(Index i);
+ void pushDownZero(Index z, Index f, Index l);
+ void step(Index f, Index l, Index iter);
+
+ }; // RealQZ
+
+ /** \internal Reduces S and T to upper Hessenberg - triangular form */
+ template<typename MatrixType>
+ void RealQZ<MatrixType>::hessenbergTriangular()
+ {
+
+ const Index dim = m_S.cols();
+
+ // perform QR decomposition of T, overwrite T with R, save Q
+ HouseholderQR<MatrixType> qrT(m_T);
+ m_T = qrT.matrixQR();
+ m_T.template triangularView<StrictlyLower>().setZero();
+ m_Q = qrT.householderQ();
+ // overwrite S with Q* S
+ m_S.applyOnTheLeft(m_Q.adjoint());
+ // init Z as Identity
+ if (m_computeQZ)
+ m_Z = MatrixType::Identity(dim,dim);
+ // reduce S to upper Hessenberg with Givens rotations
+ for (Index j=0; j<=dim-3; j++) {
+ for (Index i=dim-1; i>=j+2; i--) {
+ JRs G;
+ // kill S(i,j)
+ if(m_S.coeff(i,j) != 0)
+ {
+ G.makeGivens(m_S.coeff(i-1,j), m_S.coeff(i,j), &m_S.coeffRef(i-1, j));
+ m_S.coeffRef(i,j) = Scalar(0.0);
+ m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint());
+ m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint());
+ }
+ // update Q
+ if (m_computeQZ)
+ m_Q.applyOnTheRight(i-1,i,G);
+ // kill T(i,i-1)
+ if(m_T.coeff(i,i-1)!=Scalar(0))
+ {
+ G.makeGivens(m_T.coeff(i,i), m_T.coeff(i,i-1), &m_T.coeffRef(i,i));
+ m_T.coeffRef(i,i-1) = Scalar(0.0);
+ m_S.applyOnTheRight(i,i-1,G);
+ m_T.topRows(i).applyOnTheRight(i,i-1,G);
+ }
+ // update Z
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(i,i-1,G.adjoint());
+ }
+ }
+ }
+
+ /** \internal Computes vector L1 norms of S and T when in Hessenberg-Triangular form already */
+ template<typename MatrixType>
+ inline void RealQZ<MatrixType>::computeNorms()
+ {
+ const Index size = m_S.cols();
+ m_normOfS = Scalar(0.0);
+ m_normOfT = Scalar(0.0);
+ for (Index j = 0; j < size; ++j)
+ {
+ m_normOfS += m_S.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
+ m_normOfT += m_T.row(j).segment(j, size - j).cwiseAbs().sum();
+ }
+ }
+
+
+ /** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0) */
+ template<typename MatrixType>
+ inline typename MatrixType::Index RealQZ<MatrixType>::findSmallSubdiagEntry(Index iu)
+ {
+ using std::abs;
+ Index res = iu;
+ while (res > 0)
+ {
+ Scalar s = abs(m_S.coeff(res-1,res-1)) + abs(m_S.coeff(res,res));
+ if (s == Scalar(0.0))
+ s = m_normOfS;
+ if (abs(m_S.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
+ break;
+ res--;
+ }
+ return res;
+ }
+
+ /** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1) */
+ template<typename MatrixType>
+ inline typename MatrixType::Index RealQZ<MatrixType>::findSmallDiagEntry(Index f, Index l)
+ {
+ using std::abs;
+ Index res = l;
+ while (res >= f) {
+ if (abs(m_T.coeff(res,res)) <= NumTraits<Scalar>::epsilon() * m_normOfT)
+ break;
+ res--;
+ }
+ return res;
+ }
+
+ /** \internal decouple 2x2 diagonal block in rows i, i+1 if eigenvalues are real */
+ template<typename MatrixType>
+ inline void RealQZ<MatrixType>::splitOffTwoRows(Index i)
+ {
+ using std::abs;
+ using std::sqrt;
+ const Index dim=m_S.cols();
+ if (abs(m_S.coeff(i+1,i)==Scalar(0)))
+ return;
+ Index z = findSmallDiagEntry(i,i+1);
+ if (z==i-1)
+ {
+ // block of (S T^{-1})
+ Matrix2s STi = m_T.template block<2,2>(i,i).template triangularView<Upper>().
+ template solve<OnTheRight>(m_S.template block<2,2>(i,i));
+ Scalar p = Scalar(0.5)*(STi(0,0)-STi(1,1));
+ Scalar q = p*p + STi(1,0)*STi(0,1);
+ if (q>=0) {
+ Scalar z = sqrt(q);
+ // one QR-like iteration for ABi - lambda I
+ // is enough - when we know exact eigenvalue in advance,
+ // convergence is immediate
+ JRs G;
+ if (p>=0)
+ G.makeGivens(p + z, STi(1,0));
+ else
+ G.makeGivens(p - z, STi(1,0));
+ m_S.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint());
+ m_T.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint());
+ // update Q
+ if (m_computeQZ)
+ m_Q.applyOnTheRight(i,i+1,G);
+
+ G.makeGivens(m_T.coeff(i+1,i+1), m_T.coeff(i+1,i));
+ m_S.topRows(i+2).applyOnTheRight(i+1,i,G);
+ m_T.topRows(i+2).applyOnTheRight(i+1,i,G);
+ // update Z
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(i+1,i,G.adjoint());
+
+ m_S.coeffRef(i+1,i) = Scalar(0.0);
+ m_T.coeffRef(i+1,i) = Scalar(0.0);
+ }
+ }
+ else
+ {
+ pushDownZero(z,i,i+1);
+ }
+ }
+
+ /** \internal use zero in T(z,z) to zero S(l,l-1), working in block f..l */
+ template<typename MatrixType>
+ inline void RealQZ<MatrixType>::pushDownZero(Index z, Index f, Index l)
+ {
+ JRs G;
+ const Index dim = m_S.cols();
+ for (Index zz=z; zz<l; zz++)
+ {
+ // push 0 down
+ Index firstColS = zz>f ? (zz-1) : zz;
+ G.makeGivens(m_T.coeff(zz, zz+1), m_T.coeff(zz+1, zz+1));
+ m_S.rightCols(dim-firstColS).applyOnTheLeft(zz,zz+1,G.adjoint());
+ m_T.rightCols(dim-zz).applyOnTheLeft(zz,zz+1,G.adjoint());
+ m_T.coeffRef(zz+1,zz+1) = Scalar(0.0);
+ // update Q
+ if (m_computeQZ)
+ m_Q.applyOnTheRight(zz,zz+1,G);
+ // kill S(zz+1, zz-1)
+ if (zz>f)
+ {
+ G.makeGivens(m_S.coeff(zz+1, zz), m_S.coeff(zz+1,zz-1));
+ m_S.topRows(zz+2).applyOnTheRight(zz, zz-1,G);
+ m_T.topRows(zz+1).applyOnTheRight(zz, zz-1,G);
+ m_S.coeffRef(zz+1,zz-1) = Scalar(0.0);
+ // update Z
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(zz,zz-1,G.adjoint());
+ }
+ }
+ // finally kill S(l,l-1)
+ G.makeGivens(m_S.coeff(l,l), m_S.coeff(l,l-1));
+ m_S.applyOnTheRight(l,l-1,G);
+ m_T.applyOnTheRight(l,l-1,G);
+ m_S.coeffRef(l,l-1)=Scalar(0.0);
+ // update Z
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(l,l-1,G.adjoint());
+ }
+
+ /** \internal QR-like iterative step for block f..l */
+ template<typename MatrixType>
+ inline void RealQZ<MatrixType>::step(Index f, Index l, Index iter)
+ {
+ using std::abs;
+ const Index dim = m_S.cols();
+
+ // x, y, z
+ Scalar x, y, z;
+ if (iter==10)
+ {
+ // Wilkinson ad hoc shift
+ const Scalar
+ a11=m_S.coeff(f+0,f+0), a12=m_S.coeff(f+0,f+1),
+ a21=m_S.coeff(f+1,f+0), a22=m_S.coeff(f+1,f+1), a32=m_S.coeff(f+2,f+1),
+ b12=m_T.coeff(f+0,f+1),
+ b11i=Scalar(1.0)/m_T.coeff(f+0,f+0),
+ b22i=Scalar(1.0)/m_T.coeff(f+1,f+1),
+ a87=m_S.coeff(l-1,l-2),
+ a98=m_S.coeff(l-0,l-1),
+ b77i=Scalar(1.0)/m_T.coeff(l-2,l-2),
+ b88i=Scalar(1.0)/m_T.coeff(l-1,l-1);
+ Scalar ss = abs(a87*b77i) + abs(a98*b88i),
+ lpl = Scalar(1.5)*ss,
+ ll = ss*ss;
+ x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i
+ - a11*a21*b12*b11i*b11i*b22i;
+ y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i
+ - a21*a21*b12*b11i*b11i*b22i;
+ z = a21*a32*b11i*b22i;
+ }
+ else if (iter==16)
+ {
+ // another exceptional shift
+ x = m_S.coeff(f,f)/m_T.coeff(f,f)-m_S.coeff(l,l)/m_T.coeff(l,l) + m_S.coeff(l,l-1)*m_T.coeff(l-1,l) /
+ (m_T.coeff(l-1,l-1)*m_T.coeff(l,l));
+ y = m_S.coeff(f+1,f)/m_T.coeff(f,f);
+ z = 0;
+ }
+ else if (iter>23 && !(iter%8))
+ {
+ // extremely exceptional shift
+ x = internal::random<Scalar>(-1.0,1.0);
+ y = internal::random<Scalar>(-1.0,1.0);
+ z = internal::random<Scalar>(-1.0,1.0);
+ }
+ else
+ {
+ // Compute the shifts: (x,y,z,0...) = (AB^-1 - l1 I) (AB^-1 - l2 I) e1
+ // where l1 and l2 are the eigenvalues of the 2x2 matrix C = U V^-1 where
+ // U and V are 2x2 bottom right sub matrices of A and B. Thus:
+ // = AB^-1AB^-1 + l1 l2 I - (l1+l2)(AB^-1)
+ // = AB^-1AB^-1 + det(M) - tr(M)(AB^-1)
+ // Since we are only interested in having x, y, z with a correct ratio, we have:
+ const Scalar
+ a11 = m_S.coeff(f,f), a12 = m_S.coeff(f,f+1),
+ a21 = m_S.coeff(f+1,f), a22 = m_S.coeff(f+1,f+1),
+ a32 = m_S.coeff(f+2,f+1),
+
+ a88 = m_S.coeff(l-1,l-1), a89 = m_S.coeff(l-1,l),
+ a98 = m_S.coeff(l,l-1), a99 = m_S.coeff(l,l),
+
+ b11 = m_T.coeff(f,f), b12 = m_T.coeff(f,f+1),
+ b22 = m_T.coeff(f+1,f+1),
+
+ b88 = m_T.coeff(l-1,l-1), b89 = m_T.coeff(l-1,l),
+ b99 = m_T.coeff(l,l);
+
+ x = ( (a88/b88 - a11/b11)*(a99/b99 - a11/b11) - (a89/b99)*(a98/b88) + (a98/b88)*(b89/b99)*(a11/b11) ) * (b11/a21)
+ + a12/b22 - (a11/b11)*(b12/b22);
+ y = (a22/b22-a11/b11) - (a21/b11)*(b12/b22) - (a88/b88-a11/b11) - (a99/b99-a11/b11) + (a98/b88)*(b89/b99);
+ z = a32/b22;
+ }
+
+ JRs G;
+
+ for (Index k=f; k<=l-2; k++)
+ {
+ // variables for Householder reflections
+ Vector2s essential2;
+ Scalar tau, beta;
+
+ Vector3s hr(x,y,z);
+
+ // Q_k to annihilate S(k+1,k-1) and S(k+2,k-1)
+ hr.makeHouseholderInPlace(tau, beta);
+ essential2 = hr.template bottomRows<2>();
+ Index fc=(std::max)(k-1,Index(0)); // first col to update
+ m_S.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data());
+ m_T.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data());
+ if (m_computeQZ)
+ m_Q.template middleCols<3>(k).applyHouseholderOnTheRight(essential2, tau, m_workspace.data());
+ if (k>f)
+ m_S.coeffRef(k+2,k-1) = m_S.coeffRef(k+1,k-1) = Scalar(0.0);
+
+ // Z_{k1} to annihilate T(k+2,k+1) and T(k+2,k)
+ hr << m_T.coeff(k+2,k+2),m_T.coeff(k+2,k),m_T.coeff(k+2,k+1);
+ hr.makeHouseholderInPlace(tau, beta);
+ essential2 = hr.template bottomRows<2>();
+ {
+ Index lr = (std::min)(k+4,dim); // last row to update
+ Map<Matrix<Scalar,Dynamic,1> > tmp(m_workspace.data(),lr);
+ // S
+ tmp = m_S.template middleCols<2>(k).topRows(lr) * essential2;
+ tmp += m_S.col(k+2).head(lr);
+ m_S.col(k+2).head(lr) -= tau*tmp;
+ m_S.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint();
+ // T
+ tmp = m_T.template middleCols<2>(k).topRows(lr) * essential2;
+ tmp += m_T.col(k+2).head(lr);
+ m_T.col(k+2).head(lr) -= tau*tmp;
+ m_T.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint();
+ }
+ if (m_computeQZ)
+ {
+ // Z
+ Map<Matrix<Scalar,1,Dynamic> > tmp(m_workspace.data(),dim);
+ tmp = essential2.adjoint()*(m_Z.template middleRows<2>(k));
+ tmp += m_Z.row(k+2);
+ m_Z.row(k+2) -= tau*tmp;
+ m_Z.template middleRows<2>(k) -= essential2 * (tau*tmp);
+ }
+ m_T.coeffRef(k+2,k) = m_T.coeffRef(k+2,k+1) = Scalar(0.0);
+
+ // Z_{k2} to annihilate T(k+1,k)
+ G.makeGivens(m_T.coeff(k+1,k+1), m_T.coeff(k+1,k));
+ m_S.applyOnTheRight(k+1,k,G);
+ m_T.applyOnTheRight(k+1,k,G);
+ // update Z
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(k+1,k,G.adjoint());
+ m_T.coeffRef(k+1,k) = Scalar(0.0);
+
+ // update x,y,z
+ x = m_S.coeff(k+1,k);
+ y = m_S.coeff(k+2,k);
+ if (k < l-2)
+ z = m_S.coeff(k+3,k);
+ } // loop over k
+
+ // Q_{n-1} to annihilate y = S(l,l-2)
+ G.makeGivens(x,y);
+ m_S.applyOnTheLeft(l-1,l,G.adjoint());
+ m_T.applyOnTheLeft(l-1,l,G.adjoint());
+ if (m_computeQZ)
+ m_Q.applyOnTheRight(l-1,l,G);
+ m_S.coeffRef(l,l-2) = Scalar(0.0);
+
+ // Z_{n-1} to annihilate T(l,l-1)
+ G.makeGivens(m_T.coeff(l,l),m_T.coeff(l,l-1));
+ m_S.applyOnTheRight(l,l-1,G);
+ m_T.applyOnTheRight(l,l-1,G);
+ if (m_computeQZ)
+ m_Z.applyOnTheLeft(l,l-1,G.adjoint());
+ m_T.coeffRef(l,l-1) = Scalar(0.0);
+ }
+
+
+ template<typename MatrixType>
+ RealQZ<MatrixType>& RealQZ<MatrixType>::compute(const MatrixType& A_in, const MatrixType& B_in, bool computeQZ)
+ {
+
+ const Index dim = A_in.cols();
+
+ eigen_assert (A_in.rows()==dim && A_in.cols()==dim
+ && B_in.rows()==dim && B_in.cols()==dim
+ && "Need square matrices of the same dimension");
+
+ m_isInitialized = true;
+ m_computeQZ = computeQZ;
+ m_S = A_in; m_T = B_in;
+ m_workspace.resize(dim*2);
+ m_global_iter = 0;
+
+ // entrance point: hessenberg triangular decomposition
+ hessenbergTriangular();
+ // compute L1 vector norms of T, S into m_normOfS, m_normOfT
+ computeNorms();
+
+ Index l = dim-1,
+ f,
+ local_iter = 0;
+
+ while (l>0 && local_iter<m_maxIters)
+ {
+ f = findSmallSubdiagEntry(l);
+ // now rows and columns f..l (including) decouple from the rest of the problem
+ if (f>0) m_S.coeffRef(f,f-1) = Scalar(0.0);
+ if (f == l) // One root found
+ {
+ l--;
+ local_iter = 0;
+ }
+ else if (f == l-1) // Two roots found
+ {
+ splitOffTwoRows(f);
+ l -= 2;
+ local_iter = 0;
+ }
+ else // No convergence yet
+ {
+ // if there's zero on diagonal of T, we can isolate an eigenvalue with Givens rotations
+ Index z = findSmallDiagEntry(f,l);
+ if (z>=f)
+ {
+ // zero found
+ pushDownZero(z,f,l);
+ }
+ else
+ {
+ // We are sure now that S.block(f,f, l-f+1,l-f+1) is underuced upper-Hessenberg
+ // and T.block(f,f, l-f+1,l-f+1) is invertible uper-triangular, which allows to
+ // apply a QR-like iteration to rows and columns f..l.
+ step(f,l, local_iter);
+ local_iter++;
+ m_global_iter++;
+ }
+ }
+ }
+ // check if we converged before reaching iterations limit
+ m_info = (local_iter<m_maxIters) ? Success : NoConvergence;
+ return *this;
+ } // end compute
+
+} // end namespace Eigen
+
+#endif //EIGEN_REAL_QZ
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h
index 781692eccd3..64d13634141 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h
@@ -2,7 +2,7 @@
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -86,7 +86,8 @@ template<typename _MatrixType> class RealSchur
m_workspaceVector(size),
m_hess(size),
m_isInitialized(false),
- m_matUisUptodate(false)
+ m_matUisUptodate(false),
+ m_maxIters(-1)
{ }
/** \brief Constructor; computes real Schur decomposition of given matrix.
@@ -105,7 +106,8 @@ template<typename _MatrixType> class RealSchur
m_workspaceVector(matrix.rows()),
m_hess(matrix.rows()),
m_isInitialized(false),
- m_matUisUptodate(false)
+ m_matUisUptodate(false),
+ m_maxIters(-1)
{
compute(matrix, computeU);
}
@@ -160,9 +162,30 @@ template<typename _MatrixType> class RealSchur
*
* Example: \include RealSchur_compute.cpp
* Output: \verbinclude RealSchur_compute.out
+ *
+ * \sa compute(const MatrixType&, bool, Index)
*/
RealSchur& compute(const MatrixType& matrix, bool computeU = true);
+ /** \brief Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T
+ * \param[in] matrixH Matrix in Hessenberg form H
+ * \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T
+ * \param computeU Computes the matriX U of the Schur vectors
+ * \return Reference to \c *this
+ *
+ * This routine assumes that the matrix is already reduced in Hessenberg form matrixH
+ * using either the class HessenbergDecomposition or another mean.
+ * It computes the upper quasi-triangular matrix T of the Schur decomposition of H
+ * When computeU is true, this routine computes the matrix U such that
+ * A = U T U^T = (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix
+ *
+ * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix
+ * is not available, the user should give an identity matrix (Q.setIdentity())
+ *
+ * \sa compute(const MatrixType&, bool)
+ */
+ template<typename HessMatrixType, typename OrthMatrixType>
+ RealSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU);
/** \brief Reports whether previous computation was successful.
*
* \returns \c Success if computation was succesful, \c NoConvergence otherwise.
@@ -173,11 +196,29 @@ template<typename _MatrixType> class RealSchur
return m_info;
}
- /** \brief Maximum number of iterations.
+ /** \brief Sets the maximum number of iterations allowed.
+ *
+ * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size
+ * of the matrix.
+ */
+ RealSchur& setMaxIterations(Index maxIters)
+ {
+ m_maxIters = maxIters;
+ return *this;
+ }
+
+ /** \brief Returns the maximum number of iterations. */
+ Index getMaxIterations()
+ {
+ return m_maxIters;
+ }
+
+ /** \brief Maximum number of iterations per row.
*
- * Maximum number of iterations allowed for an eigenvalue to converge.
+ * If not otherwise specified, the maximum number of iterations is this number times the size of the
+ * matrix. It is currently set to 40.
*/
- static const int m_maxIterations = 40;
+ static const int m_maxIterationsPerRow = 40;
private:
@@ -188,12 +229,13 @@ template<typename _MatrixType> class RealSchur
ComputationInfo m_info;
bool m_isInitialized;
bool m_matUisUptodate;
+ Index m_maxIters;
typedef Matrix<Scalar,3,1> Vector3s;
Scalar computeNormOfT();
- Index findSmallSubdiagEntry(Index iu, Scalar norm);
- void splitOffTwoRows(Index iu, bool computeU, Scalar exshift);
+ Index findSmallSubdiagEntry(Index iu, const Scalar& norm);
+ void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift);
void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo);
void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector);
void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace);
@@ -203,15 +245,30 @@ template<typename _MatrixType> class RealSchur
template<typename MatrixType>
RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix, bool computeU)
{
- assert(matrix.cols() == matrix.rows());
+ eigen_assert(matrix.cols() == matrix.rows());
+ Index maxIters = m_maxIters;
+ if (maxIters == -1)
+ maxIters = m_maxIterationsPerRow * matrix.rows();
// Step 1. Reduce to Hessenberg form
m_hess.compute(matrix);
- m_matT = m_hess.matrixH();
- if (computeU)
- m_matU = m_hess.matrixQ();
// Step 2. Reduce to real Schur form
+ computeFromHessenberg(m_hess.matrixH(), m_hess.matrixQ(), computeU);
+
+ return *this;
+}
+template<typename MatrixType>
+template<typename HessMatrixType, typename OrthMatrixType>
+RealSchur<MatrixType>& RealSchur<MatrixType>::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU)
+{
+ m_matT = matrixH;
+ if(computeU)
+ m_matU = matrixQ;
+
+ Index maxIters = m_maxIters;
+ if (maxIters == -1)
+ maxIters = m_maxIterationsPerRow * matrixH.rows();
m_workspaceVector.resize(m_matT.cols());
Scalar* workspace = &m_workspaceVector.coeffRef(0);
@@ -220,8 +277,9 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix,
// Rows il,...,iu is the part we are working on (the active window).
// Rows iu+1,...,end are already brought in triangular form.
Index iu = m_matT.cols() - 1;
- Index iter = 0; // iteration count
- Scalar exshift(0); // sum of exceptional shifts
+ Index iter = 0; // iteration count for current eigenvalue
+ Index totalIter = 0; // iteration count for whole matrix
+ Scalar exshift(0); // sum of exceptional shifts
Scalar norm = computeNormOfT();
if(norm!=0)
@@ -251,14 +309,15 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix,
Vector3s firstHouseholderVector(0,0,0), shiftInfo;
computeShift(iu, iter, exshift, shiftInfo);
iter = iter + 1;
- if (iter > m_maxIterations * m_matT.cols()) break;
+ totalIter = totalIter + 1;
+ if (totalIter > maxIters) break;
Index im;
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
}
}
}
- if(iter <= m_maxIterations * m_matT.cols())
+ if(totalIter <= maxIters)
m_info = Success;
else
m_info = NoConvergence;
@@ -278,21 +337,22 @@ inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
// + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
Scalar norm(0);
for (Index j = 0; j < size; ++j)
- norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
+ norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
return norm;
}
/** \internal Look for single small sub-diagonal element and returns its index */
template<typename MatrixType>
-inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, Scalar norm)
+inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, const Scalar& norm)
{
+ using std::abs;
Index res = iu;
while (res > 0)
{
- Scalar s = internal::abs(m_matT.coeff(res-1,res-1)) + internal::abs(m_matT.coeff(res,res));
+ Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));
if (s == 0.0)
s = norm;
- if (internal::abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
+ if (abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
break;
res--;
}
@@ -301,8 +361,10 @@ inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(I
/** \internal Update T given that rows iu-1 and iu decouple from the rest. */
template<typename MatrixType>
-inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scalar exshift)
+inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift)
{
+ using std::sqrt;
+ using std::abs;
const Index size = m_matT.cols();
// The eigenvalues of the 2x2 matrix [a b; c d] are
@@ -314,7 +376,7 @@ inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scal
if (q >= Scalar(0)) // Two real eigenvalues
{
- Scalar z = internal::sqrt(internal::abs(q));
+ Scalar z = sqrt(abs(q));
JacobiRotation<Scalar> rot;
if (p >= Scalar(0))
rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
@@ -336,6 +398,8 @@ inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scal
template<typename MatrixType>
inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo)
{
+ using std::sqrt;
+ using std::abs;
shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);
@@ -346,7 +410,7 @@ inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& ex
exshift += shiftInfo.coeff(0);
for (Index i = 0; i <= iu; ++i)
m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
- Scalar s = internal::abs(m_matT.coeff(iu,iu-1)) + internal::abs(m_matT.coeff(iu-1,iu-2));
+ Scalar s = abs(m_matT.coeff(iu,iu-1)) + abs(m_matT.coeff(iu-1,iu-2));
shiftInfo.coeffRef(0) = Scalar(0.75) * s;
shiftInfo.coeffRef(1) = Scalar(0.75) * s;
shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
@@ -359,7 +423,7 @@ inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& ex
s = s * s + shiftInfo.coeff(2);
if (s > Scalar(0))
{
- s = internal::sqrt(s);
+ s = sqrt(s);
if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
s = -s;
s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
@@ -376,6 +440,7 @@ inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& ex
template<typename MatrixType>
inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector)
{
+ using std::abs;
Vector3s& v = firstHouseholderVector; // alias to save typing
for (im = iu-2; im >= il; --im)
@@ -389,9 +454,9 @@ inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const V
if (im == il) {
break;
}
- const Scalar lhs = m_matT.coeff(im,im-1) * (internal::abs(v.coeff(1)) + internal::abs(v.coeff(2)));
- const Scalar rhs = v.coeff(0) * (internal::abs(m_matT.coeff(im-1,im-1)) + internal::abs(Tmm) + internal::abs(m_matT.coeff(im+1,im+1)));
- if (internal::abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
+ const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
+ const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1)));
+ if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
{
break;
}
@@ -402,8 +467,8 @@ inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const V
template<typename MatrixType>
inline void RealSchur<MatrixType>::performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace)
{
- assert(im >= il);
- assert(im <= iu-2);
+ eigen_assert(im >= il);
+ eigen_assert(im <= iu-2);
const Index size = m_matT.cols();
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h
index 960ec3c764a..ad973646028 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h
@@ -48,7 +48,7 @@ RealSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<E
typedef MatrixType::Scalar Scalar; \
typedef MatrixType::RealScalar RealScalar; \
\
- assert(matrix.cols() == matrix.rows()); \
+ eigen_assert(matrix.cols() == matrix.rows()); \
\
lapack_int n = matrix.cols(), sdim, info; \
lapack_int lda = matrix.outerStride(); \
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index acc5576feb1..3993046a88e 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -384,6 +384,7 @@ template<typename MatrixType>
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
::compute(const MatrixType& matrix, int options)
{
+ using std::abs;
eigen_assert(matrix.cols() == matrix.rows());
eigen_assert((options&~(EigVecMask|GenEigMask))==0
&& (options&EigVecMask)!=EigVecMask
@@ -394,7 +395,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
if(n==1)
{
- m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0));
+ m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0));
if(computeEigenvectors)
m_eivec.setOnes(n,n);
m_info = Success;
@@ -408,9 +409,10 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
MatrixType& mat = m_eivec;
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
- RealScalar scale = matrix.cwiseAbs().maxCoeff();
+ mat = matrix.template triangularView<Lower>();
+ RealScalar scale = mat.cwiseAbs().maxCoeff();
if(scale==RealScalar(0)) scale = RealScalar(1);
- mat = matrix / scale;
+ mat.template triangularView<Lower>() /= scale;
m_subdiag.resize(n-1);
internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors);
@@ -421,7 +423,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
while (end>0)
{
for (Index i = start; i<end; ++i)
- if (internal::isMuchSmallerThan(internal::abs(m_subdiag[i]),(internal::abs(diag[i])+internal::abs(diag[i+1]))))
+ if (internal::isMuchSmallerThan(abs(m_subdiag[i]),(abs(diag[i])+abs(diag[i+1]))))
m_subdiag[i] = 0;
// find the largest unreduced block
@@ -667,7 +669,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
static inline void computeRoots(const MatrixType& m, VectorType& roots)
{
using std::sqrt;
- const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
+ const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
roots(0) = t1 - t0;
roots(1) = t1 + t0;
@@ -675,6 +677,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
static inline void run(SolverType& solver, const MatrixType& mat, int options)
{
+ using std::sqrt;
eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
eigen_assert((options&~(EigVecMask|GenEigMask))==0
&& (options&EigVecMask)!=EigVecMask
@@ -696,9 +699,9 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
if(computeEigenvectors)
{
scaledMat.diagonal().array () -= eivals(1);
- Scalar a2 = abs2(scaledMat(0,0));
- Scalar c2 = abs2(scaledMat(1,1));
- Scalar b2 = abs2(scaledMat(1,0));
+ Scalar a2 = numext::abs2(scaledMat(0,0));
+ Scalar c2 = numext::abs2(scaledMat(1,1));
+ Scalar b2 = numext::abs2(scaledMat(1,0));
if(a2>c2)
{
eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
@@ -736,14 +739,24 @@ namespace internal {
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
{
+ using std::abs;
RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
RealScalar e = subdiag[end-1];
// Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
// underflow thus leading to inf/NaN values when using the following commented code:
-// RealScalar e2 = abs2(subdiag[end-1]);
+// RealScalar e2 = numext::abs2(subdiag[end-1]);
// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
// This explain the following, somewhat more complicated, version:
- RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e));
+ RealScalar mu = diag[end];
+ if(td==0)
+ mu -= abs(e);
+ else
+ {
+ RealScalar e2 = numext::abs2(subdiag[end-1]);
+ RealScalar h = numext::hypot(td,e);
+ if(e2==0) mu -= (e / (td + (td>0 ? 1 : -1))) * (e / h);
+ else mu -= e2 / (td + (td>0 ? h : -h));
+ }
RealScalar x = diag[start] - mu;
RealScalar z = subdiag[start];
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
index 9380956b5f9..17c0dadd23e 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
@@ -40,7 +40,7 @@ namespace Eigen {
/** \internal Specialization for the data types supported by MKL */
#define EIGEN_MKL_EIG_SELFADJ(EIGTYPE, MKLTYPE, MKLRTYPE, MKLNAME, EIGCOLROW, MKLCOLROW ) \
-template<> inline\
+template<> inline \
SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \
SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, int options) \
{ \
@@ -56,7 +56,7 @@ SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(c
\
if(n==1) \
{ \
- m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0)); \
+ m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0)); \
if(computeEigenvectors) m_eivec.setOnes(n,n); \
m_info = Success; \
m_isInitialized = true; \
diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h
index c34b7b3b801..192278d685d 100644
--- a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h
@@ -96,7 +96,7 @@ template<typename _MatrixType> class Tridiagonalization
>::type SubDiagonalReturnType;
/** \brief Return type of matrixQ() */
- typedef typename HouseholderSequence<MatrixType,CoeffVectorType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
/** \brief Default constructor.
*
@@ -345,6 +345,7 @@ namespace internal {
template<typename MatrixType, typename CoeffVectorType>
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
{
+ using numext::conj;
typedef typename MatrixType::Index Index;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
@@ -425,8 +426,6 @@ struct tridiagonalization_inplace_selector;
template<typename MatrixType, typename DiagonalType, typename SubDiagonalType>
void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
{
- typedef typename MatrixType::Index Index;
- //Index n = mat.rows();
eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1);
tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, extractQ);
}
@@ -467,8 +466,9 @@ struct tridiagonalization_inplace_selector<MatrixType,3,false>
template<typename DiagonalType, typename SubDiagonalType>
static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
{
+ using std::sqrt;
diag[0] = mat(0,0);
- RealScalar v1norm2 = abs2(mat(2,0));
+ RealScalar v1norm2 = numext::abs2(mat(2,0));
if(v1norm2 == RealScalar(0))
{
diag[1] = mat(1,1);
@@ -480,7 +480,7 @@ struct tridiagonalization_inplace_selector<MatrixType,3,false>
}
else
{
- RealScalar beta = sqrt(abs2(mat(1,0)) + v1norm2);
+ RealScalar beta = sqrt(numext::abs2(mat(1,0)) + v1norm2);
RealScalar invBeta = RealScalar(1)/beta;
Scalar m01 = mat(1,0) * invBeta;
Scalar m02 = mat(2,0) * invBeta;
@@ -510,7 +510,7 @@ struct tridiagonalization_inplace_selector<MatrixType,1,IsComplex>
template<typename DiagonalType, typename SubDiagonalType>
static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, bool extractQ)
{
- diag(0,0) = real(mat(0,0));
+ diag(0,0) = numext::real(mat(0,0));
if(extractQ)
mat(0,0) = Scalar(1);
}
diff --git a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h
index 5830fcd35fc..8e186d57a34 100644
--- a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h
+++ b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h
@@ -56,7 +56,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
/** Default constructor initializing a null box. */
- inline explicit AlignedBox()
+ inline AlignedBox()
{ if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */
@@ -71,7 +71,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
template<typename Derived>
inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
{
- const typename internal::nested<Derived,2>::type p(a_p.derived());
+ typename internal::nested<Derived,2>::type p(a_p.derived());
m_min = p;
m_max = p;
}
@@ -79,7 +79,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
~AlignedBox() {}
/** \returns the dimension in which the box holds */
- inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : Index(AmbientDimAtCompileTime); }
+ inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size() : Index(AmbientDimAtCompileTime); }
/** \deprecated use isEmpty */
inline bool isNull() const { return isEmpty(); }
@@ -248,14 +248,14 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
*/
template<typename Derived>
inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const
- { return internal::sqrt(NonInteger(squaredExteriorDistance(p))); }
+ { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(p))); }
/** \returns the distance between the boxes \a b and \c *this,
* and zero if the boxes intersect.
* \sa squaredExteriorDistance()
*/
inline NonInteger exteriorDistance(const AlignedBox& b) const
- { return internal::sqrt(NonInteger(squaredExteriorDistance(b))); }
+ { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); }
/** \returns \c *this with scalar type casted to \a NewScalarType
*
@@ -282,7 +282,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const AlignedBox& other, RealScalar prec = ScalarTraits::dummy_precision()) const
+ bool isApprox(const AlignedBox& other, const RealScalar& prec = ScalarTraits::dummy_precision()) const
{ return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
protected:
@@ -296,7 +296,7 @@ template<typename Scalar,int AmbientDim>
template<typename Derived>
inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const MatrixBase<Derived>& a_p) const
{
- const typename internal::nested<Derived,2*AmbientDim>::type p(a_p.derived());
+ typename internal::nested<Derived,2*AmbientDim>::type p(a_p.derived());
Scalar dist2(0);
Scalar aux;
for (Index k=0; k<dim(); ++k)
diff --git a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h
index 67197ac78c3..553d38c7449 100644
--- a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h
+++ b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h
@@ -76,7 +76,7 @@ public:
* \warning If the \a axis vector is not normalized, then the angle-axis object
* represents an invalid rotation. */
template<typename Derived>
- inline AngleAxis(Scalar angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
+ inline AngleAxis(const Scalar& angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
/** Constructs and initialize the angle-axis rotation from a quaternion \a q. */
template<typename QuatDerived> inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) { *this = q; }
/** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
@@ -137,7 +137,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const AngleAxis& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_axis.isApprox(other.m_axis, prec) && internal::isApprox(m_angle,other.m_angle, prec); }
};
@@ -161,6 +161,7 @@ AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived
using std::acos;
using std::min;
using std::max;
+ using std::sqrt;
Scalar n2 = q.vec().squaredNorm();
if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
{
@@ -170,7 +171,7 @@ AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived
else
{
m_angle = Scalar(2)*acos((min)((max)(Scalar(-1),q.w()),Scalar(1)));
- m_axis = q.vec() / internal::sqrt(n2);
+ m_axis = q.vec() / sqrt(n2);
}
return *this;
}
@@ -202,9 +203,11 @@ template<typename Scalar>
typename AngleAxis<Scalar>::Matrix3
AngleAxis<Scalar>::toRotationMatrix(void) const
{
+ using std::sin;
+ using std::cos;
Matrix3 res;
- Vector3 sin_axis = internal::sin(m_angle) * m_axis;
- Scalar c = internal::cos(m_angle);
+ Vector3 sin_axis = sin(m_angle) * m_axis;
+ Scalar c = cos(m_angle);
Vector3 cos1_axis = (Scalar(1)-c) * m_axis;
Scalar tmp;
diff --git a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h
index e424d240604..82802fb43cf 100644
--- a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h
+++ b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h
@@ -27,55 +27,75 @@ namespace Eigen {
* * AngleAxisf(ea[1], Vector3f::UnitX())
* * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode
* This corresponds to the right-multiply conventions (with right hand side frames).
+ *
+ * The returned angles are in the ranges [0:pi]x[-pi:pi]x[-pi:pi].
+ *
+ * \sa class AngleAxis
*/
template<typename Derived>
inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const
{
+ using std::atan2;
+ using std::sin;
+ using std::cos;
/* Implemented from Graphics Gems IV */
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
Matrix<Scalar,3,1> res;
typedef Matrix<typename Derived::Scalar,2,1> Vector2;
- const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
const Index i = a0;
const Index j = (a0 + 1 + odd)%3;
const Index k = (a0 + 2 - odd)%3;
-
+
if (a0==a2)
{
- Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
- res[1] = internal::atan2(s, coeff(i,i));
- if (s > epsilon)
+ res[0] = atan2(coeff(j,i), coeff(k,i));
+ if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0)))
{
- res[0] = internal::atan2(coeff(j,i), coeff(k,i));
- res[2] = internal::atan2(coeff(i,j),-coeff(i,k));
+ res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
+ Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
+ res[1] = -atan2(s2, coeff(i,i));
}
else
{
- res[0] = Scalar(0);
- res[2] = (coeff(i,i)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
+ Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
+ res[1] = atan2(s2, coeff(i,i));
}
- }
+
+ // With a=(0,1,0), we have i=0; j=1; k=2, and after computing the first two angles,
+ // we can compute their respective rotation, and apply its inverse to M. Since the result must
+ // be a rotation around x, we have:
+ //
+ // c2 s1.s2 c1.s2 1 0 0
+ // 0 c1 -s1 * M = 0 c3 s3
+ // -s2 s1.c2 c1.c2 0 -s3 c3
+ //
+ // Thus: m11.c1 - m21.s1 = c3 & m12.c1 - m22.s1 = s3
+
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(c1*coeff(j,k)-s1*coeff(k,k), c1*coeff(j,j) - s1 * coeff(k,j));
+ }
else
{
- Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
- res[1] = internal::atan2(-coeff(i,k), c);
- if (c > epsilon)
- {
- res[0] = internal::atan2(coeff(j,k), coeff(k,k));
- res[2] = internal::atan2(coeff(i,j), coeff(i,i));
+ res[0] = atan2(coeff(j,k), coeff(k,k));
+ Scalar c2 = Vector2(coeff(i,i), coeff(i,j)).norm();
+ if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0))) {
+ res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
+ res[1] = atan2(-coeff(i,k), -c2);
}
else
- {
- res[0] = Scalar(0);
- res[2] = (coeff(i,k)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
- }
+ res[1] = atan2(-coeff(i,k), c2);
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(s1*coeff(k,i)-c1*coeff(j,i), c1*coeff(j,j) - s1 * coeff(k,j));
}
if (!odd)
res = -res;
+
return res;
}
diff --git a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h
index df03feb55c6..00e71d190c3 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h
@@ -59,7 +59,7 @@ template<typename MatrixType,typename Rhs> struct homogeneous_right_product_impl
} // end namespace internal
template<typename MatrixType,int _Direction> class Homogeneous
- : public MatrixBase<Homogeneous<MatrixType,_Direction> >
+ : internal::no_assignment_operator, public MatrixBase<Homogeneous<MatrixType,_Direction> >
{
public:
diff --git a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h
index 1b7c7c78c80..aeff43fefa6 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h
@@ -50,7 +50,7 @@ public:
typedef const Block<const Coefficients,AmbientDimAtCompileTime,1> ConstNormalReturnType;
/** Default constructor without initialization */
- inline explicit Hyperplane() {}
+ inline Hyperplane() {}
template<int OtherOptions>
Hyperplane(const Hyperplane<Scalar,AmbientDimAtCompileTime,OtherOptions>& other)
@@ -75,7 +75,7 @@ public:
* such that the algebraic equation of the plane is \f$ n \cdot x + d = 0 \f$.
* \warning the vector normal is assumed to be normalized.
*/
- inline Hyperplane(const VectorType& n, Scalar d)
+ inline Hyperplane(const VectorType& n, const Scalar& d)
: m_coeffs(n.size()+1)
{
normal() = n;
@@ -135,7 +135,7 @@ public:
/** \returns the absolute distance between the plane \c *this and a point \a p.
* \sa signedDistance()
*/
- inline Scalar absDistance(const VectorType& p) const { return internal::abs(signedDistance(p)); }
+ inline Scalar absDistance(const VectorType& p) const { using std::abs; return abs(signedDistance(p)); }
/** \returns the projection of a point \a p onto the plane \c *this.
*/
@@ -178,13 +178,14 @@ public:
*/
VectorType intersection(const Hyperplane& other) const
{
+ using std::abs;
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
// since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests
// whether the two lines are approximately parallel.
if(internal::isMuchSmallerThan(det, Scalar(1)))
{ // special case where the two lines are approximately parallel. Pick any point on the first line.
- if(internal::abs(coeffs().coeff(1))>internal::abs(coeffs().coeff(0)))
+ if(abs(coeffs().coeff(1))>abs(coeffs().coeff(0)))
return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0));
else
return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0));
@@ -256,7 +257,7 @@ public:
*
* \sa MatrixBase::isApprox() */
template<int OtherOptions>
- bool isApprox(const Hyperplane<Scalar,AmbientDimAtCompileTime,OtherOptions>& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const Hyperplane<Scalar,AmbientDimAtCompileTime,OtherOptions>& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
protected:
diff --git a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h
index 11ad5829cda..556bc81604e 100644
--- a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h
+++ b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h
@@ -33,9 +33,9 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
typename internal::nested<Derived,2>::type lhs(derived());
typename internal::nested<OtherDerived,2>::type rhs(other.derived());
return typename cross_product_return_type<OtherDerived>::type(
- internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
- internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
- internal::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0))
+ numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
+ numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
+ numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0))
);
}
@@ -49,9 +49,9 @@ struct cross3_impl {
run(const VectorLhs& lhs, const VectorRhs& rhs)
{
return typename internal::plain_matrix_type<VectorLhs>::type(
- internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
- internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
- internal::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)),
+ numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
+ numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
+ numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)),
0
);
}
@@ -78,8 +78,8 @@ MatrixBase<Derived>::cross3(const MatrixBase<OtherDerived>& other) const
typedef typename internal::nested<Derived,2>::type DerivedNested;
typedef typename internal::nested<OtherDerived,2>::type OtherDerivedNested;
- const DerivedNested lhs(derived());
- const OtherDerivedNested rhs(other.derived());
+ DerivedNested lhs(derived());
+ OtherDerivedNested rhs(other.derived());
return internal::cross3_impl<Architecture::Target,
typename internal::remove_all<DerivedNested>::type,
@@ -141,8 +141,8 @@ struct unitOrthogonal_selector
if (maxi==0)
sndi = 1;
RealScalar invnm = RealScalar(1)/(Vector2() << src.coeff(sndi),src.coeff(maxi)).finished().norm();
- perp.coeffRef(maxi) = -conj(src.coeff(sndi)) * invnm;
- perp.coeffRef(sndi) = conj(src.coeff(maxi)) * invnm;
+ perp.coeffRef(maxi) = -numext::conj(src.coeff(sndi)) * invnm;
+ perp.coeffRef(sndi) = numext::conj(src.coeff(maxi)) * invnm;
return perp;
}
@@ -168,8 +168,8 @@ struct unitOrthogonal_selector<Derived,3>
|| (!isMuchSmallerThan(src.y(), src.z())))
{
RealScalar invnm = RealScalar(1)/src.template head<2>().norm();
- perp.coeffRef(0) = -conj(src.y())*invnm;
- perp.coeffRef(1) = conj(src.x())*invnm;
+ perp.coeffRef(0) = -numext::conj(src.y())*invnm;
+ perp.coeffRef(1) = numext::conj(src.x())*invnm;
perp.coeffRef(2) = 0;
}
/* if both x and y are close to zero, then the vector is close
@@ -180,8 +180,8 @@ struct unitOrthogonal_selector<Derived,3>
{
RealScalar invnm = RealScalar(1)/src.template tail<2>().norm();
perp.coeffRef(0) = 0;
- perp.coeffRef(1) = -conj(src.z())*invnm;
- perp.coeffRef(2) = conj(src.y())*invnm;
+ perp.coeffRef(1) = -numext::conj(src.z())*invnm;
+ perp.coeffRef(2) = numext::conj(src.y())*invnm;
}
return perp;
@@ -193,7 +193,7 @@ struct unitOrthogonal_selector<Derived,2>
{
typedef typename plain_matrix_type<Derived>::type VectorType;
static inline VectorType run(const Derived& src)
- { return VectorType(-conj(src.y()), conj(src.x())).normalized(); }
+ { return VectorType(-numext::conj(src.y()), numext::conj(src.x())).normalized(); }
};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h
index 719a904413d..77fa228e6a5 100644
--- a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h
+++ b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h
@@ -41,7 +41,7 @@ public:
typedef Matrix<Scalar,AmbientDimAtCompileTime,1,Options> VectorType;
/** Default constructor without initialization */
- inline explicit ParametrizedLine() {}
+ inline ParametrizedLine() {}
template<int OtherOptions>
ParametrizedLine(const ParametrizedLine<Scalar,AmbientDimAtCompileTime,OtherOptions>& other)
@@ -87,13 +87,13 @@ public:
/** \returns the distance of a point \a p to its projection onto the line \c *this.
* \sa squaredDistance()
*/
- RealScalar distance(const VectorType& p) const { return internal::sqrt(squaredDistance(p)); }
+ RealScalar distance(const VectorType& p) const { using std::sqrt; return sqrt(squaredDistance(p)); }
/** \returns the projection of a point \a p onto the line \c *this. */
VectorType projection(const VectorType& p) const
{ return origin() + direction().dot(p-origin()) * direction(); }
- VectorType pointAt( Scalar t ) const;
+ VectorType pointAt(const Scalar& t) const;
template <int OtherOptions>
Scalar intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const;
@@ -154,7 +154,7 @@ inline ParametrizedLine<_Scalar, _AmbientDim,_Options>::ParametrizedLine(const H
*/
template <typename _Scalar, int _AmbientDim, int _Options>
inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType
-ParametrizedLine<_Scalar, _AmbientDim,_Options>::pointAt( _Scalar t ) const
+ParametrizedLine<_Scalar, _AmbientDim,_Options>::pointAt(const _Scalar& t) const
{
return origin() + (direction()*t);
}
diff --git a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h
index 8792e2da2ae..9fee0c91980 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h
@@ -150,18 +150,14 @@ public:
/** \returns the conjugated quaternion */
Quaternion<Scalar> conjugate() const;
- /** \returns an interpolation for a constant motion between \a other and \c *this
- * \a t in [0;1]
- * see http://en.wikipedia.org/wiki/Slerp
- */
- template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
+ template<class OtherDerived> Quaternion<Scalar> slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const;
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
template<class OtherDerived>
- bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const QuaternionBase<OtherDerived>& other, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
{ return coeffs().isApprox(other.coeffs(), prec); }
/** return the result vector of \a v through the rotation*/
@@ -193,11 +189,12 @@ public:
*
* \brief The quaternion class used to represent 3D orientations and rotations
*
- * \param _Scalar the scalar type, i.e., the type of the coefficients
+ * \tparam _Scalar the scalar type, i.e., the type of the coefficients
+ * \tparam _Options controls the memory alignment of the coefficients. Can be \# AutoAlign or \# DontAlign. Default is AutoAlign.
*
* This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of
* orientations and rotations of objects in three dimensions. Compared to other representations
- * like Euler angles or 3x3 matrices, quatertions offer the following advantages:
+ * like Euler angles or 3x3 matrices, quaternions offer the following advantages:
* \li \b compact storage (4 scalars)
* \li \b efficient to compose (28 flops),
* \li \b stable spherical interpolation
@@ -248,7 +245,7 @@ public:
* while internally the coefficients are stored in the following order:
* [\c x, \c y, \c z, \c w]
*/
- inline Quaternion(Scalar w, Scalar x, Scalar y, Scalar z) : m_coeffs(x, y, z, w){}
+ inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z) : m_coeffs(x, y, z, w){}
/** Constructs and initialize a quaternion from the array data */
inline Quaternion(const Scalar* data) : m_coeffs(data) {}
@@ -304,41 +301,29 @@ typedef Quaternion<double> Quaterniond;
namespace internal {
template<typename _Scalar, int _Options>
- struct traits<Map<Quaternion<_Scalar>, _Options> >:
- traits<Quaternion<_Scalar, _Options> >
+ struct traits<Map<Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
{
- typedef _Scalar Scalar;
typedef Map<Matrix<_Scalar,4,1>, _Options> Coefficients;
-
- typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
- enum {
- IsAligned = TraitsBase::IsAligned,
-
- Flags = TraitsBase::Flags
- };
};
}
namespace internal {
template<typename _Scalar, int _Options>
- struct traits<Map<const Quaternion<_Scalar>, _Options> >:
- traits<Quaternion<_Scalar> >
+ struct traits<Map<const Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
{
- typedef _Scalar Scalar;
typedef Map<const Matrix<_Scalar,4,1>, _Options> Coefficients;
-
- typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
+ typedef traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> > TraitsBase;
enum {
- IsAligned = TraitsBase::IsAligned,
Flags = TraitsBase::Flags & ~LvalueBit
};
};
}
-/** \brief Quaternion expression mapping a constant memory buffer
+/** \ingroup Geometry_Module
+ * \brief Quaternion expression mapping a constant memory buffer
*
- * \param _Scalar the type of the Quaternion coefficients
- * \param _Options see class Map
+ * \tparam _Scalar the type of the Quaternion coefficients
+ * \tparam _Options see class Map
*
* This is a specialization of class Map for Quaternion. This class allows to view
* a 4 scalar memory buffer as an Eigen's Quaternion object.
@@ -371,10 +356,11 @@ class Map<const Quaternion<_Scalar>, _Options >
const Coefficients m_coeffs;
};
-/** \brief Expression of a quaternion from a memory buffer
+/** \ingroup Geometry_Module
+ * \brief Expression of a quaternion from a memory buffer
*
- * \param _Scalar the type of the Quaternion coefficients
- * \param _Options see class Map
+ * \tparam _Scalar the type of the Quaternion coefficients
+ * \tparam _Options see class Map
*
* This is a specialization of class Map for Quaternion. This class allows to view
* a 4 scalar memory buffer as an Eigen's Quaternion object.
@@ -395,7 +381,7 @@ class Map<Quaternion<_Scalar>, _Options >
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
*
- * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
+ * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order:
* \code *coeffs == {x, y, z, w} \endcode
*
* If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */
@@ -409,16 +395,16 @@ class Map<Quaternion<_Scalar>, _Options >
};
/** \ingroup Geometry_Module
- * Map an unaligned array of single precision scalar as a quaternion */
+ * Map an unaligned array of single precision scalars as a quaternion */
typedef Map<Quaternion<float>, 0> QuaternionMapf;
/** \ingroup Geometry_Module
- * Map an unaligned array of double precision scalar as a quaternion */
+ * Map an unaligned array of double precision scalars as a quaternion */
typedef Map<Quaternion<double>, 0> QuaternionMapd;
/** \ingroup Geometry_Module
- * Map a 16-bits aligned array of double precision scalars as a quaternion */
+ * Map a 16-byte aligned array of single precision scalars as a quaternion */
typedef Map<Quaternion<float>, Aligned> QuaternionMapAlignedf;
/** \ingroup Geometry_Module
- * Map a 16-bits aligned array of double precision scalars as a quaternion */
+ * Map a 16-byte aligned array of double precision scalars as a quaternion */
typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
/***************************************************************************
@@ -505,9 +491,11 @@ EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const Quaternion
template<class Derived>
EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
{
+ using std::cos;
+ using std::sin;
Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
- this->w() = internal::cos(ha);
- this->vec() = internal::sin(ha) * aa.axis();
+ this->w() = cos(ha);
+ this->vec() = sin(ha) * aa.axis();
return derived();
}
@@ -581,12 +569,13 @@ template<typename Derived1, typename Derived2>
inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
{
using std::max;
+ using std::sqrt;
Vector3 v0 = a.normalized();
Vector3 v1 = b.normalized();
Scalar c = v1.dot(v0);
// if dot == -1, vectors are nearly opposites
- // => accuraletly compute the rotation axis by computing the
+ // => accurately compute the rotation axis by computing the
// intersection of the two planes. This is done by solving:
// x^T v0 = 0
// x^T v1 = 0
@@ -601,12 +590,12 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri
Vector3 axis = svd.matrixV().col(2);
Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
- this->w() = internal::sqrt(w2);
- this->vec() = axis * internal::sqrt(Scalar(1) - w2);
+ this->w() = sqrt(w2);
+ this->vec() = axis * sqrt(Scalar(1) - w2);
return derived();
}
Vector3 axis = v0.cross(v1);
- Scalar s = internal::sqrt((Scalar(1)+c)*Scalar(2));
+ Scalar s = sqrt((Scalar(1)+c)*Scalar(2));
Scalar invs = Scalar(1)/s;
this->vec() = axis * invs;
this->w() = s * Scalar(0.5);
@@ -677,24 +666,32 @@ inline typename internal::traits<Derived>::Scalar
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
{
using std::acos;
- double d = internal::abs(this->dot(other));
+ using std::abs;
+ double d = abs(this->dot(other));
if (d>=1.0)
return Scalar(0);
return static_cast<Scalar>(2 * acos(d));
}
+
+
/** \returns the spherical linear interpolation between the two quaternions
- * \c *this and \a other at the parameter \a t
+ * \c *this and \a other at the parameter \a t in [0;1].
+ *
+ * This represents an interpolation for a constant motion between \c *this and \a other,
+ * see also http://en.wikipedia.org/wiki/Slerp.
*/
template <class Derived>
template <class OtherDerived>
Quaternion<typename internal::traits<Derived>::Scalar>
-QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
+QuaternionBase<Derived>::slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
{
using std::acos;
+ using std::sin;
+ using std::abs;
static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
Scalar d = this->dot(other);
- Scalar absD = internal::abs(d);
+ Scalar absD = abs(d);
Scalar scale0;
Scalar scale1;
@@ -708,10 +705,10 @@ QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& oth
{
// theta is the angle between the 2 quaternions
Scalar theta = acos(absD);
- Scalar sinTheta = internal::sin(theta);
+ Scalar sinTheta = sin(theta);
- scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
- scale1 = internal::sin( ( t * theta) ) / sinTheta;
+ scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = sin( ( t * theta) ) / sinTheta;
}
if(d<0) scale1 = -scale1;
@@ -728,6 +725,7 @@ struct quaternionbase_assign_impl<Other,3,3>
typedef DenseIndex Index;
template<class Derived> static inline void run(QuaternionBase<Derived>& q, const Other& mat)
{
+ using std::sqrt;
// This algorithm comes from "Quaternion Calculus and Fast Animation",
// Ken Shoemake, 1987 SIGGRAPH course notes
Scalar t = mat.trace();
diff --git a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h
index 868e2ef312f..1cac343a5ee 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h
@@ -59,7 +59,7 @@ protected:
public:
/** Construct a 2D counter clock wise rotation from the angle \a a in radian. */
- inline Rotation2D(Scalar a) : m_angle(a) {}
+ inline Rotation2D(const Scalar& a) : m_angle(a) {}
/** \returns the rotation angle */
inline Scalar angle() const { return m_angle; }
@@ -89,7 +89,7 @@ public:
/** \returns the spherical interpolation between \c *this and \a other using
* parameter \a t. It is in fact equivalent to a linear interpolation.
*/
- inline Rotation2D slerp(Scalar t, const Rotation2D& other) const
+ inline Rotation2D slerp(const Scalar& t, const Rotation2D& other) const
{ return m_angle * (1-t) + other.angle() * t; }
/** \returns \c *this with scalar type casted to \a NewScalarType
@@ -114,7 +114,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const Rotation2D& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
{ return internal::isApprox(m_angle,other.m_angle, prec); }
};
@@ -133,8 +133,9 @@ template<typename Scalar>
template<typename Derived>
Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
{
+ using std::atan2;
EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
- m_angle = internal::atan2(mat.coeff(1,0), mat.coeff(0,0));
+ m_angle = atan2(mat.coeff(1,0), mat.coeff(0,0));
return *this;
}
@@ -144,8 +145,10 @@ template<typename Scalar>
typename Rotation2D<Scalar>::Matrix2
Rotation2D<Scalar>::toRotationMatrix(void) const
{
- Scalar sinA = internal::sin(m_angle);
- Scalar cosA = internal::cos(m_angle);
+ using std::sin;
+ using std::cos;
+ Scalar sinA = sin(m_angle);
+ Scalar cosA = cos(m_angle);
return (Matrix2() << cosA, -sinA, sinA, cosA).finished();
}
diff --git a/extern/Eigen3/Eigen/src/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Geometry/Scaling.h
index 8edcac31c74..1c25f36fe62 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Scaling.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Scaling.h
@@ -99,7 +99,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const UniformScaling& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
{ return internal::isApprox(m_factor, other.factor(), prec); }
};
@@ -122,11 +122,11 @@ static inline UniformScaling<std::complex<RealScalar> > Scaling(const std::compl
/** Constructs a 2D axis aligned scaling */
template<typename Scalar>
-static inline DiagonalMatrix<Scalar,2> Scaling(Scalar sx, Scalar sy)
+static inline DiagonalMatrix<Scalar,2> Scaling(const Scalar& sx, const Scalar& sy)
{ return DiagonalMatrix<Scalar,2>(sx, sy); }
/** Constructs a 3D axis aligned scaling */
template<typename Scalar>
-static inline DiagonalMatrix<Scalar,3> Scaling(Scalar sx, Scalar sy, Scalar sz)
+static inline DiagonalMatrix<Scalar,3> Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz)
{ return DiagonalMatrix<Scalar,3>(sx, sy, sz); }
/** Constructs an axis aligned scaling expression from vector expression \a coeffs
diff --git a/extern/Eigen3/Eigen/src/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Geometry/Transform.h
index 4c1ef8eaade..498fea41a90 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Transform.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Transform.h
@@ -506,8 +506,8 @@ public:
template<typename OtherDerived>
inline Transform& prescale(const MatrixBase<OtherDerived> &other);
- inline Transform& scale(Scalar s);
- inline Transform& prescale(Scalar s);
+ inline Transform& scale(const Scalar& s);
+ inline Transform& prescale(const Scalar& s);
template<typename OtherDerived>
inline Transform& translate(const MatrixBase<OtherDerived> &other);
@@ -521,8 +521,8 @@ public:
template<typename RotationType>
inline Transform& prerotate(const RotationType& rotation);
- Transform& shear(Scalar sx, Scalar sy);
- Transform& preshear(Scalar sx, Scalar sy);
+ Transform& shear(const Scalar& sx, const Scalar& sy);
+ Transform& preshear(const Scalar& sx, const Scalar& sy);
inline Transform& operator=(const TranslationType& t);
inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
@@ -530,9 +530,9 @@ public:
inline Transform& operator=(const UniformScaling<Scalar>& t);
inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
- inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry)> operator*(const UniformScaling<Scalar>& s) const
+ inline Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode))> operator*(const UniformScaling<Scalar>& s) const
{
- Transform<Scalar,Dim,(int(Mode)==int(Isometry)?Affine:Isometry),Options> res = *this;
+ Transform<Scalar,Dim,(int(Mode)==int(Isometry)?int(Affine):int(Mode)),Options> res = *this;
res.scale(s.factor());
return res;
}
@@ -584,7 +584,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
+ bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_matrix.isApprox(other.m_matrix, prec); }
/** Sets the last row to [0 ... 0 1]
@@ -794,7 +794,7 @@ Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other)
* \sa prescale(Scalar)
*/
template<typename Scalar, int Dim, int Mode, int Options>
-inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(Scalar s)
+inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(const Scalar& s)
{
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
linearExt() *= s;
@@ -821,7 +821,7 @@ Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &oth
* \sa scale(Scalar)
*/
template<typename Scalar, int Dim, int Mode, int Options>
-inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(Scalar s)
+inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(const Scalar& s)
{
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
m_matrix.template topRows<Dim>() *= s;
@@ -909,7 +909,7 @@ Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation)
*/
template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode,Options>&
-Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy)
+Transform<Scalar,Dim,Mode,Options>::shear(const Scalar& sx, const Scalar& sy)
{
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
@@ -925,7 +925,7 @@ Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy)
*/
template<typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar,Dim,Mode,Options>&
-Transform<Scalar,Dim,Mode,Options>::preshear(Scalar sx, Scalar sy)
+Transform<Scalar,Dim,Mode,Options>::preshear(const Scalar& sx, const Scalar& sy)
{
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
diff --git a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h
index ac0939cde52..345b47e0c37 100644
--- a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h
+++ b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h
@@ -153,16 +153,21 @@ umeyama(const MatrixBase<Derived>& src, const MatrixBase<OtherDerived>& dst, boo
Rt.block(0,0,m,m).noalias() = svd.matrixU() * S.asDiagonal() * svd.matrixV().transpose();
}
- // Eq. (42)
- const Scalar c = 1/src_var * svd.singularValues().dot(S);
-
- // Eq. (41)
- // Note that we first assign dst_mean to the destination so that there no need
- // for a temporary.
- Rt.col(m).head(m) = dst_mean;
- Rt.col(m).head(m).noalias() -= c*Rt.topLeftCorner(m,m)*src_mean;
-
- if (with_scaling) Rt.block(0,0,m,m) *= c;
+ if (with_scaling)
+ {
+ // Eq. (42)
+ const Scalar c = 1/src_var * svd.singularValues().dot(S);
+
+ // Eq. (41)
+ Rt.col(m).head(m) = dst_mean;
+ Rt.col(m).head(m).noalias() -= c*Rt.topLeftCorner(m,m)*src_mean;
+ Rt.block(0,0,m,m) *= c;
+ }
+ else
+ {
+ Rt.col(m).head(m) = dst_mean;
+ Rt.col(m).head(m).noalias() -= Rt.topLeftCorner(m,m)*src_mean;
+ }
return Rt;
}
diff --git a/extern/Eigen3/Eigen/src/Householder/Householder.h b/extern/Eigen3/Eigen/src/Householder/Householder.h
index 3f64b7dde2f..32112af9bfd 100644
--- a/extern/Eigen3/Eigen/src/Householder/Householder.h
+++ b/extern/Eigen3/Eigen/src/Householder/Householder.h
@@ -67,25 +67,28 @@ void MatrixBase<Derived>::makeHouseholder(
Scalar& tau,
RealScalar& beta) const
{
+ using std::sqrt;
+ using numext::conj;
+
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
Scalar c0 = coeff(0);
- if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
+ if(tailSqNorm == RealScalar(0) && numext::imag(c0)==RealScalar(0))
{
tau = RealScalar(0);
- beta = internal::real(c0);
+ beta = numext::real(c0);
essential.setZero();
}
else
{
- beta = internal::sqrt(internal::abs2(c0) + tailSqNorm);
- if (internal::real(c0)>=RealScalar(0))
+ beta = sqrt(numext::abs2(c0) + tailSqNorm);
+ if (numext::real(c0)>=RealScalar(0))
beta = -beta;
essential = tail / (c0 - beta);
- tau = internal::conj((beta - c0) / beta);
+ tau = conj((beta - c0) / beta);
}
}
diff --git a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h
index 1e71e16a785..d800ca1fa42 100644
--- a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h
+++ b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h
@@ -112,6 +112,9 @@ template<typename OtherScalarType, typename MatrixType> struct matrix_type_times
template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
: public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
{
+ typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType EssentialVectorType;
+
+ public:
enum {
RowsAtCompileTime = internal::traits<HouseholderSequence>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<HouseholderSequence>::ColsAtCompileTime,
@@ -121,13 +124,10 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
typedef typename internal::traits<HouseholderSequence>::Scalar Scalar;
typedef typename VectorsType::Index Index;
- typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType
- EssentialVectorType;
-
- public:
-
typedef HouseholderSequence<
- VectorsType,
+ typename internal::conditional<NumTraits<Scalar>::IsComplex,
+ typename internal::remove_all<typename VectorsType::ConjugateReturnType>::type,
+ VectorsType>::type,
typename internal::conditional<NumTraits<Scalar>::IsComplex,
typename internal::remove_all<typename CoeffsType::ConjugateReturnType>::type,
CoeffsType>::type,
@@ -208,7 +208,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
/** \brief Complex conjugate of the Householder sequence. */
ConjugateReturnType conjugate() const
{
- return ConjugateReturnType(m_vectors, m_coeffs.conjugate())
+ return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
.setTrans(m_trans)
.setLength(m_length)
.setShift(m_shift);
diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
index 126341be8d8..6fc6ab85225 100644
--- a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
+++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
@@ -39,10 +39,17 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
int maxIters = iters;
int n = mat.cols();
+ x = precond.solve(x);
VectorType r = rhs - mat * x;
VectorType r0 = r;
RealScalar r0_sqnorm = r0.squaredNorm();
+ RealScalar rhs_sqnorm = rhs.squaredNorm();
+ if(rhs_sqnorm == 0)
+ {
+ x.setZero();
+ return true;
+ }
Scalar rho = 1;
Scalar alpha = 1;
Scalar w = 1;
@@ -55,13 +62,22 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
RealScalar tol2 = tol*tol;
int i = 0;
+ int restarts = 0;
- while ( r.squaredNorm()/r0_sqnorm > tol2 && i<maxIters )
+ while ( r.squaredNorm()/rhs_sqnorm > tol2 && i<maxIters )
{
Scalar rho_old = rho;
rho = r0.dot(r);
- if (rho == Scalar(0)) return false; /* New search directions cannot be found */
+ if (internal::isMuchSmallerThan(rho,r0_sqnorm))
+ {
+ // The new residual vector became too orthogonal to the arbitrarily choosen direction r0
+ // Let's restart with a new r0:
+ r0 = r;
+ rho = r0_sqnorm = r.squaredNorm();
+ if(restarts++ == 0)
+ i = 0;
+ }
Scalar beta = (rho/rho_old) * (alpha / w);
p = r + beta * (p - w * v);
@@ -75,12 +91,16 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
z = precond.solve(s);
t.noalias() = mat * z;
- w = t.dot(s) / t.squaredNorm();
+ RealScalar tmp = t.squaredNorm();
+ if(tmp>RealScalar(0))
+ w = t.dot(s) / tmp;
+ else
+ w = Scalar(0);
x += alpha * y + w * z;
r = s - w * t;
++i;
}
- tol_error = sqrt(r.squaredNorm()/r0_sqnorm);
+ tol_error = sqrt(r.squaredNorm()/rhs_sqnorm);
iters = i;
return true;
}
@@ -223,7 +243,8 @@ public:
template<typename Rhs,typename Dest>
void _solve(const Rhs& b, Dest& x) const
{
- x.setZero();
+// x.setZero();
+ x = b;
_solveWithGuess(b,x);
}
diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
index f64f2534d28..a74a8155e68 100644
--- a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
+++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
@@ -41,15 +41,29 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
int n = mat.cols();
VectorType residual = rhs - mat * x; //initial residual
- VectorType p(n);
+ RealScalar rhsNorm2 = rhs.squaredNorm();
+ if(rhsNorm2 == 0)
+ {
+ x.setZero();
+ iters = 0;
+ tol_error = 0;
+ return;
+ }
+ RealScalar threshold = tol*tol*rhsNorm2;
+ RealScalar residualNorm2 = residual.squaredNorm();
+ if (residualNorm2 < threshold)
+ {
+ iters = 0;
+ tol_error = sqrt(residualNorm2 / rhsNorm2);
+ return;
+ }
+
+ VectorType p(n);
p = precond.solve(residual); //initial search direction
VectorType z(n), tmp(n);
- RealScalar absNew = internal::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
- RealScalar rhsNorm2 = rhs.squaredNorm();
- RealScalar residualNorm2 = 0;
- RealScalar threshold = tol*tol*rhsNorm2;
+ RealScalar absNew = numext::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
int i = 0;
while(i < maxIters)
{
@@ -66,7 +80,7 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
z = precond.solve(residual); // approximately solve for "A z = residual"
RealScalar absOld = absNew;
- absNew = internal::real(residual.dot(z)); // update the absolute value of r
+ absNew = numext::real(residual.dot(z)); // update the absolute value of r
RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction
p = z + beta * p; // update search direction
i++;
diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
index 224304f0eb8..b55afc13636 100644
--- a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
+++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
@@ -10,36 +10,88 @@
#ifndef EIGEN_INCOMPLETE_LUT_H
#define EIGEN_INCOMPLETE_LUT_H
+
namespace Eigen {
-/**
- * \brief Incomplete LU factorization with dual-threshold strategy
- * During the numerical factorization, two dropping rules are used :
- * 1) any element whose magnitude is less than some tolerance is dropped.
- * This tolerance is obtained by multiplying the input tolerance @p droptol
- * by the average magnitude of all the original elements in the current row.
- * 2) After the elimination of the row, only the @p fill largest elements in
- * the L part and the @p fill largest elements in the U part are kept
- * (in addition to the diagonal element ). Note that @p fill is computed from
- * the input parameter @p fillfactor which is used the ratio to control the fill_in
- * relatively to the initial number of nonzero elements.
- *
- * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements)
- * and when @p fill=n/2 with @p droptol being different to zero.
- *
- * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization,
- * Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994.
- *
- * NOTE : The following implementation is derived from the ILUT implementation
- * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota
- * released under the terms of the GNU LGPL:
- * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README
- * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2.
- * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012:
- * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html
- * alternatively, on GMANE:
- * http://comments.gmane.org/gmane.comp.lib.eigen/3302
- */
+namespace internal {
+
+/** \internal
+ * Compute a quick-sort split of a vector
+ * On output, the vector row is permuted such that its elements satisfy
+ * abs(row(i)) >= abs(row(ncut)) if i<ncut
+ * abs(row(i)) <= abs(row(ncut)) if i>ncut
+ * \param row The vector of values
+ * \param ind The array of index for the elements in @p row
+ * \param ncut The number of largest elements to keep
+ **/
+template <typename VectorV, typename VectorI, typename Index>
+Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
+{
+ typedef typename VectorV::RealScalar RealScalar;
+ using std::swap;
+ using std::abs;
+ Index mid;
+ Index n = row.size(); /* length of the vector */
+ Index first, last ;
+
+ ncut--; /* to fit the zero-based indices */
+ first = 0;
+ last = n-1;
+ if (ncut < first || ncut > last ) return 0;
+
+ do {
+ mid = first;
+ RealScalar abskey = abs(row(mid));
+ for (Index j = first + 1; j <= last; j++) {
+ if ( abs(row(j)) > abskey) {
+ ++mid;
+ swap(row(mid), row(j));
+ swap(ind(mid), ind(j));
+ }
+ }
+ /* Interchange for the pivot element */
+ swap(row(mid), row(first));
+ swap(ind(mid), ind(first));
+
+ if (mid > ncut) last = mid - 1;
+ else if (mid < ncut ) first = mid + 1;
+ } while (mid != ncut );
+
+ return 0; /* mid is equal to ncut */
+}
+
+}// end namespace internal
+
+/** \ingroup IterativeLinearSolvers_Module
+ * \class IncompleteLUT
+ * \brief Incomplete LU factorization with dual-threshold strategy
+ *
+ * During the numerical factorization, two dropping rules are used :
+ * 1) any element whose magnitude is less than some tolerance is dropped.
+ * This tolerance is obtained by multiplying the input tolerance @p droptol
+ * by the average magnitude of all the original elements in the current row.
+ * 2) After the elimination of the row, only the @p fill largest elements in
+ * the L part and the @p fill largest elements in the U part are kept
+ * (in addition to the diagonal element ). Note that @p fill is computed from
+ * the input parameter @p fillfactor which is used the ratio to control the fill_in
+ * relatively to the initial number of nonzero elements.
+ *
+ * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements)
+ * and when @p fill=n/2 with @p droptol being different to zero.
+ *
+ * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization,
+ * Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994.
+ *
+ * NOTE : The following implementation is derived from the ILUT implementation
+ * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota
+ * released under the terms of the GNU LGPL:
+ * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README
+ * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2.
+ * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012:
+ * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html
+ * alternatively, on GMANE:
+ * http://comments.gmane.org/gmane.comp.lib.eigen/3302
+ */
template <typename _Scalar>
class IncompleteLUT : internal::noncopyable
{
@@ -59,7 +111,7 @@ class IncompleteLUT : internal::noncopyable
{}
template<typename MatrixType>
- IncompleteLUT(const MatrixType& mat, RealScalar droptol=NumTraits<Scalar>::dummy_precision(), int fillfactor = 10)
+ IncompleteLUT(const MatrixType& mat, const RealScalar& droptol=NumTraits<Scalar>::dummy_precision(), int fillfactor = 10)
: m_droptol(droptol),m_fillfactor(fillfactor),
m_analysisIsOk(false),m_factorizationIsOk(false),m_isInitialized(false)
{
@@ -98,12 +150,11 @@ class IncompleteLUT : internal::noncopyable
{
analyzePattern(amat);
factorize(amat);
- eigen_assert(m_factorizationIsOk == true);
- m_isInitialized = true;
+ m_isInitialized = m_factorizationIsOk;
return *this;
}
- void setDroptol(RealScalar droptol);
+ void setDroptol(const RealScalar& droptol);
void setFillfactor(int fillfactor);
template<typename Rhs, typename Dest>
@@ -126,10 +177,6 @@ class IncompleteLUT : internal::noncopyable
protected:
- template <typename VectorV, typename VectorI>
- int QuickSplit(VectorV &row, VectorI &ind, int ncut);
-
-
/** keeps off-diagonal entries; drops diagonal entries */
struct keep_diag {
inline bool operator() (const Index& row, const Index& col, const Scalar&) const
@@ -156,7 +203,7 @@ protected:
* \param droptol Drop any element whose magnitude is less than this tolerance
**/
template<typename Scalar>
-void IncompleteLUT<Scalar>::setDroptol(RealScalar droptol)
+void IncompleteLUT<Scalar>::setDroptol(const RealScalar& droptol)
{
this->m_droptol = droptol;
}
@@ -171,51 +218,6 @@ void IncompleteLUT<Scalar>::setFillfactor(int fillfactor)
this->m_fillfactor = fillfactor;
}
-
-/**
- * Compute a quick-sort split of a vector
- * On output, the vector row is permuted such that its elements satisfy
- * abs(row(i)) >= abs(row(ncut)) if i<ncut
- * abs(row(i)) <= abs(row(ncut)) if i>ncut
- * \param row The vector of values
- * \param ind The array of index for the elements in @p row
- * \param ncut The number of largest elements to keep
- **/
-template <typename Scalar>
-template <typename VectorV, typename VectorI>
-int IncompleteLUT<Scalar>::QuickSplit(VectorV &row, VectorI &ind, int ncut)
-{
- using std::swap;
- int mid;
- int n = row.size(); /* length of the vector */
- int first, last ;
-
- ncut--; /* to fit the zero-based indices */
- first = 0;
- last = n-1;
- if (ncut < first || ncut > last ) return 0;
-
- do {
- mid = first;
- RealScalar abskey = std::abs(row(mid));
- for (int j = first + 1; j <= last; j++) {
- if ( std::abs(row(j)) > abskey) {
- ++mid;
- swap(row(mid), row(j));
- swap(ind(mid), ind(j));
- }
- }
- /* Interchange for the pivot element */
- swap(row(mid), row(first));
- swap(ind(mid), ind(first));
-
- if (mid > ncut) last = mid - 1;
- else if (mid < ncut ) first = mid + 1;
- } while (mid != ncut );
-
- return 0; /* mid is equal to ncut */
-}
-
template <typename Scalar>
template<typename _MatrixType>
void IncompleteLUT<Scalar>::analyzePattern(const _MatrixType& amat)
@@ -244,7 +246,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
using std::abs;
eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix");
- int n = amat.cols(); // Size of the matrix
+ Index n = amat.cols(); // Size of the matrix
m_lu.resize(n,n);
// Declare Working vectors and variables
Vector u(n) ; // real values of the row -- maximum size is n --
@@ -262,21 +264,21 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
u.fill(0);
// number of largest elements to keep in each row:
- int fill_in = static_cast<int> (amat.nonZeros()*m_fillfactor)/n+1;
+ Index fill_in = static_cast<Index> (amat.nonZeros()*m_fillfactor)/n+1;
if (fill_in > n) fill_in = n;
// number of largest nonzero elements to keep in the L and the U part of the current row:
- int nnzL = fill_in/2;
- int nnzU = nnzL;
+ Index nnzL = fill_in/2;
+ Index nnzU = nnzL;
m_lu.reserve(n * (nnzL + nnzU + 1));
// global loop over the rows of the sparse matrix
- for (int ii = 0; ii < n; ii++)
+ for (Index ii = 0; ii < n; ii++)
{
// 1 - copy the lower and the upper part of the row i of mat in the working vector u
- int sizeu = 1; // number of nonzero elements in the upper part of the current row
- int sizel = 0; // number of nonzero elements in the lower part of the current row
+ Index sizeu = 1; // number of nonzero elements in the upper part of the current row
+ Index sizel = 0; // number of nonzero elements in the lower part of the current row
ju(ii) = ii;
u(ii) = 0;
jr(ii) = ii;
@@ -285,7 +287,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii
for (; j_it; ++j_it)
{
- int k = j_it.index();
+ Index k = j_it.index();
if (k < ii)
{
// copy the lower part
@@ -301,13 +303,13 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
else
{
// copy the upper part
- int jpos = ii + sizeu;
+ Index jpos = ii + sizeu;
ju(jpos) = k;
u(jpos) = j_it.value();
jr(k) = jpos;
++sizeu;
}
- rownorm += internal::abs2(j_it.value());
+ rownorm += numext::abs2(j_it.value());
}
// 2 - detect possible zero row
@@ -320,19 +322,19 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
rownorm = sqrt(rownorm);
// 3 - eliminate the previous nonzero rows
- int jj = 0;
- int len = 0;
+ Index jj = 0;
+ Index len = 0;
while (jj < sizel)
{
// In order to eliminate in the correct order,
// we must select first the smallest column index among ju(jj:sizel)
- int k;
- int minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment
+ Index k;
+ Index minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment
k += jj;
if (minrow != ju(jj))
{
// swap the two locations
- int j = ju(jj);
+ Index j = ju(jj);
swap(ju(jj), ju(k));
jr(minrow) = jj; jr(j) = k;
swap(u(jj), u(k));
@@ -358,11 +360,11 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
for (; ki_it; ++ki_it)
{
Scalar prod = fact * ki_it.value();
- int j = ki_it.index();
- int jpos = jr(j);
+ Index j = ki_it.index();
+ Index jpos = jr(j);
if (jpos == -1) // fill-in element
{
- int newpos;
+ Index newpos;
if (j >= ii) // dealing with the upper part
{
newpos = ii + sizeu;
@@ -391,7 +393,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
} // end of the elimination on the row ii
// reset the upper part of the pointer jr to zero
- for(int k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
+ for(Index k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
// 4 - partially sort and insert the elements in the m_lu matrix
@@ -400,11 +402,11 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
len = (std::min)(sizel, nnzL);
typename Vector::SegmentReturnType ul(u.segment(0, sizel));
typename VectorXi::SegmentReturnType jul(ju.segment(0, sizel));
- QuickSplit(ul, jul, len);
+ internal::QuickSplit(ul, jul, len);
// store the largest m_fill elements of the L part
m_lu.startVec(ii);
- for(int k = 0; k < len; k++)
+ for(Index k = 0; k < len; k++)
m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
// store the diagonal element
@@ -416,7 +418,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
// sort the U-part of the row
// apply the dropping rule first
len = 0;
- for(int k = 1; k < sizeu; k++)
+ for(Index k = 1; k < sizeu; k++)
{
if(abs(u(ii+k)) > m_droptol * rownorm )
{
@@ -429,10 +431,10 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
len = (std::min)(sizeu, nnzU);
typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1));
typename VectorXi::SegmentReturnType juu(ju.segment(ii+1, sizeu-1));
- QuickSplit(uu, juu, len);
+ internal::QuickSplit(uu, juu, len);
// store the largest elements of the U part
- for(int k = ii + 1; k < ii + len; k++)
+ for(Index k = ii + 1; k < ii + len; k++)
m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
}
@@ -463,4 +465,3 @@ struct solve_retval<IncompleteLUT<_MatrixType>, Rhs>
} // end namespace Eigen
#endif // EIGEN_INCOMPLETE_LUT_H
-
diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
index 11706cebabd..2036922d69c 100644
--- a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
+++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
@@ -120,7 +120,7 @@ public:
RealScalar tolerance() const { return m_tolerance; }
/** Sets the tolerance threshold used by the stopping criteria */
- Derived& setTolerance(RealScalar tolerance)
+ Derived& setTolerance(const RealScalar& tolerance)
{
m_tolerance = tolerance;
return derived();
diff --git a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h
index a9c17dcdf19..956f72d5701 100644
--- a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h
+++ b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h
@@ -50,19 +50,20 @@ template<typename Scalar> class JacobiRotation
/** Concatenates two planar rotation */
JacobiRotation operator*(const JacobiRotation& other)
{
- return JacobiRotation(m_c * other.m_c - internal::conj(m_s) * other.m_s,
- internal::conj(m_c * internal::conj(other.m_s) + internal::conj(m_s) * internal::conj(other.m_c)));
+ using numext::conj;
+ return JacobiRotation(m_c * other.m_c - conj(m_s) * other.m_s,
+ conj(m_c * conj(other.m_s) + conj(m_s) * conj(other.m_c)));
}
/** Returns the transposed transformation */
- JacobiRotation transpose() const { return JacobiRotation(m_c, -internal::conj(m_s)); }
+ JacobiRotation transpose() const { using numext::conj; return JacobiRotation(m_c, -conj(m_s)); }
/** Returns the adjoint transformation */
- JacobiRotation adjoint() const { return JacobiRotation(internal::conj(m_c), -m_s); }
+ JacobiRotation adjoint() const { using numext::conj; return JacobiRotation(conj(m_c), -m_s); }
template<typename Derived>
bool makeJacobi(const MatrixBase<Derived>&, typename Derived::Index p, typename Derived::Index q);
- bool makeJacobi(RealScalar x, Scalar y, RealScalar z);
+ bool makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z);
void makeGivens(const Scalar& p, const Scalar& q, Scalar* z=0);
@@ -79,8 +80,10 @@ template<typename Scalar> class JacobiRotation
* \sa MatrixBase::makeJacobi(const MatrixBase<Derived>&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
*/
template<typename Scalar>
-bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
+bool JacobiRotation<Scalar>::makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z)
{
+ using std::sqrt;
+ using std::abs;
typedef typename NumTraits<Scalar>::Real RealScalar;
if(y == Scalar(0))
{
@@ -90,8 +93,8 @@ bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
}
else
{
- RealScalar tau = (x-z)/(RealScalar(2)*internal::abs(y));
- RealScalar w = internal::sqrt(internal::abs2(tau) + RealScalar(1));
+ RealScalar tau = (x-z)/(RealScalar(2)*abs(y));
+ RealScalar w = sqrt(numext::abs2(tau) + RealScalar(1));
RealScalar t;
if(tau>RealScalar(0))
{
@@ -102,8 +105,8 @@ bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
t = RealScalar(1) / (tau - w);
}
RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
- RealScalar n = RealScalar(1) / internal::sqrt(internal::abs2(t)+RealScalar(1));
- m_s = - sign_t * (internal::conj(y) / internal::abs(y)) * internal::abs(t) * n;
+ RealScalar n = RealScalar(1) / sqrt(numext::abs2(t)+RealScalar(1));
+ m_s = - sign_t * (numext::conj(y) / abs(y)) * abs(t) * n;
m_c = n;
return true;
}
@@ -122,7 +125,7 @@ template<typename Scalar>
template<typename Derived>
inline bool JacobiRotation<Scalar>::makeJacobi(const MatrixBase<Derived>& m, typename Derived::Index p, typename Derived::Index q)
{
- return makeJacobi(internal::real(m.coeff(p,p)), m.coeff(p,q), internal::real(m.coeff(q,q)));
+ return makeJacobi(numext::real(m.coeff(p,p)), m.coeff(p,q), numext::real(m.coeff(q,q)));
}
/** Makes \c *this as a Givens rotation \c G such that applying \f$ G^* \f$ to the left of the vector
@@ -152,52 +155,56 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
template<typename Scalar>
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type)
{
+ using std::sqrt;
+ using std::abs;
+ using numext::conj;
+
if(q==Scalar(0))
{
- m_c = internal::real(p)<0 ? Scalar(-1) : Scalar(1);
+ m_c = numext::real(p)<0 ? Scalar(-1) : Scalar(1);
m_s = 0;
if(r) *r = m_c * p;
}
else if(p==Scalar(0))
{
m_c = 0;
- m_s = -q/internal::abs(q);
- if(r) *r = internal::abs(q);
+ m_s = -q/abs(q);
+ if(r) *r = abs(q);
}
else
{
- RealScalar p1 = internal::norm1(p);
- RealScalar q1 = internal::norm1(q);
+ RealScalar p1 = numext::norm1(p);
+ RealScalar q1 = numext::norm1(q);
if(p1>=q1)
{
Scalar ps = p / p1;
- RealScalar p2 = internal::abs2(ps);
+ RealScalar p2 = numext::abs2(ps);
Scalar qs = q / p1;
- RealScalar q2 = internal::abs2(qs);
+ RealScalar q2 = numext::abs2(qs);
- RealScalar u = internal::sqrt(RealScalar(1) + q2/p2);
- if(internal::real(p)<RealScalar(0))
+ RealScalar u = sqrt(RealScalar(1) + q2/p2);
+ if(numext::real(p)<RealScalar(0))
u = -u;
m_c = Scalar(1)/u;
- m_s = -qs*internal::conj(ps)*(m_c/p2);
+ m_s = -qs*conj(ps)*(m_c/p2);
if(r) *r = p * u;
}
else
{
Scalar ps = p / q1;
- RealScalar p2 = internal::abs2(ps);
+ RealScalar p2 = numext::abs2(ps);
Scalar qs = q / q1;
- RealScalar q2 = internal::abs2(qs);
+ RealScalar q2 = numext::abs2(qs);
- RealScalar u = q1 * internal::sqrt(p2 + q2);
- if(internal::real(p)<RealScalar(0))
+ RealScalar u = q1 * sqrt(p2 + q2);
+ if(numext::real(p)<RealScalar(0))
u = -u;
- p1 = internal::abs(p);
+ p1 = abs(p);
ps = p/p1;
m_c = p1/u;
- m_s = -internal::conj(ps) * (q/u);
+ m_s = -conj(ps) * (q/u);
if(r) *r = ps * u;
}
}
@@ -207,23 +214,24 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
template<typename Scalar>
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
{
-
+ using std::sqrt;
+ using std::abs;
if(q==Scalar(0))
{
m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
m_s = Scalar(0);
- if(r) *r = internal::abs(p);
+ if(r) *r = abs(p);
}
else if(p==Scalar(0))
{
m_c = Scalar(0);
m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
- if(r) *r = internal::abs(q);
+ if(r) *r = abs(q);
}
- else if(internal::abs(p) > internal::abs(q))
+ else if(abs(p) > abs(q))
{
Scalar t = q/p;
- Scalar u = internal::sqrt(Scalar(1) + internal::abs2(t));
+ Scalar u = sqrt(Scalar(1) + numext::abs2(t));
if(p<Scalar(0))
u = -u;
m_c = Scalar(1)/u;
@@ -233,7 +241,7 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
else
{
Scalar t = p/q;
- Scalar u = internal::sqrt(Scalar(1) + internal::abs2(t));
+ Scalar u = sqrt(Scalar(1) + numext::abs2(t));
if(q<Scalar(0))
u = -u;
m_s = -Scalar(1)/u;
@@ -303,6 +311,11 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
Scalar* EIGEN_RESTRICT x = &_x.coeffRef(0);
Scalar* EIGEN_RESTRICT y = &_y.coeffRef(0);
+
+ OtherScalar c = j.c();
+ OtherScalar s = j.s();
+ if (c==OtherScalar(1) && s==OtherScalar(0))
+ return;
/*** dynamic-size vectorized paths ***/
@@ -316,16 +329,16 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
Index alignedStart = internal::first_aligned(y, size);
Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
- const Packet pc = pset1<Packet>(j.c());
- const Packet ps = pset1<Packet>(j.s());
+ const Packet pc = pset1<Packet>(c);
+ const Packet ps = pset1<Packet>(s);
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
for(Index i=0; i<alignedStart; ++i)
{
Scalar xi = x[i];
Scalar yi = y[i];
- x[i] = j.c() * xi + conj(j.s()) * yi;
- y[i] = -j.s() * xi + conj(j.c()) * yi;
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
}
Scalar* EIGEN_RESTRICT px = x + alignedStart;
@@ -372,8 +385,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
{
Scalar xi = x[i];
Scalar yi = y[i];
- x[i] = j.c() * xi + conj(j.s()) * yi;
- y[i] = -j.s() * xi + conj(j.c()) * yi;
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
}
}
@@ -382,8 +395,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
(VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
(VectorX::Flags & VectorY::Flags & AlignedBit))
{
- const Packet pc = pset1<Packet>(j.c());
- const Packet ps = pset1<Packet>(j.s());
+ const Packet pc = pset1<Packet>(c);
+ const Packet ps = pset1<Packet>(s);
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
Scalar* EIGEN_RESTRICT px = x;
Scalar* EIGEN_RESTRICT py = y;
@@ -405,8 +418,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
{
Scalar xi = *x;
Scalar yi = *y;
- *x = j.c() * xi + conj(j.s()) * yi;
- *y = -j.s() * xi + conj(j.c()) * yi;
+ *x = c * xi + numext::conj(s) * yi;
+ *y = -s * xi + numext::conj(c) * yi;
x += incrx;
y += incry;
}
diff --git a/extern/Eigen3/Eigen/src/LU/Determinant.h b/extern/Eigen3/Eigen/src/LU/Determinant.h
index d862c5d7784..bb8e78a8a8a 100644
--- a/extern/Eigen3/Eigen/src/LU/Determinant.h
+++ b/extern/Eigen3/Eigen/src/LU/Determinant.h
@@ -91,7 +91,7 @@ template<typename Derived> struct determinant_impl<Derived, 4>
template<typename Derived>
inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
{
- assert(rows() == cols());
+ eigen_assert(rows() == cols());
typedef typename internal::nested<Derived,Base::RowsAtCompileTime>::type Nested;
return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived());
}
diff --git a/extern/Eigen3/Eigen/src/LU/FullPivLU.h b/extern/Eigen3/Eigen/src/LU/FullPivLU.h
index e23f96cdcf1..dfe25f424d7 100644
--- a/extern/Eigen3/Eigen/src/LU/FullPivLU.h
+++ b/extern/Eigen3/Eigen/src/LU/FullPivLU.h
@@ -293,11 +293,12 @@ template<typename _MatrixType> class FullPivLU
*/
inline Index rank() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "LU is not initialized.");
- RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
+ RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
Index result = 0;
for(Index i = 0; i < m_nonzero_pivots; ++i)
- result += (internal::abs(m_lu.coeff(i,i)) > premultiplied_threshold);
+ result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold);
return result;
}
@@ -416,6 +417,9 @@ FullPivLU<MatrixType>::FullPivLU(const MatrixType& matrix)
template<typename MatrixType>
FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
{
+ // the permutations are stored as int indices, so just to be sure:
+ eigen_assert(matrix.rows()<=NumTraits<int>::highest() && matrix.cols()<=NumTraits<int>::highest());
+
m_isInitialized = true;
m_lu = matrix;
@@ -547,6 +551,7 @@ struct kernel_retval<FullPivLU<_MatrixType> >
template<typename Dest> void evalTo(Dest& dst) const
{
+ using std::abs;
const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
if(dimker == 0)
{
@@ -632,6 +637,7 @@ struct image_retval<FullPivLU<_MatrixType> >
template<typename Dest> void evalTo(Dest& dst) const
{
+ using std::abs;
if(rank() == 0)
{
// The Image is just {0}, so it doesn't have a basis properly speaking, but let's
diff --git a/extern/Eigen3/Eigen/src/LU/Inverse.h b/extern/Eigen3/Eigen/src/LU/Inverse.h
index 39b8cdbc8dc..3cf8871932f 100644
--- a/extern/Eigen3/Eigen/src/LU/Inverse.h
+++ b/extern/Eigen3/Eigen/src/LU/Inverse.h
@@ -55,6 +55,7 @@ struct compute_inverse_and_det_with_check<MatrixType, ResultType, 1>
bool& invertible
)
{
+ using std::abs;
determinant = matrix.coeff(0,0);
invertible = abs(determinant) > absDeterminantThreshold;
if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
@@ -98,6 +99,7 @@ struct compute_inverse_and_det_with_check<MatrixType, ResultType, 2>
bool& invertible
)
{
+ using std::abs;
typedef typename ResultType::Scalar Scalar;
determinant = matrix.determinant();
invertible = abs(determinant) > absDeterminantThreshold;
@@ -167,6 +169,7 @@ struct compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
bool& invertible
)
{
+ using std::abs;
typedef typename ResultType::Scalar Scalar;
Matrix<Scalar,3,1> cofactors_col0;
cofactors_col0.coeffRef(0) = cofactor_3x3<MatrixType,0,0>(matrix);
@@ -251,6 +254,7 @@ struct compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
bool& invertible
)
{
+ using std::abs;
determinant = matrix.determinant();
invertible = abs(determinant) > absDeterminantThreshold;
if(invertible) compute_inverse<MatrixType, ResultType>::run(matrix, inverse);
@@ -327,7 +331,7 @@ inline const internal::inverse_impl<Derived> MatrixBase<Derived>::inverse() cons
* This is only for fixed-size square matrices of size up to 4x4.
*
* \param inverse Reference to the matrix in which to store the inverse.
- * \param determinant Reference to the variable in which to store the inverse.
+ * \param determinant Reference to the variable in which to store the determinant.
* \param invertible Reference to the bool variable in which to store whether the matrix is invertible.
* \param absDeterminantThreshold Optional parameter controlling the invertibility check.
* The matrix will be declared invertible if the absolute value of its
diff --git a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h
index c9ff9dd5a36..740ee694c45 100644
--- a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h
+++ b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h
@@ -242,7 +242,7 @@ struct partial_lu_impl
const Index cols = lu.cols();
const Index size = (std::min)(rows,cols);
nb_transpositions = 0;
- int first_zero_pivot = -1;
+ Index first_zero_pivot = -1;
for(Index k = 0; k < size; ++k)
{
Index rrows = rows-k-1;
@@ -253,7 +253,7 @@ struct partial_lu_impl
= lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col);
row_of_biggest_in_col += k;
- row_transpositions[k] = row_of_biggest_in_col;
+ row_transpositions[k] = PivIndex(row_of_biggest_in_col);
if(biggest_in_corner != RealScalar(0))
{
@@ -318,7 +318,7 @@ struct partial_lu_impl
}
nb_transpositions = 0;
- int first_zero_pivot = -1;
+ Index first_zero_pivot = -1;
for(Index k = 0; k < size; k+=blockSize)
{
Index bs = (std::min)(size-k,blockSize); // actual size of the block
@@ -386,6 +386,9 @@ void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, t
template<typename MatrixType>
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix)
{
+ // the row permutation is stored as int indices, so just to be sure:
+ eigen_assert(matrix.rows()<NumTraits<int>::highest());
+
m_lu = matrix;
eigen_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
diff --git a/extern/Eigen3/Eigen/src/MetisSupport/MetisSupport.h b/extern/Eigen3/Eigen/src/MetisSupport/MetisSupport.h
new file mode 100644
index 00000000000..f2bbef20c8f
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/MetisSupport/MetisSupport.h
@@ -0,0 +1,137 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef METIS_SUPPORT_H
+#define METIS_SUPPORT_H
+
+namespace Eigen {
+/**
+ * Get the fill-reducing ordering from the METIS package
+ *
+ * If A is the original matrix and Ap is the permuted matrix,
+ * the fill-reducing permutation is defined as follows :
+ * Row (column) i of A is the matperm(i) row (column) of Ap.
+ * WARNING: As computed by METIS, this corresponds to the vector iperm (instead of perm)
+ */
+template <typename Index>
+class MetisOrdering
+{
+public:
+ typedef PermutationMatrix<Dynamic,Dynamic,Index> PermutationType;
+ typedef Matrix<Index,Dynamic,1> IndexVector;
+
+ template <typename MatrixType>
+ void get_symmetrized_graph(const MatrixType& A)
+ {
+ Index m = A.cols();
+ eigen_assert((A.rows() == A.cols()) && "ONLY FOR SQUARED MATRICES");
+ // Get the transpose of the input matrix
+ MatrixType At = A.transpose();
+ // Get the number of nonzeros elements in each row/col of At+A
+ Index TotNz = 0;
+ IndexVector visited(m);
+ visited.setConstant(-1);
+ for (int j = 0; j < m; j++)
+ {
+ // Compute the union structure of of A(j,:) and At(j,:)
+ visited(j) = j; // Do not include the diagonal element
+ // Get the nonzeros in row/column j of A
+ for (typename MatrixType::InnerIterator it(A, j); it; ++it)
+ {
+ Index idx = it.index(); // Get the row index (for column major) or column index (for row major)
+ if (visited(idx) != j )
+ {
+ visited(idx) = j;
+ ++TotNz;
+ }
+ }
+ //Get the nonzeros in row/column j of At
+ for (typename MatrixType::InnerIterator it(At, j); it; ++it)
+ {
+ Index idx = it.index();
+ if(visited(idx) != j)
+ {
+ visited(idx) = j;
+ ++TotNz;
+ }
+ }
+ }
+ // Reserve place for A + At
+ m_indexPtr.resize(m+1);
+ m_innerIndices.resize(TotNz);
+
+ // Now compute the real adjacency list of each column/row
+ visited.setConstant(-1);
+ Index CurNz = 0;
+ for (int j = 0; j < m; j++)
+ {
+ m_indexPtr(j) = CurNz;
+
+ visited(j) = j; // Do not include the diagonal element
+ // Add the pattern of row/column j of A to A+At
+ for (typename MatrixType::InnerIterator it(A,j); it; ++it)
+ {
+ Index idx = it.index(); // Get the row index (for column major) or column index (for row major)
+ if (visited(idx) != j )
+ {
+ visited(idx) = j;
+ m_innerIndices(CurNz) = idx;
+ CurNz++;
+ }
+ }
+ //Add the pattern of row/column j of At to A+At
+ for (typename MatrixType::InnerIterator it(At, j); it; ++it)
+ {
+ Index idx = it.index();
+ if(visited(idx) != j)
+ {
+ visited(idx) = j;
+ m_innerIndices(CurNz) = idx;
+ ++CurNz;
+ }
+ }
+ }
+ m_indexPtr(m) = CurNz;
+ }
+
+ template <typename MatrixType>
+ void operator() (const MatrixType& A, PermutationType& matperm)
+ {
+ Index m = A.cols();
+ IndexVector perm(m),iperm(m);
+ // First, symmetrize the matrix graph.
+ get_symmetrized_graph(A);
+ int output_error;
+
+ // Call the fill-reducing routine from METIS
+ output_error = METIS_NodeND(&m, m_indexPtr.data(), m_innerIndices.data(), NULL, NULL, perm.data(), iperm.data());
+
+ if(output_error != METIS_OK)
+ {
+ //FIXME The ordering interface should define a class of possible errors
+ std::cerr << "ERROR WHILE CALLING THE METIS PACKAGE \n";
+ return;
+ }
+
+ // Get the fill-reducing permutation
+ //NOTE: If Ap is the permuted matrix then perm and iperm vectors are defined as follows
+ // Row (column) i of Ap is the perm(i) row(column) of A, and row (column) i of A is the iperm(i) row(column) of Ap
+
+ matperm.resize(m);
+ for (int j = 0; j < m; j++)
+ matperm.indices()(iperm(j)) = j;
+
+ }
+
+ protected:
+ IndexVector m_indexPtr; // Pointer to the adjacenccy list of each row/column
+ IndexVector m_innerIndices; // Adjacency list
+};
+
+}// end namespace eigen
+#endif
diff --git a/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h
index ce04852b872..41b4fd7e392 100644
--- a/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h
+++ b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h
@@ -2,10 +2,6 @@
// for linear algebra.
//
// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
/*
@@ -86,6 +82,7 @@ Index cs_tdfs(Index j, Index k, Index *head, const Index *next, Index *post, Ind
/** \internal
+ * \ingroup OrderingMethods_Module
* Approximate minimum degree ordering algorithm.
* \returns the permutation P reducing the fill-in of the input matrix \a C
* The input matrix \a C must be a selfadjoint compressed column major SparseMatrix object. Both the upper and lower parts have to be stored, but the diagonal entries are optional.
@@ -94,7 +91,6 @@ template<typename Scalar, typename Index>
void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, PermutationMatrix<Dynamic,Dynamic,Index>& perm)
{
using std::sqrt;
- typedef SparseMatrix<Scalar,ColMajor,Index> CCS;
int d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1,
k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi,
diff --git a/extern/Eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h b/extern/Eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h
new file mode 100644
index 00000000000..44548f6607c
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h
@@ -0,0 +1,1850 @@
+// // This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Desire Nuentsa Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// This file is modified from the colamd/symamd library. The copyright is below
+
+// The authors of the code itself are Stefan I. Larimore and Timothy A.
+// Davis (davis@cise.ufl.edu), University of Florida. The algorithm was
+// developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+// Ng, Oak Ridge National Laboratory.
+//
+// Date:
+//
+// September 8, 2003. Version 2.3.
+//
+// Acknowledgements:
+//
+// This work was supported by the National Science Foundation, under
+// grants DMS-9504974 and DMS-9803599.
+//
+// Notice:
+//
+// Copyright (c) 1998-2003 by the University of Florida.
+// All Rights Reserved.
+//
+// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+//
+// Permission is hereby granted to use, copy, modify, and/or distribute
+// this program, provided that the Copyright, this License, and the
+// Availability of the original version is retained on all copies and made
+// accessible to the end-user of any code or package that includes COLAMD
+// or any modified version of COLAMD.
+//
+// Availability:
+//
+// The colamd/symamd library is available at
+//
+// http://www.cise.ufl.edu/research/sparse/colamd/
+
+// This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h
+// file. It is required by the colamd.c, colamdmex.c, and symamdmex.c
+// files, and by any C code that calls the routines whose prototypes are
+// listed below, or that uses the colamd/symamd definitions listed below.
+
+#ifndef EIGEN_COLAMD_H
+#define EIGEN_COLAMD_H
+
+namespace internal {
+/* Ensure that debugging is turned off: */
+#ifndef COLAMD_NDEBUG
+#define COLAMD_NDEBUG
+#endif /* NDEBUG */
+/* ========================================================================== */
+/* === Knob and statistics definitions ====================================== */
+/* ========================================================================== */
+
+/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */
+#define COLAMD_KNOBS 20
+
+/* number of output statistics. Only stats [0..6] are currently used. */
+#define COLAMD_STATS 20
+
+/* knobs [0] and stats [0]: dense row knob and output statistic. */
+#define COLAMD_DENSE_ROW 0
+
+/* knobs [1] and stats [1]: dense column knob and output statistic. */
+#define COLAMD_DENSE_COL 1
+
+/* stats [2]: memory defragmentation count output statistic */
+#define COLAMD_DEFRAG_COUNT 2
+
+/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */
+#define COLAMD_STATUS 3
+
+/* stats [4..6]: error info, or info on jumbled columns */
+#define COLAMD_INFO1 4
+#define COLAMD_INFO2 5
+#define COLAMD_INFO3 6
+
+/* error codes returned in stats [3]: */
+#define COLAMD_OK (0)
+#define COLAMD_OK_BUT_JUMBLED (1)
+#define COLAMD_ERROR_A_not_present (-1)
+#define COLAMD_ERROR_p_not_present (-2)
+#define COLAMD_ERROR_nrow_negative (-3)
+#define COLAMD_ERROR_ncol_negative (-4)
+#define COLAMD_ERROR_nnz_negative (-5)
+#define COLAMD_ERROR_p0_nonzero (-6)
+#define COLAMD_ERROR_A_too_small (-7)
+#define COLAMD_ERROR_col_length_negative (-8)
+#define COLAMD_ERROR_row_index_out_of_bounds (-9)
+#define COLAMD_ERROR_out_of_memory (-10)
+#define COLAMD_ERROR_internal_error (-999)
+
+/* ========================================================================== */
+/* === Definitions ========================================================== */
+/* ========================================================================== */
+
+#define COLAMD_MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define COLAMD_MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+#define ONES_COMPLEMENT(r) (-(r)-1)
+
+/* -------------------------------------------------------------------------- */
+
+#define COLAMD_EMPTY (-1)
+
+/* Row and column status */
+#define ALIVE (0)
+#define DEAD (-1)
+
+/* Column status */
+#define DEAD_PRINCIPAL (-1)
+#define DEAD_NON_PRINCIPAL (-2)
+
+/* Macros for row and column status update and checking. */
+#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark)
+#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE)
+#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE)
+#define COL_IS_DEAD(c) (Col [c].start < ALIVE)
+#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE)
+#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL)
+#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; }
+#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; }
+#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; }
+
+/* ========================================================================== */
+/* === Colamd reporting mechanism =========================================== */
+/* ========================================================================== */
+
+// == Row and Column structures ==
+template <typename Index>
+struct colamd_col
+{
+ Index start ; /* index for A of first row in this column, or DEAD */
+ /* if column is dead */
+ Index length ; /* number of rows in this column */
+ union
+ {
+ Index thickness ; /* number of original columns represented by this */
+ /* col, if the column is alive */
+ Index parent ; /* parent in parent tree super-column structure, if */
+ /* the column is dead */
+ } shared1 ;
+ union
+ {
+ Index score ; /* the score used to maintain heap, if col is alive */
+ Index order ; /* pivot ordering of this column, if col is dead */
+ } shared2 ;
+ union
+ {
+ Index headhash ; /* head of a hash bucket, if col is at the head of */
+ /* a degree list */
+ Index hash ; /* hash value, if col is not in a degree list */
+ Index prev ; /* previous column in degree list, if col is in a */
+ /* degree list (but not at the head of a degree list) */
+ } shared3 ;
+ union
+ {
+ Index degree_next ; /* next column, if col is in a degree list */
+ Index hash_next ; /* next column, if col is in a hash list */
+ } shared4 ;
+
+};
+
+template <typename Index>
+struct Colamd_Row
+{
+ Index start ; /* index for A of first col in this row */
+ Index length ; /* number of principal columns in this row */
+ union
+ {
+ Index degree ; /* number of principal & non-principal columns in row */
+ Index p ; /* used as a row pointer in init_rows_cols () */
+ } shared1 ;
+ union
+ {
+ Index mark ; /* for computing set differences and marking dead rows*/
+ Index first_column ;/* first column in row (used in garbage collection) */
+ } shared2 ;
+
+};
+
+/* ========================================================================== */
+/* === Colamd recommended memory size ======================================= */
+/* ========================================================================== */
+
+/*
+ The recommended length Alen of the array A passed to colamd is given by
+ the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. It returns -1 if any
+ argument is negative. 2*nnz space is required for the row and column
+ indices of the matrix. colamd_c (n_col) + colamd_r (n_row) space is
+ required for the Col and Row arrays, respectively, which are internal to
+ colamd. An additional n_col space is the minimal amount of "elbow room",
+ and nnz/5 more space is recommended for run time efficiency.
+
+ This macro is not needed when using symamd.
+
+ Explicit typecast to Index added Sept. 23, 2002, COLAMD version 2.2, to avoid
+ gcc -pedantic warning messages.
+*/
+template <typename Index>
+inline Index colamd_c(Index n_col)
+{ return Index( ((n_col) + 1) * sizeof (colamd_col<Index>) / sizeof (Index) ) ; }
+
+template <typename Index>
+inline Index colamd_r(Index n_row)
+{ return Index(((n_row) + 1) * sizeof (Colamd_Row<Index>) / sizeof (Index)); }
+
+// Prototypes of non-user callable routines
+template <typename Index>
+static Index init_rows_cols (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> col [], Index A [], Index p [], Index stats[COLAMD_STATS] );
+
+template <typename Index>
+static void init_scoring (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index head [], double knobs[COLAMD_KNOBS], Index *p_n_row2, Index *p_n_col2, Index *p_max_deg);
+
+template <typename Index>
+static Index find_ordering (Index n_row, Index n_col, Index Alen, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index head [], Index n_col2, Index max_deg, Index pfree);
+
+template <typename Index>
+static void order_children (Index n_col, colamd_col<Index> Col [], Index p []);
+
+template <typename Index>
+static void detect_super_cols (colamd_col<Index> Col [], Index A [], Index head [], Index row_start, Index row_length ) ;
+
+template <typename Index>
+static Index garbage_collection (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index *pfree) ;
+
+template <typename Index>
+static inline Index clear_mark (Index n_row, Colamd_Row<Index> Row [] ) ;
+
+/* === No debugging ========================================================= */
+
+#define COLAMD_DEBUG0(params) ;
+#define COLAMD_DEBUG1(params) ;
+#define COLAMD_DEBUG2(params) ;
+#define COLAMD_DEBUG3(params) ;
+#define COLAMD_DEBUG4(params) ;
+
+#define COLAMD_ASSERT(expression) ((void) 0)
+
+
+/**
+ * \brief Returns the recommended value of Alen
+ *
+ * Returns recommended value of Alen for use by colamd.
+ * Returns -1 if any input argument is negative.
+ * The use of this routine or macro is optional.
+ * Note that the macro uses its arguments more than once,
+ * so be careful for side effects, if you pass expressions as arguments to COLAMD_RECOMMENDED.
+ *
+ * \param nnz nonzeros in A
+ * \param n_row number of rows in A
+ * \param n_col number of columns in A
+ * \return recommended value of Alen for use by colamd
+ */
+template <typename Index>
+inline Index colamd_recommended ( Index nnz, Index n_row, Index n_col)
+{
+ if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0)
+ return (-1);
+ else
+ return (2 * (nnz) + colamd_c (n_col) + colamd_r (n_row) + (n_col) + ((nnz) / 5));
+}
+
+/**
+ * \brief set default parameters The use of this routine is optional.
+ *
+ * Colamd: rows with more than (knobs [COLAMD_DENSE_ROW] * n_col)
+ * entries are removed prior to ordering. Columns with more than
+ * (knobs [COLAMD_DENSE_COL] * n_row) entries are removed prior to
+ * ordering, and placed last in the output column ordering.
+ *
+ * COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1,
+ * respectively, in colamd.h. Default values of these two knobs
+ * are both 0.5. Currently, only knobs [0] and knobs [1] are
+ * used, but future versions may use more knobs. If so, they will
+ * be properly set to their defaults by the future version of
+ * colamd_set_defaults, so that the code that calls colamd will
+ * not need to change, assuming that you either use
+ * colamd_set_defaults, or pass a (double *) NULL pointer as the
+ * knobs array to colamd or symamd.
+ *
+ * \param knobs parameter settings for colamd
+ */
+
+static inline void colamd_set_defaults(double knobs[COLAMD_KNOBS])
+{
+ /* === Local variables ================================================== */
+
+ int i ;
+
+ if (!knobs)
+ {
+ return ; /* no knobs to initialize */
+ }
+ for (i = 0 ; i < COLAMD_KNOBS ; i++)
+ {
+ knobs [i] = 0 ;
+ }
+ knobs [COLAMD_DENSE_ROW] = 0.5 ; /* ignore rows over 50% dense */
+ knobs [COLAMD_DENSE_COL] = 0.5 ; /* ignore columns over 50% dense */
+}
+
+/**
+ * \brief Computes a column ordering using the column approximate minimum degree ordering
+ *
+ * Computes a column ordering (Q) of A such that P(AQ)=LU or
+ * (AQ)'AQ=LL' have less fill-in and require fewer floating point
+ * operations than factorizing the unpermuted matrix A or A'A,
+ * respectively.
+ *
+ *
+ * \param n_row number of rows in A
+ * \param n_col number of columns in A
+ * \param Alen, size of the array A
+ * \param A row indices of the matrix, of size ALen
+ * \param p column pointers of A, of size n_col+1
+ * \param knobs parameter settings for colamd
+ * \param stats colamd output statistics and error codes
+ */
+template <typename Index>
+static bool colamd(Index n_row, Index n_col, Index Alen, Index *A, Index *p, double knobs[COLAMD_KNOBS], Index stats[COLAMD_STATS])
+{
+ /* === Local variables ================================================== */
+
+ Index i ; /* loop index */
+ Index nnz ; /* nonzeros in A */
+ Index Row_size ; /* size of Row [], in integers */
+ Index Col_size ; /* size of Col [], in integers */
+ Index need ; /* minimum required length of A */
+ Colamd_Row<Index> *Row ; /* pointer into A of Row [0..n_row] array */
+ colamd_col<Index> *Col ; /* pointer into A of Col [0..n_col] array */
+ Index n_col2 ; /* number of non-dense, non-empty columns */
+ Index n_row2 ; /* number of non-dense, non-empty rows */
+ Index ngarbage ; /* number of garbage collections performed */
+ Index max_deg ; /* maximum row degree */
+ double default_knobs [COLAMD_KNOBS] ; /* default knobs array */
+
+
+ /* === Check the input arguments ======================================== */
+
+ if (!stats)
+ {
+ COLAMD_DEBUG0 (("colamd: stats not present\n")) ;
+ return (false) ;
+ }
+ for (i = 0 ; i < COLAMD_STATS ; i++)
+ {
+ stats [i] = 0 ;
+ }
+ stats [COLAMD_STATUS] = COLAMD_OK ;
+ stats [COLAMD_INFO1] = -1 ;
+ stats [COLAMD_INFO2] = -1 ;
+
+ if (!A) /* A is not present */
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ;
+ COLAMD_DEBUG0 (("colamd: A not present\n")) ;
+ return (false) ;
+ }
+
+ if (!p) /* p is not present */
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ;
+ COLAMD_DEBUG0 (("colamd: p not present\n")) ;
+ return (false) ;
+ }
+
+ if (n_row < 0) /* n_row must be >= 0 */
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ;
+ stats [COLAMD_INFO1] = n_row ;
+ COLAMD_DEBUG0 (("colamd: nrow negative %d\n", n_row)) ;
+ return (false) ;
+ }
+
+ if (n_col < 0) /* n_col must be >= 0 */
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ;
+ stats [COLAMD_INFO1] = n_col ;
+ COLAMD_DEBUG0 (("colamd: ncol negative %d\n", n_col)) ;
+ return (false) ;
+ }
+
+ nnz = p [n_col] ;
+ if (nnz < 0) /* nnz must be >= 0 */
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ;
+ stats [COLAMD_INFO1] = nnz ;
+ COLAMD_DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ;
+ return (false) ;
+ }
+
+ if (p [0] != 0)
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ;
+ stats [COLAMD_INFO1] = p [0] ;
+ COLAMD_DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ;
+ return (false) ;
+ }
+
+ /* === If no knobs, set default knobs =================================== */
+
+ if (!knobs)
+ {
+ colamd_set_defaults (default_knobs) ;
+ knobs = default_knobs ;
+ }
+
+ /* === Allocate the Row and Col arrays from array A ===================== */
+
+ Col_size = colamd_c (n_col) ;
+ Row_size = colamd_r (n_row) ;
+ need = 2*nnz + n_col + Col_size + Row_size ;
+
+ if (need > Alen)
+ {
+ /* not enough space in array A to perform the ordering */
+ stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ;
+ stats [COLAMD_INFO1] = need ;
+ stats [COLAMD_INFO2] = Alen ;
+ COLAMD_DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen));
+ return (false) ;
+ }
+
+ Alen -= Col_size + Row_size ;
+ Col = (colamd_col<Index> *) &A [Alen] ;
+ Row = (Colamd_Row<Index> *) &A [Alen + Col_size] ;
+
+ /* === Construct the row and column data structures ===================== */
+
+ if (!Eigen::internal::init_rows_cols (n_row, n_col, Row, Col, A, p, stats))
+ {
+ /* input matrix is invalid */
+ COLAMD_DEBUG0 (("colamd: Matrix invalid\n")) ;
+ return (false) ;
+ }
+
+ /* === Initialize scores, kill dense rows/columns ======================= */
+
+ Eigen::internal::init_scoring (n_row, n_col, Row, Col, A, p, knobs,
+ &n_row2, &n_col2, &max_deg) ;
+
+ /* === Order the supercolumns =========================================== */
+
+ ngarbage = Eigen::internal::find_ordering (n_row, n_col, Alen, Row, Col, A, p,
+ n_col2, max_deg, 2*nnz) ;
+
+ /* === Order the non-principal columns ================================== */
+
+ Eigen::internal::order_children (n_col, Col, p) ;
+
+ /* === Return statistics in stats ======================================= */
+
+ stats [COLAMD_DENSE_ROW] = n_row - n_row2 ;
+ stats [COLAMD_DENSE_COL] = n_col - n_col2 ;
+ stats [COLAMD_DEFRAG_COUNT] = ngarbage ;
+ COLAMD_DEBUG0 (("colamd: done.\n")) ;
+ return (true) ;
+}
+
+/* ========================================================================== */
+/* === NON-USER-CALLABLE ROUTINES: ========================================== */
+/* ========================================================================== */
+
+/* There are no user-callable routines beyond this point in the file */
+
+
+/* ========================================================================== */
+/* === init_rows_cols ======================================================= */
+/* ========================================================================== */
+
+/*
+ Takes the column form of the matrix in A and creates the row form of the
+ matrix. Also, row and column attributes are stored in the Col and Row
+ structs. If the columns are un-sorted or contain duplicate row indices,
+ this routine will also sort and remove duplicate row indices from the
+ column form of the matrix. Returns false if the matrix is invalid,
+ true otherwise. Not user-callable.
+*/
+template <typename Index>
+static Index init_rows_cols /* returns true if OK, or false otherwise */
+ (
+ /* === Parameters ======================================================= */
+
+ Index n_row, /* number of rows of A */
+ Index n_col, /* number of columns of A */
+ Colamd_Row<Index> Row [], /* of size n_row+1 */
+ colamd_col<Index> Col [], /* of size n_col+1 */
+ Index A [], /* row indices of A, of size Alen */
+ Index p [], /* pointers to columns in A, of size n_col+1 */
+ Index stats [COLAMD_STATS] /* colamd statistics */
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index col ; /* a column index */
+ Index row ; /* a row index */
+ Index *cp ; /* a column pointer */
+ Index *cp_end ; /* a pointer to the end of a column */
+ Index *rp ; /* a row pointer */
+ Index *rp_end ; /* a pointer to the end of a row */
+ Index last_row ; /* previous row */
+
+ /* === Initialize columns, and check column pointers ==================== */
+
+ for (col = 0 ; col < n_col ; col++)
+ {
+ Col [col].start = p [col] ;
+ Col [col].length = p [col+1] - p [col] ;
+
+ if (Col [col].length < 0)
+ {
+ /* column pointers must be non-decreasing */
+ stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ;
+ stats [COLAMD_INFO1] = col ;
+ stats [COLAMD_INFO2] = Col [col].length ;
+ COLAMD_DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ;
+ return (false) ;
+ }
+
+ Col [col].shared1.thickness = 1 ;
+ Col [col].shared2.score = 0 ;
+ Col [col].shared3.prev = COLAMD_EMPTY ;
+ Col [col].shared4.degree_next = COLAMD_EMPTY ;
+ }
+
+ /* p [0..n_col] no longer needed, used as "head" in subsequent routines */
+
+ /* === Scan columns, compute row degrees, and check row indices ========= */
+
+ stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/
+
+ for (row = 0 ; row < n_row ; row++)
+ {
+ Row [row].length = 0 ;
+ Row [row].shared2.mark = -1 ;
+ }
+
+ for (col = 0 ; col < n_col ; col++)
+ {
+ last_row = -1 ;
+
+ cp = &A [p [col]] ;
+ cp_end = &A [p [col+1]] ;
+
+ while (cp < cp_end)
+ {
+ row = *cp++ ;
+
+ /* make sure row indices within range */
+ if (row < 0 || row >= n_row)
+ {
+ stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ;
+ stats [COLAMD_INFO1] = col ;
+ stats [COLAMD_INFO2] = row ;
+ stats [COLAMD_INFO3] = n_row ;
+ COLAMD_DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ;
+ return (false) ;
+ }
+
+ if (row <= last_row || Row [row].shared2.mark == col)
+ {
+ /* row index are unsorted or repeated (or both), thus col */
+ /* is jumbled. This is a notice, not an error condition. */
+ stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ;
+ stats [COLAMD_INFO1] = col ;
+ stats [COLAMD_INFO2] = row ;
+ (stats [COLAMD_INFO3]) ++ ;
+ COLAMD_DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col));
+ }
+
+ if (Row [row].shared2.mark != col)
+ {
+ Row [row].length++ ;
+ }
+ else
+ {
+ /* this is a repeated entry in the column, */
+ /* it will be removed */
+ Col [col].length-- ;
+ }
+
+ /* mark the row as having been seen in this column */
+ Row [row].shared2.mark = col ;
+
+ last_row = row ;
+ }
+ }
+
+ /* === Compute row pointers ============================================= */
+
+ /* row form of the matrix starts directly after the column */
+ /* form of matrix in A */
+ Row [0].start = p [n_col] ;
+ Row [0].shared1.p = Row [0].start ;
+ Row [0].shared2.mark = -1 ;
+ for (row = 1 ; row < n_row ; row++)
+ {
+ Row [row].start = Row [row-1].start + Row [row-1].length ;
+ Row [row].shared1.p = Row [row].start ;
+ Row [row].shared2.mark = -1 ;
+ }
+
+ /* === Create row form ================================================== */
+
+ if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED)
+ {
+ /* if cols jumbled, watch for repeated row indices */
+ for (col = 0 ; col < n_col ; col++)
+ {
+ cp = &A [p [col]] ;
+ cp_end = &A [p [col+1]] ;
+ while (cp < cp_end)
+ {
+ row = *cp++ ;
+ if (Row [row].shared2.mark != col)
+ {
+ A [(Row [row].shared1.p)++] = col ;
+ Row [row].shared2.mark = col ;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* if cols not jumbled, we don't need the mark (this is faster) */
+ for (col = 0 ; col < n_col ; col++)
+ {
+ cp = &A [p [col]] ;
+ cp_end = &A [p [col+1]] ;
+ while (cp < cp_end)
+ {
+ A [(Row [*cp++].shared1.p)++] = col ;
+ }
+ }
+ }
+
+ /* === Clear the row marks and set row degrees ========================== */
+
+ for (row = 0 ; row < n_row ; row++)
+ {
+ Row [row].shared2.mark = 0 ;
+ Row [row].shared1.degree = Row [row].length ;
+ }
+
+ /* === See if we need to re-create columns ============================== */
+
+ if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED)
+ {
+ COLAMD_DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ;
+
+
+ /* === Compute col pointers ========================================= */
+
+ /* col form of the matrix starts at A [0]. */
+ /* Note, we may have a gap between the col form and the row */
+ /* form if there were duplicate entries, if so, it will be */
+ /* removed upon the first garbage collection */
+ Col [0].start = 0 ;
+ p [0] = Col [0].start ;
+ for (col = 1 ; col < n_col ; col++)
+ {
+ /* note that the lengths here are for pruned columns, i.e. */
+ /* no duplicate row indices will exist for these columns */
+ Col [col].start = Col [col-1].start + Col [col-1].length ;
+ p [col] = Col [col].start ;
+ }
+
+ /* === Re-create col form =========================================== */
+
+ for (row = 0 ; row < n_row ; row++)
+ {
+ rp = &A [Row [row].start] ;
+ rp_end = rp + Row [row].length ;
+ while (rp < rp_end)
+ {
+ A [(p [*rp++])++] = row ;
+ }
+ }
+ }
+
+ /* === Done. Matrix is not (or no longer) jumbled ====================== */
+
+ return (true) ;
+}
+
+
+/* ========================================================================== */
+/* === init_scoring ========================================================= */
+/* ========================================================================== */
+
+/*
+ Kills dense or empty columns and rows, calculates an initial score for
+ each column, and places all columns in the degree lists. Not user-callable.
+*/
+template <typename Index>
+static void init_scoring
+ (
+ /* === Parameters ======================================================= */
+
+ Index n_row, /* number of rows of A */
+ Index n_col, /* number of columns of A */
+ Colamd_Row<Index> Row [], /* of size n_row+1 */
+ colamd_col<Index> Col [], /* of size n_col+1 */
+ Index A [], /* column form and row form of A */
+ Index head [], /* of size n_col+1 */
+ double knobs [COLAMD_KNOBS],/* parameters */
+ Index *p_n_row2, /* number of non-dense, non-empty rows */
+ Index *p_n_col2, /* number of non-dense, non-empty columns */
+ Index *p_max_deg /* maximum row degree */
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index c ; /* a column index */
+ Index r, row ; /* a row index */
+ Index *cp ; /* a column pointer */
+ Index deg ; /* degree of a row or column */
+ Index *cp_end ; /* a pointer to the end of a column */
+ Index *new_cp ; /* new column pointer */
+ Index col_length ; /* length of pruned column */
+ Index score ; /* current column score */
+ Index n_col2 ; /* number of non-dense, non-empty columns */
+ Index n_row2 ; /* number of non-dense, non-empty rows */
+ Index dense_row_count ; /* remove rows with more entries than this */
+ Index dense_col_count ; /* remove cols with more entries than this */
+ Index min_score ; /* smallest column score */
+ Index max_deg ; /* maximum row degree */
+ Index next_col ; /* Used to add to degree list.*/
+
+
+ /* === Extract knobs ==================================================== */
+
+ dense_row_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_ROW] * n_col, n_col)) ;
+ dense_col_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_COL] * n_row, n_row)) ;
+ COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ;
+ max_deg = 0 ;
+ n_col2 = n_col ;
+ n_row2 = n_row ;
+
+ /* === Kill empty columns =============================================== */
+
+ /* Put the empty columns at the end in their natural order, so that LU */
+ /* factorization can proceed as far as possible. */
+ for (c = n_col-1 ; c >= 0 ; c--)
+ {
+ deg = Col [c].length ;
+ if (deg == 0)
+ {
+ /* this is a empty column, kill and order it last */
+ Col [c].shared2.order = --n_col2 ;
+ KILL_PRINCIPAL_COL (c) ;
+ }
+ }
+ COLAMD_DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ;
+
+ /* === Kill dense columns =============================================== */
+
+ /* Put the dense columns at the end, in their natural order */
+ for (c = n_col-1 ; c >= 0 ; c--)
+ {
+ /* skip any dead columns */
+ if (COL_IS_DEAD (c))
+ {
+ continue ;
+ }
+ deg = Col [c].length ;
+ if (deg > dense_col_count)
+ {
+ /* this is a dense column, kill and order it last */
+ Col [c].shared2.order = --n_col2 ;
+ /* decrement the row degrees */
+ cp = &A [Col [c].start] ;
+ cp_end = cp + Col [c].length ;
+ while (cp < cp_end)
+ {
+ Row [*cp++].shared1.degree-- ;
+ }
+ KILL_PRINCIPAL_COL (c) ;
+ }
+ }
+ COLAMD_DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ;
+
+ /* === Kill dense and empty rows ======================================== */
+
+ for (r = 0 ; r < n_row ; r++)
+ {
+ deg = Row [r].shared1.degree ;
+ COLAMD_ASSERT (deg >= 0 && deg <= n_col) ;
+ if (deg > dense_row_count || deg == 0)
+ {
+ /* kill a dense or empty row */
+ KILL_ROW (r) ;
+ --n_row2 ;
+ }
+ else
+ {
+ /* keep track of max degree of remaining rows */
+ max_deg = COLAMD_MAX (max_deg, deg) ;
+ }
+ }
+ COLAMD_DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ;
+
+ /* === Compute initial column scores ==================================== */
+
+ /* At this point the row degrees are accurate. They reflect the number */
+ /* of "live" (non-dense) columns in each row. No empty rows exist. */
+ /* Some "live" columns may contain only dead rows, however. These are */
+ /* pruned in the code below. */
+
+ /* now find the initial matlab score for each column */
+ for (c = n_col-1 ; c >= 0 ; c--)
+ {
+ /* skip dead column */
+ if (COL_IS_DEAD (c))
+ {
+ continue ;
+ }
+ score = 0 ;
+ cp = &A [Col [c].start] ;
+ new_cp = cp ;
+ cp_end = cp + Col [c].length ;
+ while (cp < cp_end)
+ {
+ /* get a row */
+ row = *cp++ ;
+ /* skip if dead */
+ if (ROW_IS_DEAD (row))
+ {
+ continue ;
+ }
+ /* compact the column */
+ *new_cp++ = row ;
+ /* add row's external degree */
+ score += Row [row].shared1.degree - 1 ;
+ /* guard against integer overflow */
+ score = COLAMD_MIN (score, n_col) ;
+ }
+ /* determine pruned column length */
+ col_length = (Index) (new_cp - &A [Col [c].start]) ;
+ if (col_length == 0)
+ {
+ /* a newly-made null column (all rows in this col are "dense" */
+ /* and have already been killed) */
+ COLAMD_DEBUG2 (("Newly null killed: %d\n", c)) ;
+ Col [c].shared2.order = --n_col2 ;
+ KILL_PRINCIPAL_COL (c) ;
+ }
+ else
+ {
+ /* set column length and set score */
+ COLAMD_ASSERT (score >= 0) ;
+ COLAMD_ASSERT (score <= n_col) ;
+ Col [c].length = col_length ;
+ Col [c].shared2.score = score ;
+ }
+ }
+ COLAMD_DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n",
+ n_col-n_col2)) ;
+
+ /* At this point, all empty rows and columns are dead. All live columns */
+ /* are "clean" (containing no dead rows) and simplicial (no supercolumns */
+ /* yet). Rows may contain dead columns, but all live rows contain at */
+ /* least one live column. */
+
+ /* === Initialize degree lists ========================================== */
+
+
+ /* clear the hash buckets */
+ for (c = 0 ; c <= n_col ; c++)
+ {
+ head [c] = COLAMD_EMPTY ;
+ }
+ min_score = n_col ;
+ /* place in reverse order, so low column indices are at the front */
+ /* of the lists. This is to encourage natural tie-breaking */
+ for (c = n_col-1 ; c >= 0 ; c--)
+ {
+ /* only add principal columns to degree lists */
+ if (COL_IS_ALIVE (c))
+ {
+ COLAMD_DEBUG4 (("place %d score %d minscore %d ncol %d\n",
+ c, Col [c].shared2.score, min_score, n_col)) ;
+
+ /* === Add columns score to DList =============================== */
+
+ score = Col [c].shared2.score ;
+
+ COLAMD_ASSERT (min_score >= 0) ;
+ COLAMD_ASSERT (min_score <= n_col) ;
+ COLAMD_ASSERT (score >= 0) ;
+ COLAMD_ASSERT (score <= n_col) ;
+ COLAMD_ASSERT (head [score] >= COLAMD_EMPTY) ;
+
+ /* now add this column to dList at proper score location */
+ next_col = head [score] ;
+ Col [c].shared3.prev = COLAMD_EMPTY ;
+ Col [c].shared4.degree_next = next_col ;
+
+ /* if there already was a column with the same score, set its */
+ /* previous pointer to this new column */
+ if (next_col != COLAMD_EMPTY)
+ {
+ Col [next_col].shared3.prev = c ;
+ }
+ head [score] = c ;
+
+ /* see if this score is less than current min */
+ min_score = COLAMD_MIN (min_score, score) ;
+
+
+ }
+ }
+
+
+ /* === Return number of remaining columns, and max row degree =========== */
+
+ *p_n_col2 = n_col2 ;
+ *p_n_row2 = n_row2 ;
+ *p_max_deg = max_deg ;
+}
+
+
+/* ========================================================================== */
+/* === find_ordering ======================================================== */
+/* ========================================================================== */
+
+/*
+ Order the principal columns of the supercolumn form of the matrix
+ (no supercolumns on input). Uses a minimum approximate column minimum
+ degree ordering method. Not user-callable.
+*/
+template <typename Index>
+static Index find_ordering /* return the number of garbage collections */
+ (
+ /* === Parameters ======================================================= */
+
+ Index n_row, /* number of rows of A */
+ Index n_col, /* number of columns of A */
+ Index Alen, /* size of A, 2*nnz + n_col or larger */
+ Colamd_Row<Index> Row [], /* of size n_row+1 */
+ colamd_col<Index> Col [], /* of size n_col+1 */
+ Index A [], /* column form and row form of A */
+ Index head [], /* of size n_col+1 */
+ Index n_col2, /* Remaining columns to order */
+ Index max_deg, /* Maximum row degree */
+ Index pfree /* index of first free slot (2*nnz on entry) */
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index k ; /* current pivot ordering step */
+ Index pivot_col ; /* current pivot column */
+ Index *cp ; /* a column pointer */
+ Index *rp ; /* a row pointer */
+ Index pivot_row ; /* current pivot row */
+ Index *new_cp ; /* modified column pointer */
+ Index *new_rp ; /* modified row pointer */
+ Index pivot_row_start ; /* pointer to start of pivot row */
+ Index pivot_row_degree ; /* number of columns in pivot row */
+ Index pivot_row_length ; /* number of supercolumns in pivot row */
+ Index pivot_col_score ; /* score of pivot column */
+ Index needed_memory ; /* free space needed for pivot row */
+ Index *cp_end ; /* pointer to the end of a column */
+ Index *rp_end ; /* pointer to the end of a row */
+ Index row ; /* a row index */
+ Index col ; /* a column index */
+ Index max_score ; /* maximum possible score */
+ Index cur_score ; /* score of current column */
+ unsigned int hash ; /* hash value for supernode detection */
+ Index head_column ; /* head of hash bucket */
+ Index first_col ; /* first column in hash bucket */
+ Index tag_mark ; /* marker value for mark array */
+ Index row_mark ; /* Row [row].shared2.mark */
+ Index set_difference ; /* set difference size of row with pivot row */
+ Index min_score ; /* smallest column score */
+ Index col_thickness ; /* "thickness" (no. of columns in a supercol) */
+ Index max_mark ; /* maximum value of tag_mark */
+ Index pivot_col_thickness ; /* number of columns represented by pivot col */
+ Index prev_col ; /* Used by Dlist operations. */
+ Index next_col ; /* Used by Dlist operations. */
+ Index ngarbage ; /* number of garbage collections performed */
+
+
+ /* === Initialization and clear mark ==================================== */
+
+ max_mark = INT_MAX - n_col ; /* INT_MAX defined in <limits.h> */
+ tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
+ min_score = 0 ;
+ ngarbage = 0 ;
+ COLAMD_DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ;
+
+ /* === Order the columns ================================================ */
+
+ for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */)
+ {
+
+ /* === Select pivot column, and order it ============================ */
+
+ /* make sure degree list isn't empty */
+ COLAMD_ASSERT (min_score >= 0) ;
+ COLAMD_ASSERT (min_score <= n_col) ;
+ COLAMD_ASSERT (head [min_score] >= COLAMD_EMPTY) ;
+
+ /* get pivot column from head of minimum degree list */
+ while (head [min_score] == COLAMD_EMPTY && min_score < n_col)
+ {
+ min_score++ ;
+ }
+ pivot_col = head [min_score] ;
+ COLAMD_ASSERT (pivot_col >= 0 && pivot_col <= n_col) ;
+ next_col = Col [pivot_col].shared4.degree_next ;
+ head [min_score] = next_col ;
+ if (next_col != COLAMD_EMPTY)
+ {
+ Col [next_col].shared3.prev = COLAMD_EMPTY ;
+ }
+
+ COLAMD_ASSERT (COL_IS_ALIVE (pivot_col)) ;
+ COLAMD_DEBUG3 (("Pivot col: %d\n", pivot_col)) ;
+
+ /* remember score for defrag check */
+ pivot_col_score = Col [pivot_col].shared2.score ;
+
+ /* the pivot column is the kth column in the pivot order */
+ Col [pivot_col].shared2.order = k ;
+
+ /* increment order count by column thickness */
+ pivot_col_thickness = Col [pivot_col].shared1.thickness ;
+ k += pivot_col_thickness ;
+ COLAMD_ASSERT (pivot_col_thickness > 0) ;
+
+ /* === Garbage_collection, if necessary ============================= */
+
+ needed_memory = COLAMD_MIN (pivot_col_score, n_col - k) ;
+ if (pfree + needed_memory >= Alen)
+ {
+ pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ;
+ ngarbage++ ;
+ /* after garbage collection we will have enough */
+ COLAMD_ASSERT (pfree + needed_memory < Alen) ;
+ /* garbage collection has wiped out the Row[].shared2.mark array */
+ tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
+
+ }
+
+ /* === Compute pivot row pattern ==================================== */
+
+ /* get starting location for this new merged row */
+ pivot_row_start = pfree ;
+
+ /* initialize new row counts to zero */
+ pivot_row_degree = 0 ;
+
+ /* tag pivot column as having been visited so it isn't included */
+ /* in merged pivot row */
+ Col [pivot_col].shared1.thickness = -pivot_col_thickness ;
+
+ /* pivot row is the union of all rows in the pivot column pattern */
+ cp = &A [Col [pivot_col].start] ;
+ cp_end = cp + Col [pivot_col].length ;
+ while (cp < cp_end)
+ {
+ /* get a row */
+ row = *cp++ ;
+ COLAMD_DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ;
+ /* skip if row is dead */
+ if (ROW_IS_DEAD (row))
+ {
+ continue ;
+ }
+ rp = &A [Row [row].start] ;
+ rp_end = rp + Row [row].length ;
+ while (rp < rp_end)
+ {
+ /* get a column */
+ col = *rp++ ;
+ /* add the column, if alive and untagged */
+ col_thickness = Col [col].shared1.thickness ;
+ if (col_thickness > 0 && COL_IS_ALIVE (col))
+ {
+ /* tag column in pivot row */
+ Col [col].shared1.thickness = -col_thickness ;
+ COLAMD_ASSERT (pfree < Alen) ;
+ /* place column in pivot row */
+ A [pfree++] = col ;
+ pivot_row_degree += col_thickness ;
+ }
+ }
+ }
+
+ /* clear tag on pivot column */
+ Col [pivot_col].shared1.thickness = pivot_col_thickness ;
+ max_deg = COLAMD_MAX (max_deg, pivot_row_degree) ;
+
+
+ /* === Kill all rows used to construct pivot row ==================== */
+
+ /* also kill pivot row, temporarily */
+ cp = &A [Col [pivot_col].start] ;
+ cp_end = cp + Col [pivot_col].length ;
+ while (cp < cp_end)
+ {
+ /* may be killing an already dead row */
+ row = *cp++ ;
+ COLAMD_DEBUG3 (("Kill row in pivot col: %d\n", row)) ;
+ KILL_ROW (row) ;
+ }
+
+ /* === Select a row index to use as the new pivot row =============== */
+
+ pivot_row_length = pfree - pivot_row_start ;
+ if (pivot_row_length > 0)
+ {
+ /* pick the "pivot" row arbitrarily (first row in col) */
+ pivot_row = A [Col [pivot_col].start] ;
+ COLAMD_DEBUG3 (("Pivotal row is %d\n", pivot_row)) ;
+ }
+ else
+ {
+ /* there is no pivot row, since it is of zero length */
+ pivot_row = COLAMD_EMPTY ;
+ COLAMD_ASSERT (pivot_row_length == 0) ;
+ }
+ COLAMD_ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ;
+
+ /* === Approximate degree computation =============================== */
+
+ /* Here begins the computation of the approximate degree. The column */
+ /* score is the sum of the pivot row "length", plus the size of the */
+ /* set differences of each row in the column minus the pattern of the */
+ /* pivot row itself. The column ("thickness") itself is also */
+ /* excluded from the column score (we thus use an approximate */
+ /* external degree). */
+
+ /* The time taken by the following code (compute set differences, and */
+ /* add them up) is proportional to the size of the data structure */
+ /* being scanned - that is, the sum of the sizes of each column in */
+ /* the pivot row. Thus, the amortized time to compute a column score */
+ /* is proportional to the size of that column (where size, in this */
+ /* context, is the column "length", or the number of row indices */
+ /* in that column). The number of row indices in a column is */
+ /* monotonically non-decreasing, from the length of the original */
+ /* column on input to colamd. */
+
+ /* === Compute set differences ====================================== */
+
+ COLAMD_DEBUG3 (("** Computing set differences phase. **\n")) ;
+
+ /* pivot row is currently dead - it will be revived later. */
+
+ COLAMD_DEBUG3 (("Pivot row: ")) ;
+ /* for each column in pivot row */
+ rp = &A [pivot_row_start] ;
+ rp_end = rp + pivot_row_length ;
+ while (rp < rp_end)
+ {
+ col = *rp++ ;
+ COLAMD_ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ;
+ COLAMD_DEBUG3 (("Col: %d\n", col)) ;
+
+ /* clear tags used to construct pivot row pattern */
+ col_thickness = -Col [col].shared1.thickness ;
+ COLAMD_ASSERT (col_thickness > 0) ;
+ Col [col].shared1.thickness = col_thickness ;
+
+ /* === Remove column from degree list =========================== */
+
+ cur_score = Col [col].shared2.score ;
+ prev_col = Col [col].shared3.prev ;
+ next_col = Col [col].shared4.degree_next ;
+ COLAMD_ASSERT (cur_score >= 0) ;
+ COLAMD_ASSERT (cur_score <= n_col) ;
+ COLAMD_ASSERT (cur_score >= COLAMD_EMPTY) ;
+ if (prev_col == COLAMD_EMPTY)
+ {
+ head [cur_score] = next_col ;
+ }
+ else
+ {
+ Col [prev_col].shared4.degree_next = next_col ;
+ }
+ if (next_col != COLAMD_EMPTY)
+ {
+ Col [next_col].shared3.prev = prev_col ;
+ }
+
+ /* === Scan the column ========================================== */
+
+ cp = &A [Col [col].start] ;
+ cp_end = cp + Col [col].length ;
+ while (cp < cp_end)
+ {
+ /* get a row */
+ row = *cp++ ;
+ row_mark = Row [row].shared2.mark ;
+ /* skip if dead */
+ if (ROW_IS_MARKED_DEAD (row_mark))
+ {
+ continue ;
+ }
+ COLAMD_ASSERT (row != pivot_row) ;
+ set_difference = row_mark - tag_mark ;
+ /* check if the row has been seen yet */
+ if (set_difference < 0)
+ {
+ COLAMD_ASSERT (Row [row].shared1.degree <= max_deg) ;
+ set_difference = Row [row].shared1.degree ;
+ }
+ /* subtract column thickness from this row's set difference */
+ set_difference -= col_thickness ;
+ COLAMD_ASSERT (set_difference >= 0) ;
+ /* absorb this row if the set difference becomes zero */
+ if (set_difference == 0)
+ {
+ COLAMD_DEBUG3 (("aggressive absorption. Row: %d\n", row)) ;
+ KILL_ROW (row) ;
+ }
+ else
+ {
+ /* save the new mark */
+ Row [row].shared2.mark = set_difference + tag_mark ;
+ }
+ }
+ }
+
+
+ /* === Add up set differences for each column ======================= */
+
+ COLAMD_DEBUG3 (("** Adding set differences phase. **\n")) ;
+
+ /* for each column in pivot row */
+ rp = &A [pivot_row_start] ;
+ rp_end = rp + pivot_row_length ;
+ while (rp < rp_end)
+ {
+ /* get a column */
+ col = *rp++ ;
+ COLAMD_ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ;
+ hash = 0 ;
+ cur_score = 0 ;
+ cp = &A [Col [col].start] ;
+ /* compact the column */
+ new_cp = cp ;
+ cp_end = cp + Col [col].length ;
+
+ COLAMD_DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ;
+
+ while (cp < cp_end)
+ {
+ /* get a row */
+ row = *cp++ ;
+ COLAMD_ASSERT(row >= 0 && row < n_row) ;
+ row_mark = Row [row].shared2.mark ;
+ /* skip if dead */
+ if (ROW_IS_MARKED_DEAD (row_mark))
+ {
+ continue ;
+ }
+ COLAMD_ASSERT (row_mark > tag_mark) ;
+ /* compact the column */
+ *new_cp++ = row ;
+ /* compute hash function */
+ hash += row ;
+ /* add set difference */
+ cur_score += row_mark - tag_mark ;
+ /* integer overflow... */
+ cur_score = COLAMD_MIN (cur_score, n_col) ;
+ }
+
+ /* recompute the column's length */
+ Col [col].length = (Index) (new_cp - &A [Col [col].start]) ;
+
+ /* === Further mass elimination ================================= */
+
+ if (Col [col].length == 0)
+ {
+ COLAMD_DEBUG4 (("further mass elimination. Col: %d\n", col)) ;
+ /* nothing left but the pivot row in this column */
+ KILL_PRINCIPAL_COL (col) ;
+ pivot_row_degree -= Col [col].shared1.thickness ;
+ COLAMD_ASSERT (pivot_row_degree >= 0) ;
+ /* order it */
+ Col [col].shared2.order = k ;
+ /* increment order count by column thickness */
+ k += Col [col].shared1.thickness ;
+ }
+ else
+ {
+ /* === Prepare for supercolumn detection ==================== */
+
+ COLAMD_DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ;
+
+ /* save score so far */
+ Col [col].shared2.score = cur_score ;
+
+ /* add column to hash table, for supercolumn detection */
+ hash %= n_col + 1 ;
+
+ COLAMD_DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ;
+ COLAMD_ASSERT (hash <= n_col) ;
+
+ head_column = head [hash] ;
+ if (head_column > COLAMD_EMPTY)
+ {
+ /* degree list "hash" is non-empty, use prev (shared3) of */
+ /* first column in degree list as head of hash bucket */
+ first_col = Col [head_column].shared3.headhash ;
+ Col [head_column].shared3.headhash = col ;
+ }
+ else
+ {
+ /* degree list "hash" is empty, use head as hash bucket */
+ first_col = - (head_column + 2) ;
+ head [hash] = - (col + 2) ;
+ }
+ Col [col].shared4.hash_next = first_col ;
+
+ /* save hash function in Col [col].shared3.hash */
+ Col [col].shared3.hash = (Index) hash ;
+ COLAMD_ASSERT (COL_IS_ALIVE (col)) ;
+ }
+ }
+
+ /* The approximate external column degree is now computed. */
+
+ /* === Supercolumn detection ======================================== */
+
+ COLAMD_DEBUG3 (("** Supercolumn detection phase. **\n")) ;
+
+ Eigen::internal::detect_super_cols (Col, A, head, pivot_row_start, pivot_row_length) ;
+
+ /* === Kill the pivotal column ====================================== */
+
+ KILL_PRINCIPAL_COL (pivot_col) ;
+
+ /* === Clear mark =================================================== */
+
+ tag_mark += (max_deg + 1) ;
+ if (tag_mark >= max_mark)
+ {
+ COLAMD_DEBUG2 (("clearing tag_mark\n")) ;
+ tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
+ }
+
+ /* === Finalize the new pivot row, and column scores ================ */
+
+ COLAMD_DEBUG3 (("** Finalize scores phase. **\n")) ;
+
+ /* for each column in pivot row */
+ rp = &A [pivot_row_start] ;
+ /* compact the pivot row */
+ new_rp = rp ;
+ rp_end = rp + pivot_row_length ;
+ while (rp < rp_end)
+ {
+ col = *rp++ ;
+ /* skip dead columns */
+ if (COL_IS_DEAD (col))
+ {
+ continue ;
+ }
+ *new_rp++ = col ;
+ /* add new pivot row to column */
+ A [Col [col].start + (Col [col].length++)] = pivot_row ;
+
+ /* retrieve score so far and add on pivot row's degree. */
+ /* (we wait until here for this in case the pivot */
+ /* row's degree was reduced due to mass elimination). */
+ cur_score = Col [col].shared2.score + pivot_row_degree ;
+
+ /* calculate the max possible score as the number of */
+ /* external columns minus the 'k' value minus the */
+ /* columns thickness */
+ max_score = n_col - k - Col [col].shared1.thickness ;
+
+ /* make the score the external degree of the union-of-rows */
+ cur_score -= Col [col].shared1.thickness ;
+
+ /* make sure score is less or equal than the max score */
+ cur_score = COLAMD_MIN (cur_score, max_score) ;
+ COLAMD_ASSERT (cur_score >= 0) ;
+
+ /* store updated score */
+ Col [col].shared2.score = cur_score ;
+
+ /* === Place column back in degree list ========================= */
+
+ COLAMD_ASSERT (min_score >= 0) ;
+ COLAMD_ASSERT (min_score <= n_col) ;
+ COLAMD_ASSERT (cur_score >= 0) ;
+ COLAMD_ASSERT (cur_score <= n_col) ;
+ COLAMD_ASSERT (head [cur_score] >= COLAMD_EMPTY) ;
+ next_col = head [cur_score] ;
+ Col [col].shared4.degree_next = next_col ;
+ Col [col].shared3.prev = COLAMD_EMPTY ;
+ if (next_col != COLAMD_EMPTY)
+ {
+ Col [next_col].shared3.prev = col ;
+ }
+ head [cur_score] = col ;
+
+ /* see if this score is less than current min */
+ min_score = COLAMD_MIN (min_score, cur_score) ;
+
+ }
+
+ /* === Resurrect the new pivot row ================================== */
+
+ if (pivot_row_degree > 0)
+ {
+ /* update pivot row length to reflect any cols that were killed */
+ /* during super-col detection and mass elimination */
+ Row [pivot_row].start = pivot_row_start ;
+ Row [pivot_row].length = (Index) (new_rp - &A[pivot_row_start]) ;
+ Row [pivot_row].shared1.degree = pivot_row_degree ;
+ Row [pivot_row].shared2.mark = 0 ;
+ /* pivot row is no longer dead */
+ }
+ }
+
+ /* === All principal columns have now been ordered ====================== */
+
+ return (ngarbage) ;
+}
+
+
+/* ========================================================================== */
+/* === order_children ======================================================= */
+/* ========================================================================== */
+
+/*
+ The find_ordering routine has ordered all of the principal columns (the
+ representatives of the supercolumns). The non-principal columns have not
+ yet been ordered. This routine orders those columns by walking up the
+ parent tree (a column is a child of the column which absorbed it). The
+ final permutation vector is then placed in p [0 ... n_col-1], with p [0]
+ being the first column, and p [n_col-1] being the last. It doesn't look
+ like it at first glance, but be assured that this routine takes time linear
+ in the number of columns. Although not immediately obvious, the time
+ taken by this routine is O (n_col), that is, linear in the number of
+ columns. Not user-callable.
+*/
+template <typename Index>
+static inline void order_children
+(
+ /* === Parameters ======================================================= */
+
+ Index n_col, /* number of columns of A */
+ colamd_col<Index> Col [], /* of size n_col+1 */
+ Index p [] /* p [0 ... n_col-1] is the column permutation*/
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index i ; /* loop counter for all columns */
+ Index c ; /* column index */
+ Index parent ; /* index of column's parent */
+ Index order ; /* column's order */
+
+ /* === Order each non-principal column ================================== */
+
+ for (i = 0 ; i < n_col ; i++)
+ {
+ /* find an un-ordered non-principal column */
+ COLAMD_ASSERT (COL_IS_DEAD (i)) ;
+ if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == COLAMD_EMPTY)
+ {
+ parent = i ;
+ /* once found, find its principal parent */
+ do
+ {
+ parent = Col [parent].shared1.parent ;
+ } while (!COL_IS_DEAD_PRINCIPAL (parent)) ;
+
+ /* now, order all un-ordered non-principal columns along path */
+ /* to this parent. collapse tree at the same time */
+ c = i ;
+ /* get order of parent */
+ order = Col [parent].shared2.order ;
+
+ do
+ {
+ COLAMD_ASSERT (Col [c].shared2.order == COLAMD_EMPTY) ;
+
+ /* order this column */
+ Col [c].shared2.order = order++ ;
+ /* collaps tree */
+ Col [c].shared1.parent = parent ;
+
+ /* get immediate parent of this column */
+ c = Col [c].shared1.parent ;
+
+ /* continue until we hit an ordered column. There are */
+ /* guarranteed not to be anymore unordered columns */
+ /* above an ordered column */
+ } while (Col [c].shared2.order == COLAMD_EMPTY) ;
+
+ /* re-order the super_col parent to largest order for this group */
+ Col [parent].shared2.order = order ;
+ }
+ }
+
+ /* === Generate the permutation ========================================= */
+
+ for (c = 0 ; c < n_col ; c++)
+ {
+ p [Col [c].shared2.order] = c ;
+ }
+}
+
+
+/* ========================================================================== */
+/* === detect_super_cols ==================================================== */
+/* ========================================================================== */
+
+/*
+ Detects supercolumns by finding matches between columns in the hash buckets.
+ Check amongst columns in the set A [row_start ... row_start + row_length-1].
+ The columns under consideration are currently *not* in the degree lists,
+ and have already been placed in the hash buckets.
+
+ The hash bucket for columns whose hash function is equal to h is stored
+ as follows:
+
+ if head [h] is >= 0, then head [h] contains a degree list, so:
+
+ head [h] is the first column in degree bucket h.
+ Col [head [h]].headhash gives the first column in hash bucket h.
+
+ otherwise, the degree list is empty, and:
+
+ -(head [h] + 2) is the first column in hash bucket h.
+
+ For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous
+ column" pointer. Col [c].shared3.hash is used instead as the hash number
+ for that column. The value of Col [c].shared4.hash_next is the next column
+ in the same hash bucket.
+
+ Assuming no, or "few" hash collisions, the time taken by this routine is
+ linear in the sum of the sizes (lengths) of each column whose score has
+ just been computed in the approximate degree computation.
+ Not user-callable.
+*/
+template <typename Index>
+static void detect_super_cols
+(
+ /* === Parameters ======================================================= */
+
+ colamd_col<Index> Col [], /* of size n_col+1 */
+ Index A [], /* row indices of A */
+ Index head [], /* head of degree lists and hash buckets */
+ Index row_start, /* pointer to set of columns to check */
+ Index row_length /* number of columns to check */
+)
+{
+ /* === Local variables ================================================== */
+
+ Index hash ; /* hash value for a column */
+ Index *rp ; /* pointer to a row */
+ Index c ; /* a column index */
+ Index super_c ; /* column index of the column to absorb into */
+ Index *cp1 ; /* column pointer for column super_c */
+ Index *cp2 ; /* column pointer for column c */
+ Index length ; /* length of column super_c */
+ Index prev_c ; /* column preceding c in hash bucket */
+ Index i ; /* loop counter */
+ Index *rp_end ; /* pointer to the end of the row */
+ Index col ; /* a column index in the row to check */
+ Index head_column ; /* first column in hash bucket or degree list */
+ Index first_col ; /* first column in hash bucket */
+
+ /* === Consider each column in the row ================================== */
+
+ rp = &A [row_start] ;
+ rp_end = rp + row_length ;
+ while (rp < rp_end)
+ {
+ col = *rp++ ;
+ if (COL_IS_DEAD (col))
+ {
+ continue ;
+ }
+
+ /* get hash number for this column */
+ hash = Col [col].shared3.hash ;
+ COLAMD_ASSERT (hash <= n_col) ;
+
+ /* === Get the first column in this hash bucket ===================== */
+
+ head_column = head [hash] ;
+ if (head_column > COLAMD_EMPTY)
+ {
+ first_col = Col [head_column].shared3.headhash ;
+ }
+ else
+ {
+ first_col = - (head_column + 2) ;
+ }
+
+ /* === Consider each column in the hash bucket ====================== */
+
+ for (super_c = first_col ; super_c != COLAMD_EMPTY ;
+ super_c = Col [super_c].shared4.hash_next)
+ {
+ COLAMD_ASSERT (COL_IS_ALIVE (super_c)) ;
+ COLAMD_ASSERT (Col [super_c].shared3.hash == hash) ;
+ length = Col [super_c].length ;
+
+ /* prev_c is the column preceding column c in the hash bucket */
+ prev_c = super_c ;
+
+ /* === Compare super_c with all columns after it ================ */
+
+ for (c = Col [super_c].shared4.hash_next ;
+ c != COLAMD_EMPTY ; c = Col [c].shared4.hash_next)
+ {
+ COLAMD_ASSERT (c != super_c) ;
+ COLAMD_ASSERT (COL_IS_ALIVE (c)) ;
+ COLAMD_ASSERT (Col [c].shared3.hash == hash) ;
+
+ /* not identical if lengths or scores are different */
+ if (Col [c].length != length ||
+ Col [c].shared2.score != Col [super_c].shared2.score)
+ {
+ prev_c = c ;
+ continue ;
+ }
+
+ /* compare the two columns */
+ cp1 = &A [Col [super_c].start] ;
+ cp2 = &A [Col [c].start] ;
+
+ for (i = 0 ; i < length ; i++)
+ {
+ /* the columns are "clean" (no dead rows) */
+ COLAMD_ASSERT (ROW_IS_ALIVE (*cp1)) ;
+ COLAMD_ASSERT (ROW_IS_ALIVE (*cp2)) ;
+ /* row indices will same order for both supercols, */
+ /* no gather scatter nessasary */
+ if (*cp1++ != *cp2++)
+ {
+ break ;
+ }
+ }
+
+ /* the two columns are different if the for-loop "broke" */
+ if (i != length)
+ {
+ prev_c = c ;
+ continue ;
+ }
+
+ /* === Got it! two columns are identical =================== */
+
+ COLAMD_ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ;
+
+ Col [super_c].shared1.thickness += Col [c].shared1.thickness ;
+ Col [c].shared1.parent = super_c ;
+ KILL_NON_PRINCIPAL_COL (c) ;
+ /* order c later, in order_children() */
+ Col [c].shared2.order = COLAMD_EMPTY ;
+ /* remove c from hash bucket */
+ Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ;
+ }
+ }
+
+ /* === Empty this hash bucket ======================================= */
+
+ if (head_column > COLAMD_EMPTY)
+ {
+ /* corresponding degree list "hash" is not empty */
+ Col [head_column].shared3.headhash = COLAMD_EMPTY ;
+ }
+ else
+ {
+ /* corresponding degree list "hash" is empty */
+ head [hash] = COLAMD_EMPTY ;
+ }
+ }
+}
+
+
+/* ========================================================================== */
+/* === garbage_collection =================================================== */
+/* ========================================================================== */
+
+/*
+ Defragments and compacts columns and rows in the workspace A. Used when
+ all avaliable memory has been used while performing row merging. Returns
+ the index of the first free position in A, after garbage collection. The
+ time taken by this routine is linear is the size of the array A, which is
+ itself linear in the number of nonzeros in the input matrix.
+ Not user-callable.
+*/
+template <typename Index>
+static Index garbage_collection /* returns the new value of pfree */
+ (
+ /* === Parameters ======================================================= */
+
+ Index n_row, /* number of rows */
+ Index n_col, /* number of columns */
+ Colamd_Row<Index> Row [], /* row info */
+ colamd_col<Index> Col [], /* column info */
+ Index A [], /* A [0 ... Alen-1] holds the matrix */
+ Index *pfree /* &A [0] ... pfree is in use */
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index *psrc ; /* source pointer */
+ Index *pdest ; /* destination pointer */
+ Index j ; /* counter */
+ Index r ; /* a row index */
+ Index c ; /* a column index */
+ Index length ; /* length of a row or column */
+
+ /* === Defragment the columns =========================================== */
+
+ pdest = &A[0] ;
+ for (c = 0 ; c < n_col ; c++)
+ {
+ if (COL_IS_ALIVE (c))
+ {
+ psrc = &A [Col [c].start] ;
+
+ /* move and compact the column */
+ COLAMD_ASSERT (pdest <= psrc) ;
+ Col [c].start = (Index) (pdest - &A [0]) ;
+ length = Col [c].length ;
+ for (j = 0 ; j < length ; j++)
+ {
+ r = *psrc++ ;
+ if (ROW_IS_ALIVE (r))
+ {
+ *pdest++ = r ;
+ }
+ }
+ Col [c].length = (Index) (pdest - &A [Col [c].start]) ;
+ }
+ }
+
+ /* === Prepare to defragment the rows =================================== */
+
+ for (r = 0 ; r < n_row ; r++)
+ {
+ if (ROW_IS_ALIVE (r))
+ {
+ if (Row [r].length == 0)
+ {
+ /* this row is of zero length. cannot compact it, so kill it */
+ COLAMD_DEBUG3 (("Defrag row kill\n")) ;
+ KILL_ROW (r) ;
+ }
+ else
+ {
+ /* save first column index in Row [r].shared2.first_column */
+ psrc = &A [Row [r].start] ;
+ Row [r].shared2.first_column = *psrc ;
+ COLAMD_ASSERT (ROW_IS_ALIVE (r)) ;
+ /* flag the start of the row with the one's complement of row */
+ *psrc = ONES_COMPLEMENT (r) ;
+
+ }
+ }
+ }
+
+ /* === Defragment the rows ============================================== */
+
+ psrc = pdest ;
+ while (psrc < pfree)
+ {
+ /* find a negative number ... the start of a row */
+ if (*psrc++ < 0)
+ {
+ psrc-- ;
+ /* get the row index */
+ r = ONES_COMPLEMENT (*psrc) ;
+ COLAMD_ASSERT (r >= 0 && r < n_row) ;
+ /* restore first column index */
+ *psrc = Row [r].shared2.first_column ;
+ COLAMD_ASSERT (ROW_IS_ALIVE (r)) ;
+
+ /* move and compact the row */
+ COLAMD_ASSERT (pdest <= psrc) ;
+ Row [r].start = (Index) (pdest - &A [0]) ;
+ length = Row [r].length ;
+ for (j = 0 ; j < length ; j++)
+ {
+ c = *psrc++ ;
+ if (COL_IS_ALIVE (c))
+ {
+ *pdest++ = c ;
+ }
+ }
+ Row [r].length = (Index) (pdest - &A [Row [r].start]) ;
+
+ }
+ }
+ /* ensure we found all the rows */
+ COLAMD_ASSERT (debug_rows == 0) ;
+
+ /* === Return the new value of pfree ==================================== */
+
+ return ((Index) (pdest - &A [0])) ;
+}
+
+
+/* ========================================================================== */
+/* === clear_mark =========================================================== */
+/* ========================================================================== */
+
+/*
+ Clears the Row [].shared2.mark array, and returns the new tag_mark.
+ Return value is the new tag_mark. Not user-callable.
+*/
+template <typename Index>
+static inline Index clear_mark /* return the new value for tag_mark */
+ (
+ /* === Parameters ======================================================= */
+
+ Index n_row, /* number of rows in A */
+ Colamd_Row<Index> Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */
+ )
+{
+ /* === Local variables ================================================== */
+
+ Index r ;
+
+ for (r = 0 ; r < n_row ; r++)
+ {
+ if (ROW_IS_ALIVE (r))
+ {
+ Row [r].shared2.mark = 0 ;
+ }
+ }
+ return (1) ;
+}
+
+
+} // namespace internal
+#endif
diff --git a/extern/Eigen3/Eigen/src/OrderingMethods/Ordering.h b/extern/Eigen3/Eigen/src/OrderingMethods/Ordering.h
new file mode 100644
index 00000000000..b4da6531a1d
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/OrderingMethods/Ordering.h
@@ -0,0 +1,150 @@
+
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_ORDERING_H
+#define EIGEN_ORDERING_H
+
+namespace Eigen {
+
+#include "Eigen_Colamd.h"
+
+namespace internal {
+
+/** \internal
+ * \ingroup OrderingMethods_Module
+ * \returns the symmetric pattern A^T+A from the input matrix A.
+ * FIXME: The values should not be considered here
+ */
+template<typename MatrixType>
+void ordering_helper_at_plus_a(const MatrixType& mat, MatrixType& symmat)
+{
+ MatrixType C;
+ C = mat.transpose(); // NOTE: Could be costly
+ for (int i = 0; i < C.rows(); i++)
+ {
+ for (typename MatrixType::InnerIterator it(C, i); it; ++it)
+ it.valueRef() = 0.0;
+ }
+ symmat = C + mat;
+}
+
+}
+
+#ifndef EIGEN_MPL2_ONLY
+
+/** \ingroup OrderingMethods_Module
+ * \class AMDOrdering
+ *
+ * Functor computing the \em approximate \em minimum \em degree ordering
+ * If the matrix is not structurally symmetric, an ordering of A^T+A is computed
+ * \tparam Index The type of indices of the matrix
+ * \sa COLAMDOrdering
+ */
+template <typename Index>
+class AMDOrdering
+{
+ public:
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
+
+ /** Compute the permutation vector from a sparse matrix
+ * This routine is much faster if the input matrix is column-major
+ */
+ template <typename MatrixType>
+ void operator()(const MatrixType& mat, PermutationType& perm)
+ {
+ // Compute the symmetric pattern
+ SparseMatrix<typename MatrixType::Scalar, ColMajor, Index> symm;
+ internal::ordering_helper_at_plus_a(mat,symm);
+
+ // Call the AMD routine
+ //m_mat.prune(keep_diag());
+ internal::minimum_degree_ordering(symm, perm);
+ }
+
+ /** Compute the permutation with a selfadjoint matrix */
+ template <typename SrcType, unsigned int SrcUpLo>
+ void operator()(const SparseSelfAdjointView<SrcType, SrcUpLo>& mat, PermutationType& perm)
+ {
+ SparseMatrix<typename SrcType::Scalar, ColMajor, Index> C; C = mat;
+
+ // Call the AMD routine
+ // m_mat.prune(keep_diag()); //Remove the diagonal elements
+ internal::minimum_degree_ordering(C, perm);
+ }
+};
+
+#endif // EIGEN_MPL2_ONLY
+
+/** \ingroup OrderingMethods_Module
+ * \class NaturalOrdering
+ *
+ * Functor computing the natural ordering (identity)
+ *
+ * \note Returns an empty permutation matrix
+ * \tparam Index The type of indices of the matrix
+ */
+template <typename Index>
+class NaturalOrdering
+{
+ public:
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
+
+ /** Compute the permutation vector from a column-major sparse matrix */
+ template <typename MatrixType>
+ void operator()(const MatrixType& /*mat*/, PermutationType& perm)
+ {
+ perm.resize(0);
+ }
+
+};
+
+/** \ingroup OrderingMethods_Module
+ * \class COLAMDOrdering
+ *
+ * Functor computing the \em column \em approximate \em minimum \em degree ordering
+ * The matrix should be in column-major format
+ */
+template<typename Index>
+class COLAMDOrdering
+{
+ public:
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
+ typedef Matrix<Index, Dynamic, 1> IndexVector;
+
+ /** Compute the permutation vector form a sparse matrix */
+ template <typename MatrixType>
+ void operator() (const MatrixType& mat, PermutationType& perm)
+ {
+ Index m = mat.rows();
+ Index n = mat.cols();
+ Index nnz = mat.nonZeros();
+ // Get the recommended value of Alen to be used by colamd
+ Index Alen = internal::colamd_recommended(nnz, m, n);
+ // Set the default parameters
+ double knobs [COLAMD_KNOBS];
+ Index stats [COLAMD_STATS];
+ internal::colamd_set_defaults(knobs);
+
+ Index info;
+ IndexVector p(n+1), A(Alen);
+ for(Index i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
+ for(Index i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
+ // Call Colamd routine to compute the ordering
+ info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats);
+ eigen_assert( info && "COLAMD failed " );
+
+ perm.resize(n);
+ for (Index i = 0; i < n; i++) perm.indices()(p(i)) = i;
+ }
+};
+
+} // end namespace Eigen
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h
index 82e137c645a..a955287d1c9 100644
--- a/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h
+++ b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h
@@ -157,27 +157,6 @@ class PastixBase : internal::noncopyable
template<typename Rhs,typename Dest>
bool _solve (const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const;
- /** \internal */
- template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
- void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
- {
- eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
- eigen_assert(rows()==b.rows());
-
- // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix.
- static const int NbColsAtOnce = 1;
- int rhsCols = b.cols();
- int size = b.rows();
- Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols);
- for(int k=0; k<rhsCols; k+=NbColsAtOnce)
- {
- int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce);
- tmp.leftCols(actualCols) = b.middleCols(k,actualCols);
- tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols));
- dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView();
- }
- }
-
Derived& derived()
{
return *static_cast<Derived*>(this);
@@ -731,7 +710,7 @@ struct sparse_solve_retval<PastixBase<_MatrixType>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- dec()._solve_sparse(rhs(),dst);
+ this->defaultEvalTo(dst);
}
};
diff --git a/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h
index e6defc8c39e..1c48f0df7b5 100644
--- a/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h
+++ b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h
@@ -108,6 +108,7 @@ class PardisoImpl
typedef Matrix<Scalar,Dynamic,1> VectorType;
typedef Matrix<Index, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<Index, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
+ typedef Array<Index,64,1,DontAlign> ParameterType;
enum {
ScalarIsComplex = NumTraits<Scalar>::IsComplex
};
@@ -142,7 +143,7 @@ class PardisoImpl
/** \warning for advanced usage only.
* \returns a reference to the parameter array controlling PARDISO.
* See the PARDISO manual to know how to use it. */
- Array<Index,64,1>& pardisoParameterArray()
+ ParameterType& pardisoParameterArray()
{
return m_iparm;
}
@@ -205,29 +206,6 @@ class PardisoImpl
template<typename BDerived, typename XDerived>
bool _solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>& x) const;
- /** \internal */
- template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
- void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
- {
- eigen_assert(m_size==b.rows());
-
- // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix.
- static const int NbColsAtOnce = 4;
- int rhsCols = b.cols();
- int size = b.rows();
- // Pardiso cannot solve in-place,
- // so we need two temporaries
- Eigen::Matrix<DestScalar,Dynamic,Dynamic,ColMajor> tmp_rhs(size,rhsCols);
- Eigen::Matrix<DestScalar,Dynamic,Dynamic,ColMajor> tmp_res(size,rhsCols);
- for(int k=0; k<rhsCols; k+=NbColsAtOnce)
- {
- int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce);
- tmp_rhs.leftCols(actualCols) = b.middleCols(k,actualCols);
- tmp_res.leftCols(actualCols) = derived().solve(tmp_rhs.leftCols(actualCols));
- dest.middleCols(k,actualCols) = tmp_res.leftCols(actualCols).sparseView();
- }
- }
-
protected:
void pardisoRelease()
{
@@ -295,7 +273,7 @@ class PardisoImpl
bool m_initialized, m_analysisIsOk, m_factorizationIsOk;
Index m_type, m_msglvl;
mutable void *m_pt[64];
- mutable Array<Index,64,1> m_iparm;
+ mutable ParameterType m_iparm;
mutable IntColVectorType m_perm;
Index m_size;
@@ -603,7 +581,7 @@ struct sparse_solve_retval<PardisoImpl<Derived>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- dec().derived()._solve_sparse(rhs(),dst);
+ this->defaultEvalTo(dst);
}
};
diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h
index 2daa23cc354..bec85810ccc 100644
--- a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h
@@ -55,7 +55,13 @@ template<typename _MatrixType> class ColPivHouseholderQR
typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
- typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
+
+ private:
+
+ typedef typename PermutationType::Index PermIndexType;
+
+ public:
/**
* \brief Default Constructor.
@@ -81,17 +87,29 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR(Index rows, Index cols)
: m_qr(rows, cols),
m_hCoeffs((std::min)(rows,cols)),
- m_colsPermutation(cols),
+ m_colsPermutation(PermIndexType(cols)),
m_colsTranspositions(cols),
m_temp(cols),
m_colSqNorms(cols),
m_isInitialized(false),
m_usePrescribedThreshold(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * ColPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
ColPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
- m_colsPermutation(matrix.cols()),
+ m_colsPermutation(PermIndexType(matrix.cols())),
m_colsTranspositions(matrix.cols()),
m_temp(matrix.cols()),
m_colSqNorms(matrix.cols()),
@@ -127,6 +145,10 @@ template<typename _MatrixType> class ColPivHouseholderQR
}
HouseholderSequenceType householderQ(void) const;
+ HouseholderSequenceType matrixQ(void) const
+ {
+ return householderQ();
+ }
/** \returns a reference to the matrix where the Householder QR decomposition is stored
*/
@@ -135,9 +157,25 @@ template<typename _MatrixType> class ColPivHouseholderQR
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_qr;
}
-
+
+ /** \returns a reference to the matrix where the result Householder QR is stored
+ * \warning The strict lower part of this matrix contains internal values.
+ * Only the upper triangular part should be referenced. To get it, use
+ * \code matrixR().template triangularView<Upper>() \endcode
+ * For rank-deficient matrices, use
+ * \code
+ * matrixR().topLeftCorner(rank(), rank()).template triangularView<Upper>()
+ * \endcode
+ */
+ const MatrixType& matrixR() const
+ {
+ eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
+ return m_qr;
+ }
+
ColPivHouseholderQR& compute(const MatrixType& matrix);
+ /** \returns a const reference to the column permutation matrix */
const PermutationType& colsPermutation() const
{
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
@@ -181,11 +219,12 @@ template<typename _MatrixType> class ColPivHouseholderQR
*/
inline Index rank() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
+ RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
Index result = 0;
for(Index i = 0; i < m_nonzero_pivots; ++i)
- result += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);
+ result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
return result;
}
@@ -255,6 +294,11 @@ template<typename _MatrixType> class ColPivHouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
/** Allows to prescribe a threshold to be used by certain methods, such as rank(),
@@ -305,7 +349,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
return m_usePrescribedThreshold ? m_prescribedThreshold
// this formula comes from experimenting (see "LU precision tuning" thread on the list)
// and turns out to be identical to Higham's formula used already in LDLt.
- : NumTraits<Scalar>::epsilon() * m_qr.diagonalSize();
+ : NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
}
/** \returns the number of nonzero pivots in the QR decomposition.
@@ -325,6 +369,18 @@ template<typename _MatrixType> class ColPivHouseholderQR
* diagonal coefficient of R.
*/
RealScalar maxPivot() const { return m_maxpivot; }
+
+ /** \brief Reports whether the QR factorization was succesful.
+ *
+ * \note This function always returns \c Success. It is provided for compatibility
+ * with other factorization routines.
+ * \returns \c Success
+ */
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return Success;
+ }
protected:
MatrixType m_qr;
@@ -342,9 +398,10 @@ template<typename _MatrixType> class ColPivHouseholderQR
template<typename MatrixType>
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
- return internal::abs(m_qr.diagonal().prod());
+ return abs(m_qr.diagonal().prod());
}
template<typename MatrixType>
@@ -355,12 +412,22 @@ typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDetermina
return m_qr.diagonal().cwiseAbs().array().log().sum();
}
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class ColPivHouseholderQR, ColPivHouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
+ using std::abs;
Index rows = matrix.rows();
Index cols = matrix.cols();
Index size = matrix.diagonalSize();
+
+ // the column permutation is stored as int indices, so just to be sure:
+ eigen_assert(cols<=NumTraits<int>::highest());
m_qr = matrix;
m_hCoeffs.resize(size);
@@ -374,7 +441,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
for(Index k = 0; k < cols; ++k)
m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
- RealScalar threshold_helper = m_colSqNorms.maxCoeff() * internal::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);
+ RealScalar threshold_helper = m_colSqNorms.maxCoeff() * numext::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
@@ -426,7 +493,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
m_qr.coeffRef(k,k) = beta;
// remember the maximum absolute value of diagonal coefficients
- if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta);
+ if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
// apply the householder transformation
m_qr.bottomRightCorner(rows-k, cols-k-1)
@@ -436,9 +503,9 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
}
- m_colsPermutation.setIdentity(cols);
- for(Index k = 0; k < m_nonzero_pivots; ++k)
- m_colsPermutation.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
+ m_colsPermutation.setIdentity(PermIndexType(cols));
+ for(PermIndexType k = 0; k < m_nonzero_pivots; ++k)
+ m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
@@ -458,8 +525,8 @@ struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
{
eigen_assert(rhs().rows() == dec().rows());
- const int cols = dec().cols(),
- nonzero_pivots = dec().nonzeroPivots();
+ const Index cols = dec().cols(),
+ nonzero_pivots = dec().nonzeroPivots();
if(nonzero_pivots == 0)
{
@@ -475,19 +542,11 @@ struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
.transpose()
);
- dec().matrixQR()
+ dec().matrixR()
.topLeftCorner(nonzero_pivots, nonzero_pivots)
.template triangularView<Upper>()
.solveInPlace(c.topRows(nonzero_pivots));
-
- typename Rhs::PlainObject d(c);
- d.topRows(nonzero_pivots)
- = dec().matrixQR()
- .topLeftCorner(nonzero_pivots, nonzero_pivots)
- .template triangularView<Upper>()
- * c.topRows(nonzero_pivots);
-
for(Index i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
for(Index i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
}
diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h
index 745ecf8be98..b5b19832652 100644
--- a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h
+++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h
@@ -41,12 +41,13 @@ namespace Eigen {
/** \internal Specialization for the data types supported by MKL */
#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \
-template<> inline\
+template<> inline \
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >& \
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >::compute( \
const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix) \
\
{ \
+ using std::abs; \
typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \
typedef MatrixType::Scalar Scalar; \
typedef MatrixType::RealScalar RealScalar; \
@@ -71,10 +72,10 @@ ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynami
m_isInitialized = true; \
m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \
m_hCoeffs.adjointInPlace(); \
- RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold(); \
+ RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); \
lapack_int *perm = m_colsPermutation.indices().data(); \
for(i=0;i<size;i++) { \
- m_nonzero_pivots += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);\
+ m_nonzero_pivots += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);\
} \
for(i=0;i<cols;i++) perm[i]--;\
\
diff --git a/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h b/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h
index 37898e77cc2..6168e7abfb4 100644
--- a/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h
@@ -63,9 +63,10 @@ template<typename _MatrixType> class FullPivHouseholderQR
typedef typename MatrixType::Index Index;
typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
- typedef Matrix<Index, 1, ColsAtCompileTime, RowMajor, 1, MaxColsAtCompileTime> IntRowVectorType;
+ typedef Matrix<Index, 1,
+ EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime,RowsAtCompileTime), RowMajor, 1,
+ EIGEN_SIZE_MIN_PREFER_FIXED(MaxColsAtCompileTime,MaxRowsAtCompileTime)> IntDiagSizeVectorType;
typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
- typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_col_type<MatrixType>::type ColVectorType;
@@ -93,20 +94,32 @@ template<typename _MatrixType> class FullPivHouseholderQR
FullPivHouseholderQR(Index rows, Index cols)
: m_qr(rows, cols),
m_hCoeffs((std::min)(rows,cols)),
- m_rows_transpositions(rows),
- m_cols_transpositions(cols),
+ m_rows_transpositions((std::min)(rows,cols)),
+ m_cols_transpositions((std::min)(rows,cols)),
m_cols_permutation(cols),
- m_temp((std::min)(rows,cols)),
+ m_temp(cols),
m_isInitialized(false),
m_usePrescribedThreshold(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * FullPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
FullPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
- m_rows_transpositions(matrix.rows()),
- m_cols_transpositions(matrix.cols()),
+ m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())),
+ m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())),
m_cols_permutation(matrix.cols()),
- m_temp((std::min)(matrix.rows(), matrix.cols())),
+ m_temp(matrix.cols()),
m_isInitialized(false),
m_usePrescribedThreshold(false)
{
@@ -114,11 +127,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
}
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
- * *this is the QR decomposition, if any exists.
+ * \c *this is the QR decomposition.
*
* \param b the right-hand-side of the equation to solve.
*
- * \returns a solution.
+ * \returns the exact or least-square solution if the rank is greater or equal to the number of columns of A,
+ * and an arbitrary solution otherwise.
*
* \note The case where b is a matrix is not yet implemented. Also, this
* code is space inefficient.
@@ -152,13 +166,15 @@ template<typename _MatrixType> class FullPivHouseholderQR
FullPivHouseholderQR& compute(const MatrixType& matrix);
+ /** \returns a const reference to the column permutation matrix */
const PermutationType& colsPermutation() const
{
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_cols_permutation;
}
- const IntColVectorType& rowsTranspositions() const
+ /** \returns a const reference to the vector of indices representing the rows transpositions */
+ const IntDiagSizeVectorType& rowsTranspositions() const
{
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rows_transpositions;
@@ -201,11 +217,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
*/
inline Index rank() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
- RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
+ RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
Index result = 0;
for(Index i = 0; i < m_nonzero_pivots; ++i)
- result += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);
+ result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
return result;
}
@@ -274,6 +291,11 @@ template<typename _MatrixType> class FullPivHouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
/** Allows to prescribe a threshold to be used by certain methods, such as rank(),
@@ -324,7 +346,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
return m_usePrescribedThreshold ? m_prescribedThreshold
// this formula comes from experimenting (see "LU precision tuning" thread on the list)
// and turns out to be identical to Higham's formula used already in LDLt.
- : NumTraits<Scalar>::epsilon() * m_qr.diagonalSize();
+ : NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
}
/** \returns the number of nonzero pivots in the QR decomposition.
@@ -348,8 +370,8 @@ template<typename _MatrixType> class FullPivHouseholderQR
protected:
MatrixType m_qr;
HCoeffsType m_hCoeffs;
- IntColVectorType m_rows_transpositions;
- IntRowVectorType m_cols_transpositions;
+ IntDiagSizeVectorType m_rows_transpositions;
+ IntDiagSizeVectorType m_cols_transpositions;
PermutationType m_cols_permutation;
RowVectorType m_temp;
bool m_isInitialized, m_usePrescribedThreshold;
@@ -362,9 +384,10 @@ template<typename _MatrixType> class FullPivHouseholderQR
template<typename MatrixType>
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
- return internal::abs(m_qr.diagonal().prod());
+ return abs(m_qr.diagonal().prod());
}
template<typename MatrixType>
@@ -375,9 +398,16 @@ typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDetermin
return m_qr.diagonal().cwiseAbs().array().log().sum();
}
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class FullPivHouseholderQR, FullPivHouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
+ using std::abs;
Index rows = matrix.rows();
Index cols = matrix.cols();
Index size = (std::min)(rows,cols);
@@ -387,10 +417,10 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
m_temp.resize(cols);
- m_precision = NumTraits<Scalar>::epsilon() * size;
+ m_precision = NumTraits<Scalar>::epsilon() * RealScalar(size);
- m_rows_transpositions.resize(matrix.rows());
- m_cols_transpositions.resize(matrix.cols());
+ m_rows_transpositions.resize(size);
+ m_cols_transpositions.resize(size);
Index number_of_transpositions = 0;
RealScalar biggest(0);
@@ -439,7 +469,7 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
m_qr.coeffRef(k,k) = beta;
// remember the maximum absolute value of diagonal coefficients
- if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta);
+ if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
m_qr.bottomRightCorner(rows-k, cols-k-1)
.applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
@@ -488,17 +518,6 @@ struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
dec().hCoeffs().coeff(k), &temp.coeffRef(0));
}
- if(!dec().isSurjective())
- {
- // is c is in the image of R ?
- RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff();
- RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff();
- // FIXME brain dead
- const RealScalar m_precision = NumTraits<Scalar>::epsilon() * (std::min)(rows,cols);
- // this internal:: prefix is needed by at least gcc 3.4 and ICC
- if(!internal::isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
- return;
- }
dec().matrixQR()
.topLeftCorner(dec().rank(), dec().rank())
.template triangularView<Upper>()
@@ -520,14 +539,14 @@ template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
{
public:
typedef typename MatrixType::Index Index;
- typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType;
+ typedef typename FullPivHouseholderQR<MatrixType>::IntDiagSizeVectorType IntDiagSizeVectorType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef Matrix<typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime, RowMajor, 1,
MatrixType::MaxRowsAtCompileTime> WorkVectorType;
FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr,
const HCoeffsType& hCoeffs,
- const IntColVectorType& rowsTranspositions)
+ const IntDiagSizeVectorType& rowsTranspositions)
: m_qr(qr),
m_hCoeffs(hCoeffs),
m_rowsTranspositions(rowsTranspositions)
@@ -544,6 +563,7 @@ public:
template <typename ResultType>
void evalTo(ResultType& result, WorkVectorType& workspace) const
{
+ using numext::conj;
// compute the product H'_0 H'_1 ... H'_n-1,
// where H_k is the k-th Householder transformation I - h_k v_k v_k'
// and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...]
@@ -555,7 +575,7 @@ public:
for (Index k = size-1; k >= 0; k--)
{
result.block(k, k, rows-k, rows-k)
- .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k));
+ .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k));
result.row(k).swap(result.row(m_rowsTranspositions.coeff(k)));
}
}
@@ -566,7 +586,7 @@ public:
protected:
typename MatrixType::Nested m_qr;
typename HCoeffsType::Nested m_hCoeffs;
- typename IntColVectorType::Nested m_rowsTranspositions;
+ typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h
index 5bcb32c1e18..abc61bcbbe1 100644
--- a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h
+++ b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h
@@ -57,14 +57,14 @@ template<typename _MatrixType> class HouseholderQR
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
- typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
/**
- * \brief Default Constructor.
- *
- * The default constructor is useful in cases in which the user intends to
- * perform decompositions via HouseholderQR::compute(const MatrixType&).
- */
+ * \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via HouseholderQR::compute(const MatrixType&).
+ */
HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {}
/** \brief Default Constructor with memory preallocation
@@ -79,6 +79,18 @@ template<typename _MatrixType> class HouseholderQR
m_temp(cols),
m_isInitialized(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * HouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
HouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
@@ -113,6 +125,14 @@ template<typename _MatrixType> class HouseholderQR
return internal::solve_retval<HouseholderQR, Rhs>(*this, b.derived());
}
+ /** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations.
+ *
+ * The returned expression can directly be used to perform matrix products. It can also be assigned to a dense Matrix object.
+ * Here is an example showing how to recover the full or thin matrix Q, as well as how to perform matrix products using operator*:
+ *
+ * Example: \include HouseholderQR_householderQ.cpp
+ * Output: \verbinclude HouseholderQR_householderQ.out
+ */
HouseholderSequenceType householderQ() const
{
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
@@ -161,6 +181,11 @@ template<typename _MatrixType> class HouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
protected:
@@ -173,9 +198,10 @@ template<typename _MatrixType> class HouseholderQR
template<typename MatrixType>
typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
{
+ using std::abs;
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
- return internal::abs(m_qr.diagonal().prod());
+ return abs(m_qr.diagonal().prod());
}
template<typename MatrixType>
@@ -232,7 +258,6 @@ void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs,
{
typedef typename MatrixQR::Index Index;
typedef typename MatrixQR::Scalar Scalar;
- typedef typename MatrixQR::RealScalar RealScalar;
typedef Block<MatrixQR,Dynamic,Dynamic> BlockType;
Index rows = mat.rows();
@@ -309,6 +334,12 @@ struct solve_retval<HouseholderQR<_MatrixType>, Rhs>
} // end namespace internal
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class HouseholderQR, HouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
diff --git a/extern/Eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/extern/Eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
new file mode 100644
index 00000000000..a2cc2a9e261
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
@@ -0,0 +1,314 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SUITESPARSEQRSUPPORT_H
+#define EIGEN_SUITESPARSEQRSUPPORT_H
+
+namespace Eigen {
+
+ template<typename MatrixType> class SPQR;
+ template<typename SPQRType> struct SPQRMatrixQReturnType;
+ template<typename SPQRType> struct SPQRMatrixQTransposeReturnType;
+ template <typename SPQRType, typename Derived> struct SPQR_QProduct;
+ namespace internal {
+ template <typename SPQRType> struct traits<SPQRMatrixQReturnType<SPQRType> >
+ {
+ typedef typename SPQRType::MatrixType ReturnType;
+ };
+ template <typename SPQRType> struct traits<SPQRMatrixQTransposeReturnType<SPQRType> >
+ {
+ typedef typename SPQRType::MatrixType ReturnType;
+ };
+ template <typename SPQRType, typename Derived> struct traits<SPQR_QProduct<SPQRType, Derived> >
+ {
+ typedef typename Derived::PlainObject ReturnType;
+ };
+ } // End namespace internal
+
+/**
+ * \ingroup SPQRSupport_Module
+ * \class SPQR
+ * \brief Sparse QR factorization based on SuiteSparseQR library
+ *
+ * This class is used to perform a multithreaded and multifrontal rank-revealing QR decomposition
+ * of sparse matrices. The result is then used to solve linear leasts_square systems.
+ * Clearly, a QR factorization is returned such that A*P = Q*R where :
+ *
+ * P is the column permutation. Use colsPermutation() to get it.
+ *
+ * Q is the orthogonal matrix represented as Householder reflectors.
+ * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
+ * You can then apply it to a vector.
+ *
+ * R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix.
+ * NOTE : The Index type of R is always UF_long. You can get it with SPQR::Index
+ *
+ * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<>
+ * NOTE
+ *
+ */
+template<typename _MatrixType>
+class SPQR
+{
+ public:
+ typedef typename _MatrixType::Scalar Scalar;
+ typedef typename _MatrixType::RealScalar RealScalar;
+ typedef UF_long Index ;
+ typedef SparseMatrix<Scalar, ColMajor, Index> MatrixType;
+ typedef PermutationMatrix<Dynamic, Dynamic> PermutationType;
+ public:
+ SPQR()
+ : m_isInitialized(false),
+ m_ordering(SPQR_ORDERING_DEFAULT),
+ m_allow_tol(SPQR_DEFAULT_TOL),
+ m_tolerance (NumTraits<Scalar>::epsilon())
+ {
+ cholmod_l_start(&m_cc);
+ }
+
+ SPQR(const _MatrixType& matrix)
+ : m_isInitialized(false),
+ m_ordering(SPQR_ORDERING_DEFAULT),
+ m_allow_tol(SPQR_DEFAULT_TOL),
+ m_tolerance (NumTraits<Scalar>::epsilon())
+ {
+ cholmod_l_start(&m_cc);
+ compute(matrix);
+ }
+
+ ~SPQR()
+ {
+ SPQR_free();
+ cholmod_l_finish(&m_cc);
+ }
+ void SPQR_free()
+ {
+ cholmod_l_free_sparse(&m_H, &m_cc);
+ cholmod_l_free_sparse(&m_cR, &m_cc);
+ cholmod_l_free_dense(&m_HTau, &m_cc);
+ std::free(m_E);
+ std::free(m_HPinv);
+ }
+
+ void compute(const _MatrixType& matrix)
+ {
+ if(m_isInitialized) SPQR_free();
+
+ MatrixType mat(matrix);
+ cholmod_sparse A;
+ A = viewAsCholmod(mat);
+ Index col = matrix.cols();
+ m_rank = SuiteSparseQR<Scalar>(m_ordering, m_tolerance, col, &A,
+ &m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc);
+
+ if (!m_cR)
+ {
+ m_info = NumericalIssue;
+ m_isInitialized = false;
+ return;
+ }
+ m_info = Success;
+ m_isInitialized = true;
+ m_isRUpToDate = false;
+ }
+ /**
+ * Get the number of rows of the input matrix and the Q matrix
+ */
+ inline Index rows() const {return m_H->nrow; }
+
+ /**
+ * Get the number of columns of the input matrix.
+ */
+ inline Index cols() const { return m_cR->ncol; }
+
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
+ *
+ * \sa compute()
+ */
+ template<typename Rhs>
+ inline const internal::solve_retval<SPQR, Rhs> solve(const MatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
+ eigen_assert(this->rows()==B.rows()
+ && "SPQR::solve(): invalid number of rows of the right hand side matrix B");
+ return internal::solve_retval<SPQR, Rhs>(*this, B.derived());
+ }
+
+ template<typename Rhs, typename Dest>
+ void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
+ {
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
+ eigen_assert(b.cols()==1 && "This method is for vectors only");
+
+ //Compute Q^T * b
+ typename Dest::PlainObject y;
+ y = matrixQ().transpose() * b;
+ // Solves with the triangular matrix R
+ Index rk = this->rank();
+ y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y.topRows(rk));
+ y.bottomRows(cols()-rk).setZero();
+ // Apply the column permutation
+ dest.topRows(cols()) = colsPermutation() * y.topRows(cols());
+
+ m_info = Success;
+ }
+
+ /** \returns the sparse triangular factor R. It is a sparse matrix
+ */
+ const MatrixType matrixR() const
+ {
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
+ if(!m_isRUpToDate) {
+ m_R = viewAsEigen<Scalar,ColMajor, typename MatrixType::Index>(*m_cR);
+ m_isRUpToDate = true;
+ }
+ return m_R;
+ }
+ /// Get an expression of the matrix Q
+ SPQRMatrixQReturnType<SPQR> matrixQ() const
+ {
+ return SPQRMatrixQReturnType<SPQR>(*this);
+ }
+ /// Get the permutation that was applied to columns of A
+ PermutationType colsPermutation() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ Index n = m_cR->ncol;
+ PermutationType colsPerm(n);
+ for(Index j = 0; j <n; j++) colsPerm.indices()(j) = m_E[j];
+ return colsPerm;
+
+ }
+ /**
+ * Gets the rank of the matrix.
+ * It should be equal to matrixQR().cols if the matrix is full-rank
+ */
+ Index rank() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return m_cc.SPQR_istat[4];
+ }
+ /// Set the fill-reducing ordering method to be used
+ void setSPQROrdering(int ord) { m_ordering = ord;}
+ /// Set the tolerance tol to treat columns with 2-norm < =tol as zero
+ void setPivotThreshold(const RealScalar& tol) { m_tolerance = tol; }
+
+ /** \returns a pointer to the SPQR workspace */
+ cholmod_common *cholmodCommon() const { return &m_cc; }
+
+
+ /** \brief Reports whether previous computation was successful.
+ *
+ * \returns \c Success if computation was succesful,
+ * \c NumericalIssue if the sparse QR can not be computed
+ */
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return m_info;
+ }
+ protected:
+ bool m_isInitialized;
+ bool m_analysisIsOk;
+ bool m_factorizationIsOk;
+ mutable bool m_isRUpToDate;
+ mutable ComputationInfo m_info;
+ int m_ordering; // Ordering method to use, see SPQR's manual
+ int m_allow_tol; // Allow to use some tolerance during numerical factorization.
+ RealScalar m_tolerance; // treat columns with 2-norm below this tolerance as zero
+ mutable cholmod_sparse *m_cR; // The sparse R factor in cholmod format
+ mutable MatrixType m_R; // The sparse matrix R in Eigen format
+ mutable Index *m_E; // The permutation applied to columns
+ mutable cholmod_sparse *m_H; //The householder vectors
+ mutable Index *m_HPinv; // The row permutation of H
+ mutable cholmod_dense *m_HTau; // The Householder coefficients
+ mutable Index m_rank; // The rank of the matrix
+ mutable cholmod_common m_cc; // Workspace and parameters
+ template<typename ,typename > friend struct SPQR_QProduct;
+};
+
+template <typename SPQRType, typename Derived>
+struct SPQR_QProduct : ReturnByValue<SPQR_QProduct<SPQRType,Derived> >
+{
+ typedef typename SPQRType::Scalar Scalar;
+ typedef typename SPQRType::Index Index;
+ //Define the constructor to get reference to argument types
+ SPQR_QProduct(const SPQRType& spqr, const Derived& other, bool transpose) : m_spqr(spqr),m_other(other),m_transpose(transpose) {}
+
+ inline Index rows() const { return m_transpose ? m_spqr.rows() : m_spqr.cols(); }
+ inline Index cols() const { return m_other.cols(); }
+ // Assign to a vector
+ template<typename ResType>
+ void evalTo(ResType& res) const
+ {
+ cholmod_dense y_cd;
+ cholmod_dense *x_cd;
+ int method = m_transpose ? SPQR_QTX : SPQR_QX;
+ cholmod_common *cc = m_spqr.cholmodCommon();
+ y_cd = viewAsCholmod(m_other.const_cast_derived());
+ x_cd = SuiteSparseQR_qmult<Scalar>(method, m_spqr.m_H, m_spqr.m_HTau, m_spqr.m_HPinv, &y_cd, cc);
+ res = Matrix<Scalar,ResType::RowsAtCompileTime,ResType::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x), x_cd->nrow, x_cd->ncol);
+ cholmod_l_free_dense(&x_cd, cc);
+ }
+ const SPQRType& m_spqr;
+ const Derived& m_other;
+ bool m_transpose;
+
+};
+template<typename SPQRType>
+struct SPQRMatrixQReturnType{
+
+ SPQRMatrixQReturnType(const SPQRType& spqr) : m_spqr(spqr) {}
+ template<typename Derived>
+ SPQR_QProduct<SPQRType, Derived> operator*(const MatrixBase<Derived>& other)
+ {
+ return SPQR_QProduct<SPQRType,Derived>(m_spqr,other.derived(),false);
+ }
+ SPQRMatrixQTransposeReturnType<SPQRType> adjoint() const
+ {
+ return SPQRMatrixQTransposeReturnType<SPQRType>(m_spqr);
+ }
+ // To use for operations with the transpose of Q
+ SPQRMatrixQTransposeReturnType<SPQRType> transpose() const
+ {
+ return SPQRMatrixQTransposeReturnType<SPQRType>(m_spqr);
+ }
+ const SPQRType& m_spqr;
+};
+
+template<typename SPQRType>
+struct SPQRMatrixQTransposeReturnType{
+ SPQRMatrixQTransposeReturnType(const SPQRType& spqr) : m_spqr(spqr) {}
+ template<typename Derived>
+ SPQR_QProduct<SPQRType,Derived> operator*(const MatrixBase<Derived>& other)
+ {
+ return SPQR_QProduct<SPQRType,Derived>(m_spqr,other.derived(), true);
+ }
+ const SPQRType& m_spqr;
+};
+
+namespace internal {
+
+template<typename _MatrixType, typename Rhs>
+struct solve_retval<SPQR<_MatrixType>, Rhs>
+ : solve_retval_base<SPQR<_MatrixType>, Rhs>
+{
+ typedef SPQR<_MatrixType> Dec;
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ dec()._solve(rhs(),dst);
+ }
+};
+
+} // end namespace internal
+
+}// End namespace Eigen
+#endif
diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h
index a7dbf073766..f44995cd39c 100644
--- a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h
+++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h
@@ -78,7 +78,8 @@ public:
{
if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
{
- m_qr = FullPivHouseholderQR<MatrixType>(svd.rows(), svd.cols());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
}
if (svd.m_computeFullU) m_workspace.resize(svd.rows());
}
@@ -96,7 +97,8 @@ public:
return false;
}
private:
- FullPivHouseholderQR<MatrixType> m_qr;
+ typedef FullPivHouseholderQR<MatrixType> QRType;
+ QRType m_qr;
WorkspaceType m_workspace;
};
@@ -121,7 +123,8 @@ public:
{
if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
{
- m_qr = FullPivHouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
}
m_adjoint.resize(svd.cols(), svd.rows());
if (svd.m_computeFullV) m_workspace.resize(svd.cols());
@@ -141,7 +144,8 @@ public:
else return false;
}
private:
- FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr;
+ typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
TransposeTypeWithSameStorageOrder m_adjoint;
typename internal::plain_row_type<MatrixType>::type m_workspace;
};
@@ -158,7 +162,8 @@ public:
{
if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
{
- m_qr = ColPivHouseholderQR<MatrixType>(svd.rows(), svd.cols());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
}
if (svd.m_computeFullU) m_workspace.resize(svd.rows());
else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
@@ -183,7 +188,8 @@ public:
}
private:
- ColPivHouseholderQR<MatrixType> m_qr;
+ typedef ColPivHouseholderQR<MatrixType> QRType;
+ QRType m_qr;
typename internal::plain_col_type<MatrixType>::type m_workspace;
};
@@ -209,7 +215,8 @@ public:
{
if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
{
- m_qr = ColPivHouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
}
if (svd.m_computeFullV) m_workspace.resize(svd.cols());
else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
@@ -237,7 +244,8 @@ public:
}
private:
- ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr;
+ typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
TransposeTypeWithSameStorageOrder m_adjoint;
typename internal::plain_row_type<MatrixType>::type m_workspace;
};
@@ -254,7 +262,8 @@ public:
{
if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
{
- m_qr = HouseholderQR<MatrixType>(svd.rows(), svd.cols());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
}
if (svd.m_computeFullU) m_workspace.resize(svd.rows());
else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
@@ -278,7 +287,8 @@ public:
return false;
}
private:
- HouseholderQR<MatrixType> m_qr;
+ typedef HouseholderQR<MatrixType> QRType;
+ QRType m_qr;
typename internal::plain_col_type<MatrixType>::type m_workspace;
};
@@ -304,7 +314,8 @@ public:
{
if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
{
- m_qr = HouseholderQR<TransposeTypeWithSameStorageOrder>(svd.cols(), svd.rows());
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
}
if (svd.m_computeFullV) m_workspace.resize(svd.cols());
else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
@@ -332,7 +343,8 @@ public:
}
private:
- HouseholderQR<TransposeTypeWithSameStorageOrder> m_qr;
+ typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
TransposeTypeWithSameStorageOrder m_adjoint;
typename internal::plain_row_type<MatrixType>::type m_workspace;
};
@@ -359,15 +371,19 @@ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
typedef typename SVD::Index Index;
static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
{
+ using std::sqrt;
Scalar z;
JacobiRotation<Scalar> rot;
- RealScalar n = sqrt(abs2(work_matrix.coeff(p,p)) + abs2(work_matrix.coeff(q,p)));
+ RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
if(n==0)
{
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
work_matrix.row(p) *= z;
if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
- z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
+ if(work_matrix.coeff(q,q)!=Scalar(0))
+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
+ else
+ z = Scalar(0);
work_matrix.row(q) *= z;
if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
}
@@ -398,9 +414,10 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
JacobiRotation<RealScalar> *j_left,
JacobiRotation<RealScalar> *j_right)
{
+ using std::sqrt;
Matrix<RealScalar,2,2> m;
- m << real(matrix.coeff(p,p)), real(matrix.coeff(p,q)),
- real(matrix.coeff(q,p)), real(matrix.coeff(q,q));
+ m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),
+ numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));
JacobiRotation<RealScalar> rot1;
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
@@ -412,7 +429,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
else
{
RealScalar u = d / t;
- rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + abs2(u));
+ rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u));
rot1.s() = rot1.c() * u;
}
m.applyOnTheLeft(0,1,rot1);
@@ -709,12 +726,14 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u
}
m_diagSize = (std::min)(m_rows, m_cols);
m_singularValues.resize(m_diagSize);
- m_matrixU.resize(m_rows, m_computeFullU ? m_rows
- : m_computeThinU ? m_diagSize
- : 0);
- m_matrixV.resize(m_cols, m_computeFullV ? m_cols
- : m_computeThinV ? m_diagSize
- : 0);
+ if(RowsAtCompileTime==Dynamic)
+ m_matrixU.resize(m_rows, m_computeFullU ? m_rows
+ : m_computeThinU ? m_diagSize
+ : 0);
+ if(ColsAtCompileTime==Dynamic)
+ m_matrixV.resize(m_cols, m_computeFullV ? m_cols
+ : m_computeThinV ? m_diagSize
+ : 0);
m_workMatrix.resize(m_diagSize, m_diagSize);
if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
@@ -725,6 +744,7 @@ template<typename MatrixType, int QRPreconditioner>
JacobiSVD<MatrixType, QRPreconditioner>&
JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
{
+ using std::abs;
allocate(matrix.rows(), matrix.cols(), computationOptions);
// currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
@@ -762,9 +782,9 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
// notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
// keep us iterating forever. Similarly, small denormal numbers are considered zero.
using std::max;
- RealScalar threshold = (max)(considerAsZero, precision * (max)(internal::abs(m_workMatrix.coeff(p,p)),
- internal::abs(m_workMatrix.coeff(q,q))));
- if((max)(internal::abs(m_workMatrix.coeff(p,q)),internal::abs(m_workMatrix.coeff(q,p))) > threshold)
+ RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
+ abs(m_workMatrix.coeff(q,q))));
+ if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)
{
finished = false;
@@ -788,7 +808,7 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
for(Index i = 0; i < m_diagSize; ++i)
{
- RealScalar a = internal::abs(m_workMatrix.coeff(i,i));
+ RealScalar a = abs(m_workMatrix.coeff(i,i));
m_singularValues.coeffRef(i) = a;
if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
}
@@ -833,17 +853,12 @@ struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
// A = U S V^*
// So A^{-1} = V S^{-1} U^*
- Index diagSize = (std::min)(dec().rows(), dec().cols());
- typename JacobiSVDType::SingularValuesType invertedSingVals(diagSize);
-
+ Matrix<Scalar, Dynamic, Rhs::ColsAtCompileTime, 0, _MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime> tmp;
Index nonzeroSingVals = dec().nonzeroSingularValues();
- invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();
- invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();
-
- dst = dec().matrixV().leftCols(diagSize)
- * invertedSingVals.asDiagonal()
- * dec().matrixU().leftCols(diagSize).adjoint()
- * rhs();
+
+ tmp.noalias() = dec().matrixU().leftCols(nonzeroSingVals).adjoint() * rhs();
+ tmp = dec().singularValues().head(nonzeroSingVals).asDiagonal().inverse() * tmp;
+ dst = dec().matrixV().leftCols(nonzeroSingVals) * tmp;
}
};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h
index 4d479f6b26e..decda754050 100644
--- a/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h
+++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h
@@ -40,7 +40,7 @@ namespace Eigen {
/** \internal Specialization for the data types supported by MKL */
#define EIGEN_MKL_SVD(EIGTYPE, MKLTYPE, MKLRTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \
-template<> inline\
+template<> inline \
JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPivHouseholderQRPreconditioner>& \
JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPivHouseholderQRPreconditioner>::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix, unsigned int computationOptions) \
{ \
diff --git a/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h b/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h
index 213b3100df5..587de37a5ad 100644
--- a/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h
@@ -39,7 +39,7 @@ template<typename _MatrixType> class UpperBidiagonalization
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Diagonal<const MatrixType,0> >
> HouseholderUSequenceType;
typedef HouseholderSequence<
- const MatrixType,
+ const typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type,
Diagonal<const MatrixType,1>,
OnTheRight
> HouseholderVSequenceType;
@@ -74,7 +74,7 @@ template<typename _MatrixType> class UpperBidiagonalization
const HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy
{
eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
- return HouseholderVSequenceType(m_householder, m_householder.const_derived().template diagonal<1>())
+ return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
.setLength(m_householder.cols()-1)
.setShift(1);
}
diff --git a/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h
index 9bf38ab2d91..f41d7e010f7 100644
--- a/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h
+++ b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h
@@ -1,52 +1,12 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-/*
-
-NOTE: the _symbolic, and _numeric functions has been adapted from
- the LDL library:
-
-LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved.
-
-LDL License:
-
- Your use or distribution of LDL or any modified version of
- LDL implies that you agree to this License.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
- USA
-
- Permission is hereby granted to use or copy this program under the
- terms of the GNU LGPL, provided that the Copyright, this License,
- and the Availability of the original version is retained on all copies.
- User documentation of any code that uses this code or any modified
- version of this code must cite the Copyright, this License, the
- Availability note, and "Used by permission." Permission to modify
- the code and to distribute modified code is granted, provided the
- Copyright, this License, and the Availability note are retained,
- and a notice that the code was modified is included.
- */
-
-#include "../Core/util/NonMPL2.h"
-
#ifndef EIGEN_SIMPLICIAL_CHOLESKY_H
#define EIGEN_SIMPLICIAL_CHOLESKY_H
@@ -215,27 +175,6 @@ class SimplicialCholeskyBase : internal::noncopyable
dest = m_Pinv * dest;
}
- /** \internal */
- template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
- void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
- {
- eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
- eigen_assert(m_matrix.rows()==b.rows());
-
- // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix.
- static const int NbColsAtOnce = 4;
- int rhsCols = b.cols();
- int size = b.rows();
- Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols);
- for(int k=0; k<rhsCols; k+=NbColsAtOnce)
- {
- int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce);
- tmp.leftCols(actualCols) = b.middleCols(k,actualCols);
- tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols));
- dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView();
- }
- }
-
#endif // EIGEN_PARSED_BY_DOXYGEN
protected:
@@ -425,7 +364,7 @@ public:
Scalar determinant() const
{
Scalar detL = Base::m_matrix.diagonal().prod();
- return internal::abs2(detL);
+ return numext::abs2(detL);
}
};
@@ -660,7 +599,7 @@ public:
else
{
Scalar detL = Diagonal<const CholMatrixType>(Base::m_matrix).prod();
- return internal::abs2(detL);
+ return numext::abs2(detL);
}
}
@@ -693,151 +632,6 @@ void SimplicialCholeskyBase<Derived>::ordering(const MatrixType& a, CholMatrixTy
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
}
-template<typename Derived>
-void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT)
-{
- const Index size = ap.rows();
- m_matrix.resize(size, size);
- m_parent.resize(size);
- m_nonZerosPerCol.resize(size);
-
- ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
-
- for(Index k = 0; k < size; ++k)
- {
- /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
- m_parent[k] = -1; /* parent of k is not yet known */
- tags[k] = k; /* mark node k as visited */
- m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
- for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it)
- {
- Index i = it.index();
- if(i < k)
- {
- /* follow path from i to root of etree, stop at flagged node */
- for(; tags[i] != k; i = m_parent[i])
- {
- /* find parent of i if not yet determined */
- if (m_parent[i] == -1)
- m_parent[i] = k;
- m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */
- tags[i] = k; /* mark i as visited */
- }
- }
- }
- }
-
- /* construct Lp index array from m_nonZerosPerCol column counts */
- Index* Lp = m_matrix.outerIndexPtr();
- Lp[0] = 0;
- for(Index k = 0; k < size; ++k)
- Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1);
-
- m_matrix.resizeNonZeros(Lp[size]);
-
- m_isInitialized = true;
- m_info = Success;
- m_analysisIsOk = true;
- m_factorizationIsOk = false;
-}
-
-
-template<typename Derived>
-template<bool DoLDLT>
-void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
-{
- eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
- eigen_assert(ap.rows()==ap.cols());
- const Index size = ap.rows();
- eigen_assert(m_parent.size()==size);
- eigen_assert(m_nonZerosPerCol.size()==size);
-
- const Index* Lp = m_matrix.outerIndexPtr();
- Index* Li = m_matrix.innerIndexPtr();
- Scalar* Lx = m_matrix.valuePtr();
-
- ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0);
- ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0);
- ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
-
- bool ok = true;
- m_diag.resize(DoLDLT ? size : 0);
-
- for(Index k = 0; k < size; ++k)
- {
- // compute nonzero pattern of kth row of L, in topological order
- y[k] = 0.0; // Y(0:k) is now all zero
- Index top = size; // stack for pattern is empty
- tags[k] = k; // mark node k as visited
- m_nonZerosPerCol[k] = 0; // count of nonzeros in column k of L
- for(typename MatrixType::InnerIterator it(ap,k); it; ++it)
- {
- Index i = it.index();
- if(i <= k)
- {
- y[i] += internal::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */
- Index len;
- for(len = 0; tags[i] != k; i = m_parent[i])
- {
- pattern[len++] = i; /* L(k,i) is nonzero */
- tags[i] = k; /* mark i as visited */
- }
- while(len > 0)
- pattern[--top] = pattern[--len];
- }
- }
-
- /* compute numerical values kth row of L (a sparse triangular solve) */
-
- RealScalar d = internal::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k)
- y[k] = 0.0;
- for(; top < size; ++top)
- {
- Index i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */
- Scalar yi = y[i]; /* get and clear Y(i) */
- y[i] = 0.0;
-
- /* the nonzero entry L(k,i) */
- Scalar l_ki;
- if(DoLDLT)
- l_ki = yi / m_diag[i];
- else
- yi = l_ki = yi / Lx[Lp[i]];
-
- Index p2 = Lp[i] + m_nonZerosPerCol[i];
- Index p;
- for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p)
- y[Li[p]] -= internal::conj(Lx[p]) * yi;
- d -= internal::real(l_ki * internal::conj(yi));
- Li[p] = k; /* store L(k,i) in column form of L */
- Lx[p] = l_ki;
- ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */
- }
- if(DoLDLT)
- {
- m_diag[k] = d;
- if(d == RealScalar(0))
- {
- ok = false; /* failure, D(k,k) is zero */
- break;
- }
- }
- else
- {
- Index p = Lp[k] + m_nonZerosPerCol[k]++;
- Li[p] = k ; /* store L(k,k) = sqrt (d) in column k */
- if(d <= RealScalar(0)) {
- ok = false; /* failure, matrix is not positive definite */
- break;
- }
- Lx[p] = internal::sqrt(d) ;
- }
- }
-
- m_info = ok ? Success : NumericalIssue;
- m_factorizationIsOk = true;
-}
-
namespace internal {
template<typename Derived, typename Rhs>
@@ -862,7 +656,7 @@ struct sparse_solve_retval<SimplicialCholeskyBase<Derived>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- dec().derived()._solve_sparse(rhs(),dst);
+ this->defaultEvalTo(dst);
}
};
diff --git a/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
new file mode 100644
index 00000000000..7aaf702beed
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
@@ -0,0 +1,199 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+
+/*
+
+NOTE: thes functions vave been adapted from the LDL library:
+
+LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved.
+
+LDL License:
+
+ Your use or distribution of LDL or any modified version of
+ LDL implies that you agree to this License.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ Permission is hereby granted to use or copy this program under the
+ terms of the GNU LGPL, provided that the Copyright, this License,
+ and the Availability of the original version is retained on all copies.
+ User documentation of any code that uses this code or any modified
+ version of this code must cite the Copyright, this License, the
+ Availability note, and "Used by permission." Permission to modify
+ the code and to distribute modified code is granted, provided the
+ Copyright, this License, and the Availability note are retained,
+ and a notice that the code was modified is included.
+ */
+
+#include "../Core/util/NonMPL2.h"
+
+#ifndef EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
+#define EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
+
+namespace Eigen {
+
+template<typename Derived>
+void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT)
+{
+ const Index size = ap.rows();
+ m_matrix.resize(size, size);
+ m_parent.resize(size);
+ m_nonZerosPerCol.resize(size);
+
+ ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
+
+ for(Index k = 0; k < size; ++k)
+ {
+ /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
+ m_parent[k] = -1; /* parent of k is not yet known */
+ tags[k] = k; /* mark node k as visited */
+ m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
+ for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it)
+ {
+ Index i = it.index();
+ if(i < k)
+ {
+ /* follow path from i to root of etree, stop at flagged node */
+ for(; tags[i] != k; i = m_parent[i])
+ {
+ /* find parent of i if not yet determined */
+ if (m_parent[i] == -1)
+ m_parent[i] = k;
+ m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */
+ tags[i] = k; /* mark i as visited */
+ }
+ }
+ }
+ }
+
+ /* construct Lp index array from m_nonZerosPerCol column counts */
+ Index* Lp = m_matrix.outerIndexPtr();
+ Lp[0] = 0;
+ for(Index k = 0; k < size; ++k)
+ Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1);
+
+ m_matrix.resizeNonZeros(Lp[size]);
+
+ m_isInitialized = true;
+ m_info = Success;
+ m_analysisIsOk = true;
+ m_factorizationIsOk = false;
+}
+
+
+template<typename Derived>
+template<bool DoLDLT>
+void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
+{
+ using std::sqrt;
+
+ eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
+ eigen_assert(ap.rows()==ap.cols());
+ const Index size = ap.rows();
+ eigen_assert(m_parent.size()==size);
+ eigen_assert(m_nonZerosPerCol.size()==size);
+
+ const Index* Lp = m_matrix.outerIndexPtr();
+ Index* Li = m_matrix.innerIndexPtr();
+ Scalar* Lx = m_matrix.valuePtr();
+
+ ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0);
+ ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0);
+ ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0);
+
+ bool ok = true;
+ m_diag.resize(DoLDLT ? size : 0);
+
+ for(Index k = 0; k < size; ++k)
+ {
+ // compute nonzero pattern of kth row of L, in topological order
+ y[k] = 0.0; // Y(0:k) is now all zero
+ Index top = size; // stack for pattern is empty
+ tags[k] = k; // mark node k as visited
+ m_nonZerosPerCol[k] = 0; // count of nonzeros in column k of L
+ for(typename MatrixType::InnerIterator it(ap,k); it; ++it)
+ {
+ Index i = it.index();
+ if(i <= k)
+ {
+ y[i] += numext::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */
+ Index len;
+ for(len = 0; tags[i] != k; i = m_parent[i])
+ {
+ pattern[len++] = i; /* L(k,i) is nonzero */
+ tags[i] = k; /* mark i as visited */
+ }
+ while(len > 0)
+ pattern[--top] = pattern[--len];
+ }
+ }
+
+ /* compute numerical values kth row of L (a sparse triangular solve) */
+
+ RealScalar d = numext::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k)
+ y[k] = 0.0;
+ for(; top < size; ++top)
+ {
+ Index i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */
+ Scalar yi = y[i]; /* get and clear Y(i) */
+ y[i] = 0.0;
+
+ /* the nonzero entry L(k,i) */
+ Scalar l_ki;
+ if(DoLDLT)
+ l_ki = yi / m_diag[i];
+ else
+ yi = l_ki = yi / Lx[Lp[i]];
+
+ Index p2 = Lp[i] + m_nonZerosPerCol[i];
+ Index p;
+ for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p)
+ y[Li[p]] -= numext::conj(Lx[p]) * yi;
+ d -= numext::real(l_ki * numext::conj(yi));
+ Li[p] = k; /* store L(k,i) in column form of L */
+ Lx[p] = l_ki;
+ ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */
+ }
+ if(DoLDLT)
+ {
+ m_diag[k] = d;
+ if(d == RealScalar(0))
+ {
+ ok = false; /* failure, D(k,k) is zero */
+ break;
+ }
+ }
+ else
+ {
+ Index p = Lp[k] + m_nonZerosPerCol[k]++;
+ Li[p] = k ; /* store L(k,k) = sqrt (d) in column k */
+ if(d <= RealScalar(0)) {
+ ok = false; /* failure, matrix is not positive definite */
+ break;
+ }
+ Lx[p] = sqrt(d) ;
+ }
+ }
+
+ m_info = ok ? Success : NumericalIssue;
+ m_factorizationIsOk = true;
+}
+
+} // end namespace Eigen
+
+#endif // EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
diff --git a/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h
index 6cfaadbaa9a..17fff96a78b 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h
@@ -288,9 +288,10 @@ class AmbiVector<_Scalar,_Index>::Iterator
* In practice, all coefficients having a magnitude smaller than \a epsilon
* are skipped.
*/
- Iterator(const AmbiVector& vec, RealScalar epsilon = 0)
+ Iterator(const AmbiVector& vec, const RealScalar& epsilon = 0)
: m_vector(vec)
{
+ using std::abs;
m_epsilon = epsilon;
m_isDense = m_vector.m_mode==IsDense;
if (m_isDense)
@@ -304,7 +305,7 @@ class AmbiVector<_Scalar,_Index>::Iterator
{
ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
m_currentEl = m_vector.m_llStart;
- while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<=m_epsilon)
+ while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<=m_epsilon)
m_currentEl = llElements[m_currentEl].next;
if (m_currentEl<0)
{
@@ -326,11 +327,12 @@ class AmbiVector<_Scalar,_Index>::Iterator
Iterator& operator++()
{
+ using std::abs;
if (m_isDense)
{
do {
++m_cachedIndex;
- } while (m_cachedIndex<m_vector.m_end && internal::abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
+ } while (m_cachedIndex<m_vector.m_end && abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
if (m_cachedIndex<m_vector.m_end)
m_cachedValue = m_vector.m_buffer[m_cachedIndex];
else
@@ -341,7 +343,7 @@ class AmbiVector<_Scalar,_Index>::Iterator
ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
do {
m_currentEl = llElements[m_currentEl].next;
- } while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<m_epsilon);
+ } while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<m_epsilon);
if (m_currentEl<0)
{
m_cachedIndex = -1;
diff --git a/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h
index 85a998aff10..3321fab4a8a 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h
@@ -139,7 +139,7 @@ class CompressedStorage
/** \returns the stored value at index \a key
* If the value does not exist, then the value \a defaultValue is returned without any insertion. */
- inline Scalar at(Index key, Scalar defaultValue = Scalar(0)) const
+ inline Scalar at(Index key, const Scalar& defaultValue = Scalar(0)) const
{
if (m_size==0)
return defaultValue;
@@ -152,7 +152,7 @@ class CompressedStorage
}
/** Like at(), but the search is performed in the range [start,end) */
- inline Scalar atInRange(size_t start, size_t end, Index key, Scalar defaultValue = Scalar(0)) const
+ inline Scalar atInRange(size_t start, size_t end, Index key, const Scalar& defaultValue = Scalar(0)) const
{
if (start>=end)
return Scalar(0);
@@ -167,7 +167,7 @@ class CompressedStorage
/** \returns a reference to the value at index \a key
* If the value does not exist, then the value \a defaultValue is inserted
* such that the keys are sorted. */
- inline Scalar& atWithInsertion(Index key, Scalar defaultValue = Scalar(0))
+ inline Scalar& atWithInsertion(Index key, const Scalar& defaultValue = Scalar(0))
{
size_t id = searchLowerIndex(0,m_size,key);
if (id>=m_size || m_indices[id]!=key)
@@ -184,7 +184,7 @@ class CompressedStorage
return m_values[id];
}
- void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
+ void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
{
size_t k = 0;
size_t n = size();
diff --git a/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
index 16b5e1dba6c..5c320e2d2db 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
@@ -66,9 +66,9 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
}
// unordered insertion
- for(int k=0; k<nnz; ++k)
+ for(Index k=0; k<nnz; ++k)
{
- int i = indices[k];
+ Index i = indices[k];
res.insertBackByOuterInnerUnordered(j,i) = values[i];
mask[i] = false;
}
@@ -76,8 +76,8 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
#if 0
// alternative ordered insertion code:
- int t200 = rows/(log2(200)*1.39);
- int t = (rows*100)/139;
+ Index t200 = rows/(log2(200)*1.39);
+ Index t = (rows*100)/139;
// FIXME reserve nnz non zeros
// FIXME implement fast sort algorithms for very small nnz
@@ -90,9 +90,9 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
if(true)
{
if(nnz>1) std::sort(indices.data(),indices.data()+nnz);
- for(int k=0; k<nnz; ++k)
+ for(Index k=0; k<nnz; ++k)
{
- int i = indices[k];
+ Index i = indices[k];
res.insertBackByOuterInner(j,i) = values[i];
mask[i] = false;
}
@@ -100,7 +100,7 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
else
{
// dense path
- for(int i=0; i<rows; ++i)
+ for(Index i=0; i<rows; ++i)
{
if(mask[i])
{
@@ -121,9 +121,9 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
namespace internal {
template<typename Lhs, typename Rhs, typename ResultType,
- int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit,
- int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit,
- int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit>
+ int LhsStorageOrder = (traits<Lhs>::Flags&RowMajorBit) ? RowMajor : ColMajor,
+ int RhsStorageOrder = (traits<Rhs>::Flags&RowMajorBit) ? RowMajor : ColMajor,
+ int ResStorageOrder = (traits<ResultType>::Flags&RowMajorBit) ? RowMajor : ColMajor>
struct conservative_sparse_sparse_product_selector;
template<typename Lhs, typename Rhs, typename ResultType>
@@ -134,8 +134,8 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,C
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix;
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::Index> RowMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> ColMajorMatrix;
ColMajorMatrix resCol(lhs.rows(),rhs.cols());
internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol);
// sort the non zeros:
@@ -149,7 +149,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,C
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::Index> RowMajorMatrix;
RowMajorMatrix rhsRow = rhs;
RowMajorMatrix resRow(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<RowMajorMatrix,Lhs,RowMajorMatrix>(rhsRow, lhs, resRow);
@@ -162,7 +162,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::Index> RowMajorMatrix;
RowMajorMatrix lhsRow = lhs;
RowMajorMatrix resRow(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorMatrix,RowMajorMatrix>(rhs, lhsRow, resRow);
@@ -175,7 +175,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::Index> RowMajorMatrix;
RowMajorMatrix resRow(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow);
res = resRow;
@@ -190,7 +190,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,C
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> ColMajorMatrix;
ColMajorMatrix resCol(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol);
res = resCol;
@@ -202,7 +202,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,C
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> ColMajorMatrix;
ColMajorMatrix lhsCol = lhs;
ColMajorMatrix resCol(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<ColMajorMatrix,Rhs,ColMajorMatrix>(lhsCol, rhs, resCol);
@@ -215,7 +215,7 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> ColMajorMatrix;
ColMajorMatrix rhsCol = rhs;
ColMajorMatrix resCol(lhs.rows(), rhs.cols());
internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorMatrix,ColMajorMatrix>(lhs, rhsCol, resCol);
@@ -228,8 +228,8 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix;
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::Index> RowMajorMatrix;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> ColMajorMatrix;
RowMajorMatrix resRow(lhs.rows(),rhs.cols());
internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow);
// sort the non zeros:
diff --git a/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h
index 93cd4832dea..ab1a266a905 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h
@@ -50,6 +50,8 @@ class MappedSparseMatrix
inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
inline Index innerSize() const { return m_innerSize; }
inline Index outerSize() const { return m_outerSize; }
+
+ bool isCompressed() const { return true; }
//----------------------------------------
// direct access interface
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h
index eefd8070251..16a20a5744e 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h
@@ -12,51 +12,37 @@
namespace Eigen {
-namespace internal {
-template<typename MatrixType, int Size>
-struct traits<SparseInnerVectorSet<MatrixType, Size> >
+template<typename XprType, int BlockRows, int BlockCols>
+class BlockImpl<XprType,BlockRows,BlockCols,true,Sparse>
+ : public SparseMatrixBase<Block<XprType,BlockRows,BlockCols,true> >
{
- typedef typename traits<MatrixType>::Scalar Scalar;
- typedef typename traits<MatrixType>::Index Index;
- typedef typename traits<MatrixType>::StorageKind StorageKind;
- typedef MatrixXpr XprKind;
- enum {
- IsRowMajor = (int(MatrixType::Flags)&RowMajorBit)==RowMajorBit,
- Flags = MatrixType::Flags,
- RowsAtCompileTime = IsRowMajor ? Size : MatrixType::RowsAtCompileTime,
- ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : Size,
- MaxRowsAtCompileTime = RowsAtCompileTime,
- MaxColsAtCompileTime = ColsAtCompileTime,
- CoeffReadCost = MatrixType::CoeffReadCost
- };
-};
-} // end namespace internal
-
-template<typename MatrixType, int Size>
-class SparseInnerVectorSet : internal::no_assignment_operator,
- public SparseMatrixBase<SparseInnerVectorSet<MatrixType, Size> >
-{
- public:
-
- enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
-
- EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
- class InnerIterator: public MatrixType::InnerIterator
+ typedef typename internal::remove_all<typename XprType::Nested>::type _MatrixTypeNested;
+ typedef Block<XprType, BlockRows, BlockCols, true> BlockType;
+public:
+ enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
+protected:
+ enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
+public:
+ EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
+
+ class InnerIterator: public XprType::InnerIterator
{
+ typedef typename BlockImpl::Index Index;
public:
- inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
- : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
+ inline InnerIterator(const BlockType& xpr, Index outer)
+ : XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
- class ReverseInnerIterator: public MatrixType::ReverseInnerIterator
+ class ReverseInnerIterator: public XprType::ReverseInnerIterator
{
+ typedef typename BlockImpl::Index Index;
public:
- inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer)
- : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
+ inline ReverseInnerIterator(const BlockType& xpr, Index outer)
+ : XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
@@ -64,39 +50,24 @@ class SparseInnerVectorSet : internal::no_assignment_operator,
Index m_outer;
};
- inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
- : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
- {
- eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
- }
-
- inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
- : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
- {
- eigen_assert(Size!=Dynamic);
- eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
- }
-
-// template<typename OtherDerived>
-// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
-// {
-// return *this;
-// }
+ inline BlockImpl(const XprType& xpr, int i)
+ : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
+ {}
-// template<typename Sparse>
-// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
-// {
-// return *this;
-// }
+ inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
+ : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
+ {}
EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
protected:
- const typename MatrixType::Nested m_matrix;
+ typename XprType::Nested m_matrix;
Index m_outerStart;
- const internal::variable_if_dynamic<Index, Size> m_outerSize;
+ const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
};
@@ -104,32 +75,36 @@ class SparseInnerVectorSet : internal::no_assignment_operator,
* specialisation for SparseMatrix
***************************************************************************/
-template<typename _Scalar, int _Options, typename _Index, int Size>
-class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
- : public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> >
+template<typename _Scalar, int _Options, typename _Index, int BlockRows, int BlockCols>
+class BlockImpl<SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true,Sparse>
+ : public SparseMatrixBase<Block<SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true> >
{
- typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType;
- public:
-
- enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
-
- EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
- class InnerIterator: public MatrixType::InnerIterator
+ typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType;
+ typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _MatrixTypeNested;
+ typedef Block<SparseMatrixType, BlockRows, BlockCols, true> BlockType;
+public:
+ enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
+ EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
+protected:
+ enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
+public:
+
+ class InnerIterator: public SparseMatrixType::InnerIterator
{
public:
- inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
- : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
+ inline InnerIterator(const BlockType& xpr, Index outer)
+ : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
- class ReverseInnerIterator: public MatrixType::ReverseInnerIterator
+ class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
{
public:
- inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer)
- : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
+ inline ReverseInnerIterator(const BlockType& xpr, Index outer)
+ : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
@@ -137,23 +112,18 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
Index m_outer;
};
- inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
- : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
- {
- eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
- }
+ inline BlockImpl(const SparseMatrixType& xpr, int i)
+ : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
+ {}
- inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
- : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
- {
- eigen_assert(Size==1);
- eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
- }
+ inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols)
+ : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
+ {}
template<typename OtherDerived>
- inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
+ inline BlockType& operator=(const SparseMatrixBase<OtherDerived>& other)
{
- typedef typename internal::remove_all<typename MatrixType::Nested>::type _NestedMatrixType;
+ typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _NestedMatrixType;
_NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);;
// This assignement is slow if this vector set is not empty
// and/or it is not at the end of the nonzeros of the underlying matrix.
@@ -163,70 +133,69 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
// 2 - let's check whether there is enough allocated memory
Index nnz = tmp.nonZeros();
- Index nnz_previous = nonZeros();
- Index free_size = Index(matrix.data().allocatedSize()) + nnz_previous;
- Index nnz_head = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart];
- Index tail = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()];
- Index nnz_tail = matrix.nonZeros() - tail;
-
- if(nnz>free_size)
+ Index start = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart]; // starting position of the current block
+ Index end = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]; // ending posiiton of the current block
+ Index block_size = end - start; // available room in the current block
+ Index tail_size = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end;
+
+ Index free_size = m_matrix.isCompressed()
+ ? Index(matrix.data().allocatedSize()) + block_size
+ : block_size;
+
+ if(nnz>free_size)
{
// realloc manually to reduce copies
- typename MatrixType::Storage newdata(m_matrix.nonZeros() - nnz_previous + nnz);
+ typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);
- std::memcpy(&newdata.value(0), &m_matrix.data().value(0), nnz_head*sizeof(Scalar));
- std::memcpy(&newdata.index(0), &m_matrix.data().index(0), nnz_head*sizeof(Index));
+ std::memcpy(&newdata.value(0), &m_matrix.data().value(0), start*sizeof(Scalar));
+ std::memcpy(&newdata.index(0), &m_matrix.data().index(0), start*sizeof(Index));
- std::memcpy(&newdata.value(nnz_head), &tmp.data().value(0), nnz*sizeof(Scalar));
- std::memcpy(&newdata.index(nnz_head), &tmp.data().index(0), nnz*sizeof(Index));
+ std::memcpy(&newdata.value(start), &tmp.data().value(0), nnz*sizeof(Scalar));
+ std::memcpy(&newdata.index(start), &tmp.data().index(0), nnz*sizeof(Index));
- std::memcpy(&newdata.value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*sizeof(Scalar));
- std::memcpy(&newdata.index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*sizeof(Index));
+ std::memcpy(&newdata.value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar));
+ std::memcpy(&newdata.index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index));
+
+ newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);
matrix.data().swap(newdata);
}
else
{
// no need to realloc, simply copy the tail at its respective position and insert tmp
- matrix.data().resize(nnz_head + nnz + nnz_tail);
-
- if(nnz<nnz_previous)
- {
- std::memcpy(&matrix.data().value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*sizeof(Scalar));
- std::memcpy(&matrix.data().index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*sizeof(Index));
- }
- else
- {
- for(Index i=nnz_tail-1; i>=0; --i)
- {
- matrix.data().value(nnz_head+nnz+i) = matrix.data().value(tail+i);
- matrix.data().index(nnz_head+nnz+i) = matrix.data().index(tail+i);
- }
- }
-
- std::memcpy(&matrix.data().value(nnz_head), &tmp.data().value(0), nnz*sizeof(Scalar));
- std::memcpy(&matrix.data().index(nnz_head), &tmp.data().index(0), nnz*sizeof(Index));
+ matrix.data().resize(start + nnz + tail_size);
+
+ std::memmove(&matrix.data().value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar));
+ std::memmove(&matrix.data().index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index));
+
+ std::memcpy(&matrix.data().value(start), &tmp.data().value(0), nnz*sizeof(Scalar));
+ std::memcpy(&matrix.data().index(start), &tmp.data().index(0), nnz*sizeof(Index));
}
+
+ // update innerNonZeros
+ if(!m_matrix.isCompressed())
+ for(Index j=0; j<m_outerSize.value(); ++j)
+ matrix.innerNonZeroPtr()[m_outerStart+j] = tmp.innerVector(j).nonZeros();
// update outer index pointers
- Index p = nnz_head;
+ Index p = start;
for(Index k=0; k<m_outerSize.value(); ++k)
{
matrix.outerIndexPtr()[m_outerStart+k] = p;
p += tmp.innerVector(k).nonZeros();
}
- std::ptrdiff_t offset = nnz - nnz_previous;
+ std::ptrdiff_t offset = nnz - block_size;
for(Index k = m_outerStart + m_outerSize.value(); k<=matrix.outerSize(); ++k)
{
matrix.outerIndexPtr()[k] += offset;
}
- return *this;
+ return derived();
}
- inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
+ inline BlockType& operator=(const BlockType& other)
{
- return operator=<SparseInnerVectorSet>(other);
+ return operator=<BlockType>(other);
}
inline const Scalar* valuePtr() const
@@ -252,12 +221,12 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
else if(m_outerSize.value()==0)
return 0;
else
- return Map<const Matrix<Index,Size,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
+ return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
}
const Scalar& lastCoeff() const
{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl);
eigen_assert(nonZeros()>0);
if(m_matrix.isCompressed())
return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1];
@@ -265,122 +234,175 @@ class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1];
}
-// template<typename Sparse>
-// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
-// {
-// return *this;
-// }
-
EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
protected:
- typename MatrixType::Nested m_matrix;
+ typename SparseMatrixType::Nested m_matrix;
Index m_outerStart;
- const internal::variable_if_dynamic<Index, Size> m_outerSize;
+ const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
};
//----------
-/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
-template<typename Derived>
-SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(Index i)
-{
- EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
- return innerVector(i);
-}
-
-/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
- * (read-only version) */
-template<typename Derived>
-const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(Index i) const
-{
- EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
- return innerVector(i);
-}
-
-/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
-template<typename Derived>
-SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(Index i)
-{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
- return innerVector(i);
-}
-
-/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
- * (read-only version) */
-template<typename Derived>
-const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(Index i) const
-{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
- return innerVector(i);
-}
-
/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
* is col-major (resp. row-major).
*/
template<typename Derived>
-SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(Index outer)
-{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+typename SparseMatrixBase<Derived>::InnerVectorReturnType SparseMatrixBase<Derived>::innerVector(Index outer)
+{ return InnerVectorReturnType(derived(), outer); }
/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
* is col-major (resp. row-major). Read-only.
*/
template<typename Derived>
-const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(Index outer) const
-{ return SparseInnerVectorSet<Derived,1>(derived(), outer); }
+const typename SparseMatrixBase<Derived>::ConstInnerVectorReturnType SparseMatrixBase<Derived>::innerVector(Index outer) const
+{ return ConstInnerVectorReturnType(derived(), outer); }
-/** \returns the i-th row of the matrix \c *this. For row-major matrix only. */
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major).
+ */
template<typename Derived>
-SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleRows(Index start, Index size)
+Block<Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
{
- EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
- return innerVectors(start, size);
+ return Block<Derived,Dynamic,Dynamic,true>(derived(),
+ IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
+ IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize);
+
}
-/** \returns the i-th row of the matrix \c *this. For row-major matrix only.
- * (read-only version) */
+/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
+ * is col-major (resp. row-major). Read-only.
+ */
template<typename Derived>
-const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleRows(Index start, Index size) const
+const Block<const Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
{
- EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
- return innerVectors(start, size);
+ return Block<const Derived,Dynamic,Dynamic,true>(derived(),
+ IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
+ IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize);
+
}
-/** \returns the i-th column of the matrix \c *this. For column-major matrix only. */
-template<typename Derived>
-SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleCols(Index start, Index size)
+/** Generic implementation of sparse Block expression.
+ * Real-only.
+ */
+template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
+class BlockImpl<XprType,BlockRows,BlockCols,InnerPanel,Sparse>
+ : public SparseMatrixBase<Block<XprType,BlockRows,BlockCols,InnerPanel> >, internal::no_assignment_operator
{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
- return innerVectors(start, size);
-}
+ typedef typename internal::remove_all<typename XprType::Nested>::type _MatrixTypeNested;
+ typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
+public:
+ enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
+ EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
+
+ /** Column or Row constructor
+ */
+ inline BlockImpl(const XprType& xpr, int i)
+ : m_matrix(xpr),
+ m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
+ m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ m_blockRows(xpr.rows()),
+ m_blockCols(xpr.cols())
+ {}
+
+ /** Dynamic-size constructor
+ */
+ inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
+ : m_matrix(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols)
+ {}
+
+ inline int rows() const { return m_blockRows.value(); }
+ inline int cols() const { return m_blockCols.value(); }
+
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(row + m_startRow.value(), col + m_startCol.value());
+ }
-/** \returns the i-th column of the matrix \c *this. For column-major matrix only.
- * (read-only version) */
-template<typename Derived>
-const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::middleCols(Index start, Index size) const
-{
- EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
- return innerVectors(start, size);
-}
+ inline const Scalar coeff(int row, int col) const
+ {
+ return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
+ }
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived()
+ .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+ inline const Scalar coeff(int index) const
+ {
+ return m_matrix
+ .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
+ m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
+ }
+
+ inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
+
+ class InnerIterator : public _MatrixTypeNested::InnerIterator
+ {
+ typedef typename _MatrixTypeNested::InnerIterator Base;
+ const BlockType& m_block;
+ Index m_end;
+ public:
+
+ EIGEN_STRONG_INLINE InnerIterator(const BlockType& block, Index outer)
+ : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
+ m_block(block),
+ m_end(IsRowMajor ? block.m_startCol.value()+block.m_blockCols.value() : block.m_startRow.value()+block.m_blockRows.value())
+ {
+ while( (Base::operator bool()) && (Base::index() < (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value())) )
+ Base::operator++();
+ }
-/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
- * is col-major (resp. row-major).
- */
-template<typename Derived>
-SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
-{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
+ inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
+ inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
+ inline Index row() const { return Base::row() - m_block.m_startRow.value(); }
+ inline Index col() const { return Base::col() - m_block.m_startCol.value(); }
+
+ inline operator bool() const { return Base::operator bool() && Base::index() < m_end; }
+ };
+ class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator
+ {
+ typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
+ const BlockType& m_block;
+ Index m_begin;
+ public:
+
+ EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer)
+ : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
+ m_block(block),
+ m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value())
+ {
+ while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) )
+ Base::operator--();
+ }
-/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
- * is col-major (resp. row-major). Read-only.
- */
-template<typename Derived>
-const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
-{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
+ inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
+ inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
+ inline Index row() const { return Base::row() - m_block.m_startRow.value(); }
+ inline Index col() const { return Base::col() - m_block.m_startCol.value(); }
+
+ inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; }
+ };
+ protected:
+ friend class InnerIterator;
+ friend class ReverseInnerIterator;
+
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
+
+ typename XprType::Nested m_matrix;
+ const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
+ const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
+ const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
+ const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
+
+};
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseColEtree.h b/extern/Eigen3/Eigen/src/SparseCore/SparseColEtree.h
new file mode 100644
index 00000000000..f8745f46100
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseColEtree.h
@@ -0,0 +1,206 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+/*
+
+ * NOTE: This file is the modified version of sp_coletree.c file in SuperLU
+
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSE_COLETREE_H
+#define SPARSE_COLETREE_H
+
+namespace Eigen {
+
+namespace internal {
+
+/** Find the root of the tree/set containing the vertex i : Use Path halving */
+template<typename Index, typename IndexVector>
+Index etree_find (Index i, IndexVector& pp)
+{
+ Index p = pp(i); // Parent
+ Index gp = pp(p); // Grand parent
+ while (gp != p)
+ {
+ pp(i) = gp; // Parent pointer on find path is changed to former grand parent
+ i = gp;
+ p = pp(i);
+ gp = pp(p);
+ }
+ return p;
+}
+
+/** Compute the column elimination tree of a sparse matrix
+ * \param mat The matrix in column-major format.
+ * \param parent The elimination tree
+ * \param firstRowElt The column index of the first element in each row
+ * \param perm The permutation to apply to the column of \b mat
+ */
+template <typename MatrixType, typename IndexVector>
+int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowElt, typename MatrixType::Index *perm=0)
+{
+ typedef typename MatrixType::Index Index;
+ Index nc = mat.cols(); // Number of columns
+ Index m = mat.rows();
+ Index diagSize = (std::min)(nc,m);
+ IndexVector root(nc); // root of subtree of etree
+ root.setZero();
+ IndexVector pp(nc); // disjoint sets
+ pp.setZero(); // Initialize disjoint sets
+ parent.resize(mat.cols());
+ //Compute first nonzero column in each row
+ Index row,col;
+ firstRowElt.resize(m);
+ firstRowElt.setConstant(nc);
+ firstRowElt.segment(0, diagSize).setLinSpaced(diagSize, 0, diagSize-1);
+ bool found_diag;
+ for (col = 0; col < nc; col++)
+ {
+ Index pcol = col;
+ if(perm) pcol = perm[col];
+ for (typename MatrixType::InnerIterator it(mat, pcol); it; ++it)
+ {
+ row = it.row();
+ firstRowElt(row) = (std::min)(firstRowElt(row), col);
+ }
+ }
+ /* Compute etree by Liu's algorithm for symmetric matrices,
+ except use (firstRowElt[r],c) in place of an edge (r,c) of A.
+ Thus each row clique in A'*A is replaced by a star
+ centered at its first vertex, which has the same fill. */
+ Index rset, cset, rroot;
+ for (col = 0; col < nc; col++)
+ {
+ found_diag = col>=m;
+ pp(col) = col;
+ cset = col;
+ root(cset) = col;
+ parent(col) = nc;
+ /* The diagonal element is treated here even if it does not exist in the matrix
+ * hence the loop is executed once more */
+ Index pcol = col;
+ if(perm) pcol = perm[col];
+ for (typename MatrixType::InnerIterator it(mat, pcol); it||!found_diag; ++it)
+ { // A sequence of interleaved find and union is performed
+ Index i = col;
+ if(it) i = it.index();
+ if (i == col) found_diag = true;
+
+ row = firstRowElt(i);
+ if (row >= col) continue;
+ rset = internal::etree_find(row, pp); // Find the name of the set containing row
+ rroot = root(rset);
+ if (rroot != col)
+ {
+ parent(rroot) = col;
+ pp(cset) = rset;
+ cset = rset;
+ root(cset) = col;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Depth-first search from vertex n. No recursion.
+ * This routine was contributed by Cédric Doucet, CEDRAT Group, Meylan, France.
+*/
+template <typename Index, typename IndexVector>
+void nr_etdfs (Index n, IndexVector& parent, IndexVector& first_kid, IndexVector& next_kid, IndexVector& post, Index postnum)
+{
+ Index current = n, first, next;
+ while (postnum != n)
+ {
+ // No kid for the current node
+ first = first_kid(current);
+
+ // no kid for the current node
+ if (first == -1)
+ {
+ // Numbering this node because it has no kid
+ post(current) = postnum++;
+
+ // looking for the next kid
+ next = next_kid(current);
+ while (next == -1)
+ {
+ // No more kids : back to the parent node
+ current = parent(current);
+ // numbering the parent node
+ post(current) = postnum++;
+
+ // Get the next kid
+ next = next_kid(current);
+ }
+ // stopping criterion
+ if (postnum == n+1) return;
+
+ // Updating current node
+ current = next;
+ }
+ else
+ {
+ current = first;
+ }
+ }
+}
+
+
+/**
+ * \brief Post order a tree
+ * \param n the number of nodes
+ * \param parent Input tree
+ * \param post postordered tree
+ */
+template <typename Index, typename IndexVector>
+void treePostorder(Index n, IndexVector& parent, IndexVector& post)
+{
+ IndexVector first_kid, next_kid; // Linked list of children
+ Index postnum;
+ // Allocate storage for working arrays and results
+ first_kid.resize(n+1);
+ next_kid.setZero(n+1);
+ post.setZero(n+1);
+
+ // Set up structure describing children
+ Index v, dad;
+ first_kid.setConstant(-1);
+ for (v = n-1; v >= 0; v--)
+ {
+ dad = parent(v);
+ next_kid(v) = first_kid(dad);
+ first_kid(dad) = v;
+ }
+
+ // Depth-first search from dummy root vertex #n
+ postnum = 0;
+ internal::nr_etdfs(n, parent, first_kid, next_kid, post, postnum);
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+
+#endif // SPARSE_COLETREE_H
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
index d5f97f78fc9..ec86ca933c2 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
@@ -73,7 +73,7 @@ class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
BinaryOp,Lhs,Rhs, InnerIterator> Base;
- EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer)
+ EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer)
: Base(binOp.derived(),outer)
{}
};
@@ -300,7 +300,7 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
{
- return *this = derived() - other.derived();
+ return derived() = derived() - other.derived();
}
template<typename Derived>
@@ -308,7 +308,7 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
{
- return *this = derived() + other.derived();
+ return derived() = derived() + other.derived();
}
template<typename Derived>
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h
index 6f32940d6c1..54fd633a10c 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h
@@ -39,7 +39,7 @@ struct traits<SparseDenseOuterProduct<Lhs,Rhs,Tr> >
{
typedef Sparse StorageKind;
typedef typename scalar_product_traits<typename traits<Lhs>::Scalar,
- typename traits<Rhs>::Scalar>::ReturnType Scalar;
+ typename traits<Rhs>::Scalar>::ReturnType Scalar;
typedef typename Lhs::Index Index;
typedef typename Lhs::Nested LhsNested;
typedef typename Rhs::Nested RhsNested;
@@ -111,6 +111,7 @@ template<typename Lhs, typename Rhs, bool Transpose>
class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNested::InnerIterator
{
typedef typename _LhsNested::InnerIterator Base;
+ typedef typename SparseDenseOuterProduct::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer)
: Base(prod.lhs(), 0), m_outer(outer), m_factor(prod.rhs().coeff(outer))
@@ -124,7 +125,7 @@ class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNes
inline Scalar value() const { return Base::value() * m_factor; }
protected:
- int m_outer;
+ Index m_outer;
Scalar m_factor;
};
@@ -150,11 +151,11 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, R
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::Index Index;
typedef typename Lhs::InnerIterator LhsInnerIterator;
- static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha)
+ static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
for(Index c=0; c<rhs.cols(); ++c)
{
- int n = lhs.outerSize();
+ Index n = lhs.outerSize();
for(Index j=0; j<n; ++j)
{
typename Res::Scalar tmp(0);
@@ -174,7 +175,7 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, C
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::InnerIterator LhsInnerIterator;
typedef typename Lhs::Index Index;
- static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha)
+ static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
for(Index c=0; c<rhs.cols(); ++c)
{
@@ -196,7 +197,7 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, R
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::InnerIterator LhsInnerIterator;
typedef typename Lhs::Index Index;
- static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha)
+ static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
for(Index j=0; j<lhs.outerSize(); ++j)
{
@@ -215,7 +216,7 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, C
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::InnerIterator LhsInnerIterator;
typedef typename Lhs::Index Index;
- static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha)
+ static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
for(Index j=0; j<lhs.outerSize(); ++j)
{
@@ -244,7 +245,7 @@ class SparseTimeDenseProduct
SparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
internal::sparse_time_dense_product(m_lhs, m_rhs, dest, alpha);
}
@@ -274,7 +275,7 @@ class DenseTimeSparseProduct
DenseTimeSparseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
Transpose<const _LhsNested> lhs_t(m_lhs);
Transpose<const _RhsNested> rhs_t(m_rhs);
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h
index 095bf6863fc..1bb590e64d4 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h
@@ -78,7 +78,11 @@ class SparseDiagonalProduct
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
typedef internal::sparse_diagonal_product_inner_iterator_selector
- <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
+ <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
+
+ // We do not want ReverseInnerIterator for diagonal-sparse products,
+ // but this dummy declaration is needed to make diag * sparse * diag compile.
+ class ReverseInnerIterator;
EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
@@ -118,19 +122,23 @@ class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
: public CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
- SparseInnerVectorSet<Rhs,1>,
- typename Lhs::DiagonalVectorType>::InnerIterator
+ const typename Rhs::ConstInnerVectorReturnType,
+ const typename Lhs::DiagonalVectorType>::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
- SparseInnerVectorSet<Rhs,1>,
- typename Lhs::DiagonalVectorType>::InnerIterator Base;
+ const typename Rhs::ConstInnerVectorReturnType,
+ const typename Lhs::DiagonalVectorType>::InnerIterator Base;
typedef typename Lhs::Index Index;
+ Index m_outer;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
- : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0)
+ : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0), m_outer(outer)
{}
+
+ inline Index outer() const { return m_outer; }
+ inline Index col() const { return m_outer; }
};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
@@ -152,19 +160,23 @@ class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
: public CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
- SparseInnerVectorSet<Lhs,1>,
- Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
+ const typename Lhs::ConstInnerVectorReturnType,
+ const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
- SparseInnerVectorSet<Lhs,1>,
- Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
+ const typename Lhs::ConstInnerVectorReturnType,
+ const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
typedef typename Lhs::Index Index;
+ Index m_outer;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
- : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0)
+ : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0), m_outer(outer)
{}
+
+ inline Index outer() const { return m_outer; }
+ inline Index row() const { return m_outer; }
};
} // end namespace internal
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h
index 5c4a593dc01..db39c9aecc7 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h
@@ -30,7 +30,7 @@ SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
Scalar res(0);
while (i)
{
- res += internal::conj(i.value()) * other.coeff(i.index());
+ res += numext::conj(i.value()) * other.coeff(i.index());
++i;
}
return res;
@@ -54,8 +54,8 @@ SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) cons
typedef typename internal::remove_all<Nested>::type NestedCleaned;
typedef typename internal::remove_all<OtherNested>::type OtherNestedCleaned;
- const Nested nthis(derived());
- const OtherNested nother(other.derived());
+ Nested nthis(derived());
+ OtherNested nother(other.derived());
typename NestedCleaned::InnerIterator i(nthis,0);
typename OtherNestedCleaned::InnerIterator j(nother,0);
@@ -64,7 +64,7 @@ SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) cons
{
if (i.index()==j.index())
{
- res += internal::conj(i.value()) * j.value();
+ res += numext::conj(i.value()) * j.value();
++i; ++j;
}
else if (i.index()<j.index())
@@ -79,16 +79,23 @@ template<typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
SparseMatrixBase<Derived>::squaredNorm() const
{
- return internal::real((*this).cwiseAbs2().sum());
+ return numext::real((*this).cwiseAbs2().sum());
}
template<typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
SparseMatrixBase<Derived>::norm() const
{
- return internal::sqrt(squaredNorm());
+ using std::sqrt;
+ return sqrt(squaredNorm());
}
+template<typename Derived>
+inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
+SparseMatrixBase<Derived>::blueNorm() const
+{
+ return internal::blueNorm_impl(*this);
+}
} // end namespace Eigen
#endif // EIGEN_SPARSE_DOT_H
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h
index efb774f031b..01ce0dcfee3 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h
@@ -31,7 +31,7 @@ namespace Eigen {
*
* \tparam _Scalar the scalar type, i.e. the type of the coefficients
* \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility
- * is RowMajor. The default is 0 which means column-major.
+ * is ColMajor or RowMajor. The default is 0 which means column-major.
* \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int.
*
* This class can be extended with the help of the plugin mechanism described on the page
@@ -170,6 +170,8 @@ class SparseMatrix
* This function returns Scalar(0) if the element is an explicit \em zero */
inline Scalar coeff(Index row, Index col) const
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1];
@@ -186,6 +188,8 @@ class SparseMatrix
*/
inline Scalar& coeffRef(Index row, Index col)
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
@@ -213,11 +217,13 @@ class SparseMatrix
* inserted in increasing inner index order, and in O(nnz_j) for a random insertion.
*
*/
- EIGEN_DONT_INLINE Scalar& insert(Index row, Index col)
+ Scalar& insert(Index row, Index col)
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
if(isCompressed())
{
- reserve(VectorXi::Constant(outerSize(), 2));
+ reserve(Matrix<Index,Dynamic,1>::Constant(outerSize(), 2));
}
return insertUncompressed(row,col);
}
@@ -281,12 +287,12 @@ class SparseMatrix
template<class SizesType>
inline void reserveInnerVectors(const SizesType& reserveSizes)
{
-
if(isCompressed())
{
std::size_t totalReserveSize = 0;
// turn the matrix into non-compressed mode
- m_innerNonZeros = new Index[m_outerSize];
+ m_innerNonZeros = static_cast<Index*>(std::malloc(m_outerSize * sizeof(Index)));
+ if (!m_innerNonZeros) internal::throw_std_bad_alloc();
// temporarily use m_innerSizes to hold the new starting points.
Index* newOuterIndex = m_innerNonZeros;
@@ -299,11 +305,11 @@ class SparseMatrix
totalReserveSize += reserveSizes[j];
}
m_data.reserve(totalReserveSize);
- std::ptrdiff_t previousOuterIndex = m_outerIndex[m_outerSize];
- for(std::ptrdiff_t j=m_outerSize-1; j>=0; --j)
+ Index previousOuterIndex = m_outerIndex[m_outerSize];
+ for(Index j=m_outerSize-1; j>=0; --j)
{
- ptrdiff_t innerNNZ = previousOuterIndex - m_outerIndex[j];
- for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i)
+ Index innerNNZ = previousOuterIndex - m_outerIndex[j];
+ for(Index i=innerNNZ-1; i>=0; --i)
{
m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i);
m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i);
@@ -318,25 +324,27 @@ class SparseMatrix
}
else
{
- Index* newOuterIndex = new Index[m_outerSize+1];
+ Index* newOuterIndex = static_cast<Index*>(std::malloc((m_outerSize+1)*sizeof(Index)));
+ if (!newOuterIndex) internal::throw_std_bad_alloc();
+
Index count = 0;
for(Index j=0; j<m_outerSize; ++j)
{
newOuterIndex[j] = count;
Index alreadyReserved = (m_outerIndex[j+1]-m_outerIndex[j]) - m_innerNonZeros[j];
- Index toReserve = std::max<std::ptrdiff_t>(reserveSizes[j], alreadyReserved);
+ Index toReserve = std::max<Index>(reserveSizes[j], alreadyReserved);
count += toReserve + m_innerNonZeros[j];
}
newOuterIndex[m_outerSize] = count;
m_data.resize(count);
- for(ptrdiff_t j=m_outerSize-1; j>=0; --j)
+ for(Index j=m_outerSize-1; j>=0; --j)
{
- std::ptrdiff_t offset = newOuterIndex[j] - m_outerIndex[j];
+ Index offset = newOuterIndex[j] - m_outerIndex[j];
if(offset>0)
{
- std::ptrdiff_t innerNNZ = m_innerNonZeros[j];
- for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i)
+ Index innerNNZ = m_innerNonZeros[j];
+ for(Index i=innerNNZ-1; i>=0; --i)
{
m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i);
m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i);
@@ -345,7 +353,7 @@ class SparseMatrix
}
std::swap(m_outerIndex, newOuterIndex);
- delete[] newOuterIndex;
+ std::free(newOuterIndex);
}
}
@@ -394,7 +402,7 @@ class SparseMatrix
* \sa insertBack, insertBackByOuterInner */
inline void startVec(Index outer)
{
- eigen_assert(m_outerIndex[outer]==int(m_data.size()) && "You must call startVec for each inner vector sequentially");
+ eigen_assert(m_outerIndex[outer]==Index(m_data.size()) && "You must call startVec for each inner vector sequentially");
eigen_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially");
m_outerIndex[outer+1] = m_outerIndex[outer];
}
@@ -431,7 +439,7 @@ class SparseMatrix
/** \internal
* same as insert(Index,Index) except that the indices are given relative to the storage order */
- EIGEN_DONT_INLINE Scalar& insertByOuterInner(Index j, Index i)
+ Scalar& insertByOuterInner(Index j, Index i)
{
return insert(IsRowMajor ? j : i, IsRowMajor ? i : j);
}
@@ -448,7 +456,7 @@ class SparseMatrix
for(Index j=1; j<m_outerSize; ++j)
{
Index nextOldStart = m_outerIndex[j+1];
- std::ptrdiff_t offset = oldStart - m_outerIndex[j];
+ Index offset = oldStart - m_outerIndex[j];
if(offset>0)
{
for(Index k=0; k<m_innerNonZeros[j]; ++k)
@@ -460,14 +468,26 @@ class SparseMatrix
m_outerIndex[j+1] = m_outerIndex[j] + m_innerNonZeros[j];
oldStart = nextOldStart;
}
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
m_data.squeeze();
}
+ /** Turns the matrix into the uncompressed mode */
+ void uncompress()
+ {
+ if(m_innerNonZeros != 0)
+ return;
+ m_innerNonZeros = static_cast<Index*>(std::malloc(m_outerSize * sizeof(Index)));
+ for (Index i = 0; i < m_outerSize; i++)
+ {
+ m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
+ }
+ }
+
/** Suppresses all nonzeros which are \b much \b smaller \b than \a reference under the tolerence \a epsilon */
- void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
+ void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
{
prune(default_prunning_func(reference,epsilon));
}
@@ -506,6 +526,70 @@ class SparseMatrix
m_data.resize(k,0);
}
+ /** Resizes the matrix to a \a rows x \a cols matrix leaving old values untouched.
+ * \sa resizeNonZeros(Index), reserve(), setZero()
+ */
+ void conservativeResize(Index rows, Index cols)
+ {
+ // No change
+ if (this->rows() == rows && this->cols() == cols) return;
+
+ // If one dimension is null, then there is nothing to be preserved
+ if(rows==0 || cols==0) return resize(rows,cols);
+
+ Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows();
+ Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols();
+ Index newInnerSize = IsRowMajor ? cols : rows;
+
+ // Deals with inner non zeros
+ if (m_innerNonZeros)
+ {
+ // Resize m_innerNonZeros
+ Index *newInnerNonZeros = static_cast<Index*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index)));
+ if (!newInnerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = newInnerNonZeros;
+
+ for(Index i=m_outerSize; i<m_outerSize+outerChange; i++)
+ m_innerNonZeros[i] = 0;
+ }
+ else if (innerChange < 0)
+ {
+ // Inner size decreased: allocate a new m_innerNonZeros
+ m_innerNonZeros = static_cast<Index*>(std::malloc((m_outerSize+outerChange+1) * sizeof(Index)));
+ if (!m_innerNonZeros) internal::throw_std_bad_alloc();
+ for(Index i = 0; i < m_outerSize; i++)
+ m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
+ }
+
+ // Change the m_innerNonZeros in case of a decrease of inner size
+ if (m_innerNonZeros && innerChange < 0)
+ {
+ for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++)
+ {
+ Index &n = m_innerNonZeros[i];
+ Index start = m_outerIndex[i];
+ while (n > 0 && m_data.index(start+n-1) >= newInnerSize) --n;
+ }
+ }
+
+ m_innerSize = newInnerSize;
+
+ // Re-allocate outer index structure if necessary
+ if (outerChange == 0)
+ return;
+
+ Index *newOuterIndex = static_cast<Index*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index)));
+ if (!newOuterIndex) internal::throw_std_bad_alloc();
+ m_outerIndex = newOuterIndex;
+ if (outerChange > 0)
+ {
+ Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize];
+ for(Index i=m_outerSize; i<m_outerSize+outerChange+1; i++)
+ m_outerIndex[i] = last;
+ }
+ m_outerSize += outerChange;
+ }
+
/** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero.
* \sa resizeNonZeros(Index), reserve(), setZero()
*/
@@ -516,13 +600,15 @@ class SparseMatrix
m_data.clear();
if (m_outerSize != outerSize || m_outerSize==0)
{
- delete[] m_outerIndex;
- m_outerIndex = new Index [outerSize+1];
+ std::free(m_outerIndex);
+ m_outerIndex = static_cast<Index*>(std::malloc((outerSize + 1) * sizeof(Index)));
+ if (!m_outerIndex) internal::throw_std_bad_alloc();
+
m_outerSize = outerSize;
}
if(m_innerNonZeros)
{
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
}
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index));
@@ -560,9 +646,20 @@ class SparseMatrix
inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other)
: m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
{
+ EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
check_template_parameters();
*this = other.derived();
}
+
+ /** Constructs a sparse matrix from the sparse selfadjoint view \a other */
+ template<typename OtherDerived, unsigned int UpLo>
+ inline SparseMatrix(const SparseSelfAdjointView<OtherDerived, UpLo>& other)
+ : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
+ {
+ check_template_parameters();
+ *this = other;
+ }
/** Copy constructor (it performs a deep copy) */
inline SparseMatrix(const SparseMatrix& other)
@@ -572,6 +669,16 @@ class SparseMatrix
*this = other.derived();
}
+ /** \brief Copy constructor with in-place evaluation */
+ template<typename OtherDerived>
+ SparseMatrix(const ReturnByValue<OtherDerived>& other)
+ : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
+ {
+ check_template_parameters();
+ initAssignment(other);
+ other.evalTo(*this);
+ }
+
/** Swaps the content of two sparse matrices of the same type.
* This is a fast operation that simply swaps the underlying pointers and parameters. */
inline void swap(SparseMatrix& other)
@@ -584,13 +691,22 @@ class SparseMatrix
m_data.swap(other.m_data);
}
+ /** Sets *this to the identity matrix */
+ inline void setIdentity()
+ {
+ eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES");
+ this->m_data.resize(rows());
+ Eigen::Map<Matrix<Index, Dynamic, 1> >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1);
+ Eigen::Map<Matrix<Scalar, Dynamic, 1> >(&this->m_data.value(0), rows()).setOnes();
+ Eigen::Map<Matrix<Index, Dynamic, 1> >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows());
+ }
inline SparseMatrix& operator=(const SparseMatrix& other)
{
if (other.isRValue())
{
swap(other.const_cast_derived());
}
- else
+ else if(this!=&other)
{
initAssignment(other);
if(other.isCompressed())
@@ -613,7 +729,10 @@ class SparseMatrix
template<typename OtherDerived>
inline SparseMatrix& operator=(const ReturnByValue<OtherDerived>& other)
- { return Base::operator=(other.derived()); }
+ {
+ initAssignment(other);
+ return Base::operator=(other.derived());
+ }
template<typename OtherDerived>
inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other)
@@ -621,58 +740,7 @@ class SparseMatrix
#endif
template<typename OtherDerived>
- EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
- {
- initAssignment(other.derived());
- const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
- if (needToTranspose)
- {
- // two passes algorithm:
- // 1 - compute the number of coeffs per dest inner vector
- // 2 - do the actual copy/eval
- // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed
- typedef typename internal::nested<OtherDerived,2>::type OtherCopy;
- typedef typename internal::remove_all<OtherCopy>::type _OtherCopy;
- OtherCopy otherCopy(other.derived());
-
- Eigen::Map<Matrix<Index, Dynamic, 1> > (m_outerIndex,outerSize()).setZero();
- // pass 1
- // FIXME the above copy could be merged with that pass
- for (Index j=0; j<otherCopy.outerSize(); ++j)
- for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
- ++m_outerIndex[it.index()];
-
- // prefix sum
- Index count = 0;
- VectorXi positions(outerSize());
- for (Index j=0; j<outerSize(); ++j)
- {
- Index tmp = m_outerIndex[j];
- m_outerIndex[j] = count;
- positions[j] = count;
- count += tmp;
- }
- m_outerIndex[outerSize()] = count;
- // alloc
- m_data.resize(count);
- // pass 2
- for (Index j=0; j<otherCopy.outerSize(); ++j)
- {
- for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
- {
- Index pos = positions[it.index()]++;
- m_data.index(pos) = j;
- m_data.value(pos) = it.value();
- }
- }
- return *this;
- }
- else
- {
- // there is no special optimization
- return Base::operator=(other.derived());
- }
- }
+ EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other);
friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m)
{
@@ -684,8 +752,8 @@ class SparseMatrix
else
for (Index i=0; i<m.outerSize(); ++i)
{
- int p = m.m_outerIndex[i];
- int pe = m.m_outerIndex[i]+m.m_innerNonZeros[i];
+ Index p = m.m_outerIndex[i];
+ Index pe = m.m_outerIndex[i]+m.m_innerNonZeros[i];
Index k=p;
for (; k<pe; ++k)
s << "(" << m.m_data.value(k) << "," << m.m_data.index(k) << ") ";
@@ -714,8 +782,8 @@ class SparseMatrix
/** Destructor */
inline ~SparseMatrix()
{
- delete[] m_outerIndex;
- delete[] m_innerNonZeros;
+ std::free(m_outerIndex);
+ std::free(m_innerNonZeros);
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -735,118 +803,14 @@ protected:
resize(other.rows(), other.cols());
if(m_innerNonZeros)
{
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
}
}
/** \internal
* \sa insert(Index,Index) */
- EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col)
- {
- eigen_assert(isCompressed());
-
- const Index outer = IsRowMajor ? row : col;
- const Index inner = IsRowMajor ? col : row;
-
- Index previousOuter = outer;
- if (m_outerIndex[outer+1]==0)
- {
- // we start a new inner vector
- while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
- {
- m_outerIndex[previousOuter] = static_cast<Index>(m_data.size());
- --previousOuter;
- }
- m_outerIndex[outer+1] = m_outerIndex[outer];
- }
-
- // here we have to handle the tricky case where the outerIndex array
- // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g.,
- // the 2nd inner vector...
- bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0))
- && (size_t(m_outerIndex[outer+1]) == m_data.size());
-
- size_t startId = m_outerIndex[outer];
- // FIXME let's make sure sizeof(long int) == sizeof(size_t)
- size_t p = m_outerIndex[outer+1];
- ++m_outerIndex[outer+1];
-
- float reallocRatio = 1;
- if (m_data.allocatedSize()<=m_data.size())
- {
- // if there is no preallocated memory, let's reserve a minimum of 32 elements
- if (m_data.size()==0)
- {
- m_data.reserve(32);
- }
- else
- {
- // we need to reallocate the data, to reduce multiple reallocations
- // we use a smart resize algorithm based on the current filling ratio
- // in addition, we use float to avoid integers overflows
- float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1);
- reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
- // furthermore we bound the realloc ratio to:
- // 1) reduce multiple minor realloc when the matrix is almost filled
- // 2) avoid to allocate too much memory when the matrix is almost empty
- reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f);
- }
- }
- m_data.resize(m_data.size()+1,reallocRatio);
-
- if (!isLastVec)
- {
- if (previousOuter==-1)
- {
- // oops wrong guess.
- // let's correct the outer offsets
- for (Index k=0; k<=(outer+1); ++k)
- m_outerIndex[k] = 0;
- Index k=outer+1;
- while(m_outerIndex[k]==0)
- m_outerIndex[k++] = 1;
- while (k<=m_outerSize && m_outerIndex[k]!=0)
- m_outerIndex[k++]++;
- p = 0;
- --k;
- k = m_outerIndex[k]-1;
- while (k>0)
- {
- m_data.index(k) = m_data.index(k-1);
- m_data.value(k) = m_data.value(k-1);
- k--;
- }
- }
- else
- {
- // we are not inserting into the last inner vec
- // update outer indices:
- Index j = outer+2;
- while (j<=m_outerSize && m_outerIndex[j]!=0)
- m_outerIndex[j++]++;
- --j;
- // shift data of last vecs:
- Index k = m_outerIndex[j]-1;
- while (k>=Index(p))
- {
- m_data.index(k) = m_data.index(k-1);
- m_data.value(k) = m_data.value(k-1);
- k--;
- }
- }
- }
-
- while ( (p > startId) && (m_data.index(p-1) > inner) )
- {
- m_data.index(p) = m_data.index(p-1);
- m_data.value(p) = m_data.value(p-1);
- --p;
- }
-
- m_data.index(p) = inner;
- return (m_data.value(p) = 0);
- }
+ EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col);
/** \internal
* A vector object that is equal to 0 everywhere but v at the position i */
@@ -865,40 +829,12 @@ protected:
/** \internal
* \sa insert(Index,Index) */
- EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col)
- {
- eigen_assert(!isCompressed());
-
- const Index outer = IsRowMajor ? row : col;
- const Index inner = IsRowMajor ? col : row;
-
- std::ptrdiff_t room = m_outerIndex[outer+1] - m_outerIndex[outer];
- std::ptrdiff_t innerNNZ = m_innerNonZeros[outer];
- if(innerNNZ>=room)
- {
- // this inner vector is full, we need to reallocate the whole buffer :(
- reserve(SingletonVector(outer,std::max<std::ptrdiff_t>(2,innerNNZ)));
- }
-
- Index startId = m_outerIndex[outer];
- Index p = startId + m_innerNonZeros[outer];
- while ( (p > startId) && (m_data.index(p-1) > inner) )
- {
- m_data.index(p) = m_data.index(p-1);
- m_data.value(p) = m_data.value(p-1);
- --p;
- }
-
- m_innerNonZeros[outer]++;
-
- m_data.index(p) = inner;
- return (m_data.value(p) = 0);
- }
+ EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col);
public:
/** \internal
* \sa insert(Index,Index) */
- inline Scalar& insertBackUncompressed(Index row, Index col)
+ EIGEN_STRONG_INLINE Scalar& insertBackUncompressed(Index row, Index col)
{
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
@@ -906,8 +842,7 @@ public:
eigen_assert(!isCompressed());
eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer]));
- Index p = m_outerIndex[outer] + m_innerNonZeros[outer];
- m_innerNonZeros[outer]++;
+ Index p = m_outerIndex[outer] + m_innerNonZeros[outer]++;
m_data.index(p) = inner;
return (m_data.value(p) = 0);
}
@@ -916,10 +851,11 @@ private:
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+ EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
}
struct default_prunning_func {
- default_prunning_func(Scalar ref, RealScalar eps) : reference(ref), epsilon(eps) {}
+ default_prunning_func(const Scalar& ref, const RealScalar& eps) : reference(ref), epsilon(eps) {}
inline bool operator() (const Index&, const Index&, const Scalar& value) const
{
return !internal::isMuchSmallerThan(value, reference, epsilon);
@@ -1006,19 +942,25 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa
typedef typename SparseMatrixType::Index Index;
SparseMatrix<Scalar,IsRowMajor?ColMajor:RowMajor> trMat(mat.rows(),mat.cols());
- // pass 1: count the nnz per inner-vector
- VectorXi wi(trMat.outerSize());
- wi.setZero();
- for(InputIterator it(begin); it!=end; ++it)
- wi(IsRowMajor ? it->col() : it->row())++;
+ if(begin!=end)
+ {
+ // pass 1: count the nnz per inner-vector
+ Matrix<Index,Dynamic,1> wi(trMat.outerSize());
+ wi.setZero();
+ for(InputIterator it(begin); it!=end; ++it)
+ {
+ eigen_assert(it->row()>=0 && it->row()<mat.rows() && it->col()>=0 && it->col()<mat.cols());
+ wi(IsRowMajor ? it->col() : it->row())++;
+ }
- // pass 2: insert all the elements into trMat
- trMat.reserve(wi);
- for(InputIterator it(begin); it!=end; ++it)
- trMat.insertBackUncompressed(it->row(),it->col()) = it->value();
+ // pass 2: insert all the elements into trMat
+ trMat.reserve(wi);
+ for(InputIterator it(begin); it!=end; ++it)
+ trMat.insertBackUncompressed(it->row(),it->col()) = it->value();
- // pass 3:
- trMat.sumupDuplicates();
+ // pass 3:
+ trMat.sumupDuplicates();
+ }
// pass 4: transposed copy -> implicit sorting
mat = trMat;
@@ -1027,7 +969,7 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa
}
-/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \b.
+/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \a end.
*
* A \em triplet is a tuple (i,j,value) defining a non-zero element.
* The input list of triplets does not have to be sorted, and can contains duplicated elements.
@@ -1077,11 +1019,11 @@ void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates()
{
eigen_assert(!isCompressed());
// TODO, in practice we should be able to use m_innerNonZeros for that task
- VectorXi wi(innerSize());
+ Matrix<Index,Dynamic,1> wi(innerSize());
wi.fill(-1);
Index count = 0;
// for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers
- for(int j=0; j<outerSize(); ++j)
+ for(Index j=0; j<outerSize(); ++j)
{
Index start = count;
Index oldEnd = m_outerIndex[j]+m_innerNonZeros[j];
@@ -1106,11 +1048,212 @@ void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates()
m_outerIndex[m_outerSize] = count;
// turn the matrix into compressed form
- delete[] m_innerNonZeros;
+ std::free(m_innerNonZeros);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
}
+template<typename Scalar, int _Options, typename _Index>
+template<typename OtherDerived>
+EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other)
+{
+ EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
+ const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
+ if (needToTranspose)
+ {
+ // two passes algorithm:
+ // 1 - compute the number of coeffs per dest inner vector
+ // 2 - do the actual copy/eval
+ // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed
+ typedef typename internal::nested<OtherDerived,2>::type OtherCopy;
+ typedef typename internal::remove_all<OtherCopy>::type _OtherCopy;
+ OtherCopy otherCopy(other.derived());
+
+ SparseMatrix dest(other.rows(),other.cols());
+ Eigen::Map<Matrix<Index, Dynamic, 1> > (dest.m_outerIndex,dest.outerSize()).setZero();
+
+ // pass 1
+ // FIXME the above copy could be merged with that pass
+ for (Index j=0; j<otherCopy.outerSize(); ++j)
+ for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+ ++dest.m_outerIndex[it.index()];
+
+ // prefix sum
+ Index count = 0;
+ Matrix<Index,Dynamic,1> positions(dest.outerSize());
+ for (Index j=0; j<dest.outerSize(); ++j)
+ {
+ Index tmp = dest.m_outerIndex[j];
+ dest.m_outerIndex[j] = count;
+ positions[j] = count;
+ count += tmp;
+ }
+ dest.m_outerIndex[dest.outerSize()] = count;
+ // alloc
+ dest.m_data.resize(count);
+ // pass 2
+ for (Index j=0; j<otherCopy.outerSize(); ++j)
+ {
+ for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
+ {
+ Index pos = positions[it.index()]++;
+ dest.m_data.index(pos) = j;
+ dest.m_data.value(pos) = it.value();
+ }
+ }
+ this->swap(dest);
+ return *this;
+ }
+ else
+ {
+ if(other.isRValue())
+ initAssignment(other.derived());
+ // there is no special optimization
+ return Base::operator=(other.derived());
+ }
+}
+
+template<typename _Scalar, int _Options, typename _Index>
+EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col)
+{
+ eigen_assert(!isCompressed());
+
+ const Index outer = IsRowMajor ? row : col;
+ const Index inner = IsRowMajor ? col : row;
+
+ Index room = m_outerIndex[outer+1] - m_outerIndex[outer];
+ Index innerNNZ = m_innerNonZeros[outer];
+ if(innerNNZ>=room)
+ {
+ // this inner vector is full, we need to reallocate the whole buffer :(
+ reserve(SingletonVector(outer,std::max<Index>(2,innerNNZ)));
+ }
+
+ Index startId = m_outerIndex[outer];
+ Index p = startId + m_innerNonZeros[outer];
+ while ( (p > startId) && (m_data.index(p-1) > inner) )
+ {
+ m_data.index(p) = m_data.index(p-1);
+ m_data.value(p) = m_data.value(p-1);
+ --p;
+ }
+ eigen_assert((p<=startId || m_data.index(p-1)!=inner) && "you cannot insert an element that already exist, you must call coeffRef to this end");
+
+ m_innerNonZeros[outer]++;
+
+ m_data.index(p) = inner;
+ return (m_data.value(p) = 0);
+}
+
+template<typename _Scalar, int _Options, typename _Index>
+EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertCompressed(Index row, Index col)
+{
+ eigen_assert(isCompressed());
+
+ const Index outer = IsRowMajor ? row : col;
+ const Index inner = IsRowMajor ? col : row;
+
+ Index previousOuter = outer;
+ if (m_outerIndex[outer+1]==0)
+ {
+ // we start a new inner vector
+ while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
+ {
+ m_outerIndex[previousOuter] = static_cast<Index>(m_data.size());
+ --previousOuter;
+ }
+ m_outerIndex[outer+1] = m_outerIndex[outer];
+ }
+
+ // here we have to handle the tricky case where the outerIndex array
+ // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g.,
+ // the 2nd inner vector...
+ bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0))
+ && (size_t(m_outerIndex[outer+1]) == m_data.size());
+
+ size_t startId = m_outerIndex[outer];
+ // FIXME let's make sure sizeof(long int) == sizeof(size_t)
+ size_t p = m_outerIndex[outer+1];
+ ++m_outerIndex[outer+1];
+
+ float reallocRatio = 1;
+ if (m_data.allocatedSize()<=m_data.size())
+ {
+ // if there is no preallocated memory, let's reserve a minimum of 32 elements
+ if (m_data.size()==0)
+ {
+ m_data.reserve(32);
+ }
+ else
+ {
+ // we need to reallocate the data, to reduce multiple reallocations
+ // we use a smart resize algorithm based on the current filling ratio
+ // in addition, we use float to avoid integers overflows
+ float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1);
+ reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size());
+ // furthermore we bound the realloc ratio to:
+ // 1) reduce multiple minor realloc when the matrix is almost filled
+ // 2) avoid to allocate too much memory when the matrix is almost empty
+ reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f);
+ }
+ }
+ m_data.resize(m_data.size()+1,reallocRatio);
+
+ if (!isLastVec)
+ {
+ if (previousOuter==-1)
+ {
+ // oops wrong guess.
+ // let's correct the outer offsets
+ for (Index k=0; k<=(outer+1); ++k)
+ m_outerIndex[k] = 0;
+ Index k=outer+1;
+ while(m_outerIndex[k]==0)
+ m_outerIndex[k++] = 1;
+ while (k<=m_outerSize && m_outerIndex[k]!=0)
+ m_outerIndex[k++]++;
+ p = 0;
+ --k;
+ k = m_outerIndex[k]-1;
+ while (k>0)
+ {
+ m_data.index(k) = m_data.index(k-1);
+ m_data.value(k) = m_data.value(k-1);
+ k--;
+ }
+ }
+ else
+ {
+ // we are not inserting into the last inner vec
+ // update outer indices:
+ Index j = outer+2;
+ while (j<=m_outerSize && m_outerIndex[j]!=0)
+ m_outerIndex[j++]++;
+ --j;
+ // shift data of last vecs:
+ Index k = m_outerIndex[j]-1;
+ while (k>=Index(p))
+ {
+ m_data.index(k) = m_data.index(k-1);
+ m_data.value(k) = m_data.value(k-1);
+ k--;
+ }
+ }
+ }
+
+ while ( (p > startId) && (m_data.index(p-1) > inner) )
+ {
+ m_data.index(p) = m_data.index(p-1);
+ m_data.value(p) = m_data.value(p-1);
+ --p;
+ }
+
+ m_data.index(p) = inner;
+ return (m_data.value(p) = 0);
+}
+
} // end namespace Eigen
#endif // EIGEN_SPARSEMATRIX_H
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h
index 9a1258097fe..bbcf7fb1c62 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h
@@ -89,6 +89,9 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
*/
IsRowMajor = Flags&RowMajorBit ? 1 : 0,
+
+ InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
+ : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
#ifndef EIGEN_PARSED_BY_DOXYGEN
_HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
@@ -102,7 +105,7 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
>::type AdjointReturnType;
- typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject;
+ typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject;
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -136,13 +139,13 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
# include "../plugins/CommonCwiseBinaryOps.h"
# include "../plugins/MatrixCwiseUnaryOps.h"
# include "../plugins/MatrixCwiseBinaryOps.h"
+# include "../plugins/BlockMethods.h"
# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
# include EIGEN_SPARSEMATRIXBASE_PLUGIN
# endif
# undef EIGEN_CURRENT_STORAGE_BASE_CLASS
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
-
/** \returns the number of rows. \sa cols() */
inline Index rows() const { return derived().rows(); }
/** \returns the number of columns. \sa rows() */
@@ -299,8 +302,8 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
}
else
{
- SparseMatrix<Scalar, RowMajorBit> trans = m;
- s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit> >&>(trans);
+ SparseMatrix<Scalar, RowMajorBit, Index> trans = m;
+ s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans);
}
}
return s;
@@ -322,8 +325,8 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
typename internal::traits<OtherDerived>::Scalar \
>::ReturnType \
>, \
- Derived, \
- OtherDerived \
+ const Derived, \
+ const OtherDerived \
>
template<typename OtherDerived>
@@ -387,55 +390,45 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
RealScalar squaredNorm() const;
RealScalar norm() const;
+ RealScalar blueNorm() const;
Transpose<Derived> transpose() { return derived(); }
const Transpose<const Derived> transpose() const { return derived(); }
const AdjointReturnType adjoint() const { return transpose(); }
- // sub-vector
- SparseInnerVectorSet<Derived,1> row(Index i);
- const SparseInnerVectorSet<Derived,1> row(Index i) const;
- SparseInnerVectorSet<Derived,1> col(Index j);
- const SparseInnerVectorSet<Derived,1> col(Index j) const;
- SparseInnerVectorSet<Derived,1> innerVector(Index outer);
- const SparseInnerVectorSet<Derived,1> innerVector(Index outer) const;
-
- // set of sub-vectors
- SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size);
- const SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size) const;
- SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size);
- const SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size) const;
-
- SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size);
- const SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size) const;
- SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size);
- const SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size) const;
- SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize);
- const SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize) const;
-
- /** \internal use operator= */
- template<typename DenseDerived>
- void evalTo(MatrixBase<DenseDerived>& dst) const
- {
- dst.setZero();
- for (Index j=0; j<outerSize(); ++j)
- for (typename Derived::InnerIterator i(derived(),j); i; ++i)
- dst.coeffRef(i.row(),i.col()) = i.value();
- }
+ // inner-vector
+ typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> InnerVectorReturnType;
+ typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType;
+ InnerVectorReturnType innerVector(Index outer);
+ const ConstInnerVectorReturnType innerVector(Index outer) const;
- Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
- {
- return derived();
- }
+ // set of inner-vectors
+ Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
+ const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
+
+ /** \internal use operator= */
+ template<typename DenseDerived>
+ void evalTo(MatrixBase<DenseDerived>& dst) const
+ {
+ dst.setZero();
+ for (Index j=0; j<outerSize(); ++j)
+ for (typename Derived::InnerIterator i(derived(),j); i; ++i)
+ dst.coeffRef(i.row(),i.col()) = i.value();
+ }
+
+ Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
+ {
+ return derived();
+ }
template<typename OtherDerived>
bool isApprox(const SparseMatrixBase<OtherDerived>& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
{ return toDense().isApprox(other.toDense(),prec); }
template<typename OtherDerived>
bool isApprox(const MatrixBase<OtherDerived>& other,
- RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
+ const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
{ return toDense().isApprox(other,prec); }
/** \returns the matrix or vector obtained by evaluating this expression.
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h b/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h
index b897b7595b5..b85be93f6f9 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h
@@ -57,7 +57,7 @@ struct permut_sparsematrix_product_retval
if(MoveOuter)
{
SparseMatrix<Scalar,SrcStorageOrder,Index> tmp(m_matrix.rows(), m_matrix.cols());
- VectorXi sizes(m_matrix.outerSize());
+ Matrix<Index,Dynamic,1> sizes(m_matrix.outerSize());
for(Index j=0; j<m_matrix.outerSize(); ++j)
{
Index jp = m_permutation.indices().coeff(j);
@@ -77,7 +77,7 @@ struct permut_sparsematrix_product_retval
else
{
SparseMatrix<Scalar,int(SrcStorageOrder)==RowMajor?ColMajor:RowMajor,Index> tmp(m_matrix.rows(), m_matrix.cols());
- VectorXi sizes(tmp.outerSize());
+ Matrix<Index,Dynamic,1> sizes(tmp.outerSize());
sizes.setZero();
PermutationMatrix<Dynamic,Dynamic,Index> perm;
if((Side==OnTheLeft) ^ Transposed)
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h
index 6a555b83434..cf766307008 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h
@@ -16,6 +16,7 @@ template<typename Lhs, typename Rhs>
struct SparseSparseProductReturnType
{
typedef typename internal::traits<Lhs>::Scalar Scalar;
+ typedef typename internal::traits<Lhs>::Index Index;
enum {
LhsRowMajor = internal::traits<Lhs>::Flags & RowMajorBit,
RhsRowMajor = internal::traits<Rhs>::Flags & RowMajorBit,
@@ -24,11 +25,11 @@ struct SparseSparseProductReturnType
};
typedef typename internal::conditional<TransposeLhs,
- SparseMatrix<Scalar,0>,
+ SparseMatrix<Scalar,0,Index>,
typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested;
typedef typename internal::conditional<TransposeRhs,
- SparseMatrix<Scalar,0>,
+ SparseMatrix<Scalar,0,Index>,
typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested;
typedef SparseSparseProduct<LhsNested, RhsNested> Type;
@@ -99,15 +100,16 @@ class SparseSparseProduct : internal::no_assignment_operator,
}
template<typename Lhs, typename Rhs>
- EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, RealScalar tolerance)
+ EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance)
: m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
{
init();
}
- SparseSparseProduct pruned(Scalar reference = 0, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) const
+ SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const
{
- return SparseSparseProduct(m_lhs,m_rhs,internal::abs(reference)*epsilon);
+ using std::abs;
+ return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon);
}
template<typename Dest>
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h
index 86ec0a6c5e2..0eda96bc471 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h
@@ -69,6 +69,30 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView
const _MatrixTypeNested& matrix() const { return m_matrix; }
_MatrixTypeNested& matrix() { return m_matrix.const_cast_derived(); }
+ /** \returns an expression of the matrix product between a sparse self-adjoint matrix \c *this and a sparse matrix \a rhs.
+ *
+ * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
+ * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
+ */
+ template<typename OtherDerived>
+ SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>
+ operator*(const SparseMatrixBase<OtherDerived>& rhs) const
+ {
+ return SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>(*this, rhs.derived());
+ }
+
+ /** \returns an expression of the matrix product between a sparse matrix \a lhs and a sparse self-adjoint matrix \a rhs.
+ *
+ * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
+ * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
+ */
+ template<typename OtherDerived> friend
+ SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject >
+ operator*(const SparseMatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
+ {
+ return SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject>(lhs.derived(), rhs);
+ }
+
/** Efficient sparse self-adjoint matrix times dense vector/matrix product */
template<typename OtherDerived>
SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo>
@@ -94,7 +118,7 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView
* call this function with u.adjoint().
*/
template<typename DerivedU>
- SparseSelfAdjointView& rankUpdate(const SparseMatrixBase<DerivedU>& u, Scalar alpha = Scalar(1));
+ SparseSelfAdjointView& rankUpdate(const SparseMatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
/** \internal triggered by sparse_matrix = SparseSelfadjointView; */
template<typename DestScalar,int StorageOrder> void evalTo(SparseMatrix<DestScalar,StorageOrder,Index>& _dest) const
@@ -173,7 +197,7 @@ SparseSelfAdjointView<Derived, UpLo> SparseMatrixBase<Derived>::selfadjointView(
template<typename MatrixType, unsigned int UpLo>
template<typename DerivedU>
SparseSelfAdjointView<MatrixType,UpLo>&
-SparseSelfAdjointView<MatrixType,UpLo>::rankUpdate(const SparseMatrixBase<DerivedU>& u, Scalar alpha)
+SparseSelfAdjointView<MatrixType,UpLo>::rankUpdate(const SparseMatrixBase<DerivedU>& u, const Scalar& alpha)
{
SparseMatrix<Scalar,MatrixType::Flags&RowMajorBit?RowMajor:ColMajor> tmp = u * u.adjoint();
if(alpha==Scalar(0))
@@ -207,12 +231,12 @@ class SparseSelfAdjointTimeDenseProduct
SparseSelfAdjointTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
- template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const
+ template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
+ EIGEN_ONLY_USED_FOR_DEBUG(alpha);
// TODO use alpha
eigen_assert(alpha==Scalar(1) && "alpha != 1 is not implemented yet, sorry");
typedef typename internal::remove_all<Lhs>::type _Lhs;
- typedef typename internal::remove_all<Rhs>::type _Rhs;
typedef typename _Lhs::InnerIterator LhsInnerIterator;
enum {
LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit,
@@ -240,7 +264,7 @@ class SparseSelfAdjointTimeDenseProduct
Index b = LhsIsRowMajor ? i.index() : j;
typename Lhs::Scalar v = i.value();
dest.row(a) += (v) * m_rhs.row(b);
- dest.row(b) += internal::conj(v) * m_rhs.row(a);
+ dest.row(b) += numext::conj(v) * m_rhs.row(a);
}
if (ProcessFirstHalf && i && (i.index()==j))
dest.row(j) += i.value() * m_rhs.row(j);
@@ -268,7 +292,7 @@ class DenseTimeSparseSelfAdjointProduct
DenseTimeSparseSelfAdjointProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
- template<typename Dest> void scaleAndAddTo(Dest& /*dest*/, Scalar /*alpha*/) const
+ template<typename Dest> void scaleAndAddTo(Dest& /*dest*/, const Scalar& /*alpha*/) const
{
// TODO
}
@@ -367,7 +391,7 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix<typename Matri
dest.valuePtr()[k] = it.value();
k = count[ip]++;
dest.innerIndexPtr()[k] = jp;
- dest.valuePtr()[k] = internal::conj(it.value());
+ dest.valuePtr()[k] = numext::conj(it.value());
}
}
}
@@ -428,7 +452,7 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixTyp
if(!StorageOrderMatch) std::swap(ip,jp);
if( ((int(DstUpLo)==int(Lower) && ip<jp) || (int(DstUpLo)==int(Upper) && ip>jp)))
- dest.valuePtr()[k] = conj(it.value());
+ dest.valuePtr()[k] = numext::conj(it.value());
else
dest.valuePtr()[k] = it.value();
}
@@ -461,7 +485,10 @@ class SparseSymmetricPermutationProduct
template<typename DestScalar, int Options, typename DstIndex>
void evalTo(SparseMatrix<DestScalar,Options,DstIndex>& _dest) const
{
- internal::permute_symm_to_fullsymm<UpLo>(m_matrix,_dest,m_perm.indices().data());
+// internal::permute_symm_to_fullsymm<UpLo>(m_matrix,_dest,m_perm.indices().data());
+ SparseMatrix<DestScalar,(Options&RowMajor)==RowMajor ? ColMajor : RowMajor, DstIndex> tmp;
+ internal::permute_symm_to_fullsymm<UpLo>(m_matrix,tmp,m_perm.indices().data());
+ _dest = tmp;
}
template<typename DestType,unsigned int DestUpLo> void evalTo(SparseSelfAdjointView<DestType,DestUpLo>& dest) const
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
index 2438ac573d0..fcc18f5c9c8 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
@@ -17,7 +17,7 @@ namespace internal {
// perform a pseudo in-place sparse * sparse product assuming all matrices are col major
template<typename Lhs, typename Rhs, typename ResultType>
-static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, typename ResultType::RealScalar tolerance)
+static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, const typename ResultType::RealScalar& tolerance)
{
// return sparse_sparse_product_with_pruning_impl2(lhs,rhs,res);
@@ -27,7 +27,7 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
// make sure to call innerSize/outerSize since we fake the storage order.
Index rows = lhs.innerSize();
Index cols = rhs.outerSize();
- //int size = lhs.outerSize();
+ //Index size = lhs.outerSize();
eigen_assert(lhs.outerSize() == rhs.innerSize());
// allocate a temporary buffer
@@ -85,7 +85,7 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,C
typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
typedef typename ResultType::RealScalar RealScalar;
- static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance)
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
typename remove_all<ResultType>::type _res(res.rows(), res.cols());
internal::sparse_sparse_product_with_pruning_impl<Lhs,Rhs,ResultType>(lhs, rhs, _res, tolerance);
@@ -97,10 +97,10 @@ template<typename Lhs, typename Rhs, typename ResultType>
struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor>
{
typedef typename ResultType::RealScalar RealScalar;
- static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance)
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
// we need a col-major matrix to hold the result
- typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::Index> SparseTemporaryType;
SparseTemporaryType _res(res.rows(), res.cols());
internal::sparse_sparse_product_with_pruning_impl<Lhs,Rhs,SparseTemporaryType>(lhs, rhs, _res, tolerance);
res = _res;
@@ -111,7 +111,7 @@ template<typename Lhs, typename Rhs, typename ResultType>
struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor>
{
typedef typename ResultType::RealScalar RealScalar;
- static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance)
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
// let's transpose the product to get a column x column product
typename remove_all<ResultType>::type _res(res.rows(), res.cols());
@@ -124,12 +124,13 @@ template<typename Lhs, typename Rhs, typename ResultType>
struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor>
{
typedef typename ResultType::RealScalar RealScalar;
- static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance)
+ static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix;
- ColMajorMatrix colLhs(lhs);
- ColMajorMatrix colRhs(rhs);
- internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrix,ColMajorMatrix,ResultType>(colLhs, colRhs, res, tolerance);
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::Index> ColMajorMatrixLhs;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::Index> ColMajorMatrixRhs;
+ ColMajorMatrixLhs colLhs(lhs);
+ ColMajorMatrixRhs colRhs(rhs);
+ internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrixLhs,ColMajorMatrixRhs,ResultType>(colLhs, colRhs, res, tolerance);
// let's transpose the product to get a column x column product
// typedef SparseMatrix<typename ResultType::Scalar> SparseTemporaryType;
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h
index 273f9de688f..7c300ee8dbc 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h
@@ -18,7 +18,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>
typedef typename internal::remove_all<typename MatrixType::Nested>::type _MatrixTypeNested;
public:
- EIGEN_SPARSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
+ EIGEN_SPARSE_PUBLIC_INTERFACE(Transpose<MatrixType> )
class InnerIterator;
class ReverseInnerIterator;
@@ -34,26 +34,28 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerItera
: public _MatrixTypeNested::InnerIterator
{
typedef typename _MatrixTypeNested::InnerIterator Base;
+ typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(trans.derived().nestedExpression(), outer)
{}
- inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); }
- inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); }
+ Index row() const { return Base::col(); }
+ Index col() const { return Base::row(); }
};
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator
: public _MatrixTypeNested::ReverseInnerIterator
{
typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
+ typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(xpr.derived().nestedExpression(), outer)
{}
- inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); }
- inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); }
+ Index row() const { return Base::col(); }
+ Index col() const { return Base::row(); }
};
} // end namespace Eigen
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h
index 477e4bd94b0..333127b78e8 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h
@@ -2,6 +2,7 @@
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -27,6 +28,7 @@ template<typename MatrixType, int Mode> class SparseTriangularView
enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
|| ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)),
SkipLast = !SkipFirst,
+ SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
};
@@ -64,6 +66,7 @@ template<typename MatrixType, int Mode>
class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator
{
typedef typename MatrixTypeNestedCleaned::InnerIterator Base;
+ typedef typename SparseTriangularView::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer)
@@ -71,7 +74,7 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
{
if(SkipFirst)
{
- while((*this) && (HasUnitDiag ? this->index()<=outer : this->index()<outer))
+ while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer))
Base::operator++();
if(HasUnitDiag)
m_returnOne = true;
@@ -101,8 +104,8 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
return *this;
}
- inline Index row() const { return Base::row(); }
- inline Index col() const { return Base::col(); }
+ inline Index row() const { return (MatrixType::Flags&RowMajorBit ? Base::outer() : this->index()); }
+ inline Index col() const { return (MatrixType::Flags&RowMajorBit ? this->index() : Base::outer()); }
inline Index index() const
{
if(HasUnitDiag && m_returnOne) return Base::outer();
@@ -118,7 +121,12 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
{
if(HasUnitDiag && m_returnOne)
return true;
- return (SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer()));
+ if(SkipFirst) return Base::operator bool();
+ else
+ {
+ if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
+ else return (Base::operator bool() && this->index() <= this->outer());
+ }
}
protected:
bool m_returnOne;
@@ -128,18 +136,20 @@ template<typename MatrixType, int Mode>
class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator
{
typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base;
+ typedef typename SparseTriangularView::Index Index;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer)
: Base(view.nestedExpression(), outer)
{
eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal");
- if(SkipLast)
- while((*this) && this->index()>outer)
+ if(SkipLast) {
+ while((*this) && (SkipDiag ? this->index()>=outer : this->index()>outer))
--(*this);
+ }
}
- EIGEN_STRONG_INLINE InnerIterator& operator--()
+ EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
{ Base::operator--(); return *this; }
inline Index row() const { return Base::row(); }
@@ -147,7 +157,12 @@ class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public Matri
EIGEN_STRONG_INLINE operator bool() const
{
- return SkipLast ? Base::operator bool() : (Base::operator bool() && this->index() >= this->outer());
+ if (SkipLast) return Base::operator bool() ;
+ else
+ {
+ if(SkipDiag) return (Base::operator bool() && this->index() > this->outer());
+ else return (Base::operator bool() && this->index() >= this->outer());
+ }
}
};
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h
index 6062a086ff7..05023858b16 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h
@@ -73,7 +73,6 @@ template<typename _Scalar, int _Flags = 0, typename _Index = int> class Dynamic
template<typename _Scalar, int _Flags = 0, typename _Index = int> class SparseVector;
template<typename _Scalar, int _Flags = 0, typename _Index = int> class MappedSparseMatrix;
-template<typename MatrixType, int Size> class SparseInnerVectorSet;
template<typename MatrixType, int Mode> class SparseTriangularView;
template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView;
template<typename Lhs, typename Rhs> class SparseDiagonalProduct;
@@ -99,23 +98,24 @@ template<typename T> struct eval<T,Sparse>
template<typename T,int Cols> struct sparse_eval<T,1,Cols> {
typedef typename traits<T>::Scalar _Scalar;
- enum { _Flags = traits<T>::Flags| RowMajorBit };
+ typedef typename traits<T>::Index _Index;
public:
- typedef SparseVector<_Scalar, _Flags> type;
+ typedef SparseVector<_Scalar, RowMajor, _Index> type;
};
template<typename T,int Rows> struct sparse_eval<T,Rows,1> {
typedef typename traits<T>::Scalar _Scalar;
- enum { _Flags = traits<T>::Flags & (~RowMajorBit) };
+ typedef typename traits<T>::Index _Index;
public:
- typedef SparseVector<_Scalar, _Flags> type;
+ typedef SparseVector<_Scalar, ColMajor, _Index> type;
};
template<typename T,int Rows,int Cols> struct sparse_eval {
typedef typename traits<T>::Scalar _Scalar;
- enum { _Flags = traits<T>::Flags };
+ typedef typename traits<T>::Index _Index;
+ enum { _Options = ((traits<T>::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor };
public:
- typedef SparseMatrix<_Scalar, _Flags> type;
+ typedef SparseMatrix<_Scalar, _Options, _Index> type;
};
template<typename T> struct sparse_eval<T,1,1> {
@@ -127,12 +127,10 @@ template<typename T> struct sparse_eval<T,1,1> {
template<typename T> struct plain_matrix_type<T,Sparse>
{
typedef typename traits<T>::Scalar _Scalar;
- enum {
- _Flags = traits<T>::Flags
- };
-
+ typedef typename traits<T>::Index _Index;
+ enum { _Options = ((traits<T>::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor };
public:
- typedef SparseMatrix<_Scalar, _Flags> type;
+ typedef SparseMatrix<_Scalar, _Options, _Index> type;
};
} // end namespace internal
@@ -145,7 +143,7 @@ template<typename T> struct plain_matrix_type<T,Sparse>
*
* \sa SparseMatrix::setFromTriplets()
*/
-template<typename Scalar, typename Index=unsigned int>
+template<typename Scalar, typename Index=typename SparseMatrix<Scalar>::Index >
class Triplet
{
public:
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h
index c952f654038..7e15c814b6f 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h
@@ -45,35 +45,40 @@ struct traits<SparseVector<_Scalar, _Options, _Index> >
SupportedAccessPatterns = InnerRandomAccessPattern
};
};
+
+// Sparse-Vector-Assignment kinds:
+enum {
+ SVA_RuntimeSwitch,
+ SVA_Inner,
+ SVA_Outer
+};
+
+template< typename Dest, typename Src,
+ int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
+ : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
+ : SVA_Inner>
+struct sparse_vector_assign_selector;
+
}
template<typename _Scalar, int _Options, typename _Index>
class SparseVector
: public SparseMatrixBase<SparseVector<_Scalar, _Options, _Index> >
{
+ typedef SparseMatrixBase<SparseVector> SparseBase;
+
public:
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
-
- protected:
- public:
-
- typedef SparseMatrixBase<SparseVector> SparseBase;
+
+ typedef internal::CompressedStorage<Scalar,Index> Storage;
enum { IsColVector = internal::traits<SparseVector>::IsColVector };
enum {
Options = _Options
};
-
- internal::CompressedStorage<Scalar,Index> m_data;
- Index m_size;
-
- internal::CompressedStorage<Scalar,Index>& _data() { return m_data; }
- internal::CompressedStorage<Scalar,Index>& _data() const { return m_data; }
-
- public:
-
+
EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
@@ -84,17 +89,26 @@ class SparseVector
EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); }
EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); }
+
+ /** \internal */
+ inline Storage& data() { return m_data; }
+ /** \internal */
+ inline const Storage& data() const { return m_data; }
inline Scalar coeff(Index row, Index col) const
{
- eigen_assert((IsColVector ? col : row)==0);
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
return coeff(IsColVector ? row : col);
}
- inline Scalar coeff(Index i) const { return m_data.at(i); }
+ inline Scalar coeff(Index i) const
+ {
+ eigen_assert(i>=0 && i<m_size);
+ return m_data.at(i);
+ }
inline Scalar& coeffRef(Index row, Index col)
{
- eigen_assert((IsColVector ? col : row)==0);
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
return coeff(IsColVector ? row : col);
}
@@ -106,6 +120,7 @@ class SparseVector
*/
inline Scalar& coeffRef(Index i)
{
+ eigen_assert(i>=0 && i<m_size);
return m_data.atWithInsertion(i);
}
@@ -139,6 +154,8 @@ class SparseVector
inline Scalar& insert(Index row, Index col)
{
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
+
Index inner = IsColVector ? row : col;
Index outer = IsColVector ? col : row;
eigen_assert(outer==0);
@@ -146,6 +163,8 @@ class SparseVector
}
Scalar& insert(Index i)
{
+ eigen_assert(i>=0 && i<m_size);
+
Index startId = 0;
Index p = Index(m_data.size()) - 1;
// TODO smart realloc
@@ -169,7 +188,7 @@ class SparseVector
inline void finalize() {}
- void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
+ void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
{
m_data.prune(reference,epsilon);
}
@@ -188,25 +207,31 @@ class SparseVector
void resizeNonZeros(Index size) { m_data.resize(size); }
- inline SparseVector() : m_size(0) { resize(0); }
+ inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
- inline SparseVector(Index size) : m_size(0) { resize(size); }
+ inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
- inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); }
+ inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
template<typename OtherDerived>
inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
: m_size(0)
{
+ check_template_parameters();
*this = other.derived();
}
inline SparseVector(const SparseVector& other)
- : m_size(0)
+ : SparseBase(other), m_size(0)
{
+ check_template_parameters();
*this = other.derived();
}
+ /** Swaps the values of \c *this and \a other.
+ * Overloaded for performance: this version performs a \em shallow swap by swaping pointers and attributes only.
+ * \sa SparseMatrixBase::swap()
+ */
inline void swap(SparseVector& other)
{
std::swap(m_size, other.m_size);
@@ -230,10 +255,10 @@ class SparseVector
template<typename OtherDerived>
inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
{
- if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
- return assign(other.transpose());
- else
- return assign(other);
+ SparseVector tmp(other.size());
+ internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
+ this->swap(tmp);
+ return *this;
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -260,73 +285,63 @@ class SparseVector
public:
- /** \deprecated use setZero() and reserve() */
+ /** \internal \deprecated use setZero() and reserve() */
EIGEN_DEPRECATED void startFill(Index reserve)
{
setZero();
m_data.reserve(reserve);
}
- /** \deprecated use insertBack(Index,Index) */
+ /** \internal \deprecated use insertBack(Index,Index) */
EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
{
eigen_assert(r==0 || c==0);
return fill(IsColVector ? r : c);
}
- /** \deprecated use insertBack(Index) */
+ /** \internal \deprecated use insertBack(Index) */
EIGEN_DEPRECATED Scalar& fill(Index i)
{
m_data.append(0, i);
return m_data.value(m_data.size()-1);
}
- /** \deprecated use insert(Index,Index) */
+ /** \internal \deprecated use insert(Index,Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
{
eigen_assert(r==0 || c==0);
return fillrand(IsColVector ? r : c);
}
- /** \deprecated use insert(Index) */
+ /** \internal \deprecated use insert(Index) */
EIGEN_DEPRECATED Scalar& fillrand(Index i)
{
return insert(i);
}
- /** \deprecated use finalize() */
+ /** \internal \deprecated use finalize() */
EIGEN_DEPRECATED void endFill() {}
+ // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
+ /** \internal \deprecated use data() */
+ EIGEN_DEPRECATED Storage& _data() { return m_data; }
+ /** \internal \deprecated use data() */
+ EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
+
# ifdef EIGEN_SPARSEVECTOR_PLUGIN
# include EIGEN_SPARSEVECTOR_PLUGIN
# endif
protected:
- template<typename OtherDerived>
- EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other)
+
+ static void check_template_parameters()
{
- const OtherDerived& other(_other.derived());
- const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
- if(needToTranspose)
- {
- Index size = other.size();
- Index nnz = other.nonZeros();
- resize(size);
- reserve(nnz);
- for(Index i=0; i<size; ++i)
- {
- typename OtherDerived::InnerIterator it(other, i);
- if(it)
- insert(i) = it.value();
- }
- return *this;
- }
- else
- {
- // there is no special optimization
- return Base::operator=(other);
- }
+ EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+ EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
}
+
+ Storage m_data;
+ Index m_size;
};
template<typename Scalar, int _Options, typename _Index>
@@ -393,6 +408,40 @@ class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
const Index m_start;
};
+namespace internal {
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
+ static void run(Dest& dst, const Src& src) {
+ eigen_internal_assert(src.innerSize()==src.size());
+ for(typename Src::InnerIterator it(src, 0); it; ++it)
+ dst.insert(it.index()) = it.value();
+ }
+};
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
+ static void run(Dest& dst, const Src& src) {
+ eigen_internal_assert(src.outerSize()==src.size());
+ for(typename Dest::Index i=0; i<src.size(); ++i)
+ {
+ typename Src::InnerIterator it(src, i);
+ if(it)
+ dst.insert(i) = it.value();
+ }
+ }
+};
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
+ static void run(Dest& dst, const Src& src) {
+ if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
+ else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
+ }
+};
+
+}
+
} // end namespace Eigen
#endif // EIGEN_SPARSEVECTOR_H
diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h
index 8b0b9ea0304..fd8450463fe 100644
--- a/extern/Eigen3/Eigen/src/SparseCore/SparseView.h
+++ b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h
@@ -18,7 +18,7 @@ namespace internal {
template<typename MatrixType>
struct traits<SparseView<MatrixType> > : traits<MatrixType>
{
- typedef int Index;
+ typedef typename MatrixType::Index Index;
typedef Sparse StorageKind;
enum {
Flags = int(traits<MatrixType>::Flags) & (RowMajorBit)
@@ -56,6 +56,7 @@ protected:
template<typename MatrixType>
class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
{
+ typedef typename SparseView::Index Index;
public:
typedef typename _MatrixTypeNested::InnerIterator IterBase;
InnerIterator(const SparseView& view, Index outer) :
@@ -88,7 +89,7 @@ private:
template<typename Derived>
const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& m_reference,
- typename NumTraits<Scalar>::Real m_epsilon) const
+ const typename NumTraits<Scalar>::Real& m_epsilon) const
{
return SparseView<Derived>(derived(), m_reference, m_epsilon);
}
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU.h
new file mode 100644
index 00000000000..1d592f2c8c7
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU.h
@@ -0,0 +1,758 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#ifndef EIGEN_SPARSE_LU_H
+#define EIGEN_SPARSE_LU_H
+
+namespace Eigen {
+
+template <typename _MatrixType, typename _OrderingType = COLAMDOrdering<typename _MatrixType::Index> > class SparseLU;
+template <typename MappedSparseMatrixType> struct SparseLUMatrixLReturnType;
+template <typename MatrixLType, typename MatrixUType> struct SparseLUMatrixUReturnType;
+
+/** \ingroup SparseLU_Module
+ * \class SparseLU
+ *
+ * \brief Sparse supernodal LU factorization for general matrices
+ *
+ * This class implements the supernodal LU factorization for general matrices.
+ * It uses the main techniques from the sequential SuperLU package
+ * (http://crd-legacy.lbl.gov/~xiaoye/SuperLU/). It handles transparently real
+ * and complex arithmetics with single and double precision, depending on the
+ * scalar type of your input matrix.
+ * The code has been optimized to provide BLAS-3 operations during supernode-panel updates.
+ * It benefits directly from the built-in high-performant Eigen BLAS routines.
+ * Moreover, when the size of a supernode is very small, the BLAS calls are avoided to
+ * enable a better optimization from the compiler. For best performance,
+ * you should compile it with NDEBUG flag to avoid the numerous bounds checking on vectors.
+ *
+ * An important parameter of this class is the ordering method. It is used to reorder the columns
+ * (and eventually the rows) of the matrix to reduce the number of new elements that are created during
+ * numerical factorization. The cheapest method available is COLAMD.
+ * See \link OrderingMethods_Module the OrderingMethods module \endlink for the list of
+ * built-in and external ordering methods.
+ *
+ * Simple example with key steps
+ * \code
+ * VectorXd x(n), b(n);
+ * SparseMatrix<double, ColMajor> A;
+ * SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<Index> > solver;
+ * // fill A and b;
+ * // Compute the ordering permutation vector from the structural pattern of A
+ * solver.analyzePattern(A);
+ * // Compute the numerical factorization
+ * solver.factorize(A);
+ * //Use the factors to solve the linear system
+ * x = solver.solve(b);
+ * \endcode
+ *
+ * \warning The input matrix A should be in a \b compressed and \b column-major form.
+ * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
+ *
+ * \note Unlike the initial SuperLU implementation, there is no step to equilibrate the matrix.
+ * For badly scaled matrices, this step can be useful to reduce the pivoting during factorization.
+ * If this is the case for your matrices, you can try the basic scaling method at
+ * "unsupported/Eigen/src/IterativeSolvers/Scaling.h"
+ *
+ * \tparam _MatrixType The type of the sparse matrix. It must be a column-major SparseMatrix<>
+ * \tparam _OrderingType The ordering method to use, either AMD, COLAMD or METIS. Default is COLMAD
+ *
+ *
+ * \sa \ref TutorialSparseDirectSolvers
+ * \sa \ref OrderingMethods_Module
+ */
+template <typename _MatrixType, typename _OrderingType>
+class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typename _MatrixType::Index>
+{
+ public:
+ typedef _MatrixType MatrixType;
+ typedef _OrderingType OrderingType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename MatrixType::Index Index;
+ typedef SparseMatrix<Scalar,ColMajor,Index> NCMatrix;
+ typedef internal::MappedSuperNodalMatrix<Scalar, Index> SCMatrix;
+ typedef Matrix<Scalar,Dynamic,1> ScalarVector;
+ typedef Matrix<Index,Dynamic,1> IndexVector;
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
+ typedef internal::SparseLUImpl<Scalar, Index> Base;
+
+ public:
+ SparseLU():m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
+ {
+ initperfvalues();
+ }
+ SparseLU(const MatrixType& matrix):m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
+ {
+ initperfvalues();
+ compute(matrix);
+ }
+
+ ~SparseLU()
+ {
+ // Free all explicit dynamic pointers
+ }
+
+ void analyzePattern (const MatrixType& matrix);
+ void factorize (const MatrixType& matrix);
+ void simplicialfactorize(const MatrixType& matrix);
+
+ /**
+ * Compute the symbolic and numeric factorization of the input sparse matrix.
+ * The input matrix should be in column-major storage.
+ */
+ void compute (const MatrixType& matrix)
+ {
+ // Analyze
+ analyzePattern(matrix);
+ //Factorize
+ factorize(matrix);
+ }
+
+ inline Index rows() const { return m_mat.rows(); }
+ inline Index cols() const { return m_mat.cols(); }
+ /** Indicate that the pattern of the input matrix is symmetric */
+ void isSymmetric(bool sym)
+ {
+ m_symmetricmode = sym;
+ }
+
+ /** \returns an expression of the matrix L, internally stored as supernodes
+ * The only operation available with this expression is the triangular solve
+ * \code
+ * y = b; matrixL().solveInPlace(y);
+ * \endcode
+ */
+ SparseLUMatrixLReturnType<SCMatrix> matrixL() const
+ {
+ return SparseLUMatrixLReturnType<SCMatrix>(m_Lstore);
+ }
+ /** \returns an expression of the matrix U,
+ * The only operation available with this expression is the triangular solve
+ * \code
+ * y = b; matrixU().solveInPlace(y);
+ * \endcode
+ */
+ SparseLUMatrixUReturnType<SCMatrix,MappedSparseMatrix<Scalar,ColMajor,Index> > matrixU() const
+ {
+ return SparseLUMatrixUReturnType<SCMatrix, MappedSparseMatrix<Scalar,ColMajor,Index> >(m_Lstore, m_Ustore);
+ }
+
+ /**
+ * \returns a reference to the row matrix permutation \f$ P_r \f$ such that \f$P_r A P_c^T = L U\f$
+ * \sa colsPermutation()
+ */
+ inline const PermutationType& rowsPermutation() const
+ {
+ return m_perm_r;
+ }
+ /**
+ * \returns a reference to the column matrix permutation\f$ P_c^T \f$ such that \f$P_r A P_c^T = L U\f$
+ * \sa rowsPermutation()
+ */
+ inline const PermutationType& colsPermutation() const
+ {
+ return m_perm_c;
+ }
+ /** Set the threshold used for a diagonal entry to be an acceptable pivot. */
+ void setPivotThreshold(const RealScalar& thresh)
+ {
+ m_diagpivotthresh = thresh;
+ }
+
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
+ *
+ * \warning the destination matrix X in X = this->solve(B) must be colmun-major.
+ *
+ * \sa compute()
+ */
+ template<typename Rhs>
+ inline const internal::solve_retval<SparseLU, Rhs> solve(const MatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_factorizationIsOk && "SparseLU is not initialized.");
+ eigen_assert(rows()==B.rows()
+ && "SparseLU::solve(): invalid number of rows of the right hand side matrix B");
+ return internal::solve_retval<SparseLU, Rhs>(*this, B.derived());
+ }
+
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
+ *
+ * \sa compute()
+ */
+ template<typename Rhs>
+ inline const internal::sparse_solve_retval<SparseLU, Rhs> solve(const SparseMatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_factorizationIsOk && "SparseLU is not initialized.");
+ eigen_assert(rows()==B.rows()
+ && "SparseLU::solve(): invalid number of rows of the right hand side matrix B");
+ return internal::sparse_solve_retval<SparseLU, Rhs>(*this, B.derived());
+ }
+
+ /** \brief Reports whether previous computation was successful.
+ *
+ * \returns \c Success if computation was succesful,
+ * \c NumericalIssue if the LU factorization reports a problem, zero diagonal for instance
+ * \c InvalidInput if the input matrix is invalid
+ *
+ * \sa iparm()
+ */
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return m_info;
+ }
+
+ /**
+ * \returns A string describing the type of error
+ */
+ std::string lastErrorMessage() const
+ {
+ return m_lastError;
+ }
+
+ template<typename Rhs, typename Dest>
+ bool _solve(const MatrixBase<Rhs> &B, MatrixBase<Dest> &X_base) const
+ {
+ Dest& X(X_base.derived());
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first");
+ EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0,
+ THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
+
+ // Permute the right hand side to form X = Pr*B
+ // on return, X is overwritten by the computed solution
+ X.resize(B.rows(),B.cols());
+
+ // this ugly const_cast_derived() helps to detect aliasing when applying the permutations
+ for(Index j = 0; j < B.cols(); ++j)
+ X.col(j) = rowsPermutation() * B.const_cast_derived().col(j);
+
+ //Forward substitution with L
+ this->matrixL().solveInPlace(X);
+ this->matrixU().solveInPlace(X);
+
+ // Permute back the solution
+ for (Index j = 0; j < B.cols(); ++j)
+ X.col(j) = colsPermutation().inverse() * X.col(j);
+
+ return true;
+ }
+
+ /**
+ * \returns the absolute value of the determinant of the matrix of which
+ * *this is the QR decomposition.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa logAbsDeterminant(), signDeterminant()
+ */
+ Scalar absDeterminant()
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ // Initialize with the determinant of the row matrix
+ Scalar det = Scalar(1.);
+ //Note that the diagonal blocks of U are stored in supernodes,
+ // which are available in the L part :)
+ for (Index j = 0; j < this->cols(); ++j)
+ {
+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
+ {
+ if(it.row() < j) continue;
+ if(it.row() == j)
+ {
+ det *= (std::abs)(it.value());
+ break;
+ }
+ }
+ }
+ return det;
+ }
+
+ /** \returns the natural log of the absolute value of the determinant of the matrix
+ * of which **this is the QR decomposition
+ *
+ * \note This method is useful to work around the risk of overflow/underflow that's
+ * inherent to the determinant computation.
+ *
+ * \sa absDeterminant(), signDeterminant()
+ */
+ Scalar logAbsDeterminant() const
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ Scalar det = Scalar(0.);
+ for (Index j = 0; j < this->cols(); ++j)
+ {
+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
+ {
+ if(it.row() < j) continue;
+ if(it.row() == j)
+ {
+ det += (std::log)((std::abs)(it.value()));
+ break;
+ }
+ }
+ }
+ return det;
+ }
+
+ /** \returns A number representing the sign of the determinant
+ *
+ * \sa absDeterminant(), logAbsDeterminant()
+ */
+ Scalar signDeterminant()
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ return Scalar(m_detPermR);
+ }
+
+ protected:
+ // Functions
+ void initperfvalues()
+ {
+ m_perfv.panel_size = 1;
+ m_perfv.relax = 1;
+ m_perfv.maxsuper = 128;
+ m_perfv.rowblk = 16;
+ m_perfv.colblk = 8;
+ m_perfv.fillfactor = 20;
+ }
+
+ // Variables
+ mutable ComputationInfo m_info;
+ bool m_isInitialized;
+ bool m_factorizationIsOk;
+ bool m_analysisIsOk;
+ std::string m_lastError;
+ NCMatrix m_mat; // The input (permuted ) matrix
+ SCMatrix m_Lstore; // The lower triangular matrix (supernodal)
+ MappedSparseMatrix<Scalar,ColMajor,Index> m_Ustore; // The upper triangular matrix
+ PermutationType m_perm_c; // Column permutation
+ PermutationType m_perm_r ; // Row permutation
+ IndexVector m_etree; // Column elimination tree
+
+ typename Base::GlobalLU_t m_glu;
+
+ // SparseLU options
+ bool m_symmetricmode;
+ // values for performance
+ internal::perfvalues<Index> m_perfv;
+ RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot
+ Index m_nnzL, m_nnzU; // Nonzeros in L and U factors
+ Index m_detPermR; // Determinant of the coefficient matrix
+ private:
+ // Disable copy constructor
+ SparseLU (const SparseLU& );
+
+}; // End class SparseLU
+
+
+
+// Functions needed by the anaysis phase
+/**
+ * Compute the column permutation to minimize the fill-in
+ *
+ * - Apply this permutation to the input matrix -
+ *
+ * - Compute the column elimination tree on the permuted matrix
+ *
+ * - Postorder the elimination tree and the column permutation
+ *
+ */
+template <typename MatrixType, typename OrderingType>
+void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
+{
+
+ //TODO It is possible as in SuperLU to compute row and columns scaling vectors to equilibrate the matrix mat.
+
+ OrderingType ord;
+ ord(mat,m_perm_c);
+
+ // Apply the permutation to the column of the input matrix
+ //First copy the whole input matrix.
+ m_mat = mat;
+ if (m_perm_c.size()) {
+ m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. FIXME : This vector is filled but not subsequently used.
+ //Then, permute only the column pointers
+ const Index * outerIndexPtr;
+ if (mat.isCompressed()) outerIndexPtr = mat.outerIndexPtr();
+ else
+ {
+ Index *outerIndexPtr_t = new Index[mat.cols()+1];
+ for(Index i = 0; i <= mat.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
+ outerIndexPtr = outerIndexPtr_t;
+ }
+ for (Index i = 0; i < mat.cols(); i++)
+ {
+ m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
+ m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
+ }
+ if(!mat.isCompressed()) delete[] outerIndexPtr;
+ }
+ // Compute the column elimination tree of the permuted matrix
+ IndexVector firstRowElt;
+ internal::coletree(m_mat, m_etree,firstRowElt);
+
+ // In symmetric mode, do not do postorder here
+ if (!m_symmetricmode) {
+ IndexVector post, iwork;
+ // Post order etree
+ internal::treePostorder(m_mat.cols(), m_etree, post);
+
+
+ // Renumber etree in postorder
+ Index m = m_mat.cols();
+ iwork.resize(m+1);
+ for (Index i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i));
+ m_etree = iwork;
+
+ // Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree
+ PermutationType post_perm(m);
+ for (Index i = 0; i < m; i++)
+ post_perm.indices()(i) = post(i);
+
+ // Combine the two permutations : postorder the permutation for future use
+ if(m_perm_c.size()) {
+ m_perm_c = post_perm * m_perm_c;
+ }
+
+ } // end postordering
+
+ m_analysisIsOk = true;
+}
+
+// Functions needed by the numerical factorization phase
+
+
+/**
+ * - Numerical factorization
+ * - Interleaved with the symbolic factorization
+ * On exit, info is
+ *
+ * = 0: successful factorization
+ *
+ * > 0: if info = i, and i is
+ *
+ * <= A->ncol: U(i,i) is exactly zero. The factorization has
+ * been completed, but the factor U is exactly singular,
+ * and division by zero will occur if it is used to solve a
+ * system of equations.
+ *
+ * > A->ncol: number of bytes allocated when memory allocation
+ * failure occurred, plus A->ncol. If lwork = -1, it is
+ * the estimated amount of space needed, plus A->ncol.
+ */
+template <typename MatrixType, typename OrderingType>
+void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
+{
+ using internal::emptyIdxLU;
+ eigen_assert(m_analysisIsOk && "analyzePattern() should be called first");
+ eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices");
+
+ typedef typename IndexVector::Scalar Index;
+
+
+ // Apply the column permutation computed in analyzepattern()
+ // m_mat = matrix * m_perm_c.inverse();
+ m_mat = matrix;
+ if (m_perm_c.size())
+ {
+ m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers.
+ //Then, permute only the column pointers
+ const Index * outerIndexPtr;
+ if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
+ else
+ {
+ Index* outerIndexPtr_t = new Index[matrix.cols()+1];
+ for(Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
+ outerIndexPtr = outerIndexPtr_t;
+ }
+ for (Index i = 0; i < matrix.cols(); i++)
+ {
+ m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
+ m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
+ }
+ if(!matrix.isCompressed()) delete[] outerIndexPtr;
+ }
+ else
+ { //FIXME This should not be needed if the empty permutation is handled transparently
+ m_perm_c.resize(matrix.cols());
+ for(Index i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i;
+ }
+
+ Index m = m_mat.rows();
+ Index n = m_mat.cols();
+ Index nnz = m_mat.nonZeros();
+ Index maxpanel = m_perfv.panel_size * m;
+ // Allocate working storage common to the factor routines
+ Index lwork = 0;
+ Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
+ if (info)
+ {
+ m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
+ m_factorizationIsOk = false;
+ return ;
+ }
+
+ // Set up pointers for integer working arrays
+ IndexVector segrep(m); segrep.setZero();
+ IndexVector parent(m); parent.setZero();
+ IndexVector xplore(m); xplore.setZero();
+ IndexVector repfnz(maxpanel);
+ IndexVector panel_lsub(maxpanel);
+ IndexVector xprune(n); xprune.setZero();
+ IndexVector marker(m*internal::LUNoMarker); marker.setZero();
+
+ repfnz.setConstant(-1);
+ panel_lsub.setConstant(-1);
+
+ // Set up pointers for scalar working arrays
+ ScalarVector dense;
+ dense.setZero(maxpanel);
+ ScalarVector tempv;
+ tempv.setZero(internal::LUnumTempV(m, m_perfv.panel_size, m_perfv.maxsuper, /*m_perfv.rowblk*/m) );
+
+ // Compute the inverse of perm_c
+ PermutationType iperm_c(m_perm_c.inverse());
+
+ // Identify initial relaxed snodes
+ IndexVector relax_end(n);
+ if ( m_symmetricmode == true )
+ Base::heap_relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
+ else
+ Base::relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
+
+
+ m_perm_r.resize(m);
+ m_perm_r.indices().setConstant(-1);
+ marker.setConstant(-1);
+ m_detPermR = 1; // Record the determinant of the row permutation
+
+ m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0);
+ m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) = Index(0);
+
+ // Work on one 'panel' at a time. A panel is one of the following :
+ // (a) a relaxed supernode at the bottom of the etree, or
+ // (b) panel_size contiguous columns, <panel_size> defined by the user
+ Index jcol;
+ IndexVector panel_histo(n);
+ Index pivrow; // Pivotal row number in the original row matrix
+ Index nseg1; // Number of segments in U-column above panel row jcol
+ Index nseg; // Number of segments in each U-column
+ Index irep;
+ Index i, k, jj;
+ for (jcol = 0; jcol < n; )
+ {
+ // Adjust panel size so that a panel won't overlap with the next relaxed snode.
+ Index panel_size = m_perfv.panel_size; // upper bound on panel width
+ for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++)
+ {
+ if (relax_end(k) != emptyIdxLU)
+ {
+ panel_size = k - jcol;
+ break;
+ }
+ }
+ if (k == n)
+ panel_size = n - jcol;
+
+ // Symbolic outer factorization on a panel of columns
+ Base::panel_dfs(m, panel_size, jcol, m_mat, m_perm_r.indices(), nseg1, dense, panel_lsub, segrep, repfnz, xprune, marker, parent, xplore, m_glu);
+
+ // Numeric sup-panel updates in topological order
+ Base::panel_bmod(m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu);
+
+ // Sparse LU within the panel, and below the panel diagonal
+ for ( jj = jcol; jj< jcol + panel_size; jj++)
+ {
+ k = (jj - jcol) * m; // Column index for w-wide arrays
+
+ nseg = nseg1; // begin after all the panel segments
+ //Depth-first-search for the current column
+ VectorBlock<IndexVector> panel_lsubk(panel_lsub, k, m);
+ VectorBlock<IndexVector> repfnz_k(repfnz, k, m);
+ info = Base::column_dfs(m, jj, m_perm_r.indices(), m_perfv.maxsuper, nseg, panel_lsubk, segrep, repfnz_k, xprune, marker, parent, xplore, m_glu);
+ if ( info )
+ {
+ m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
+ m_info = NumericalIssue;
+ m_factorizationIsOk = false;
+ return;
+ }
+ // Numeric updates to this column
+ VectorBlock<ScalarVector> dense_k(dense, k, m);
+ VectorBlock<IndexVector> segrep_k(segrep, nseg1, m-nseg1);
+ info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu);
+ if ( info )
+ {
+ m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
+ m_info = NumericalIssue;
+ m_factorizationIsOk = false;
+ return;
+ }
+
+ // Copy the U-segments to ucol(*)
+ info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu);
+ if ( info )
+ {
+ m_lastError = "UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
+ m_info = NumericalIssue;
+ m_factorizationIsOk = false;
+ return;
+ }
+
+ // Form the L-segment
+ info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu);
+ if ( info )
+ {
+ m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR ... ZERO COLUMN AT ";
+ std::ostringstream returnInfo;
+ returnInfo << info;
+ m_lastError += returnInfo.str();
+ m_info = NumericalIssue;
+ m_factorizationIsOk = false;
+ return;
+ }
+
+ // Update the determinant of the row permutation matrix
+ if (pivrow != jj) m_detPermR *= -1;
+
+ // Prune columns (0:jj-1) using column jj
+ Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
+
+ // Reset repfnz for this column
+ for (i = 0; i < nseg; i++)
+ {
+ irep = segrep(i);
+ repfnz_k(irep) = emptyIdxLU;
+ }
+ } // end SparseLU within the panel
+ jcol += panel_size; // Move to the next panel
+ } // end for -- end elimination
+
+ // Count the number of nonzeros in factors
+ Base::countnz(n, m_nnzL, m_nnzU, m_glu);
+ // Apply permutation to the L subscripts
+ Base::fixupL(n, m_perm_r.indices(), m_glu);
+
+ // Create supernode matrix L
+ m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
+ // Create the column major upper sparse matrix U;
+ new (&m_Ustore) MappedSparseMatrix<Scalar, ColMajor, Index> ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() );
+
+ m_info = Success;
+ m_factorizationIsOk = true;
+}
+
+template<typename MappedSupernodalType>
+struct SparseLUMatrixLReturnType : internal::no_assignment_operator
+{
+ typedef typename MappedSupernodalType::Index Index;
+ typedef typename MappedSupernodalType::Scalar Scalar;
+ SparseLUMatrixLReturnType(const MappedSupernodalType& mapL) : m_mapL(mapL)
+ { }
+ Index rows() { return m_mapL.rows(); }
+ Index cols() { return m_mapL.cols(); }
+ template<typename Dest>
+ void solveInPlace( MatrixBase<Dest> &X) const
+ {
+ m_mapL.solveInPlace(X);
+ }
+ const MappedSupernodalType& m_mapL;
+};
+
+template<typename MatrixLType, typename MatrixUType>
+struct SparseLUMatrixUReturnType : internal::no_assignment_operator
+{
+ typedef typename MatrixLType::Index Index;
+ typedef typename MatrixLType::Scalar Scalar;
+ SparseLUMatrixUReturnType(const MatrixLType& mapL, const MatrixUType& mapU)
+ : m_mapL(mapL),m_mapU(mapU)
+ { }
+ Index rows() { return m_mapL.rows(); }
+ Index cols() { return m_mapL.cols(); }
+
+ template<typename Dest> void solveInPlace(MatrixBase<Dest> &X) const
+ {
+ Index nrhs = X.cols();
+ Index n = X.rows();
+ // Backward solve with U
+ for (Index k = m_mapL.nsuper(); k >= 0; k--)
+ {
+ Index fsupc = m_mapL.supToCol()[k];
+ Index lda = m_mapL.colIndexPtr()[fsupc+1] - m_mapL.colIndexPtr()[fsupc]; // leading dimension
+ Index nsupc = m_mapL.supToCol()[k+1] - fsupc;
+ Index luptr = m_mapL.colIndexPtr()[fsupc];
+
+ if (nsupc == 1)
+ {
+ for (Index j = 0; j < nrhs; j++)
+ {
+ X(fsupc, j) /= m_mapL.valuePtr()[luptr];
+ }
+ }
+ else
+ {
+ Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
+ Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
+ U = A.template triangularView<Upper>().solve(U);
+ }
+
+ for (Index j = 0; j < nrhs; ++j)
+ {
+ for (Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
+ {
+ typename MatrixUType::InnerIterator it(m_mapU, jcol);
+ for ( ; it; ++it)
+ {
+ Index irow = it.index();
+ X(irow, j) -= X(jcol, j) * it.value();
+ }
+ }
+ }
+ } // End For U-solve
+ }
+ const MatrixLType& m_mapL;
+ const MatrixUType& m_mapU;
+};
+
+namespace internal {
+
+template<typename _MatrixType, typename Derived, typename Rhs>
+struct solve_retval<SparseLU<_MatrixType,Derived>, Rhs>
+ : solve_retval_base<SparseLU<_MatrixType,Derived>, Rhs>
+{
+ typedef SparseLU<_MatrixType,Derived> Dec;
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ dec()._solve(rhs(),dst);
+ }
+};
+
+template<typename _MatrixType, typename Derived, typename Rhs>
+struct sparse_solve_retval<SparseLU<_MatrixType,Derived>, Rhs>
+ : sparse_solve_retval_base<SparseLU<_MatrixType,Derived>, Rhs>
+{
+ typedef SparseLU<_MatrixType,Derived> Dec;
+ EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ this->defaultEvalTo(dst);
+ }
+};
+} // end namespace internal
+
+} // End namespace Eigen
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLUImpl.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLUImpl.h
new file mode 100644
index 00000000000..14d70897df7
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLUImpl.h
@@ -0,0 +1,64 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef SPARSELU_IMPL_H
+#define SPARSELU_IMPL_H
+
+namespace Eigen {
+namespace internal {
+
+/** \ingroup SparseLU_Module
+ * \class SparseLUImpl
+ * Base class for sparseLU
+ */
+template <typename Scalar, typename Index>
+class SparseLUImpl
+{
+ public:
+ typedef Matrix<Scalar,Dynamic,1> ScalarVector;
+ typedef Matrix<Index,Dynamic,1> IndexVector;
+ typedef typename ScalarVector::RealScalar RealScalar;
+ typedef Ref<Matrix<Scalar,Dynamic,1> > BlockScalarVector;
+ typedef Ref<Matrix<Index,Dynamic,1> > BlockIndexVector;
+ typedef LU_GlobalLU_t<IndexVector, ScalarVector> GlobalLU_t;
+ typedef SparseMatrix<Scalar,ColMajor,Index> MatrixType;
+
+ protected:
+ template <typename VectorType>
+ Index expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions);
+ Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu);
+ template <typename VectorType>
+ Index memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions);
+ void heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end);
+ void relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end);
+ Index snode_dfs(const Index jcol, const Index kcol,const MatrixType& mat, IndexVector& xprune, IndexVector& marker, GlobalLU_t& glu);
+ Index snode_bmod (const Index jcol, const Index fsupc, ScalarVector& dense, GlobalLU_t& glu);
+ Index pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu);
+ template <typename Traits>
+ void dfs_kernel(const Index jj, IndexVector& perm_r,
+ Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
+ Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
+ IndexVector& xplore, GlobalLU_t& glu, Index& nextl_col, Index krow, Traits& traits);
+ void panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu);
+
+ void panel_bmod(const Index m, const Index w, const Index jcol, const Index nseg, ScalarVector& dense, ScalarVector& tempv, IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu);
+ Index column_dfs(const Index m, const Index jcol, IndexVector& perm_r, Index maxsuper, Index& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu);
+ Index column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu);
+ Index copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu);
+ void pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu);
+ void countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu);
+ void fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu);
+
+ template<typename , typename >
+ friend struct column_dfs_traits;
+};
+
+} // end namespace internal
+} // namespace Eigen
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Memory.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Memory.h
new file mode 100644
index 00000000000..1ffa7d54e96
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Memory.h
@@ -0,0 +1,227 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]memory.c files in SuperLU
+
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+
+#ifndef EIGEN_SPARSELU_MEMORY
+#define EIGEN_SPARSELU_MEMORY
+
+namespace Eigen {
+namespace internal {
+
+enum { LUNoMarker = 3 };
+enum {emptyIdxLU = -1};
+template<typename Index>
+inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b)
+{
+ return (std::max)(m, (t+b)*w);
+}
+
+template< typename Scalar, typename Index>
+inline Index LUTempSpace(Index&m, Index& w)
+{
+ return (2*w + 4 + LUNoMarker) * m * sizeof(Index) + (w + 1) * m * sizeof(Scalar);
+}
+
+
+
+
+/**
+ * Expand the existing storage to accomodate more fill-ins
+ * \param vec Valid pointer to the vector to allocate or expand
+ * \param[in,out] length At input, contain the current length of the vector that is to be increased. At output, length of the newly allocated vector
+ * \param[in] nbElts Current number of elements in the factors
+ * \param keep_prev 1: use length and do not expand the vector; 0: compute new_len and expand
+ * \param[in,out] num_expansions Number of times the memory has been expanded
+ */
+template <typename Scalar, typename Index>
+template <typename VectorType>
+Index SparseLUImpl<Scalar,Index>::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions)
+{
+
+ float alpha = 1.5; // Ratio of the memory increase
+ Index new_len; // New size of the allocated memory
+
+ if(num_expansions == 0 || keep_prev)
+ new_len = length ; // First time allocate requested
+ else
+ new_len = (std::max)(length+1,Index(alpha * length));
+
+ VectorType old_vec; // Temporary vector to hold the previous values
+ if (nbElts > 0 )
+ old_vec = vec.segment(0,nbElts);
+
+ //Allocate or expand the current vector
+#ifdef EIGEN_EXCEPTIONS
+ try
+#endif
+ {
+ vec.resize(new_len);
+ }
+#ifdef EIGEN_EXCEPTIONS
+ catch(std::bad_alloc& )
+#else
+ if(!vec.size())
+#endif
+ {
+ if (!num_expansions)
+ {
+ // First time to allocate from LUMemInit()
+ // Let LUMemInit() deals with it.
+ return -1;
+ }
+ if (keep_prev)
+ {
+ // In this case, the memory length should not not be reduced
+ return new_len;
+ }
+ else
+ {
+ // Reduce the size and increase again
+ Index tries = 0; // Number of attempts
+ do
+ {
+ alpha = (alpha + 1)/2;
+ new_len = (std::max)(length+1,Index(alpha * length));
+#ifdef EIGEN_EXCEPTIONS
+ try
+#endif
+ {
+ vec.resize(new_len);
+ }
+#ifdef EIGEN_EXCEPTIONS
+ catch(std::bad_alloc& )
+#else
+ if (!vec.size())
+#endif
+ {
+ tries += 1;
+ if ( tries > 10) return new_len;
+ }
+ } while (!vec.size());
+ }
+ }
+ //Copy the previous values to the newly allocated space
+ if (nbElts > 0)
+ vec.segment(0, nbElts) = old_vec;
+
+
+ length = new_len;
+ if(num_expansions) ++num_expansions;
+ return 0;
+}
+
+/**
+ * \brief Allocate various working space for the numerical factorization phase.
+ * \param m number of rows of the input matrix
+ * \param n number of columns
+ * \param annz number of initial nonzeros in the matrix
+ * \param lwork if lwork=-1, this routine returns an estimated size of the required memory
+ * \param glu persistent data to facilitate multiple factors : will be deleted later ??
+ * \param fillratio estimated ratio of fill in the factors
+ * \param panel_size Size of a panel
+ * \return an estimated size of the required memory if lwork = -1; otherwise, return the size of actually allocated memory when allocation failed, and 0 on success
+ * \note Unlike SuperLU, this routine does not support successive factorization with the same pattern and the same row permutation
+ */
+template <typename Scalar, typename Index>
+Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu)
+{
+ Index& num_expansions = glu.num_expansions; //No memory expansions so far
+ num_expansions = 0;
+ glu.nzumax = glu.nzlumax = (std::min)(fillratio * annz / n, m) * n; // estimated number of nonzeros in U
+ glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor
+ // Return the estimated size to the user if necessary
+ Index tempSpace;
+ tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
+ if (lwork == emptyIdxLU)
+ {
+ Index estimated_size;
+ estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace
+ + (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n;
+ return estimated_size;
+ }
+
+ // Setup the required space
+
+ // First allocate Integer pointers for L\U factors
+ glu.xsup.resize(n+1);
+ glu.supno.resize(n+1);
+ glu.xlsub.resize(n+1);
+ glu.xlusup.resize(n+1);
+ glu.xusub.resize(n+1);
+
+ // Reserve memory for L/U factors
+ do
+ {
+ if( (expand<ScalarVector>(glu.lusup, glu.nzlumax, 0, 0, num_expansions)<0)
+ || (expand<ScalarVector>(glu.ucol, glu.nzumax, 0, 0, num_expansions)<0)
+ || (expand<IndexVector> (glu.lsub, glu.nzlmax, 0, 0, num_expansions)<0)
+ || (expand<IndexVector> (glu.usub, glu.nzumax, 0, 1, num_expansions)<0) )
+ {
+ //Reduce the estimated size and retry
+ glu.nzlumax /= 2;
+ glu.nzumax /= 2;
+ glu.nzlmax /= 2;
+ if (glu.nzlumax < annz ) return glu.nzlumax;
+ }
+ } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size());
+
+ ++num_expansions;
+ return 0;
+
+} // end LuMemInit
+
+/**
+ * \brief Expand the existing storage
+ * \param vec vector to expand
+ * \param[in,out] maxlen On input, previous size of vec (Number of elements to copy ). on output, new size
+ * \param nbElts current number of elements in the vector.
+ * \param memtype Type of the element to expand
+ * \param num_expansions Number of expansions
+ * \return 0 on success, > 0 size of the memory allocated so far
+ */
+template <typename Scalar, typename Index>
+template <typename VectorType>
+Index SparseLUImpl<Scalar,Index>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions)
+{
+ Index failed_size;
+ if (memtype == USUB)
+ failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
+ else
+ failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 0, num_expansions);
+
+ if (failed_size)
+ return failed_size;
+
+ return 0 ;
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif // EIGEN_SPARSELU_MEMORY
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Structs.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Structs.h
new file mode 100644
index 00000000000..24d6bf17946
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Structs.h
@@ -0,0 +1,111 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+ * NOTE: This file comes from a partly modified version of files slu_[s,d,c,z]defs.h
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ *
+ * Global data structures used in LU factorization -
+ *
+ * nsuper: #supernodes = nsuper + 1, numbered [0, nsuper].
+ * (xsup,supno): supno[i] is the supernode no to which i belongs;
+ * xsup(s) points to the beginning of the s-th supernode.
+ * e.g. supno 0 1 2 2 3 3 3 4 4 4 4 4 (n=12)
+ * xsup 0 1 2 4 7 12
+ * Note: dfs will be performed on supernode rep. relative to the new
+ * row pivoting ordering
+ *
+ * (xlsub,lsub): lsub[*] contains the compressed subscript of
+ * rectangular supernodes; xlsub[j] points to the starting
+ * location of the j-th column in lsub[*]. Note that xlsub
+ * is indexed by column.
+ * Storage: original row subscripts
+ *
+ * During the course of sparse LU factorization, we also use
+ * (xlsub,lsub) for the purpose of symmetric pruning. For each
+ * supernode {s,s+1,...,t=s+r} with first column s and last
+ * column t, the subscript set
+ * lsub[j], j=xlsub[s], .., xlsub[s+1]-1
+ * is the structure of column s (i.e. structure of this supernode).
+ * It is used for the storage of numerical values.
+ * Furthermore,
+ * lsub[j], j=xlsub[t], .., xlsub[t+1]-1
+ * is the structure of the last column t of this supernode.
+ * It is for the purpose of symmetric pruning. Therefore, the
+ * structural subscripts can be rearranged without making physical
+ * interchanges among the numerical values.
+ *
+ * However, if the supernode has only one column, then we
+ * only keep one set of subscripts. For any subscript interchange
+ * performed, similar interchange must be done on the numerical
+ * values.
+ *
+ * The last column structures (for pruning) will be removed
+ * after the numercial LU factorization phase.
+ *
+ * (xlusup,lusup): lusup[*] contains the numerical values of the
+ * rectangular supernodes; xlusup[j] points to the starting
+ * location of the j-th column in storage vector lusup[*]
+ * Note: xlusup is indexed by column.
+ * Each rectangular supernode is stored by column-major
+ * scheme, consistent with Fortran 2-dim array storage.
+ *
+ * (xusub,ucol,usub): ucol[*] stores the numerical values of
+ * U-columns outside the rectangular supernodes. The row
+ * subscript of nonzero ucol[k] is stored in usub[k].
+ * xusub[i] points to the starting location of column i in ucol.
+ * Storage: new row subscripts; that is subscripts of PA.
+ */
+
+#ifndef EIGEN_LU_STRUCTS
+#define EIGEN_LU_STRUCTS
+namespace Eigen {
+namespace internal {
+
+typedef enum {LUSUP, UCOL, LSUB, USUB, LLVL, ULVL} MemType;
+
+template <typename IndexVector, typename ScalarVector>
+struct LU_GlobalLU_t {
+ typedef typename IndexVector::Scalar Index;
+ IndexVector xsup; //First supernode column ... xsup(s) points to the beginning of the s-th supernode
+ IndexVector supno; // Supernode number corresponding to this column (column to supernode mapping)
+ ScalarVector lusup; // nonzero values of L ordered by columns
+ IndexVector lsub; // Compressed row indices of L rectangular supernodes.
+ IndexVector xlusup; // pointers to the beginning of each column in lusup
+ IndexVector xlsub; // pointers to the beginning of each column in lsub
+ Index nzlmax; // Current max size of lsub
+ Index nzlumax; // Current max size of lusup
+ ScalarVector ucol; // nonzero values of U ordered by columns
+ IndexVector usub; // row indices of U columns in ucol
+ IndexVector xusub; // Pointers to the beginning of each column of U in ucol
+ Index nzumax; // Current max size of ucol
+ Index n; // Number of columns in the matrix
+ Index num_expansions;
+};
+
+// Values to set for performance
+template <typename Index>
+struct perfvalues {
+ Index panel_size; // a panel consists of at most <panel_size> consecutive columns
+ Index relax; // To control degree of relaxing supernodes. If the number of nodes (columns)
+ // in a subtree of the elimination tree is less than relax, this subtree is considered
+ // as one supernode regardless of the row structures of those columns
+ Index maxsuper; // The maximum size for a supernode in complete LU
+ Index rowblk; // The minimum row dimension for 2-D blocking to be used;
+ Index colblk; // The minimum column dimension for 2-D blocking to be used;
+ Index fillfactor; // The estimated fills factors for L and U, compared with A
+};
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif // EIGEN_LU_STRUCTS
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
new file mode 100644
index 00000000000..ad6f2183fed
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
@@ -0,0 +1,298 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSELU_SUPERNODAL_MATRIX_H
+#define EIGEN_SPARSELU_SUPERNODAL_MATRIX_H
+
+namespace Eigen {
+namespace internal {
+
+/** \ingroup SparseLU_Module
+ * \brief a class to manipulate the L supernodal factor from the SparseLU factorization
+ *
+ * This class contain the data to easily store
+ * and manipulate the supernodes during the factorization and solution phase of Sparse LU.
+ * Only the lower triangular matrix has supernodes.
+ *
+ * NOTE : This class corresponds to the SCformat structure in SuperLU
+ *
+ */
+/* TODO
+ * InnerIterator as for sparsematrix
+ * SuperInnerIterator to iterate through all supernodes
+ * Function for triangular solve
+ */
+template <typename _Scalar, typename _Index>
+class MappedSuperNodalMatrix
+{
+ public:
+ typedef _Scalar Scalar;
+ typedef _Index Index;
+ typedef Matrix<Index,Dynamic,1> IndexVector;
+ typedef Matrix<Scalar,Dynamic,1> ScalarVector;
+ public:
+ MappedSuperNodalMatrix()
+ {
+
+ }
+ MappedSuperNodalMatrix(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind,
+ IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col )
+ {
+ setInfos(m, n, nzval, nzval_colptr, rowind, rowind_colptr, col_to_sup, sup_to_col);
+ }
+
+ ~MappedSuperNodalMatrix()
+ {
+
+ }
+ /**
+ * Set appropriate pointers for the lower triangular supernodal matrix
+ * These infos are available at the end of the numerical factorization
+ * FIXME This class will be modified such that it can be use in the course
+ * of the factorization.
+ */
+ void setInfos(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind,
+ IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col )
+ {
+ m_row = m;
+ m_col = n;
+ m_nzval = nzval.data();
+ m_nzval_colptr = nzval_colptr.data();
+ m_rowind = rowind.data();
+ m_rowind_colptr = rowind_colptr.data();
+ m_nsuper = col_to_sup(n);
+ m_col_to_sup = col_to_sup.data();
+ m_sup_to_col = sup_to_col.data();
+ }
+
+ /**
+ * Number of rows
+ */
+ Index rows() { return m_row; }
+
+ /**
+ * Number of columns
+ */
+ Index cols() { return m_col; }
+
+ /**
+ * Return the array of nonzero values packed by column
+ *
+ * The size is nnz
+ */
+ Scalar* valuePtr() { return m_nzval; }
+
+ const Scalar* valuePtr() const
+ {
+ return m_nzval;
+ }
+ /**
+ * Return the pointers to the beginning of each column in \ref valuePtr()
+ */
+ Index* colIndexPtr()
+ {
+ return m_nzval_colptr;
+ }
+
+ const Index* colIndexPtr() const
+ {
+ return m_nzval_colptr;
+ }
+
+ /**
+ * Return the array of compressed row indices of all supernodes
+ */
+ Index* rowIndex() { return m_rowind; }
+
+ const Index* rowIndex() const
+ {
+ return m_rowind;
+ }
+
+ /**
+ * Return the location in \em rowvaluePtr() which starts each column
+ */
+ Index* rowIndexPtr() { return m_rowind_colptr; }
+
+ const Index* rowIndexPtr() const
+ {
+ return m_rowind_colptr;
+ }
+
+ /**
+ * Return the array of column-to-supernode mapping
+ */
+ Index* colToSup() { return m_col_to_sup; }
+
+ const Index* colToSup() const
+ {
+ return m_col_to_sup;
+ }
+ /**
+ * Return the array of supernode-to-column mapping
+ */
+ Index* supToCol() { return m_sup_to_col; }
+
+ const Index* supToCol() const
+ {
+ return m_sup_to_col;
+ }
+
+ /**
+ * Return the number of supernodes
+ */
+ Index nsuper() const
+ {
+ return m_nsuper;
+ }
+
+ class InnerIterator;
+ template<typename Dest>
+ void solveInPlace( MatrixBase<Dest>&X) const;
+
+
+
+
+ protected:
+ Index m_row; // Number of rows
+ Index m_col; // Number of columns
+ Index m_nsuper; // Number of supernodes
+ Scalar* m_nzval; //array of nonzero values packed by column
+ Index* m_nzval_colptr; //nzval_colptr[j] Stores the location in nzval[] which starts column j
+ Index* m_rowind; // Array of compressed row indices of rectangular supernodes
+ Index* m_rowind_colptr; //rowind_colptr[j] stores the location in rowind[] which starts column j
+ Index* m_col_to_sup; // col_to_sup[j] is the supernode number to which column j belongs
+ Index* m_sup_to_col; //sup_to_col[s] points to the starting column of the s-th supernode
+
+ private :
+};
+
+/**
+ * \brief InnerIterator class to iterate over nonzero values of the current column in the supernodal matrix L
+ *
+ */
+template<typename Scalar, typename Index>
+class MappedSuperNodalMatrix<Scalar,Index>::InnerIterator
+{
+ public:
+ InnerIterator(const MappedSuperNodalMatrix& mat, Index outer)
+ : m_matrix(mat),
+ m_outer(outer),
+ m_supno(mat.colToSup()[outer]),
+ m_idval(mat.colIndexPtr()[outer]),
+ m_startidval(m_idval),
+ m_endidval(mat.colIndexPtr()[outer+1]),
+ m_idrow(mat.rowIndexPtr()[outer]),
+ m_endidrow(mat.rowIndexPtr()[outer+1])
+ {}
+ inline InnerIterator& operator++()
+ {
+ m_idval++;
+ m_idrow++;
+ return *this;
+ }
+ inline Scalar value() const { return m_matrix.valuePtr()[m_idval]; }
+
+ inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_idval]); }
+
+ inline Index index() const { return m_matrix.rowIndex()[m_idrow]; }
+ inline Index row() const { return index(); }
+ inline Index col() const { return m_outer; }
+
+ inline Index supIndex() const { return m_supno; }
+
+ inline operator bool() const
+ {
+ return ( (m_idval < m_endidval) && (m_idval >= m_startidval)
+ && (m_idrow < m_endidrow) );
+ }
+
+ protected:
+ const MappedSuperNodalMatrix& m_matrix; // Supernodal lower triangular matrix
+ const Index m_outer; // Current column
+ const Index m_supno; // Current SuperNode number
+ Index m_idval; // Index to browse the values in the current column
+ const Index m_startidval; // Start of the column value
+ const Index m_endidval; // End of the column value
+ Index m_idrow; // Index to browse the row indices
+ Index m_endidrow; // End index of row indices of the current column
+};
+
+/**
+ * \brief Solve with the supernode triangular matrix
+ *
+ */
+template<typename Scalar, typename Index>
+template<typename Dest>
+void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) const
+{
+ Index n = X.rows();
+ Index nrhs = X.cols();
+ const Scalar * Lval = valuePtr(); // Nonzero values
+ Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector
+ work.setZero();
+ for (Index k = 0; k <= nsuper(); k ++)
+ {
+ Index fsupc = supToCol()[k]; // First column of the current supernode
+ Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column
+ Index nsupr = rowIndexPtr()[fsupc+1] - istart; // Number of rows in the current supernode
+ Index nsupc = supToCol()[k+1] - fsupc; // Number of columns in the current supernode
+ Index nrow = nsupr - nsupc; // Number of rows in the non-diagonal part of the supernode
+ Index irow; //Current index row
+
+ if (nsupc == 1 )
+ {
+ for (Index j = 0; j < nrhs; j++)
+ {
+ InnerIterator it(*this, fsupc);
+ ++it; // Skip the diagonal element
+ for (; it; ++it)
+ {
+ irow = it.row();
+ X(irow, j) -= X(fsupc, j) * it.value();
+ }
+ }
+ }
+ else
+ {
+ // The supernode has more than one column
+ Index luptr = colIndexPtr()[fsupc];
+ Index lda = colIndexPtr()[fsupc+1] - luptr;
+
+ // Triangular solve
+ Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) );
+ Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
+ U = A.template triangularView<UnitLower>().solve(U);
+
+ // Matrix-vector product
+ new (&A) Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
+ work.block(0, 0, nrow, nrhs) = A * U;
+
+ //Begin Scatter
+ for (Index j = 0; j < nrhs; j++)
+ {
+ Index iptr = istart + nsupc;
+ for (Index i = 0; i < nrow; i++)
+ {
+ irow = rowIndex()[iptr];
+ X(irow, j) -= work(i, j); // Scatter operation
+ work(i, j) = Scalar(0);
+ iptr++;
+ }
+ }
+ }
+ }
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+
+#endif // EIGEN_SPARSELU_MATRIX_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Utils.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Utils.h
new file mode 100644
index 00000000000..15352ac33ae
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_Utils.h
@@ -0,0 +1,80 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#ifndef EIGEN_SPARSELU_UTILS_H
+#define EIGEN_SPARSELU_UTILS_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Count Nonzero elements in the factors
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu)
+{
+ nnzL = 0;
+ nnzU = (glu.xusub)(n);
+ Index nsuper = (glu.supno)(n);
+ Index jlen;
+ Index i, j, fsupc;
+ if (n <= 0 ) return;
+ // For each supernode
+ for (i = 0; i <= nsuper; i++)
+ {
+ fsupc = glu.xsup(i);
+ jlen = glu.xlsub(fsupc+1) - glu.xlsub(fsupc);
+
+ for (j = fsupc; j < glu.xsup(i+1); j++)
+ {
+ nnzL += jlen;
+ nnzU += j - fsupc + 1;
+ jlen--;
+ }
+ }
+}
+
+/**
+ * \brief Fix up the data storage lsub for L-subscripts.
+ *
+ * It removes the subscripts sets for structural pruning,
+ * and applies permutation to the remaining subscripts
+ *
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu)
+{
+ Index fsupc, i, j, k, jstart;
+
+ Index nextl = 0;
+ Index nsuper = (glu.supno)(n);
+
+ // For each supernode
+ for (i = 0; i <= nsuper; i++)
+ {
+ fsupc = glu.xsup(i);
+ jstart = glu.xlsub(fsupc);
+ glu.xlsub(fsupc) = nextl;
+ for (j = jstart; j < glu.xlsub(fsupc + 1); j++)
+ {
+ glu.lsub(nextl) = perm_r(glu.lsub(j)); // Now indexed into P*A
+ nextl++;
+ }
+ for (k = fsupc+1; k < glu.xsup(i+1); k++)
+ glu.xlsub(k) = nextl; // other columns in supernode i
+ }
+
+ glu.xlsub(n) = nextl;
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif // EIGEN_SPARSELU_UTILS_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h
new file mode 100644
index 00000000000..f24bd87d3e9
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h
@@ -0,0 +1,180 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of xcolumn_bmod.c file in SuperLU
+
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_COLUMN_BMOD_H
+#define SPARSELU_COLUMN_BMOD_H
+
+namespace Eigen {
+
+namespace internal {
+/**
+ * \brief Performs numeric block updates (sup-col) in topological order
+ *
+ * \param jcol current column to update
+ * \param nseg Number of segments in the U part
+ * \param dense Store the full representation of the column
+ * \param tempv working array
+ * \param segrep segment representative ...
+ * \param repfnz ??? First nonzero column in each row ??? ...
+ * \param fpanelc First column in the current panel
+ * \param glu Global LU data.
+ * \return 0 - successful return
+ * > 0 - number of bytes allocated when run out of space
+ *
+ */
+template <typename Scalar, typename Index>
+Index SparseLUImpl<Scalar,Index>::column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu)
+{
+ Index jsupno, k, ksub, krep, ksupno;
+ Index lptr, nrow, isub, irow, nextlu, new_next, ufirst;
+ Index fsupc, nsupc, nsupr, luptr, kfnz, no_zeros;
+ /* krep = representative of current k-th supernode
+ * fsupc = first supernodal column
+ * nsupc = number of columns in a supernode
+ * nsupr = number of rows in a supernode
+ * luptr = location of supernodal LU-block in storage
+ * kfnz = first nonz in the k-th supernodal segment
+ * no_zeros = no lf leading zeros in a supernodal U-segment
+ */
+
+ jsupno = glu.supno(jcol);
+ // For each nonzero supernode segment of U[*,j] in topological order
+ k = nseg - 1;
+ Index d_fsupc; // distance between the first column of the current panel and the
+ // first column of the current snode
+ Index fst_col; // First column within small LU update
+ Index segsize;
+ for (ksub = 0; ksub < nseg; ksub++)
+ {
+ krep = segrep(k); k--;
+ ksupno = glu.supno(krep);
+ if (jsupno != ksupno )
+ {
+ // outside the rectangular supernode
+ fsupc = glu.xsup(ksupno);
+ fst_col = (std::max)(fsupc, fpanelc);
+
+ // Distance from the current supernode to the current panel;
+ // d_fsupc = 0 if fsupc > fpanelc
+ d_fsupc = fst_col - fsupc;
+
+ luptr = glu.xlusup(fst_col) + d_fsupc;
+ lptr = glu.xlsub(fsupc) + d_fsupc;
+
+ kfnz = repfnz(krep);
+ kfnz = (std::max)(kfnz, fpanelc);
+
+ segsize = krep - kfnz + 1;
+ nsupc = krep - fst_col + 1;
+ nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc);
+ nrow = nsupr - d_fsupc - nsupc;
+ Index lda = glu.xlusup(fst_col+1) - glu.xlusup(fst_col);
+
+
+ // Perform a triangular solver and block update,
+ // then scatter the result of sup-col update to dense
+ no_zeros = kfnz - fst_col;
+ if(segsize==1)
+ LU_kernel_bmod<1>::run(segsize, dense, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ else
+ LU_kernel_bmod<Dynamic>::run(segsize, dense, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ } // end if jsupno
+ } // end for each segment
+
+ // Process the supernodal portion of L\U[*,j]
+ nextlu = glu.xlusup(jcol);
+ fsupc = glu.xsup(jsupno);
+
+ // copy the SPA dense into L\U[*,j]
+ Index mem;
+ new_next = nextlu + glu.xlsub(fsupc + 1) - glu.xlsub(fsupc);
+ Index offset = internal::first_multiple<Index>(new_next, internal::packet_traits<Scalar>::size) - new_next;
+ if(offset)
+ new_next += offset;
+ while (new_next > glu.nzlumax )
+ {
+ mem = memXpand<ScalarVector>(glu.lusup, glu.nzlumax, nextlu, LUSUP, glu.num_expansions);
+ if (mem) return mem;
+ }
+
+ for (isub = glu.xlsub(fsupc); isub < glu.xlsub(fsupc+1); isub++)
+ {
+ irow = glu.lsub(isub);
+ glu.lusup(nextlu) = dense(irow);
+ dense(irow) = Scalar(0.0);
+ ++nextlu;
+ }
+
+ if(offset)
+ {
+ glu.lusup.segment(nextlu,offset).setZero();
+ nextlu += offset;
+ }
+ glu.xlusup(jcol + 1) = nextlu; // close L\U(*,jcol);
+
+ /* For more updates within the panel (also within the current supernode),
+ * should start from the first column of the panel, or the first column
+ * of the supernode, whichever is bigger. There are two cases:
+ * 1) fsupc < fpanelc, then fst_col <-- fpanelc
+ * 2) fsupc >= fpanelc, then fst_col <-- fsupc
+ */
+ fst_col = (std::max)(fsupc, fpanelc);
+
+ if (fst_col < jcol)
+ {
+ // Distance between the current supernode and the current panel
+ // d_fsupc = 0 if fsupc >= fpanelc
+ d_fsupc = fst_col - fsupc;
+
+ lptr = glu.xlsub(fsupc) + d_fsupc;
+ luptr = glu.xlusup(fst_col) + d_fsupc;
+ nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); // leading dimension
+ nsupc = jcol - fst_col; // excluding jcol
+ nrow = nsupr - d_fsupc - nsupc;
+
+ // points to the beginning of jcol in snode L\U(jsupno)
+ ufirst = glu.xlusup(jcol) + d_fsupc;
+ Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol);
+ Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
+ VectorBlock<ScalarVector> u(glu.lusup, ufirst, nsupc);
+ u = A.template triangularView<UnitLower>().solve(u);
+
+ new (&A) Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
+ VectorBlock<ScalarVector> l(glu.lusup, ufirst+nsupc, nrow);
+ l.noalias() -= A * u;
+
+ } // End if fst_col
+ return 0;
+}
+
+} // end namespace internal
+} // end namespace Eigen
+
+#endif // SPARSELU_COLUMN_BMOD_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h
new file mode 100644
index 00000000000..4c04b0e44e9
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h
@@ -0,0 +1,177 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]column_dfs.c file in SuperLU
+
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_COLUMN_DFS_H
+#define SPARSELU_COLUMN_DFS_H
+
+template <typename Scalar, typename Index> class SparseLUImpl;
+namespace Eigen {
+
+namespace internal {
+
+template<typename IndexVector, typename ScalarVector>
+struct column_dfs_traits : no_assignment_operator
+{
+ typedef typename ScalarVector::Scalar Scalar;
+ typedef typename IndexVector::Scalar Index;
+ column_dfs_traits(Index jcol, Index& jsuper, typename SparseLUImpl<Scalar, Index>::GlobalLU_t& glu, SparseLUImpl<Scalar, Index>& luImpl)
+ : m_jcol(jcol), m_jsuper_ref(jsuper), m_glu(glu), m_luImpl(luImpl)
+ {}
+ bool update_segrep(Index /*krep*/, Index /*jj*/)
+ {
+ return true;
+ }
+ void mem_expand(IndexVector& lsub, Index& nextl, Index chmark)
+ {
+ if (nextl >= m_glu.nzlmax)
+ m_luImpl.memXpand(lsub, m_glu.nzlmax, nextl, LSUB, m_glu.num_expansions);
+ if (chmark != (m_jcol-1)) m_jsuper_ref = emptyIdxLU;
+ }
+ enum { ExpandMem = true };
+
+ Index m_jcol;
+ Index& m_jsuper_ref;
+ typename SparseLUImpl<Scalar, Index>::GlobalLU_t& m_glu;
+ SparseLUImpl<Scalar, Index>& m_luImpl;
+};
+
+
+/**
+ * \brief Performs a symbolic factorization on column jcol and decide the supernode boundary
+ *
+ * A supernode representative is the last column of a supernode.
+ * The nonzeros in U[*,j] are segments that end at supernodes representatives.
+ * The routine returns a list of the supernodal representatives
+ * in topological order of the dfs that generates them.
+ * The location of the first nonzero in each supernodal segment
+ * (supernodal entry location) is also returned.
+ *
+ * \param m number of rows in the matrix
+ * \param jcol Current column
+ * \param perm_r Row permutation
+ * \param maxsuper Maximum number of column allowed in a supernode
+ * \param [in,out] nseg Number of segments in current U[*,j] - new segments appended
+ * \param lsub_col defines the rhs vector to start the dfs
+ * \param [in,out] segrep Segment representatives - new segments appended
+ * \param repfnz First nonzero location in each row
+ * \param xprune
+ * \param marker marker[i] == jj, if i was visited during dfs of current column jj;
+ * \param parent
+ * \param xplore working array
+ * \param glu global LU data
+ * \return 0 success
+ * > 0 number of bytes allocated when run out of space
+ *
+ */
+template <typename Scalar, typename Index>
+Index SparseLUImpl<Scalar,Index>::column_dfs(const Index m, const Index jcol, IndexVector& perm_r, Index maxsuper, Index& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu)
+{
+
+ Index jsuper = glu.supno(jcol);
+ Index nextl = glu.xlsub(jcol);
+ VectorBlock<IndexVector> marker2(marker, 2*m, m);
+
+
+ column_dfs_traits<IndexVector, ScalarVector> traits(jcol, jsuper, glu, *this);
+
+ // For each nonzero in A(*,jcol) do dfs
+ for (Index k = 0; ((k < m) ? lsub_col[k] != emptyIdxLU : false) ; k++)
+ {
+ Index krow = lsub_col(k);
+ lsub_col(k) = emptyIdxLU;
+ Index kmark = marker2(krow);
+
+ // krow was visited before, go to the next nonz;
+ if (kmark == jcol) continue;
+
+ dfs_kernel(jcol, perm_r, nseg, glu.lsub, segrep, repfnz, xprune, marker2, parent,
+ xplore, glu, nextl, krow, traits);
+ } // for each nonzero ...
+
+ Index fsupc, jptr, jm1ptr, ito, ifrom, istop;
+ Index nsuper = glu.supno(jcol);
+ Index jcolp1 = jcol + 1;
+ Index jcolm1 = jcol - 1;
+
+ // check to see if j belongs in the same supernode as j-1
+ if ( jcol == 0 )
+ { // Do nothing for column 0
+ nsuper = glu.supno(0) = 0 ;
+ }
+ else
+ {
+ fsupc = glu.xsup(nsuper);
+ jptr = glu.xlsub(jcol); // Not yet compressed
+ jm1ptr = glu.xlsub(jcolm1);
+
+ // Use supernodes of type T2 : see SuperLU paper
+ if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = emptyIdxLU;
+
+ // Make sure the number of columns in a supernode doesn't
+ // exceed threshold
+ if ( (jcol - fsupc) >= maxsuper) jsuper = emptyIdxLU;
+
+ /* If jcol starts a new supernode, reclaim storage space in
+ * glu.lsub from previous supernode. Note we only store
+ * the subscript set of the first and last columns of
+ * a supernode. (first for num values, last for pruning)
+ */
+ if (jsuper == emptyIdxLU)
+ { // starts a new supernode
+ if ( (fsupc < jcolm1-1) )
+ { // >= 3 columns in nsuper
+ ito = glu.xlsub(fsupc+1);
+ glu.xlsub(jcolm1) = ito;
+ istop = ito + jptr - jm1ptr;
+ xprune(jcolm1) = istop; // intialize xprune(jcol-1)
+ glu.xlsub(jcol) = istop;
+
+ for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito)
+ glu.lsub(ito) = glu.lsub(ifrom);
+ nextl = ito; // = istop + length(jcol)
+ }
+ nsuper++;
+ glu.supno(jcol) = nsuper;
+ } // if a new supernode
+ } // end else: jcol > 0
+
+ // Tidy up the pointers before exit
+ glu.xsup(nsuper+1) = jcolp1;
+ glu.supno(jcolp1) = nsuper;
+ xprune(jcol) = nextl; // Intialize upper bound for pruning
+ glu.xlsub(jcolp1) = nextl;
+
+ return 0;
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
new file mode 100644
index 00000000000..170610d9f29
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
@@ -0,0 +1,106 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]copy_to_ucol.c file in SuperLU
+
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_COPY_TO_UCOL_H
+#define SPARSELU_COPY_TO_UCOL_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Performs numeric block updates (sup-col) in topological order
+ *
+ * \param jcol current column to update
+ * \param nseg Number of segments in the U part
+ * \param segrep segment representative ...
+ * \param repfnz First nonzero column in each row ...
+ * \param perm_r Row permutation
+ * \param dense Store the full representation of the column
+ * \param glu Global LU data.
+ * \return 0 - successful return
+ * > 0 - number of bytes allocated when run out of space
+ *
+ */
+template <typename Scalar, typename Index>
+Index SparseLUImpl<Scalar,Index>::copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu)
+{
+ Index ksub, krep, ksupno;
+
+ Index jsupno = glu.supno(jcol);
+
+ // For each nonzero supernode segment of U[*,j] in topological order
+ Index k = nseg - 1, i;
+ Index nextu = glu.xusub(jcol);
+ Index kfnz, isub, segsize;
+ Index new_next,irow;
+ Index fsupc, mem;
+ for (ksub = 0; ksub < nseg; ksub++)
+ {
+ krep = segrep(k); k--;
+ ksupno = glu.supno(krep);
+ if (jsupno != ksupno ) // should go into ucol();
+ {
+ kfnz = repfnz(krep);
+ if (kfnz != emptyIdxLU)
+ { // Nonzero U-segment
+ fsupc = glu.xsup(ksupno);
+ isub = glu.xlsub(fsupc) + kfnz - fsupc;
+ segsize = krep - kfnz + 1;
+ new_next = nextu + segsize;
+ while (new_next > glu.nzumax)
+ {
+ mem = memXpand<ScalarVector>(glu.ucol, glu.nzumax, nextu, UCOL, glu.num_expansions);
+ if (mem) return mem;
+ mem = memXpand<IndexVector>(glu.usub, glu.nzumax, nextu, USUB, glu.num_expansions);
+ if (mem) return mem;
+
+ }
+
+ for (i = 0; i < segsize; i++)
+ {
+ irow = glu.lsub(isub);
+ glu.usub(nextu) = perm_r(irow); // Unlike the L part, the U part is stored in its final order
+ glu.ucol(nextu) = dense(irow);
+ dense(irow) = Scalar(0.0);
+ nextu++;
+ isub++;
+ }
+
+ } // end nonzero U-segment
+
+ } // end if jsupno
+
+ } // end for each segment
+ glu.xusub(jcol + 1) = nextu; // close U(*,jcol)
+ return 0;
+}
+
+} // namespace internal
+} // end namespace Eigen
+
+#endif // SPARSELU_COPY_TO_UCOL_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
new file mode 100644
index 00000000000..9e4e3e72b70
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
@@ -0,0 +1,279 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSELU_GEMM_KERNEL_H
+#define EIGEN_SPARSELU_GEMM_KERNEL_H
+
+namespace Eigen {
+
+namespace internal {
+
+
+/** \internal
+ * A general matrix-matrix product kernel optimized for the SparseLU factorization.
+ * - A, B, and C must be column major
+ * - lda and ldc must be multiples of the respective packet size
+ * - C must have the same alignment as A
+ */
+template<typename Scalar,typename Index>
+EIGEN_DONT_INLINE
+void sparselu_gemm(Index m, Index n, Index d, const Scalar* A, Index lda, const Scalar* B, Index ldb, Scalar* C, Index ldc)
+{
+ using namespace Eigen::internal;
+
+ typedef typename packet_traits<Scalar>::type Packet;
+ enum {
+ NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS,
+ PacketSize = packet_traits<Scalar>::size,
+ PM = 8, // peeling in M
+ RN = 2, // register blocking
+ RK = NumberOfRegisters>=16 ? 4 : 2, // register blocking
+ BM = 4096/sizeof(Scalar), // number of rows of A-C per chunk
+ SM = PM*PacketSize // step along M
+ };
+ Index d_end = (d/RK)*RK; // number of columns of A (rows of B) suitable for full register blocking
+ Index n_end = (n/RN)*RN; // number of columns of B-C suitable for processing RN columns at once
+ Index i0 = internal::first_aligned(A,m);
+
+ eigen_internal_assert(((lda%PacketSize)==0) && ((ldc%PacketSize)==0) && (i0==internal::first_aligned(C,m)));
+
+ // handle the non aligned rows of A and C without any optimization:
+ for(Index i=0; i<i0; ++i)
+ {
+ for(Index j=0; j<n; ++j)
+ {
+ Scalar c = C[i+j*ldc];
+ for(Index k=0; k<d; ++k)
+ c += B[k+j*ldb] * A[i+k*lda];
+ C[i+j*ldc] = c;
+ }
+ }
+ // process the remaining rows per chunk of BM rows
+ for(Index ib=i0; ib<m; ib+=BM)
+ {
+ Index actual_b = std::min<Index>(BM, m-ib); // actual number of rows
+ Index actual_b_end1 = (actual_b/SM)*SM; // actual number of rows suitable for peeling
+ Index actual_b_end2 = (actual_b/PacketSize)*PacketSize; // actual number of rows suitable for vectorization
+
+ // Let's process two columns of B-C at once
+ for(Index j=0; j<n_end; j+=RN)
+ {
+ const Scalar* Bc0 = B+(j+0)*ldb;
+ const Scalar* Bc1 = B+(j+1)*ldb;
+
+ for(Index k=0; k<d_end; k+=RK)
+ {
+
+ // load and expand a RN x RK block of B
+ Packet b00, b10, b20, b30, b01, b11, b21, b31;
+ b00 = pset1<Packet>(Bc0[0]);
+ b10 = pset1<Packet>(Bc0[1]);
+ if(RK==4) b20 = pset1<Packet>(Bc0[2]);
+ if(RK==4) b30 = pset1<Packet>(Bc0[3]);
+ b01 = pset1<Packet>(Bc1[0]);
+ b11 = pset1<Packet>(Bc1[1]);
+ if(RK==4) b21 = pset1<Packet>(Bc1[2]);
+ if(RK==4) b31 = pset1<Packet>(Bc1[3]);
+
+ Packet a0, a1, a2, a3, c0, c1, t0, t1;
+
+ const Scalar* A0 = A+ib+(k+0)*lda;
+ const Scalar* A1 = A+ib+(k+1)*lda;
+ const Scalar* A2 = A+ib+(k+2)*lda;
+ const Scalar* A3 = A+ib+(k+3)*lda;
+
+ Scalar* C0 = C+ib+(j+0)*ldc;
+ Scalar* C1 = C+ib+(j+1)*ldc;
+
+ a0 = pload<Packet>(A0);
+ a1 = pload<Packet>(A1);
+ if(RK==4)
+ {
+ a2 = pload<Packet>(A2);
+ a3 = pload<Packet>(A3);
+ }
+ else
+ {
+ // workaround "may be used uninitialized in this function" warning
+ a2 = a3 = a0;
+ }
+
+#define KMADD(c, a, b, tmp) {tmp = b; tmp = pmul(a,tmp); c = padd(c,tmp);}
+#define WORK(I) \
+ c0 = pload<Packet>(C0+i+(I)*PacketSize); \
+ c1 = pload<Packet>(C1+i+(I)*PacketSize); \
+ KMADD(c0, a0, b00, t0) \
+ KMADD(c1, a0, b01, t1) \
+ a0 = pload<Packet>(A0+i+(I+1)*PacketSize); \
+ KMADD(c0, a1, b10, t0) \
+ KMADD(c1, a1, b11, t1) \
+ a1 = pload<Packet>(A1+i+(I+1)*PacketSize); \
+ if(RK==4) KMADD(c0, a2, b20, t0) \
+ if(RK==4) KMADD(c1, a2, b21, t1) \
+ if(RK==4) a2 = pload<Packet>(A2+i+(I+1)*PacketSize); \
+ if(RK==4) KMADD(c0, a3, b30, t0) \
+ if(RK==4) KMADD(c1, a3, b31, t1) \
+ if(RK==4) a3 = pload<Packet>(A3+i+(I+1)*PacketSize); \
+ pstore(C0+i+(I)*PacketSize, c0); \
+ pstore(C1+i+(I)*PacketSize, c1)
+
+ // process rows of A' - C' with aggressive vectorization and peeling
+ for(Index i=0; i<actual_b_end1; i+=PacketSize*8)
+ {
+ EIGEN_ASM_COMMENT("SPARSELU_GEMML_KERNEL1");
+ prefetch((A0+i+(5)*PacketSize));
+ prefetch((A1+i+(5)*PacketSize));
+ if(RK==4) prefetch((A2+i+(5)*PacketSize));
+ if(RK==4) prefetch((A3+i+(5)*PacketSize));
+ WORK(0);
+ WORK(1);
+ WORK(2);
+ WORK(3);
+ WORK(4);
+ WORK(5);
+ WORK(6);
+ WORK(7);
+ }
+ // process the remaining rows with vectorization only
+ for(Index i=actual_b_end1; i<actual_b_end2; i+=PacketSize)
+ {
+ WORK(0);
+ }
+#undef WORK
+ // process the remaining rows without vectorization
+ for(Index i=actual_b_end2; i<actual_b; ++i)
+ {
+ if(RK==4)
+ {
+ C0[i] += A0[i]*Bc0[0]+A1[i]*Bc0[1]+A2[i]*Bc0[2]+A3[i]*Bc0[3];
+ C1[i] += A0[i]*Bc1[0]+A1[i]*Bc1[1]+A2[i]*Bc1[2]+A3[i]*Bc1[3];
+ }
+ else
+ {
+ C0[i] += A0[i]*Bc0[0]+A1[i]*Bc0[1];
+ C1[i] += A0[i]*Bc1[0]+A1[i]*Bc1[1];
+ }
+ }
+
+ Bc0 += RK;
+ Bc1 += RK;
+ } // peeled loop on k
+ } // peeled loop on the columns j
+ // process the last column (we now perform a matrux-vector product)
+ if((n-n_end)>0)
+ {
+ const Scalar* Bc0 = B+(n-1)*ldb;
+
+ for(Index k=0; k<d_end; k+=RK)
+ {
+
+ // load and expand a 1 x RK block of B
+ Packet b00, b10, b20, b30;
+ b00 = pset1<Packet>(Bc0[0]);
+ b10 = pset1<Packet>(Bc0[1]);
+ if(RK==4) b20 = pset1<Packet>(Bc0[2]);
+ if(RK==4) b30 = pset1<Packet>(Bc0[3]);
+
+ Packet a0, a1, a2, a3, c0, t0/*, t1*/;
+
+ const Scalar* A0 = A+ib+(k+0)*lda;
+ const Scalar* A1 = A+ib+(k+1)*lda;
+ const Scalar* A2 = A+ib+(k+2)*lda;
+ const Scalar* A3 = A+ib+(k+3)*lda;
+
+ Scalar* C0 = C+ib+(n_end)*ldc;
+
+ a0 = pload<Packet>(A0);
+ a1 = pload<Packet>(A1);
+ if(RK==4)
+ {
+ a2 = pload<Packet>(A2);
+ a3 = pload<Packet>(A3);
+ }
+ else
+ {
+ // workaround "may be used uninitialized in this function" warning
+ a2 = a3 = a0;
+ }
+
+#define WORK(I) \
+ c0 = pload<Packet>(C0+i+(I)*PacketSize); \
+ KMADD(c0, a0, b00, t0) \
+ a0 = pload<Packet>(A0+i+(I+1)*PacketSize); \
+ KMADD(c0, a1, b10, t0) \
+ a1 = pload<Packet>(A1+i+(I+1)*PacketSize); \
+ if(RK==4) KMADD(c0, a2, b20, t0) \
+ if(RK==4) a2 = pload<Packet>(A2+i+(I+1)*PacketSize); \
+ if(RK==4) KMADD(c0, a3, b30, t0) \
+ if(RK==4) a3 = pload<Packet>(A3+i+(I+1)*PacketSize); \
+ pstore(C0+i+(I)*PacketSize, c0);
+
+ // agressive vectorization and peeling
+ for(Index i=0; i<actual_b_end1; i+=PacketSize*8)
+ {
+ EIGEN_ASM_COMMENT("SPARSELU_GEMML_KERNEL2");
+ WORK(0);
+ WORK(1);
+ WORK(2);
+ WORK(3);
+ WORK(4);
+ WORK(5);
+ WORK(6);
+ WORK(7);
+ }
+ // vectorization only
+ for(Index i=actual_b_end1; i<actual_b_end2; i+=PacketSize)
+ {
+ WORK(0);
+ }
+ // remaining scalars
+ for(Index i=actual_b_end2; i<actual_b; ++i)
+ {
+ if(RK==4)
+ C0[i] += A0[i]*Bc0[0]+A1[i]*Bc0[1]+A2[i]*Bc0[2]+A3[i]*Bc0[3];
+ else
+ C0[i] += A0[i]*Bc0[0]+A1[i]*Bc0[1];
+ }
+
+ Bc0 += RK;
+#undef WORK
+ }
+ }
+
+ // process the last columns of A, corresponding to the last rows of B
+ Index rd = d-d_end;
+ if(rd>0)
+ {
+ for(Index j=0; j<n; ++j)
+ {
+ enum {
+ Alignment = PacketSize>1 ? Aligned : 0
+ };
+ typedef Map<Matrix<Scalar,Dynamic,1>, Alignment > MapVector;
+ typedef Map<const Matrix<Scalar,Dynamic,1>, Alignment > ConstMapVector;
+ if(rd==1) MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b);
+
+ else if(rd==2) MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b)
+ + B[1+d_end+j*ldb] * ConstMapVector(A+(d_end+1)*lda+ib, actual_b);
+
+ else MapVector(C+j*ldc+ib,actual_b) += B[0+d_end+j*ldb] * ConstMapVector(A+(d_end+0)*lda+ib, actual_b)
+ + B[1+d_end+j*ldb] * ConstMapVector(A+(d_end+1)*lda+ib, actual_b)
+ + B[2+d_end+j*ldb] * ConstMapVector(A+(d_end+2)*lda+ib, actual_b);
+ }
+ }
+
+ } // blocking on the rows of A and C
+}
+#undef KMADD
+
+} // namespace internal
+
+} // namespace Eigen
+
+#endif // EIGEN_SPARSELU_GEMM_KERNEL_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
new file mode 100644
index 00000000000..7a4e4305aa9
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
@@ -0,0 +1,127 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/* This file is a modified version of heap_relax_snode.c file in SuperLU
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+
+#ifndef SPARSELU_HEAP_RELAX_SNODE_H
+#define SPARSELU_HEAP_RELAX_SNODE_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Identify the initial relaxed supernodes
+ *
+ * This routine applied to a symmetric elimination tree.
+ * It assumes that the matrix has been reordered according to the postorder of the etree
+ * \param n The number of columns
+ * \param et elimination tree
+ * \param relax_columns Maximum number of columns allowed in a relaxed snode
+ * \param descendants Number of descendants of each node in the etree
+ * \param relax_end last column in a supernode
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
+{
+
+ // The etree may not be postordered, but its heap ordered
+ IndexVector post;
+ internal::treePostorder(n, et, post); // Post order etree
+ IndexVector inv_post(n+1);
+ Index i;
+ for (i = 0; i < n+1; ++i) inv_post(post(i)) = i; // inv_post = post.inverse()???
+
+ // Renumber etree in postorder
+ IndexVector iwork(n);
+ IndexVector et_save(n+1);
+ for (i = 0; i < n; ++i)
+ {
+ iwork(post(i)) = post(et(i));
+ }
+ et_save = et; // Save the original etree
+ et = iwork;
+
+ // compute the number of descendants of each node in the etree
+ relax_end.setConstant(emptyIdxLU);
+ Index j, parent;
+ descendants.setZero();
+ for (j = 0; j < n; j++)
+ {
+ parent = et(j);
+ if (parent != n) // not the dummy root
+ descendants(parent) += descendants(j) + 1;
+ }
+ // Identify the relaxed supernodes by postorder traversal of the etree
+ Index snode_start; // beginning of a snode
+ Index k;
+ Index nsuper_et_post = 0; // Number of relaxed snodes in postordered etree
+ Index nsuper_et = 0; // Number of relaxed snodes in the original etree
+ Index l;
+ for (j = 0; j < n; )
+ {
+ parent = et(j);
+ snode_start = j;
+ while ( parent != n && descendants(parent) < relax_columns )
+ {
+ j = parent;
+ parent = et(j);
+ }
+ // Found a supernode in postordered etree, j is the last column
+ ++nsuper_et_post;
+ k = n;
+ for (i = snode_start; i <= j; ++i)
+ k = (std::min)(k, inv_post(i));
+ l = inv_post(j);
+ if ( (l - k) == (j - snode_start) ) // Same number of columns in the snode
+ {
+ // This is also a supernode in the original etree
+ relax_end(k) = l; // Record last column
+ ++nsuper_et;
+ }
+ else
+ {
+ for (i = snode_start; i <= j; ++i)
+ {
+ l = inv_post(i);
+ if (descendants(i) == 0)
+ {
+ relax_end(l) = l;
+ ++nsuper_et;
+ }
+ }
+ }
+ j++;
+ // Search for a new leaf
+ while (descendants(j) != 0 && j < n) j++;
+ } // End postorder traversal of the etree
+
+ // Recover the original etree
+ et = et_save;
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif // SPARSELU_HEAP_RELAX_SNODE_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
new file mode 100644
index 00000000000..0d0283b132b
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
@@ -0,0 +1,130 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef SPARSELU_KERNEL_BMOD_H
+#define SPARSELU_KERNEL_BMOD_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Performs numeric block updates from a given supernode to a single column
+ *
+ * \param segsize Size of the segment (and blocks ) to use for updates
+ * \param[in,out] dense Packed values of the original matrix
+ * \param tempv temporary vector to use for updates
+ * \param lusup array containing the supernodes
+ * \param lda Leading dimension in the supernode
+ * \param nrow Number of rows in the rectangular part of the supernode
+ * \param lsub compressed row subscripts of supernodes
+ * \param lptr pointer to the first column of the current supernode in lsub
+ * \param no_zeros Number of nonzeros elements before the diagonal part of the supernode
+ * \return 0 on success
+ */
+template <int SegSizeAtCompileTime> struct LU_kernel_bmod
+{
+ template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
+ static EIGEN_DONT_INLINE void run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, Index& luptr, const Index lda,
+ const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros);
+};
+
+template <int SegSizeAtCompileTime>
+template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
+EIGEN_DONT_INLINE void LU_kernel_bmod<SegSizeAtCompileTime>::run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, Index& luptr, const Index lda,
+ const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros)
+{
+ typedef typename ScalarVector::Scalar Scalar;
+ // First, copy U[*,j] segment from dense(*) to tempv(*)
+ // The result of triangular solve is in tempv[*];
+ // The result of matric-vector update is in dense[*]
+ Index isub = lptr + no_zeros;
+ int i;
+ Index irow;
+ for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++)
+ {
+ irow = lsub(isub);
+ tempv(i) = dense(irow);
+ ++isub;
+ }
+ // Dense triangular solve -- start effective triangle
+ luptr += lda * no_zeros + no_zeros;
+ // Form Eigen matrix and vector
+ Map<Matrix<Scalar,SegSizeAtCompileTime,SegSizeAtCompileTime>, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) );
+ Map<Matrix<Scalar,SegSizeAtCompileTime,1> > u(tempv.data(), segsize);
+
+ u = A.template triangularView<UnitLower>().solve(u);
+
+ // Dense matrix-vector product y <-- B*x
+ luptr += segsize;
+ const Index PacketSize = internal::packet_traits<Scalar>::size;
+ Index ldl = internal::first_multiple(nrow, PacketSize);
+ Map<Matrix<Scalar,Dynamic,SegSizeAtCompileTime>, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) );
+ Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize);
+ Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize;
+ Map<Matrix<Scalar,Dynamic,1>, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) );
+
+ l.setZero();
+ internal::sparselu_gemm<Scalar>(l.rows(), l.cols(), B.cols(), B.data(), B.outerStride(), u.data(), u.outerStride(), l.data(), l.outerStride());
+
+ // Scatter tempv[] into SPA dense[] as a temporary storage
+ isub = lptr + no_zeros;
+ for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++)
+ {
+ irow = lsub(isub++);
+ dense(irow) = tempv(i);
+ }
+
+ // Scatter l into SPA dense[]
+ for (i = 0; i < nrow; i++)
+ {
+ irow = lsub(isub++);
+ dense(irow) -= l(i);
+ }
+}
+
+template <> struct LU_kernel_bmod<1>
+{
+ template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
+ static EIGEN_DONT_INLINE void run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr,
+ const Index lda, const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros);
+};
+
+
+template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
+EIGEN_DONT_INLINE void LU_kernel_bmod<1>::run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr,
+ const Index lda, const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros)
+{
+ typedef typename ScalarVector::Scalar Scalar;
+ Scalar f = dense(lsub(lptr + no_zeros));
+ luptr += lda * no_zeros + no_zeros + 1;
+ const Scalar* a(lusup.data() + luptr);
+ const /*typename IndexVector::Scalar*/Index* irow(lsub.data()+lptr + no_zeros + 1);
+ Index i = 0;
+ for (; i+1 < nrow; i+=2)
+ {
+ Index i0 = *(irow++);
+ Index i1 = *(irow++);
+ Scalar a0 = *(a++);
+ Scalar a1 = *(a++);
+ Scalar d0 = dense.coeff(i0);
+ Scalar d1 = dense.coeff(i1);
+ d0 -= f*a0;
+ d1 -= f*a1;
+ dense.coeffRef(i0) = d0;
+ dense.coeffRef(i1) = d1;
+ }
+ if(i<nrow)
+ dense.coeffRef(*(irow++)) -= f * *(a++);
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif // SPARSELU_KERNEL_BMOD_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h
new file mode 100644
index 00000000000..da0e0fc3c60
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h
@@ -0,0 +1,223 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]panel_bmod.c file in SuperLU
+
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_PANEL_BMOD_H
+#define SPARSELU_PANEL_BMOD_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Performs numeric block updates (sup-panel) in topological order.
+ *
+ * Before entering this routine, the original nonzeros in the panel
+ * were already copied i nto the spa[m,w]
+ *
+ * \param m number of rows in the matrix
+ * \param w Panel size
+ * \param jcol Starting column of the panel
+ * \param nseg Number of segments in the U part
+ * \param dense Store the full representation of the panel
+ * \param tempv working array
+ * \param segrep segment representative... first row in the segment
+ * \param repfnz First nonzero rows
+ * \param glu Global LU data.
+ *
+ *
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::panel_bmod(const Index m, const Index w, const Index jcol,
+ const Index nseg, ScalarVector& dense, ScalarVector& tempv,
+ IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu)
+{
+
+ Index ksub,jj,nextl_col;
+ Index fsupc, nsupc, nsupr, nrow;
+ Index krep, kfnz;
+ Index lptr; // points to the row subscripts of a supernode
+ Index luptr; // ...
+ Index segsize,no_zeros ;
+ // For each nonz supernode segment of U[*,j] in topological order
+ Index k = nseg - 1;
+ const Index PacketSize = internal::packet_traits<Scalar>::size;
+
+ for (ksub = 0; ksub < nseg; ksub++)
+ { // For each updating supernode
+ /* krep = representative of current k-th supernode
+ * fsupc = first supernodal column
+ * nsupc = number of columns in a supernode
+ * nsupr = number of rows in a supernode
+ */
+ krep = segrep(k); k--;
+ fsupc = glu.xsup(glu.supno(krep));
+ nsupc = krep - fsupc + 1;
+ nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc);
+ nrow = nsupr - nsupc;
+ lptr = glu.xlsub(fsupc);
+
+ // loop over the panel columns to detect the actual number of columns and rows
+ Index u_rows = 0;
+ Index u_cols = 0;
+ for (jj = jcol; jj < jcol + w; jj++)
+ {
+ nextl_col = (jj-jcol) * m;
+ VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row
+
+ kfnz = repfnz_col(krep);
+ if ( kfnz == emptyIdxLU )
+ continue; // skip any zero segment
+
+ segsize = krep - kfnz + 1;
+ u_cols++;
+ u_rows = (std::max)(segsize,u_rows);
+ }
+
+ if(nsupc >= 2)
+ {
+ Index ldu = internal::first_multiple<Index>(u_rows, PacketSize);
+ Map<Matrix<Scalar,Dynamic,Dynamic>, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu));
+
+ // gather U
+ Index u_col = 0;
+ for (jj = jcol; jj < jcol + w; jj++)
+ {
+ nextl_col = (jj-jcol) * m;
+ VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row
+ VectorBlock<ScalarVector> dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here
+
+ kfnz = repfnz_col(krep);
+ if ( kfnz == emptyIdxLU )
+ continue; // skip any zero segment
+
+ segsize = krep - kfnz + 1;
+ luptr = glu.xlusup(fsupc);
+ no_zeros = kfnz - fsupc;
+
+ Index isub = lptr + no_zeros;
+ Index off = u_rows-segsize;
+ for (Index i = 0; i < off; i++) U(i,u_col) = 0;
+ for (Index i = 0; i < segsize; i++)
+ {
+ Index irow = glu.lsub(isub);
+ U(i+off,u_col) = dense_col(irow);
+ ++isub;
+ }
+ u_col++;
+ }
+ // solve U = A^-1 U
+ luptr = glu.xlusup(fsupc);
+ Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc);
+ no_zeros = (krep - u_rows + 1) - fsupc;
+ luptr += lda * no_zeros + no_zeros;
+ Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) );
+ U = A.template triangularView<UnitLower>().solve(U);
+
+ // update
+ luptr += u_rows;
+ Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) );
+ eigen_assert(tempv.size()>w*ldu + nrow*w + 1);
+
+ Index ldl = internal::first_multiple<Index>(nrow, PacketSize);
+ Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize;
+ Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl));
+
+ L.setZero();
+ internal::sparselu_gemm<Scalar>(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride());
+
+ // scatter U and L
+ u_col = 0;
+ for (jj = jcol; jj < jcol + w; jj++)
+ {
+ nextl_col = (jj-jcol) * m;
+ VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row
+ VectorBlock<ScalarVector> dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here
+
+ kfnz = repfnz_col(krep);
+ if ( kfnz == emptyIdxLU )
+ continue; // skip any zero segment
+
+ segsize = krep - kfnz + 1;
+ no_zeros = kfnz - fsupc;
+ Index isub = lptr + no_zeros;
+
+ Index off = u_rows-segsize;
+ for (Index i = 0; i < segsize; i++)
+ {
+ Index irow = glu.lsub(isub++);
+ dense_col(irow) = U.coeff(i+off,u_col);
+ U.coeffRef(i+off,u_col) = 0;
+ }
+
+ // Scatter l into SPA dense[]
+ for (Index i = 0; i < nrow; i++)
+ {
+ Index irow = glu.lsub(isub++);
+ dense_col(irow) -= L.coeff(i,u_col);
+ L.coeffRef(i,u_col) = 0;
+ }
+ u_col++;
+ }
+ }
+ else // level 2 only
+ {
+ // Sequence through each column in the panel
+ for (jj = jcol; jj < jcol + w; jj++)
+ {
+ nextl_col = (jj-jcol) * m;
+ VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m); // First nonzero column index for each row
+ VectorBlock<ScalarVector> dense_col(dense, nextl_col, m); // Scatter/gather entire matrix column from/to here
+
+ kfnz = repfnz_col(krep);
+ if ( kfnz == emptyIdxLU )
+ continue; // skip any zero segment
+
+ segsize = krep - kfnz + 1;
+ luptr = glu.xlusup(fsupc);
+
+ Index lda = glu.xlusup(fsupc+1)-glu.xlusup(fsupc);// nsupr
+
+ // Perform a trianglar solve and block update,
+ // then scatter the result of sup-col update to dense[]
+ no_zeros = kfnz - fsupc;
+ if(segsize==1) LU_kernel_bmod<1>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ else if(segsize==2) LU_kernel_bmod<2>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ else if(segsize==3) LU_kernel_bmod<3>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ else LU_kernel_bmod<Dynamic>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
+ } // End for each column in the panel
+ }
+
+ } // End for each updating supernode
+} // end panel bmod
+
+} // end namespace internal
+
+} // end namespace Eigen
+
+#endif // SPARSELU_PANEL_BMOD_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h
new file mode 100644
index 00000000000..dc0054efd25
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h
@@ -0,0 +1,258 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]panel_dfs.c file in SuperLU
+
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_PANEL_DFS_H
+#define SPARSELU_PANEL_DFS_H
+
+namespace Eigen {
+
+namespace internal {
+
+template<typename IndexVector>
+struct panel_dfs_traits
+{
+ typedef typename IndexVector::Scalar Index;
+ panel_dfs_traits(Index jcol, Index* marker)
+ : m_jcol(jcol), m_marker(marker)
+ {}
+ bool update_segrep(Index krep, Index jj)
+ {
+ if(m_marker[krep]<m_jcol)
+ {
+ m_marker[krep] = jj;
+ return true;
+ }
+ return false;
+ }
+ void mem_expand(IndexVector& /*glu.lsub*/, Index /*nextl*/, Index /*chmark*/) {}
+ enum { ExpandMem = false };
+ Index m_jcol;
+ Index* m_marker;
+};
+
+
+template <typename Scalar, typename Index>
+template <typename Traits>
+void SparseLUImpl<Scalar,Index>::dfs_kernel(const Index jj, IndexVector& perm_r,
+ Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
+ Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
+ IndexVector& xplore, GlobalLU_t& glu,
+ Index& nextl_col, Index krow, Traits& traits
+ )
+{
+
+ Index kmark = marker(krow);
+
+ // For each unmarked krow of jj
+ marker(krow) = jj;
+ Index kperm = perm_r(krow);
+ if (kperm == emptyIdxLU ) {
+ // krow is in L : place it in structure of L(*, jj)
+ panel_lsub(nextl_col++) = krow; // krow is indexed into A
+
+ traits.mem_expand(panel_lsub, nextl_col, kmark);
+ }
+ else
+ {
+ // krow is in U : if its supernode-representative krep
+ // has been explored, update repfnz(*)
+ // krep = supernode representative of the current row
+ Index krep = glu.xsup(glu.supno(kperm)+1) - 1;
+ // First nonzero element in the current column:
+ Index myfnz = repfnz_col(krep);
+
+ if (myfnz != emptyIdxLU )
+ {
+ // Representative visited before
+ if (myfnz > kperm ) repfnz_col(krep) = kperm;
+
+ }
+ else
+ {
+ // Otherwise, perform dfs starting at krep
+ Index oldrep = emptyIdxLU;
+ parent(krep) = oldrep;
+ repfnz_col(krep) = kperm;
+ Index xdfs = glu.xlsub(krep);
+ Index maxdfs = xprune(krep);
+
+ Index kpar;
+ do
+ {
+ // For each unmarked kchild of krep
+ while (xdfs < maxdfs)
+ {
+ Index kchild = glu.lsub(xdfs);
+ xdfs++;
+ Index chmark = marker(kchild);
+
+ if (chmark != jj )
+ {
+ marker(kchild) = jj;
+ Index chperm = perm_r(kchild);
+
+ if (chperm == emptyIdxLU)
+ {
+ // case kchild is in L: place it in L(*, j)
+ panel_lsub(nextl_col++) = kchild;
+ traits.mem_expand(panel_lsub, nextl_col, chmark);
+ }
+ else
+ {
+ // case kchild is in U :
+ // chrep = its supernode-rep. If its rep has been explored,
+ // update its repfnz(*)
+ Index chrep = glu.xsup(glu.supno(chperm)+1) - 1;
+ myfnz = repfnz_col(chrep);
+
+ if (myfnz != emptyIdxLU)
+ { // Visited before
+ if (myfnz > chperm)
+ repfnz_col(chrep) = chperm;
+ }
+ else
+ { // Cont. dfs at snode-rep of kchild
+ xplore(krep) = xdfs;
+ oldrep = krep;
+ krep = chrep; // Go deeper down G(L)
+ parent(krep) = oldrep;
+ repfnz_col(krep) = chperm;
+ xdfs = glu.xlsub(krep);
+ maxdfs = xprune(krep);
+
+ } // end if myfnz != -1
+ } // end if chperm == -1
+
+ } // end if chmark !=jj
+ } // end while xdfs < maxdfs
+
+ // krow has no more unexplored nbrs :
+ // Place snode-rep krep in postorder DFS, if this
+ // segment is seen for the first time. (Note that
+ // "repfnz(krep)" may change later.)
+ // Baktrack dfs to its parent
+ if(traits.update_segrep(krep,jj))
+ //if (marker1(krep) < jcol )
+ {
+ segrep(nseg) = krep;
+ ++nseg;
+ //marker1(krep) = jj;
+ }
+
+ kpar = parent(krep); // Pop recursion, mimic recursion
+ if (kpar == emptyIdxLU)
+ break; // dfs done
+ krep = kpar;
+ xdfs = xplore(krep);
+ maxdfs = xprune(krep);
+
+ } while (kpar != emptyIdxLU); // Do until empty stack
+
+ } // end if (myfnz = -1)
+
+ } // end if (kperm == -1)
+}
+
+/**
+ * \brief Performs a symbolic factorization on a panel of columns [jcol, jcol+w)
+ *
+ * A supernode representative is the last column of a supernode.
+ * The nonzeros in U[*,j] are segments that end at supernodes representatives
+ *
+ * The routine returns a list of the supernodal representatives
+ * in topological order of the dfs that generates them. This list is
+ * a superset of the topological order of each individual column within
+ * the panel.
+ * The location of the first nonzero in each supernodal segment
+ * (supernodal entry location) is also returned. Each column has
+ * a separate list for this purpose.
+ *
+ * Two markers arrays are used for dfs :
+ * marker[i] == jj, if i was visited during dfs of current column jj;
+ * marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ * \param[in] m number of rows in the matrix
+ * \param[in] w Panel size
+ * \param[in] jcol Starting column of the panel
+ * \param[in] A Input matrix in column-major storage
+ * \param[in] perm_r Row permutation
+ * \param[out] nseg Number of U segments
+ * \param[out] dense Accumulate the column vectors of the panel
+ * \param[out] panel_lsub Subscripts of the row in the panel
+ * \param[out] segrep Segment representative i.e first nonzero row of each segment
+ * \param[out] repfnz First nonzero location in each row
+ * \param[out] xprune The pruned elimination tree
+ * \param[out] marker work vector
+ * \param parent The elimination tree
+ * \param xplore work vector
+ * \param glu The global data structure
+ *
+ */
+
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu)
+{
+ Index nextl_col; // Next available position in panel_lsub[*,jj]
+
+ // Initialize pointers
+ VectorBlock<IndexVector> marker1(marker, m, m);
+ nseg = 0;
+
+ panel_dfs_traits<IndexVector> traits(jcol, marker1.data());
+
+ // For each column in the panel
+ for (Index jj = jcol; jj < jcol + w; jj++)
+ {
+ nextl_col = (jj - jcol) * m;
+
+ VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m); // First nonzero location in each row
+ VectorBlock<ScalarVector> dense_col(dense,nextl_col, m); // Accumulate a column vector here
+
+
+ // For each nnz in A[*, jj] do depth first search
+ for (typename MatrixType::InnerIterator it(A, jj); it; ++it)
+ {
+ Index krow = it.row();
+ dense_col(krow) = it.value();
+
+ Index kmark = marker(krow);
+ if (kmark == jj)
+ continue; // krow visited before, go to the next nonzero
+
+ dfs_kernel(jj, perm_r, nseg, panel_lsub, segrep, repfnz_col, xprune, marker, parent,
+ xplore, glu, nextl_col, krow, traits);
+ }// end for nonzeros in column jj
+
+ } // end for column jj
+}
+
+} // end namespace internal
+} // end namespace Eigen
+
+#endif // SPARSELU_PANEL_DFS_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h
new file mode 100644
index 00000000000..ddcd4ec98f8
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h
@@ -0,0 +1,134 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of xpivotL.c file in SuperLU
+
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_PIVOTL_H
+#define SPARSELU_PIVOTL_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Performs the numerical pivotin on the current column of L, and the CDIV operation.
+ *
+ * Pivot policy :
+ * (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ * (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ * pivot row = k;
+ * ELSE IF abs(A_jj) >= thresh THEN
+ * pivot row = j;
+ * ELSE
+ * pivot row = m;
+ *
+ * Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ * \param jcol The current column of L
+ * \param diagpivotthresh diagonal pivoting threshold
+ * \param[in,out] perm_r Row permutation (threshold pivoting)
+ * \param[in] iperm_c column permutation - used to finf diagonal of Pc*A*Pc'
+ * \param[out] pivrow The pivot row
+ * \param glu Global LU data
+ * \return 0 if success, i > 0 if U(i,i) is exactly zero
+ *
+ */
+template <typename Scalar, typename Index>
+Index SparseLUImpl<Scalar,Index>::pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu)
+{
+
+ Index fsupc = (glu.xsup)((glu.supno)(jcol)); // First column in the supernode containing the column jcol
+ Index nsupc = jcol - fsupc; // Number of columns in the supernode portion, excluding jcol; nsupc >=0
+ Index lptr = glu.xlsub(fsupc); // pointer to the starting location of the row subscripts for this supernode portion
+ Index nsupr = glu.xlsub(fsupc+1) - lptr; // Number of rows in the supernode
+ Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); // leading dimension
+ Scalar* lu_sup_ptr = &(glu.lusup.data()[glu.xlusup(fsupc)]); // Start of the current supernode
+ Scalar* lu_col_ptr = &(glu.lusup.data()[glu.xlusup(jcol)]); // Start of jcol in the supernode
+ Index* lsub_ptr = &(glu.lsub.data()[lptr]); // Start of row indices of the supernode
+
+ // Determine the largest abs numerical value for partial pivoting
+ Index diagind = iperm_c(jcol); // diagonal index
+ RealScalar pivmax = 0.0;
+ Index pivptr = nsupc;
+ Index diag = emptyIdxLU;
+ RealScalar rtemp;
+ Index isub, icol, itemp, k;
+ for (isub = nsupc; isub < nsupr; ++isub) {
+ rtemp = std::abs(lu_col_ptr[isub]);
+ if (rtemp > pivmax) {
+ pivmax = rtemp;
+ pivptr = isub;
+ }
+ if (lsub_ptr[isub] == diagind) diag = isub;
+ }
+
+ // Test for singularity
+ if ( pivmax == 0.0 ) {
+ pivrow = lsub_ptr[pivptr];
+ perm_r(pivrow) = jcol;
+ return (jcol+1);
+ }
+
+ RealScalar thresh = diagpivotthresh * pivmax;
+
+ // Choose appropriate pivotal element
+
+ {
+ // Test if the diagonal element can be used as a pivot (given the threshold value)
+ if (diag >= 0 )
+ {
+ // Diagonal element exists
+ rtemp = std::abs(lu_col_ptr[diag]);
+ if (rtemp != 0.0 && rtemp >= thresh) pivptr = diag;
+ }
+ pivrow = lsub_ptr[pivptr];
+ }
+
+ // Record pivot row
+ perm_r(pivrow) = jcol;
+ // Interchange row subscripts
+ if (pivptr != nsupc )
+ {
+ std::swap( lsub_ptr[pivptr], lsub_ptr[nsupc] );
+ // Interchange numerical values as well, for the two rows in the whole snode
+ // such that L is indexed the same way as A
+ for (icol = 0; icol <= nsupc; icol++)
+ {
+ itemp = pivptr + icol * lda;
+ std::swap(lu_sup_ptr[itemp], lu_sup_ptr[nsupc + icol * lda]);
+ }
+ }
+ // cdiv operations
+ Scalar temp = Scalar(1.0) / lu_col_ptr[nsupc];
+ for (k = nsupc+1; k < nsupr; k++)
+ lu_col_ptr[k] *= temp;
+ return 0;
+}
+
+} // end namespace internal
+} // end namespace Eigen
+
+#endif // SPARSELU_PIVOTL_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h
new file mode 100644
index 00000000000..66460d16884
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h
@@ -0,0 +1,135 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/*
+
+ * NOTE: This file is the modified version of [s,d,c,z]pruneL.c file in SuperLU
+
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+#ifndef SPARSELU_PRUNEL_H
+#define SPARSELU_PRUNEL_H
+
+namespace Eigen {
+namespace internal {
+
+/**
+ * \brief Prunes the L-structure.
+ *
+ * It prunes the L-structure of supernodes whose L-structure contains the current pivot row "pivrow"
+ *
+ *
+ * \param jcol The current column of L
+ * \param[in] perm_r Row permutation
+ * \param[out] pivrow The pivot row
+ * \param nseg Number of segments
+ * \param segrep
+ * \param repfnz
+ * \param[out] xprune
+ * \param glu Global LU data
+ *
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu)
+{
+ // For each supernode-rep irep in U(*,j]
+ Index jsupno = glu.supno(jcol);
+ Index i,irep,irep1;
+ bool movnum, do_prune = false;
+ Index kmin = 0, kmax = 0, minloc, maxloc,krow;
+ for (i = 0; i < nseg; i++)
+ {
+ irep = segrep(i);
+ irep1 = irep + 1;
+ do_prune = false;
+
+ // Don't prune with a zero U-segment
+ if (repfnz(irep) == emptyIdxLU) continue;
+
+ // If a snode overlaps with the next panel, then the U-segment
+ // is fragmented into two parts -- irep and irep1. We should let
+ // pruning occur at the rep-column in irep1s snode.
+ if (glu.supno(irep) == glu.supno(irep1) ) continue; // don't prune
+
+ // If it has not been pruned & it has a nonz in row L(pivrow,i)
+ if (glu.supno(irep) != jsupno )
+ {
+ if ( xprune (irep) >= glu.xlsub(irep1) )
+ {
+ kmin = glu.xlsub(irep);
+ kmax = glu.xlsub(irep1) - 1;
+ for (krow = kmin; krow <= kmax; krow++)
+ {
+ if (glu.lsub(krow) == pivrow)
+ {
+ do_prune = true;
+ break;
+ }
+ }
+ }
+
+ if (do_prune)
+ {
+ // do a quicksort-type partition
+ // movnum=true means that the num values have to be exchanged
+ movnum = false;
+ if (irep == glu.xsup(glu.supno(irep)) ) // Snode of size 1
+ movnum = true;
+
+ while (kmin <= kmax)
+ {
+ if (perm_r(glu.lsub(kmax)) == emptyIdxLU)
+ kmax--;
+ else if ( perm_r(glu.lsub(kmin)) != emptyIdxLU)
+ kmin++;
+ else
+ {
+ // kmin below pivrow (not yet pivoted), and kmax
+ // above pivrow: interchange the two suscripts
+ std::swap(glu.lsub(kmin), glu.lsub(kmax));
+
+ // If the supernode has only one column, then we
+ // only keep one set of subscripts. For any subscript
+ // intercnahge performed, similar interchange must be
+ // done on the numerical values.
+ if (movnum)
+ {
+ minloc = glu.xlusup(irep) + ( kmin - glu.xlsub(irep) );
+ maxloc = glu.xlusup(irep) + ( kmax - glu.xlsub(irep) );
+ std::swap(glu.lusup(minloc), glu.lusup(maxloc));
+ }
+ kmin++;
+ kmax--;
+ }
+ } // end while
+
+ xprune(irep) = kmin; //Pruning
+ } // end if do_prune
+ } // end pruning
+ } // End for each U-segment
+}
+
+} // end namespace internal
+} // end namespace Eigen
+
+#endif // SPARSELU_PRUNEL_H
diff --git a/extern/Eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h
new file mode 100644
index 00000000000..58ec32e27e9
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h
@@ -0,0 +1,83 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/* This file is a modified version of heap_relax_snode.c file in SuperLU
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ */
+
+#ifndef SPARSELU_RELAX_SNODE_H
+#define SPARSELU_RELAX_SNODE_H
+
+namespace Eigen {
+
+namespace internal {
+
+/**
+ * \brief Identify the initial relaxed supernodes
+ *
+ * This routine is applied to a column elimination tree.
+ * It assumes that the matrix has been reordered according to the postorder of the etree
+ * \param n the number of columns
+ * \param et elimination tree
+ * \param relax_columns Maximum number of columns allowed in a relaxed snode
+ * \param descendants Number of descendants of each node in the etree
+ * \param relax_end last column in a supernode
+ */
+template <typename Scalar, typename Index>
+void SparseLUImpl<Scalar,Index>::relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
+{
+
+ // compute the number of descendants of each node in the etree
+ Index j, parent;
+ relax_end.setConstant(emptyIdxLU);
+ descendants.setZero();
+ for (j = 0; j < n; j++)
+ {
+ parent = et(j);
+ if (parent != n) // not the dummy root
+ descendants(parent) += descendants(j) + 1;
+ }
+ // Identify the relaxed supernodes by postorder traversal of the etree
+ Index snode_start; // beginning of a snode
+ for (j = 0; j < n; )
+ {
+ parent = et(j);
+ snode_start = j;
+ while ( parent != n && descendants(parent) < relax_columns )
+ {
+ j = parent;
+ parent = et(j);
+ }
+ // Found a supernode in postordered etree, j is the last column
+ relax_end(snode_start) = j; // Record last column
+ j++;
+ // Search for a new leaf
+ while (descendants(j) != 0 && j < n) j++;
+ } // End postorder traversal of the etree
+
+}
+
+} // end namespace internal
+
+} // end namespace Eigen
+#endif
diff --git a/extern/Eigen3/Eigen/src/SparseQR/SparseQR.h b/extern/Eigen3/Eigen/src/SparseQR/SparseQR.h
new file mode 100644
index 00000000000..afda43bfc67
--- /dev/null
+++ b/extern/Eigen3/Eigen/src/SparseQR/SparseQR.h
@@ -0,0 +1,657 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2012-2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
+// Copyright (C) 2012-2013 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSE_QR_H
+#define EIGEN_SPARSE_QR_H
+
+namespace Eigen {
+
+template<typename MatrixType, typename OrderingType> class SparseQR;
+template<typename SparseQRType> struct SparseQRMatrixQReturnType;
+template<typename SparseQRType> struct SparseQRMatrixQTransposeReturnType;
+template<typename SparseQRType, typename Derived> struct SparseQR_QProduct;
+namespace internal {
+ template <typename SparseQRType> struct traits<SparseQRMatrixQReturnType<SparseQRType> >
+ {
+ typedef typename SparseQRType::MatrixType ReturnType;
+ typedef typename ReturnType::Index Index;
+ typedef typename ReturnType::StorageKind StorageKind;
+ };
+ template <typename SparseQRType> struct traits<SparseQRMatrixQTransposeReturnType<SparseQRType> >
+ {
+ typedef typename SparseQRType::MatrixType ReturnType;
+ };
+ template <typename SparseQRType, typename Derived> struct traits<SparseQR_QProduct<SparseQRType, Derived> >
+ {
+ typedef typename Derived::PlainObject ReturnType;
+ };
+} // End namespace internal
+
+/**
+ * \ingroup SparseQR_Module
+ * \class SparseQR
+ * \brief Sparse left-looking rank-revealing QR factorization
+ *
+ * This class implements a left-looking rank-revealing QR decomposition
+ * of sparse matrices. When a column has a norm less than a given tolerance
+ * it is implicitly permuted to the end. The QR factorization thus obtained is
+ * given by A*P = Q*R where R is upper triangular or trapezoidal.
+ *
+ * P is the column permutation which is the product of the fill-reducing and the
+ * rank-revealing permutations. Use colsPermutation() to get it.
+ *
+ * Q is the orthogonal matrix represented as products of Householder reflectors.
+ * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
+ * You can then apply it to a vector.
+ *
+ * R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient.
+ * matrixR().topLeftCorner(rank(), rank()) always returns a triangular factor of full rank.
+ *
+ * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<>
+ * \tparam _OrderingType The fill-reducing ordering method. See the \link OrderingMethods_Module
+ * OrderingMethods \endlink module for the list of built-in and external ordering methods.
+ *
+ *
+ */
+template<typename _MatrixType, typename _OrderingType>
+class SparseQR
+{
+ public:
+ typedef _MatrixType MatrixType;
+ typedef _OrderingType OrderingType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename MatrixType::Index Index;
+ typedef SparseMatrix<Scalar,ColMajor,Index> QRMatrixType;
+ typedef Matrix<Index, Dynamic, 1> IndexVector;
+ typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
+ public:
+ SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false)
+ { }
+
+ SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false)
+ {
+ compute(mat);
+ }
+ void compute(const MatrixType& mat)
+ {
+ analyzePattern(mat);
+ factorize(mat);
+ }
+ void analyzePattern(const MatrixType& mat);
+ void factorize(const MatrixType& mat);
+
+ /** \returns the number of rows of the represented matrix.
+ */
+ inline Index rows() const { return m_pmat.rows(); }
+
+ /** \returns the number of columns of the represented matrix.
+ */
+ inline Index cols() const { return m_pmat.cols();}
+
+ /** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization.
+ */
+ const QRMatrixType& matrixR() const { return m_R; }
+
+ /** \returns the number of non linearly dependent columns as determined by the pivoting threshold.
+ *
+ * \sa setPivotThreshold()
+ */
+ Index rank() const
+ {
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
+ return m_nonzeropivots;
+ }
+
+ /** \returns an expression of the matrix Q as products of sparse Householder reflectors.
+ * The common usage of this function is to apply it to a dense matrix or vector
+ * \code
+ * VectorXd B1, B2;
+ * // Initialize B1
+ * B2 = matrixQ() * B1;
+ * \endcode
+ *
+ * To get a plain SparseMatrix representation of Q:
+ * \code
+ * SparseMatrix<double> Q;
+ * Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
+ * \endcode
+ * Internally, this call simply performs a sparse product between the matrix Q
+ * and a sparse identity matrix. However, due to the fact that the sparse
+ * reflectors are stored unsorted, two transpositions are needed to sort
+ * them before performing the product.
+ */
+ SparseQRMatrixQReturnType<SparseQR> matrixQ() const
+ { return SparseQRMatrixQReturnType<SparseQR>(*this); }
+
+ /** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R
+ * It is the combination of the fill-in reducing permutation and numerical column pivoting.
+ */
+ const PermutationType& colsPermutation() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return m_outputPerm_c;
+ }
+
+ /** \returns A string describing the type of error.
+ * This method is provided to ease debugging, not to handle errors.
+ */
+ std::string lastErrorMessage() const { return m_lastError; }
+
+ /** \internal */
+ template<typename Rhs, typename Dest>
+ bool _solve(const MatrixBase<Rhs> &B, MatrixBase<Dest> &dest) const
+ {
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
+
+ Index rank = this->rank();
+
+ // Compute Q^T * b;
+ typename Dest::PlainObject y, b;
+ y = this->matrixQ().transpose() * B;
+ b = y;
+
+ // Solve with the triangular matrix R
+ y.resize((std::max)(cols(),Index(y.rows())),y.cols());
+ y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
+ y.bottomRows(y.rows()-rank).setZero();
+
+ // Apply the column permutation
+ if (m_perm_c.size()) dest.topRows(cols()) = colsPermutation() * y.topRows(cols());
+ else dest = y.topRows(cols());
+
+ m_info = Success;
+ return true;
+ }
+
+
+ /** Sets the threshold that is used to determine linearly dependent columns during the factorization.
+ *
+ * In practice, if during the factorization the norm of the column that has to be eliminated is below
+ * this threshold, then the entire column is treated as zero, and it is moved at the end.
+ */
+ void setPivotThreshold(const RealScalar& threshold)
+ {
+ m_useDefaultThreshold = false;
+ m_threshold = threshold;
+ }
+
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
+ *
+ * \sa compute()
+ */
+ template<typename Rhs>
+ inline const internal::solve_retval<SparseQR, Rhs> solve(const MatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
+ return internal::solve_retval<SparseQR, Rhs>(*this, B.derived());
+ }
+ template<typename Rhs>
+ inline const internal::sparse_solve_retval<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
+ return internal::sparse_solve_retval<SparseQR, Rhs>(*this, B.derived());
+ }
+
+ /** \brief Reports whether previous computation was successful.
+ *
+ * \returns \c Success if computation was succesful,
+ * \c NumericalIssue if the QR factorization reports a numerical problem
+ * \c InvalidInput if the input matrix is invalid
+ *
+ * \sa iparm()
+ */
+ ComputationInfo info() const
+ {
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+ return m_info;
+ }
+
+ protected:
+ inline void sort_matrix_Q()
+ {
+ if(this->m_isQSorted) return;
+ // The matrix Q is sorted during the transposition
+ SparseMatrix<Scalar, RowMajor, Index> mQrm(this->m_Q);
+ this->m_Q = mQrm;
+ this->m_isQSorted = true;
+ }
+
+
+ protected:
+ bool m_isInitialized;
+ bool m_analysisIsok;
+ bool m_factorizationIsok;
+ mutable ComputationInfo m_info;
+ std::string m_lastError;
+ QRMatrixType m_pmat; // Temporary matrix
+ QRMatrixType m_R; // The triangular factor matrix
+ QRMatrixType m_Q; // The orthogonal reflectors
+ ScalarVector m_hcoeffs; // The Householder coefficients
+ PermutationType m_perm_c; // Fill-reducing Column permutation
+ PermutationType m_pivotperm; // The permutation for rank revealing
+ PermutationType m_outputPerm_c; // The final column permutation
+ RealScalar m_threshold; // Threshold to determine null Householder reflections
+ bool m_useDefaultThreshold; // Use default threshold
+ Index m_nonzeropivots; // Number of non zero pivots found
+ IndexVector m_etree; // Column elimination tree
+ IndexVector m_firstRowElt; // First element in each row
+ bool m_isQSorted; // whether Q is sorted or not
+
+ template <typename, typename > friend struct SparseQR_QProduct;
+ template <typename > friend struct SparseQRMatrixQReturnType;
+
+};
+
+/** \brief Preprocessing step of a QR factorization
+ *
+ * In this step, the fill-reducing permutation is computed and applied to the columns of A
+ * and the column elimination tree is computed as well. Only the sparcity pattern of \a mat is exploited.
+ *
+ * \note In this step it is assumed that there is no empty row in the matrix \a mat.
+ */
+template <typename MatrixType, typename OrderingType>
+void SparseQR<MatrixType,OrderingType>::analyzePattern(const MatrixType& mat)
+{
+ // Compute the column fill reducing ordering
+ OrderingType ord;
+ ord(mat, m_perm_c);
+ Index n = mat.cols();
+ Index m = mat.rows();
+
+ if (!m_perm_c.size())
+ {
+ m_perm_c.resize(n);
+ m_perm_c.indices().setLinSpaced(n, 0,n-1);
+ }
+
+ // Compute the column elimination tree of the permuted matrix
+ m_outputPerm_c = m_perm_c.inverse();
+ internal::coletree(mat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
+
+ m_R.resize(n, n);
+ m_Q.resize(m, n);
+
+ // Allocate space for nonzero elements : rough estimation
+ m_R.reserve(2*mat.nonZeros()); //FIXME Get a more accurate estimation through symbolic factorization with the etree
+ m_Q.reserve(2*mat.nonZeros());
+ m_hcoeffs.resize(n);
+ m_analysisIsok = true;
+}
+
+/** \brief Performs the numerical QR factorization of the input matrix
+ *
+ * The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with
+ * a matrix having the same sparcity pattern than \a mat.
+ *
+ * \param mat The sparse column-major matrix
+ */
+template <typename MatrixType, typename OrderingType>
+void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
+{
+ using std::abs;
+ using std::max;
+
+ eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step");
+ Index m = mat.rows();
+ Index n = mat.cols();
+ IndexVector mark(m); mark.setConstant(-1); // Record the visited nodes
+ IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q
+ Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q
+ ScalarVector tval(m); // The dense vector used to compute the current column
+ bool found_diag;
+
+ m_pmat = mat;
+ m_pmat.uncompress(); // To have the innerNonZeroPtr allocated
+ // Apply the fill-in reducing permutation lazily:
+ for (int i = 0; i < n; i++)
+ {
+ Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
+ m_pmat.outerIndexPtr()[p] = mat.outerIndexPtr()[i];
+ m_pmat.innerNonZeroPtr()[p] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i];
+ }
+
+ /* Compute the default threshold, see :
+ * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
+ * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
+ */
+ if(m_useDefaultThreshold)
+ {
+ RealScalar max2Norm = 0.0;
+ for (int j = 0; j < n; j++) max2Norm = (max)(max2Norm, m_pmat.col(j).norm());
+ m_threshold = 20 * (m + n) * max2Norm * NumTraits<RealScalar>::epsilon();
+ }
+
+ // Initialize the numerical permutation
+ m_pivotperm.setIdentity(n);
+
+ Index nonzeroCol = 0; // Record the number of valid pivots
+
+ // Left looking rank-revealing QR factorization: compute a column of R and Q at a time
+ for (Index col = 0; col < (std::min)(n,m); ++col)
+ {
+ mark.setConstant(-1);
+ m_R.startVec(col);
+ m_Q.startVec(col);
+ mark(nonzeroCol) = col;
+ Qidx(0) = nonzeroCol;
+ nzcolR = 0; nzcolQ = 1;
+ found_diag = col>=m;
+ tval.setZero();
+
+ // Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e.,
+ // all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node k.
+ // Note: if the diagonal entry does not exist, then its contribution must be explicitly added,
+ // thus the trick with found_diag that permits to do one more iteration on the diagonal element if this one has not been found.
+ for (typename MatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp)
+ {
+ Index curIdx = nonzeroCol ;
+ if(itp) curIdx = itp.row();
+ if(curIdx == nonzeroCol) found_diag = true;
+
+ // Get the nonzeros indexes of the current column of R
+ Index st = m_firstRowElt(curIdx); // The traversal of the etree starts here
+ if (st < 0 )
+ {
+ m_lastError = "Empty row found during numerical factorization";
+ m_info = InvalidInput;
+ return;
+ }
+
+ // Traverse the etree
+ Index bi = nzcolR;
+ for (; mark(st) != col; st = m_etree(st))
+ {
+ Ridx(nzcolR) = st; // Add this row to the list,
+ mark(st) = col; // and mark this row as visited
+ nzcolR++;
+ }
+
+ // Reverse the list to get the topological ordering
+ Index nt = nzcolR-bi;
+ for(Index i = 0; i < nt/2; i++) std::swap(Ridx(bi+i), Ridx(nzcolR-i-1));
+
+ // Copy the current (curIdx,pcol) value of the input matrix
+ if(itp) tval(curIdx) = itp.value();
+ else tval(curIdx) = Scalar(0);
+
+ // Compute the pattern of Q(:,k)
+ if(curIdx > nonzeroCol && mark(curIdx) != col )
+ {
+ Qidx(nzcolQ) = curIdx; // Add this row to the pattern of Q,
+ mark(curIdx) = col; // and mark it as visited
+ nzcolQ++;
+ }
+ }
+
+ // Browse all the indexes of R(:,col) in reverse order
+ for (Index i = nzcolR-1; i >= 0; i--)
+ {
+ Index curIdx = m_pivotperm.indices()(Ridx(i));
+
+ // Apply the curIdx-th householder vector to the current column (temporarily stored into tval)
+ Scalar tdot(0);
+
+ // First compute q' * tval
+ tdot = m_Q.col(curIdx).dot(tval);
+
+ tdot *= m_hcoeffs(curIdx);
+
+ // Then update tval = tval - q * tau
+ // FIXME: tval -= tdot * m_Q.col(curIdx) should amount to the same (need to check/add support for efficient "dense ?= sparse")
+ for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
+ tval(itq.row()) -= itq.value() * tdot;
+
+ // Detect fill-in for the current column of Q
+ if(m_etree(Ridx(i)) == nonzeroCol)
+ {
+ for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
+ {
+ Index iQ = itq.row();
+ if (mark(iQ) != col)
+ {
+ Qidx(nzcolQ++) = iQ; // Add this row to the pattern of Q,
+ mark(iQ) = col; // and mark it as visited
+ }
+ }
+ }
+ } // End update current column
+
+ // Compute the Householder reflection that eliminate the current column
+ // FIXME this step should call the Householder module.
+ Scalar tau;
+ RealScalar beta;
+ Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0);
+
+ // First, the squared norm of Q((col+1):m, col)
+ RealScalar sqrNorm = 0.;
+ for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq)));
+
+ if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0))
+ {
+ tau = RealScalar(0);
+ beta = numext::real(c0);
+ tval(Qidx(0)) = 1;
+ }
+ else
+ {
+ beta = std::sqrt(numext::abs2(c0) + sqrNorm);
+ if(numext::real(c0) >= RealScalar(0))
+ beta = -beta;
+ tval(Qidx(0)) = 1;
+ for (Index itq = 1; itq < nzcolQ; ++itq)
+ tval(Qidx(itq)) /= (c0 - beta);
+ tau = numext::conj((beta-c0) / beta);
+
+ }
+
+ // Insert values in R
+ for (Index i = nzcolR-1; i >= 0; i--)
+ {
+ Index curIdx = Ridx(i);
+ if(curIdx < nonzeroCol)
+ {
+ m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx);
+ tval(curIdx) = Scalar(0.);
+ }
+ }
+
+ if(abs(beta) >= m_threshold)
+ {
+ m_R.insertBackByOuterInner(col, nonzeroCol) = beta;
+ nonzeroCol++;
+ // The householder coefficient
+ m_hcoeffs(col) = tau;
+ // Record the householder reflections
+ for (Index itq = 0; itq < nzcolQ; ++itq)
+ {
+ Index iQ = Qidx(itq);
+ m_Q.insertBackByOuterInnerUnordered(col,iQ) = tval(iQ);
+ tval(iQ) = Scalar(0.);
+ }
+ }
+ else
+ {
+ // Zero pivot found: move implicitly this column to the end
+ m_hcoeffs(col) = Scalar(0);
+ for (Index j = nonzeroCol; j < n-1; j++)
+ std::swap(m_pivotperm.indices()(j), m_pivotperm.indices()[j+1]);
+
+ // Recompute the column elimination tree
+ internal::coletree(m_pmat, m_etree, m_firstRowElt, m_pivotperm.indices().data());
+ }
+ }
+
+ // Finalize the column pointers of the sparse matrices R and Q
+ m_Q.finalize();
+ m_Q.makeCompressed();
+ m_R.finalize();
+ m_R.makeCompressed();
+ m_isQSorted = false;
+
+ m_nonzeropivots = nonzeroCol;
+
+ if(nonzeroCol<n)
+ {
+ // Permute the triangular factor to put the 'dead' columns to the end
+ MatrixType tempR(m_R);
+ m_R = tempR * m_pivotperm;
+
+ // Update the column permutation
+ m_outputPerm_c = m_outputPerm_c * m_pivotperm;
+ }
+
+ m_isInitialized = true;
+ m_factorizationIsok = true;
+ m_info = Success;
+}
+
+namespace internal {
+
+template<typename _MatrixType, typename OrderingType, typename Rhs>
+struct solve_retval<SparseQR<_MatrixType,OrderingType>, Rhs>
+ : solve_retval_base<SparseQR<_MatrixType,OrderingType>, Rhs>
+{
+ typedef SparseQR<_MatrixType,OrderingType> Dec;
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ dec()._solve(rhs(),dst);
+ }
+};
+template<typename _MatrixType, typename OrderingType, typename Rhs>
+struct sparse_solve_retval<SparseQR<_MatrixType, OrderingType>, Rhs>
+ : sparse_solve_retval_base<SparseQR<_MatrixType, OrderingType>, Rhs>
+{
+ typedef SparseQR<_MatrixType, OrderingType> Dec;
+ EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec, Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ this->defaultEvalTo(dst);
+ }
+};
+} // end namespace internal
+
+template <typename SparseQRType, typename Derived>
+struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> >
+{
+ typedef typename SparseQRType::QRMatrixType MatrixType;
+ typedef typename SparseQRType::Scalar Scalar;
+ typedef typename SparseQRType::Index Index;
+ // Get the references
+ SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose) :
+ m_qr(qr),m_other(other),m_transpose(transpose) {}
+ inline Index rows() const { return m_transpose ? m_qr.rows() : m_qr.cols(); }
+ inline Index cols() const { return m_other.cols(); }
+
+ // Assign to a vector
+ template<typename DesType>
+ void evalTo(DesType& res) const
+ {
+ Index n = m_qr.cols();
+ res = m_other;
+ if (m_transpose)
+ {
+ eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
+ //Compute res = Q' * other column by column
+ for(Index j = 0; j < res.cols(); j++){
+ for (Index k = 0; k < n; k++)
+ {
+ Scalar tau = Scalar(0);
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
+ if(tau==Scalar(0)) continue;
+ tau = tau * m_qr.m_hcoeffs(k);
+ res.col(j) -= tau * m_qr.m_Q.col(k);
+ }
+ }
+ }
+ else
+ {
+ eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
+ // Compute res = Q' * other column by column
+ for(Index j = 0; j < res.cols(); j++)
+ {
+ for (Index k = n-1; k >=0; k--)
+ {
+ Scalar tau = Scalar(0);
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
+ if(tau==Scalar(0)) continue;
+ tau = tau * m_qr.m_hcoeffs(k);
+ res.col(j) -= tau * m_qr.m_Q.col(k);
+ }
+ }
+ }
+ }
+
+ const SparseQRType& m_qr;
+ const Derived& m_other;
+ bool m_transpose;
+};
+
+template<typename SparseQRType>
+struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> >
+{
+ typedef typename SparseQRType::Index Index;
+ typedef typename SparseQRType::Scalar Scalar;
+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
+ SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {}
+ template<typename Derived>
+ SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other)
+ {
+ return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(),false);
+ }
+ SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const
+ {
+ return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
+ }
+ inline Index rows() const { return m_qr.rows(); }
+ inline Index cols() const { return m_qr.cols(); }
+ // To use for operations with the transpose of Q
+ SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
+ {
+ return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
+ }
+ template<typename Dest> void evalTo(MatrixBase<Dest>& dest) const
+ {
+ dest.derived() = m_qr.matrixQ() * Dest::Identity(m_qr.rows(), m_qr.rows());
+ }
+ template<typename Dest> void evalTo(SparseMatrixBase<Dest>& dest) const
+ {
+ Dest idMat(m_qr.rows(), m_qr.rows());
+ idMat.setIdentity();
+ // Sort the sparse householder reflectors if needed
+ const_cast<SparseQRType *>(&m_qr)->sort_matrix_Q();
+ dest.derived() = SparseQR_QProduct<SparseQRType, Dest>(m_qr, idMat, false);
+ }
+
+ const SparseQRType& m_qr;
+};
+
+template<typename SparseQRType>
+struct SparseQRMatrixQTransposeReturnType
+{
+ SparseQRMatrixQTransposeReturnType(const SparseQRType& qr) : m_qr(qr) {}
+ template<typename Derived>
+ SparseQR_QProduct<SparseQRType,Derived> operator*(const MatrixBase<Derived>& other)
+ {
+ return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(), true);
+ }
+ const SparseQRType& m_qr;
+};
+
+} // end namespace Eigen
+
+#endif
diff --git a/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h
index 11fb014dd93..bcb355760c5 100644
--- a/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h
+++ b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h
@@ -160,7 +160,7 @@ struct SluMatrix : SuperMatrix
res.ncol = mat.cols();
res.storage.lda = MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride();
- res.storage.values = mat.data();
+ res.storage.values = (void*)(mat.data());
return res;
}
@@ -353,14 +353,14 @@ class SuperLUBase : internal::noncopyable
*
* \sa compute()
*/
-// template<typename Rhs>
-// inline const internal::sparse_solve_retval<SuperLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const
-// {
-// eigen_assert(m_isInitialized && "SuperLU is not initialized.");
-// eigen_assert(rows()==b.rows()
-// && "SuperLU::solve(): invalid number of rows of the right hand side matrix b");
-// return internal::sparse_solve_retval<SuperLU, Rhs>(*this, b.derived());
-// }
+ template<typename Rhs>
+ inline const internal::sparse_solve_retval<SuperLUBase, Rhs> solve(const SparseMatrixBase<Rhs>& b) const
+ {
+ eigen_assert(m_isInitialized && "SuperLU is not initialized.");
+ eigen_assert(rows()==b.rows()
+ && "SuperLU::solve(): invalid number of rows of the right hand side matrix b");
+ return internal::sparse_solve_retval<SuperLUBase, Rhs>(*this, b.derived());
+ }
/** Performs a symbolic decomposition on the sparcity of \a matrix.
*
@@ -377,7 +377,7 @@ class SuperLUBase : internal::noncopyable
}
template<typename Stream>
- void dumpMemory(Stream& s)
+ void dumpMemory(Stream& /*s*/)
{}
protected:
@@ -496,8 +496,8 @@ class SuperLU : public SuperLUBase<_MatrixType,SuperLU<_MatrixType> >
SuperLU(const MatrixType& matrix) : Base()
{
- Base::init();
- compute(matrix);
+ init();
+ Base::compute(matrix);
}
~SuperLU()
@@ -612,6 +612,7 @@ void SuperLU<MatrixType>::factorize(const MatrixType& a)
this->initFactorization(a);
+ m_sluOptions.ColPerm = COLAMD;
int info = 0;
RealScalar recip_pivot_growth, rcond;
RealScalar ferr, berr;
@@ -833,7 +834,7 @@ class SuperILU : public SuperLUBase<_MatrixType,SuperILU<_MatrixType> >
SuperILU(const MatrixType& matrix) : Base()
{
init();
- compute(matrix);
+ Base::compute(matrix);
}
~SuperILU()
@@ -1014,7 +1015,7 @@ struct sparse_solve_retval<SuperLUBase<_MatrixType,Derived>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- dec().derived()._solve(rhs(),dst);
+ this->defaultEvalTo(dst);
}
};
diff --git a/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h
index f01720362de..3a48cecf769 100644
--- a/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h
+++ b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h
@@ -39,7 +39,7 @@ inline int umfpack_symbolic(int n_row,int n_col,
const int Ap[], const int Ai[], const std::complex<double> Ax[], void **Symbolic,
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
{
- return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Control,Info);
+ return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Control,Info);
}
inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[],
@@ -53,7 +53,7 @@ inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex<d
void *Symbolic, void **Numeric,
const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
{
- return umfpack_zi_numeric(Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info);
+ return umfpack_zi_numeric(Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info);
}
inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[],
@@ -67,7 +67,7 @@ inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::co
std::complex<double> X[], const std::complex<double> B[], void *Numeric,
const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
{
- return umfpack_zi_solve(sys,Ap,Ai,&internal::real_ref(Ax[0]),0,&internal::real_ref(X[0]),0,&internal::real_ref(B[0]),0,Numeric,Control,Info);
+ return umfpack_zi_solve(sys,Ap,Ai,&numext::real_ref(Ax[0]),0,&numext::real_ref(X[0]),0,&numext::real_ref(B[0]),0,Numeric,Control,Info);
}
inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double)
@@ -89,9 +89,9 @@ inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui
inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[], std::complex<double> Ux[],
int P[], int Q[], std::complex<double> Dx[], int *do_recip, double Rs[], void *Numeric)
{
- double& lx0_real = internal::real_ref(Lx[0]);
- double& ux0_real = internal::real_ref(Ux[0]);
- double& dx0_real = internal::real_ref(Dx[0]);
+ double& lx0_real = numext::real_ref(Lx[0]);
+ double& ux0_real = numext::real_ref(Ux[0]);
+ double& dx0_real = numext::real_ref(Dx[0]);
return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q,
Dx?&dx0_real:0,0,do_recip,Rs,Numeric);
}
@@ -103,7 +103,7 @@ inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle,
inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
{
- double& mx_real = internal::real_ref(*Mx);
+ double& mx_real = numext::real_ref(*Mx);
return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info);
}
@@ -114,7 +114,7 @@ inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *N
* using the UmfPack library. The sparse matrix A must be squared and full rank.
* The vectors or matrices X and B can be either dense or sparse.
*
- * \WARNING The input matrix A should be in a \b compressed and \b column-major form.
+ * \warning The input matrix A should be in a \b compressed and \b column-major form.
* Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
*
@@ -215,14 +215,14 @@ class UmfPackLU : internal::noncopyable
*
* \sa compute()
*/
-// template<typename Rhs>
-// inline const internal::sparse_solve_retval<UmfPAckLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const
-// {
-// eigen_assert(m_isInitialized && "UmfPAckLU is not initialized.");
-// eigen_assert(rows()==b.rows()
-// && "UmfPAckLU::solve(): invalid number of rows of the right hand side matrix b");
-// return internal::sparse_solve_retval<UmfPAckLU, Rhs>(*this, b.derived());
-// }
+ template<typename Rhs>
+ inline const internal::sparse_solve_retval<UmfPackLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const
+ {
+ eigen_assert(m_isInitialized && "UmfPackLU is not initialized.");
+ eigen_assert(rows()==b.rows()
+ && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b");
+ return internal::sparse_solve_retval<UmfPackLU, Rhs>(*this, b.derived());
+ }
/** Performs a symbolic decomposition on the sparcity of \a matrix.
*
@@ -381,7 +381,8 @@ bool UmfPackLU<MatrixType>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDe
const int rhsCols = b.cols();
eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet");
eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet");
-
+ eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve");
+
int errorCode;
for (int j=0; j<rhsCols; ++j)
{
@@ -420,7 +421,7 @@ struct sparse_solve_retval<UmfPackLU<_MatrixType>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- dec()._solve(rhs(),dst);
+ this->defaultEvalTo(dst);
}
};
diff --git a/extern/Eigen3/Eigen/src/misc/SparseSolve.h b/extern/Eigen3/Eigen/src/misc/SparseSolve.h
index 272c4a479d7..244bb8ec753 100644
--- a/extern/Eigen3/Eigen/src/misc/SparseSolve.h
+++ b/extern/Eigen3/Eigen/src/misc/SparseSolve.h
@@ -47,6 +47,23 @@ template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval_b
}
protected:
+ template<typename DestScalar, int DestOptions, typename DestIndex>
+ inline void defaultEvalTo(SparseMatrix<DestScalar,DestOptions,DestIndex>& dst) const
+ {
+ // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix.
+ static const int NbColsAtOnce = 4;
+ int rhsCols = m_rhs.cols();
+ int size = m_rhs.rows();
+ Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols);
+ Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmpX(size,rhsCols);
+ for(int k=0; k<rhsCols; k+=NbColsAtOnce)
+ {
+ int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce);
+ tmp.leftCols(actualCols) = m_rhs.middleCols(k,actualCols);
+ tmpX.leftCols(actualCols) = m_dec.solve(tmp.leftCols(actualCols));
+ dst.middleCols(k,actualCols) = tmpX.leftCols(actualCols).sparseView();
+ }
+ }
const DecompositionType& m_dec;
typename Rhs::Nested m_rhs;
};
diff --git a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h
index 5b979ebf89d..5c8c476eecf 100644
--- a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h
+++ b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h
@@ -33,8 +33,14 @@ EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op)
*
* \sa max()
*/
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const ConstantReturnType>
-(min)(const Scalar &other) const
+EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived,
+ const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
+#ifdef EIGEN_PARSED_BY_DOXYGEN
+min
+#else
+(min)
+#endif
+(const Scalar &other) const
{
return (min)(Derived::PlainObject::Constant(rows(), cols(), other));
}
@@ -52,8 +58,14 @@ EIGEN_MAKE_CWISE_BINARY_OP(max,internal::scalar_max_op)
*
* \sa min()
*/
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType>
-(max)(const Scalar &other) const
+EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived,
+ const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
+#ifdef EIGEN_PARSED_BY_DOXYGEN
+max
+#else
+(max)
+#endif
+(const Scalar &other) const
{
return (max)(Derived::PlainObject::Constant(rows(), cols(), other));
}
diff --git a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h
index 0dffaf4135c..a596367906f 100644
--- a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+++ b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h
@@ -200,3 +200,4 @@ EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal)
+
diff --git a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h
index ef224001a54..2788251e0cd 100644
--- a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h
+++ b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h
@@ -8,8 +8,6 @@
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef EIGEN_BLOCKMETHODS_H
-#define EIGEN_BLOCKMETHODS_H
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -32,6 +30,10 @@ template<int N> struct ConstNColsBlockXpr { typedef const Block<const Derived, i
template<int N> struct NRowsBlockXpr { typedef Block<Derived, N, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> Type; };
template<int N> struct ConstNRowsBlockXpr { typedef const Block<const Derived, N, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> Type; };
+typedef VectorBlock<Derived> SegmentReturnType;
+typedef const VectorBlock<const Derived> ConstSegmentReturnType;
+template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
+template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
#endif // not EIGEN_PARSED_BY_DOXYGEN
@@ -88,12 +90,13 @@ inline const Block<const Derived> topRightCorner(Index cRows, Index cCols) const
/** \returns an expression of a fixed-size top-right corner of *this.
*
- * The template parameters CRows and CCols are the number of rows and columns in the corner.
+ * \tparam CRows the number of rows in the corner
+ * \tparam CCols the number of columns in the corner
*
* Example: \include MatrixBase_template_int_int_topRightCorner.cpp
* Output: \verbinclude MatrixBase_template_int_int_topRightCorner.out
*
- * \sa class Block, block(Index,Index,Index,Index)
+ * \sa class Block, block<int,int>(Index,Index)
*/
template<int CRows, int CCols>
inline Block<Derived, CRows, CCols> topRightCorner()
@@ -108,6 +111,35 @@ inline const Block<const Derived, CRows, CCols> topRightCorner() const
return Block<const Derived, CRows, CCols>(derived(), 0, cols() - CCols);
}
+/** \returns an expression of a top-right corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile-time
+ * \tparam CCols number of columns in corner as specified at compile-time
+ * \param cRows number of rows in corner as specified at run-time
+ * \param cCols number of columns in corner as specified at run-time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile-time
+ * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_topRightCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_topRightCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> topRightCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), 0, cols() - cCols, cRows, cCols);
+}
+
+/** This is the const version of topRightCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> topRightCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), 0, cols() - cCols, cRows, cCols);
+}
@@ -154,6 +186,36 @@ inline const Block<const Derived, CRows, CCols> topLeftCorner() const
return Block<const Derived, CRows, CCols>(derived(), 0, 0);
}
+/** \returns an expression of a top-left corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile-time
+ * \tparam CCols number of columns in corner as specified at compile-time
+ * \param cRows number of rows in corner as specified at run-time
+ * \param cCols number of columns in corner as specified at run-time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile-time
+ * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_topLeftCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_topLeftCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> topLeftCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), 0, 0, cRows, cCols);
+}
+
+/** This is the const version of topLeftCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> topLeftCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), 0, 0, cRows, cCols);
+}
+
/** \returns a dynamic-size expression of a bottom-right corner of *this.
@@ -199,6 +261,36 @@ inline const Block<const Derived, CRows, CCols> bottomRightCorner() const
return Block<const Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
}
+/** \returns an expression of a bottom-right corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile-time
+ * \tparam CCols number of columns in corner as specified at compile-time
+ * \param cRows number of rows in corner as specified at run-time
+ * \param cCols number of columns in corner as specified at run-time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile-time
+ * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_bottomRightCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> bottomRightCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+}
+
+/** This is the const version of bottomRightCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> bottomRightCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+}
+
/** \returns a dynamic-size expression of a bottom-left corner of *this.
@@ -244,6 +336,36 @@ inline const Block<const Derived, CRows, CCols> bottomLeftCorner() const
return Block<const Derived, CRows, CCols>(derived(), rows() - CRows, 0);
}
+/** \returns an expression of a bottom-left corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile-time
+ * \tparam CCols number of columns in corner as specified at compile-time
+ * \param cRows number of rows in corner as specified at run-time
+ * \param cCols number of columns in corner as specified at run-time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile-time
+ * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> bottomLeftCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), rows() - cRows, 0, cRows, cCols);
+}
+
+/** This is the const version of bottomLeftCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> bottomLeftCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), rows() - cRows, 0, cRows, cCols);
+}
+
/** \returns a block consisting of the top rows of *this.
@@ -268,7 +390,11 @@ inline ConstRowsBlockXpr topRows(Index n) const
/** \returns a block consisting of the top rows of *this.
*
- * \tparam N the number of rows in the block
+ * \tparam N the number of rows in the block as specified at compile-time
+ * \param n the number of rows in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include MatrixBase_template_int_topRows.cpp
* Output: \verbinclude MatrixBase_template_int_topRows.out
@@ -276,16 +402,16 @@ inline ConstRowsBlockXpr topRows(Index n) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NRowsBlockXpr<N>::Type topRows()
+inline typename NRowsBlockXpr<N>::Type topRows(Index n = N)
{
- return typename NRowsBlockXpr<N>::Type(derived(), 0, 0, N, cols());
+ return typename NRowsBlockXpr<N>::Type(derived(), 0, 0, n, cols());
}
/** This is the const version of topRows<int>().*/
template<int N>
-inline typename ConstNRowsBlockXpr<N>::Type topRows() const
+inline typename ConstNRowsBlockXpr<N>::Type topRows(Index n = N) const
{
- return typename ConstNRowsBlockXpr<N>::Type(derived(), 0, 0, N, cols());
+ return typename ConstNRowsBlockXpr<N>::Type(derived(), 0, 0, n, cols());
}
@@ -312,7 +438,11 @@ inline ConstRowsBlockXpr bottomRows(Index n) const
/** \returns a block consisting of the bottom rows of *this.
*
- * \tparam N the number of rows in the block
+ * \tparam N the number of rows in the block as specified at compile-time
+ * \param n the number of rows in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include MatrixBase_template_int_bottomRows.cpp
* Output: \verbinclude MatrixBase_template_int_bottomRows.out
@@ -320,16 +450,16 @@ inline ConstRowsBlockXpr bottomRows(Index n) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NRowsBlockXpr<N>::Type bottomRows()
+inline typename NRowsBlockXpr<N>::Type bottomRows(Index n = N)
{
- return typename NRowsBlockXpr<N>::Type(derived(), rows() - N, 0, N, cols());
+ return typename NRowsBlockXpr<N>::Type(derived(), rows() - n, 0, n, cols());
}
/** This is the const version of bottomRows<int>().*/
template<int N>
-inline typename ConstNRowsBlockXpr<N>::Type bottomRows() const
+inline typename ConstNRowsBlockXpr<N>::Type bottomRows(Index n = N) const
{
- return typename ConstNRowsBlockXpr<N>::Type(derived(), rows() - N, 0, N, cols());
+ return typename ConstNRowsBlockXpr<N>::Type(derived(), rows() - n, 0, n, cols());
}
@@ -337,28 +467,32 @@ inline typename ConstNRowsBlockXpr<N>::Type bottomRows() const
/** \returns a block consisting of a range of rows of *this.
*
* \param startRow the index of the first row in the block
- * \param numRows the number of rows in the block
+ * \param n the number of rows in the block
*
* Example: \include DenseBase_middleRows_int.cpp
* Output: \verbinclude DenseBase_middleRows_int.out
*
* \sa class Block, block(Index,Index,Index,Index)
*/
-inline RowsBlockXpr middleRows(Index startRow, Index numRows)
+inline RowsBlockXpr middleRows(Index startRow, Index n)
{
- return RowsBlockXpr(derived(), startRow, 0, numRows, cols());
+ return RowsBlockXpr(derived(), startRow, 0, n, cols());
}
/** This is the const version of middleRows(Index,Index).*/
-inline ConstRowsBlockXpr middleRows(Index startRow, Index numRows) const
+inline ConstRowsBlockXpr middleRows(Index startRow, Index n) const
{
- return ConstRowsBlockXpr(derived(), startRow, 0, numRows, cols());
+ return ConstRowsBlockXpr(derived(), startRow, 0, n, cols());
}
/** \returns a block consisting of a range of rows of *this.
*
- * \tparam N the number of rows in the block
+ * \tparam N the number of rows in the block as specified at compile-time
* \param startRow the index of the first row in the block
+ * \param n the number of rows in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include DenseBase_template_int_middleRows.cpp
* Output: \verbinclude DenseBase_template_int_middleRows.out
@@ -366,16 +500,16 @@ inline ConstRowsBlockXpr middleRows(Index startRow, Index numRows) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NRowsBlockXpr<N>::Type middleRows(Index startRow)
+inline typename NRowsBlockXpr<N>::Type middleRows(Index startRow, Index n = N)
{
- return typename NRowsBlockXpr<N>::Type(derived(), startRow, 0, N, cols());
+ return typename NRowsBlockXpr<N>::Type(derived(), startRow, 0, n, cols());
}
/** This is the const version of middleRows<int>().*/
template<int N>
-inline typename ConstNRowsBlockXpr<N>::Type middleRows(Index startRow) const
+inline typename ConstNRowsBlockXpr<N>::Type middleRows(Index startRow, Index n = N) const
{
- return typename ConstNRowsBlockXpr<N>::Type(derived(), startRow, 0, N, cols());
+ return typename ConstNRowsBlockXpr<N>::Type(derived(), startRow, 0, n, cols());
}
@@ -402,7 +536,11 @@ inline ConstColsBlockXpr leftCols(Index n) const
/** \returns a block consisting of the left columns of *this.
*
- * \tparam N the number of columns in the block
+ * \tparam N the number of columns in the block as specified at compile-time
+ * \param n the number of columns in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include MatrixBase_template_int_leftCols.cpp
* Output: \verbinclude MatrixBase_template_int_leftCols.out
@@ -410,16 +548,16 @@ inline ConstColsBlockXpr leftCols(Index n) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NColsBlockXpr<N>::Type leftCols()
+inline typename NColsBlockXpr<N>::Type leftCols(Index n = N)
{
- return typename NColsBlockXpr<N>::Type(derived(), 0, 0, rows(), N);
+ return typename NColsBlockXpr<N>::Type(derived(), 0, 0, rows(), n);
}
/** This is the const version of leftCols<int>().*/
template<int N>
-inline typename ConstNColsBlockXpr<N>::Type leftCols() const
+inline typename ConstNColsBlockXpr<N>::Type leftCols(Index n = N) const
{
- return typename ConstNColsBlockXpr<N>::Type(derived(), 0, 0, rows(), N);
+ return typename ConstNColsBlockXpr<N>::Type(derived(), 0, 0, rows(), n);
}
@@ -446,7 +584,11 @@ inline ConstColsBlockXpr rightCols(Index n) const
/** \returns a block consisting of the right columns of *this.
*
- * \tparam N the number of columns in the block
+ * \tparam N the number of columns in the block as specified at compile-time
+ * \param n the number of columns in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include MatrixBase_template_int_rightCols.cpp
* Output: \verbinclude MatrixBase_template_int_rightCols.out
@@ -454,16 +596,16 @@ inline ConstColsBlockXpr rightCols(Index n) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NColsBlockXpr<N>::Type rightCols()
+inline typename NColsBlockXpr<N>::Type rightCols(Index n = N)
{
- return typename NColsBlockXpr<N>::Type(derived(), 0, cols() - N, rows(), N);
+ return typename NColsBlockXpr<N>::Type(derived(), 0, cols() - n, rows(), n);
}
/** This is the const version of rightCols<int>().*/
template<int N>
-inline typename ConstNColsBlockXpr<N>::Type rightCols() const
+inline typename ConstNColsBlockXpr<N>::Type rightCols(Index n = N) const
{
- return typename ConstNColsBlockXpr<N>::Type(derived(), 0, cols() - N, rows(), N);
+ return typename ConstNColsBlockXpr<N>::Type(derived(), 0, cols() - n, rows(), n);
}
@@ -491,8 +633,12 @@ inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const
/** \returns a block consisting of a range of columns of *this.
*
- * \tparam N the number of columns in the block
+ * \tparam N the number of columns in the block as specified at compile-time
* \param startCol the index of the first column in the block
+ * \param n the number of columns in the block as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
*
* Example: \include DenseBase_template_int_middleCols.cpp
* Output: \verbinclude DenseBase_template_int_middleCols.out
@@ -500,16 +646,16 @@ inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const
* \sa class Block, block(Index,Index,Index,Index)
*/
template<int N>
-inline typename NColsBlockXpr<N>::Type middleCols(Index startCol)
+inline typename NColsBlockXpr<N>::Type middleCols(Index startCol, Index n = N)
{
- return typename NColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), N);
+ return typename NColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), n);
}
/** This is the const version of middleCols<int>().*/
template<int N>
-inline typename ConstNColsBlockXpr<N>::Type middleCols(Index startCol) const
+inline typename ConstNColsBlockXpr<N>::Type middleCols(Index startCol, Index n = N) const
{
- return typename ConstNColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), N);
+ return typename ConstNColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), n);
}
@@ -543,6 +689,40 @@ inline const Block<const Derived, BlockRows, BlockCols> block(Index startRow, In
return Block<const Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
}
+/** \returns an expression of a block in *this.
+ *
+ * \tparam BlockRows number of rows in block as specified at compile-time
+ * \tparam BlockCols number of columns in block as specified at compile-time
+ * \param startRow the first row in the block
+ * \param startCol the first column in the block
+ * \param blockRows number of rows in block as specified at run-time
+ * \param blockCols number of columns in block as specified at run-time
+ *
+ * This function is mainly useful for blocks where the number of rows is specified at compile-time
+ * and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a blockRows should equal \a BlockRows unless
+ * \a BlockRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_block_int_int_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_block_int_int_int_int.cpp
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<int BlockRows, int BlockCols>
+inline Block<Derived, BlockRows, BlockCols> block(Index startRow, Index startCol,
+ Index blockRows, Index blockCols)
+{
+ return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol, blockRows, blockCols);
+}
+
+/** This is the const version of block<>(Index, Index, Index, Index). */
+template<int BlockRows, int BlockCols>
+inline const Block<const Derived, BlockRows, BlockCols> block(Index startRow, Index startCol,
+ Index blockRows, Index blockCols) const
+{
+ return Block<const Derived, BlockRows, BlockCols>(derived(), startRow, startCol, blockRows, blockCols);
+}
+
/** \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
*
* Example: \include MatrixBase_col.cpp
@@ -577,4 +757,179 @@ inline ConstRowXpr row(Index i) const
return ConstRowXpr(derived(), i);
}
-#endif // EIGEN_BLOCKMETHODS_H
+/** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
+ *
+ * \only_for_vectors
+ *
+ * \param start the first coefficient in the segment
+ * \param n the number of coefficients in the segment
+ *
+ * Example: \include MatrixBase_segment_int_int.cpp
+ * Output: \verbinclude MatrixBase_segment_int_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, segment(Index)
+ */
+inline SegmentReturnType segment(Index start, Index n)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return SegmentReturnType(derived(), start, n);
+}
+
+
+/** This is the const version of segment(Index,Index).*/
+inline ConstSegmentReturnType segment(Index start, Index n) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return ConstSegmentReturnType(derived(), start, n);
+}
+
+/** \returns a dynamic-size expression of the first coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \param n the number of coefficients in the segment
+ *
+ * Example: \include MatrixBase_start_int.cpp
+ * Output: \verbinclude MatrixBase_start_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(Index,Index)
+ */
+inline SegmentReturnType head(Index n)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return SegmentReturnType(derived(), 0, n);
+}
+
+/** This is the const version of head(Index).*/
+inline ConstSegmentReturnType head(Index n) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return ConstSegmentReturnType(derived(), 0, n);
+}
+
+/** \returns a dynamic-size expression of the last coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \param n the number of coefficients in the segment
+ *
+ * Example: \include MatrixBase_end_int.cpp
+ * Output: \verbinclude MatrixBase_end_int.out
+ *
+ * \note Even though the returned expression has dynamic size, in the case
+ * when it is applied to a fixed-size vector, it inherits a fixed maximal size,
+ * which means that evaluating it does not cause a dynamic memory allocation.
+ *
+ * \sa class Block, block(Index,Index)
+ */
+inline SegmentReturnType tail(Index n)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return SegmentReturnType(derived(), this->size() - n, n);
+}
+
+/** This is the const version of tail(Index).*/
+inline ConstSegmentReturnType tail(Index n) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return ConstSegmentReturnType(derived(), this->size() - n, n);
+}
+
+/** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this
+ *
+ * \only_for_vectors
+ *
+ * \tparam N the number of coefficients in the segment as specified at compile-time
+ * \param start the index of the first element in the segment
+ * \param n the number of coefficients in the segment as specified at compile-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
+ *
+ * Example: \include MatrixBase_template_int_segment.cpp
+ * Output: \verbinclude MatrixBase_template_int_segment.out
+ *
+ * \sa class Block
+ */
+template<int N>
+inline typename FixedSegmentReturnType<N>::Type segment(Index start, Index n = N)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename FixedSegmentReturnType<N>::Type(derived(), start, n);
+}
+
+/** This is the const version of segment<int>(Index).*/
+template<int N>
+inline typename ConstFixedSegmentReturnType<N>::Type segment(Index start, Index n = N) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename ConstFixedSegmentReturnType<N>::Type(derived(), start, n);
+}
+
+/** \returns a fixed-size expression of the first coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \tparam N the number of coefficients in the segment as specified at compile-time
+ * \param n the number of coefficients in the segment as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
+ *
+ * Example: \include MatrixBase_template_int_start.cpp
+ * Output: \verbinclude MatrixBase_template_int_start.out
+ *
+ * \sa class Block
+ */
+template<int N>
+inline typename FixedSegmentReturnType<N>::Type head(Index n = N)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename FixedSegmentReturnType<N>::Type(derived(), 0, n);
+}
+
+/** This is the const version of head<int>().*/
+template<int N>
+inline typename ConstFixedSegmentReturnType<N>::Type head(Index n = N) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename ConstFixedSegmentReturnType<N>::Type(derived(), 0, n);
+}
+
+/** \returns a fixed-size expression of the last coefficients of *this.
+ *
+ * \only_for_vectors
+ *
+ * \tparam N the number of coefficients in the segment as specified at compile-time
+ * \param n the number of coefficients in the segment as specified at run-time
+ *
+ * The compile-time and run-time information should not contradict. In other words,
+ * \a n should equal \a N unless \a N is \a Dynamic.
+ *
+ * Example: \include MatrixBase_template_int_end.cpp
+ * Output: \verbinclude MatrixBase_template_int_end.out
+ *
+ * \sa class Block
+ */
+template<int N>
+inline typename FixedSegmentReturnType<N>::Type tail(Index n = N)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename FixedSegmentReturnType<N>::Type(derived(), size() - n);
+}
+
+/** This is the const version of tail<int>.*/
+template<int N>
+inline typename ConstFixedSegmentReturnType<N>::Type tail(Index n = N) const
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ return typename ConstFixedSegmentReturnType<N>::Type(derived(), size() - n);
+}
diff --git a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
index 3a737df7b86..7f62149e04b 100644
--- a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
+++ b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
@@ -83,7 +83,7 @@ cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const ConstantReturnType>
cwiseMin(const Scalar &other) const
{
- return cwiseMin(Derived::PlainObject::Constant(rows(), cols(), other));
+ return cwiseMin(Derived::Constant(rows(), cols(), other));
}
/** \returns an expression of the coefficient-wise max of *this and \a other
@@ -107,7 +107,7 @@ cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType>
cwiseMax(const Scalar &other) const
{
- return cwiseMax(Derived::PlainObject::Constant(rows(), cols(), other));
+ return cwiseMax(Derived::Constant(rows(), cols(), other));
}
diff --git a/extern/Eigen3/eigen-update.sh b/extern/Eigen3/eigen-update.sh
index 7be67890173..1cf0337adf6 100755..100644
--- a/extern/Eigen3/eigen-update.sh
+++ b/extern/Eigen3/eigen-update.sh
@@ -17,7 +17,7 @@ if [ -d eigen ]
then
cd eigen
# put here the version you want to use
- hg up 3.0
+ hg up 3.2.1
rm -f `find Eigen/ -type f -name "CMakeLists.txt"`
cp -r Eigen ..
cd ..
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
index aff9f27f594..aff9f27f594 100755..100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
index 57ebb47d8e7..57ebb47d8e7 100755..100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
index 27ccefe4169..8e4456e617a 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
@@ -37,8 +37,13 @@ struct btSimdScalar
{
}
-
+/* workaround for clang 3.4 ( == apple clang 5.1 ) issue, friction would fail with forced inlining */
+#if (defined(__clang__) && defined(__apple_build_version__) && (__clang_major__ == 5) && (__clang_minor__ == 1)) \
+|| (defined(__clang__) && !defined(__apple_build_version__) && (__clang_major__ == 3) && (__clang_minor__ == 4))
+ inline __attribute__ ((noinline)) btSimdScalar(float fl)
+#else
SIMD_FORCE_INLINE btSimdScalar(float fl)
+#endif
:m_vec128 (_mm_set1_ps(fl))
{
}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
index cf735569a9d..893453bddaf 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
@@ -354,11 +354,11 @@ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float
// btVoronoiSimplexSolver sGjkSimplexSolver;
// btGjkEpaPenetrationDepthSolver penSolverPtr;
- static btSimplexSolverInterface sGjkSimplexSolver;
+ /*static*/ btSimplexSolverInterface sGjkSimplexSolver;
sGjkSimplexSolver.reset();
- static btGjkEpaPenetrationDepthSolver Solver0;
- static btMinkowskiPenetrationDepthSolver Solver1;
+ /*static*/ btGjkEpaPenetrationDepthSolver Solver0;
+ /*static*/ btMinkowskiPenetrationDepthSolver Solver1;
btConvexPenetrationDepthSolver* Solver = NULL;
diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript
index ff2e86affb4..20a87d5d12c 100644
--- a/extern/bullet2/src/SConscript
+++ b/extern/bullet2/src/SConscript
@@ -19,7 +19,7 @@ elif env['OURPLATFORM'] in ('linux', 'freebsd4', 'freebsd5'):
cflags += ['-O2']
elif sys.platform=='darwin':
defs += ' NDEBUG'
- cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math']
+ cflags += ['-O3','-fPIC']
bullet2_src = env.Glob("LinearMath/*.cpp")
bullet2_src += env.Glob("BulletCollision/BroadphaseCollision/*.cpp")
@@ -37,7 +37,4 @@ bullet2_src += env.Glob("BulletSoftBody/*.cpp")
incs = '. BulletCollision BulletDynamics LinearMath BulletSoftBody'
-if sys.platform=='darwin' and env['CC'][:-2].endswith('4.6'): # workaround for an gcc-4.6 compiler bug
- env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags, cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
-else:
- env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags )
+env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags )
diff --git a/extern/carve/CMakeLists.txt b/extern/carve/CMakeLists.txt
index 11a92f92abc..5754290d710 100644
--- a/extern/carve/CMakeLists.txt
+++ b/extern/carve/CMakeLists.txt
@@ -140,6 +140,7 @@ set(SRC
include/carve/tag.hpp
include/carve/timing.hpp
include/carve/tree.hpp
+ include/carve/triangle_intersection.hpp
include/carve/triangulator.hpp
include/carve/triangulator_impl.hpp
include/carve/util.hpp
diff --git a/extern/carve/bundle.sh b/extern/carve/bundle.sh
index 91d5f44a880..2a3e621fab0 100755..100644
--- a/extern/carve/bundle.sh
+++ b/extern/carve/bundle.sh
@@ -111,6 +111,7 @@ cat > SConscript << EOF
Import ('env')
sources = env.Glob('lib/*.cpp')
+sources += env.Glob('*.cc')
defs = []
incs = ['include']
diff --git a/extern/carve/carve-capi.cc b/extern/carve/carve-capi.cc
index aaf5761516c..af9ecad685d 100644
--- a/extern/carve/carve-capi.cc
+++ b/extern/carve/carve-capi.cc
@@ -29,6 +29,8 @@
#include <carve/interpolator.hpp>
#include <carve/rescale.hpp>
+#include <carve/csg_triangulator.hpp>
+#include <carve/mesh_simplify.hpp>
using carve::mesh::MeshSet;
@@ -36,14 +38,15 @@ typedef std::pair<int, int> OrigIndex;
typedef std::pair<MeshSet<3>::vertex_t *, MeshSet<3>::vertex_t *> VertexPair;
typedef carve::interpolate::VertexAttr<OrigIndex> OrigVertMapping;
typedef carve::interpolate::FaceAttr<OrigIndex> OrigFaceMapping;
-typedef carve::interpolate::FaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
+typedef carve::interpolate::SwapableFaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
+typedef carve::interpolate::SimpleFaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
typedef struct CarveMeshDescr {
// Stores mesh data itself.
MeshSet<3> *poly;
// N-th element of the vector indicates index of an original mesh loop.
- std::vector<int> orig_loop_index_map;
+ std::unordered_map<std::pair<int, int>, int> orig_loop_index_map;
// N-th element of the vector indicates index of an original mesh poly.
std::vector<int> orig_poly_index_map;
@@ -56,6 +59,8 @@ typedef struct CarveMeshDescr {
// Mapping from the face edges back to (original edge index, original loop index).
OrigFaceEdgeMapping orig_face_edge_mapping;
+ FaceEdgeTriangulatedFlag face_edge_triangulated_flag;
+
// Mapping from the faces back to original poly index.
OrigFaceMapping orig_face_mapping;
} CarveMeshDescr;
@@ -118,6 +123,24 @@ bool edgeIndexMap_get_if_exists(const std::unordered_map<std::pair<T1, T1>, T2>
return true;
}
+template <typename T1, typename T2>
+bool edgeIndexMap_exists(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
+ const T1 &v1,
+ const T1 &v2)
+{
+ typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
+ typename Map::const_iterator found;
+
+ if (v1 < v2) {
+ found = edge_map.find(std::make_pair(v1, v2));
+ }
+ else {
+ found = edge_map.find(std::make_pair(v2, v1));
+ }
+
+ return found != edge_map.end();
+}
+
template <typename T>
inline int indexOf(const T *element, const std::vector<T> &vector_from)
{
@@ -126,10 +149,11 @@ inline int indexOf(const T *element, const std::vector<T> &vector_from)
void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
int which_mesh,
- const std::vector<int> &orig_loop_index_map,
+ std::unordered_map<std::pair<int, int>, int> &orig_loop_index_map,
const std::vector<int> &orig_poly_index_map,
OrigVertMapping *orig_vert_mapping,
OrigFaceEdgeMapping *orig_face_edge_mapping,
+ FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
OrigFaceMapping *orig_face_attr)
{
MeshSet<3> *poly = mesh->poly;
@@ -160,7 +184,17 @@ void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
edge_iter != face->end();
++edge_iter, ++loop_map_index)
{
- int orig_loop_index = orig_loop_index_map[loop_map_index];
+ int v1 = indexOf(edge_iter->v1(), poly->vertex_storage);
+ int v2 = indexOf(edge_iter->v2(), poly->vertex_storage);
+
+ int orig_loop_index;
+ if (!edgeIndexMap_get_if_exists(orig_loop_index_map,
+ v1, v2,
+ &orig_loop_index))
+ {
+ orig_loop_index = -1;
+ }
+
if (orig_loop_index != -1) {
// Mapping from carve face edge back to original loop index.
orig_face_edge_mapping->setAttribute(face,
@@ -168,6 +202,11 @@ void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
std::make_pair(which_mesh,
orig_loop_index));
}
+ else {
+ face_edge_triangulated_flag->setAttribute(face,
+ edge_iter.idx(),
+ true);
+ }
}
}
}
@@ -176,6 +215,7 @@ void initOrigIndexMapping(CarveMeshDescr *left_mesh,
CarveMeshDescr *right_mesh,
OrigVertMapping *orig_vert_mapping,
OrigFaceEdgeMapping *orig_face_edge_mapping,
+ FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
OrigFaceMapping *orig_face_mapping)
{
initOrigIndexMeshFaceMapping(left_mesh,
@@ -184,6 +224,7 @@ void initOrigIndexMapping(CarveMeshDescr *left_mesh,
left_mesh->orig_poly_index_map,
orig_vert_mapping,
orig_face_edge_mapping,
+ face_edge_triangulated_flag,
orig_face_mapping);
initOrigIndexMeshFaceMapping(right_mesh,
@@ -192,9 +233,328 @@ void initOrigIndexMapping(CarveMeshDescr *left_mesh,
right_mesh->orig_poly_index_map,
orig_vert_mapping,
orig_face_edge_mapping,
+ face_edge_triangulated_flag,
orig_face_mapping);
}
+void origEdgeMappingForFace(MeshSet<3>::face_t *face,
+ OrigFaceEdgeMapping *orig_face_edge_mapping,
+ std::unordered_map<VertexPair, OrigIndex> *edge_origindex_map)
+{
+ OrigIndex origindex_none = std::make_pair((int)CARVE_MESH_NONE, -1);
+
+ MeshSet<3>::edge_t *edge = face->edge;
+ for (int i = 0;
+ i < face->nEdges();
+ ++i, edge = edge->next)
+ {
+ MeshSet<3>::vertex_t *v1 = edge->v1();
+ MeshSet<3>::vertex_t *v2 = edge->v2();
+
+ OrigIndex orig_edge_index =
+ orig_face_edge_mapping->getAttribute(edge->face, i, origindex_none);
+
+ edgeIndexMap_put(edge_origindex_map, v1, v2, orig_edge_index);
+ }
+}
+
+void dissolveTriangulatedEdges(MeshSet<3>::mesh_t *mesh,
+ const std::set< std::pair<int, int> > &open_edges,
+ FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
+ OrigFaceEdgeMapping *orig_face_edge_mapping)
+{
+ typedef std::unordered_set<MeshSet<3>::edge_t *> edge_set_t;
+ typedef std::unordered_set<MeshSet<3>::face_t *> face_set_t;
+ edge_set_t triangulated_face_edges;
+
+ for (int face_index = 0; face_index < mesh->faces.size(); ++face_index) {
+ MeshSet<3>::face_t *face = mesh->faces[face_index];
+ MeshSet<3>::edge_t *edge = face->edge;
+ for (int edge_index = 0;
+ edge_index < face->nEdges();
+ ++edge_index, edge = edge->next)
+ {
+ if (edge->rev) {
+ const bool is_triangulated_edge =
+ face_edge_triangulated_flag->getAttribute(face,
+ edge_index,
+ false);
+ if (is_triangulated_edge) {
+ MeshSet<3>::edge_t *e1 = std::min(edge, edge->rev);
+ int v1 = indexOf(e1->v1(), mesh->meshset->vertex_storage),
+ v2 = indexOf(e1->v2(), mesh->meshset->vertex_storage);
+
+ bool is_open = false;
+ if (v1 < v2) {
+ is_open = open_edges.find(std::make_pair(v1, v2)) != open_edges.end();
+ }
+ else {
+ is_open = open_edges.find(std::make_pair(v2, v1)) != open_edges.end();
+ }
+
+ if (is_open == false) {
+ triangulated_face_edges.insert(e1);
+ }
+ }
+ }
+ }
+ }
+
+ if (triangulated_face_edges.size()) {
+ face_set_t triangulated_faces;
+ std::unordered_map<VertexPair, OrigIndex> edge_origindex_map;
+
+ for (edge_set_t::iterator it = triangulated_face_edges.begin();
+ it != triangulated_face_edges.end();
+ ++it)
+ {
+ MeshSet<3>::edge_t *edge = *it;
+
+ origEdgeMappingForFace(edge->face,
+ orig_face_edge_mapping,
+ &edge_origindex_map);
+ triangulated_faces.insert(edge->face);
+
+ origEdgeMappingForFace(edge->rev->face,
+ orig_face_edge_mapping,
+ &edge_origindex_map);
+ triangulated_faces.insert(edge->rev->face);
+ }
+
+ carve::mesh::MeshSimplifier simplifier;
+ simplifier.dissolveMeshEdges(mesh, triangulated_face_edges);
+
+ for (int face_index = 0; face_index < mesh->faces.size(); face_index++) {
+ MeshSet<3>::face_t *face = mesh->faces[face_index];
+
+ if (triangulated_faces.find(face) != triangulated_faces.end()) {
+ MeshSet<3>::edge_t *edge = face->edge;
+ for (int edge_index = 0;
+ edge_index < face->nEdges();
+ ++edge_index, edge = edge->next)
+ {
+ MeshSet<3>::vertex_t *v1 = edge->v1();
+ MeshSet<3>::vertex_t *v2 = edge->v2();
+
+ OrigIndex orig_edge_index =
+ edgeIndexMap_get(edge_origindex_map,
+ v1,
+ v2);
+
+ orig_face_edge_mapping->setAttribute(face, edge_index, orig_edge_index);
+ }
+ }
+ }
+ }
+}
+
+void dissolveTriangulatedEdges(CarveMeshDescr *mesh_descr)
+{
+ MeshSet<3> *poly = mesh_descr->poly;
+ FaceEdgeTriangulatedFlag *face_edge_triangulated_flag =
+ &mesh_descr->face_edge_triangulated_flag;
+
+ std::set< std::pair<int, int> > open_edges;
+ for (int mesh_index = 0;
+ mesh_index < poly->meshes.size();
+ ++mesh_index)
+ {
+ const MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
+ for (int edge_index = 0;
+ edge_index < mesh->open_edges.size();
+ ++edge_index)
+ {
+ const MeshSet<3>::edge_t *edge = mesh->open_edges[edge_index];
+ int v1 = indexOf(edge->v1(), poly->vertex_storage),
+ v2 = indexOf(edge->v2(), poly->vertex_storage);
+ if (v1 < v2) {
+ open_edges.insert(std::make_pair(v1, v2));
+ }
+ else {
+ open_edges.insert(std::make_pair(v2, v1));
+ }
+ }
+ }
+
+ for (int mesh_index = 0; mesh_index < poly->meshes.size(); ++mesh_index) {
+ MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
+ dissolveTriangulatedEdges(mesh,
+ open_edges,
+ face_edge_triangulated_flag,
+ &mesh_descr->orig_face_edge_mapping);
+ }
+}
+
+void clipEar(MeshSet<3>::edge_t *ear)
+{
+ MeshSet<3>::edge_t *p_edge = ear->prev;
+ MeshSet<3>::edge_t *n_edge = ear->next;
+
+ p_edge->next = n_edge;
+ n_edge->prev = p_edge;
+
+ if (ear->face->edge == ear) {
+ ear->face->edge = n_edge;
+ }
+ ear->face->n_edges--;
+
+ delete ear;
+}
+
+MeshSet<3>::edge_t *findDegenerateEar(MeshSet<3>::face_t *face)
+{
+ for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
+ edge_iter != face->end();
+ ++edge_iter)
+ {
+ MeshSet<3>::edge_t &edge = *edge_iter;
+ if (edge.vert == edge.next->next->vert) {
+ return edge.next->next;
+ }
+ }
+ return NULL;
+}
+
+class EarClipper : public carve::csg::CSG::Hook {
+public:
+ virtual ~EarClipper() {
+ }
+
+ virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
+ const MeshSet<3>::face_t *orig,
+ bool flipped) {
+ for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
+ carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
+
+ // There's no ears in quads and tris.
+ if (face->nVertices() <= 4) {
+ continue;
+ }
+
+ MeshSet<3>::edge_t *ear;
+ while ((ear = findDegenerateEar(face)) != NULL) {
+ clipEar(ear);
+ }
+
+ }
+ }
+};
+
+class HoleResolver : public carve::csg::CarveHoleResolver {
+
+ void removeDuplicatedFaces(std::vector<MeshSet<3>::face_t *> &faces) {
+ std::vector<MeshSet<3>::face_t *> out_faces;
+ std::vector<MeshSet<3>::face_t *> duplicated_faces;
+
+ for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
+ carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
+ face->canonicalize();
+ }
+
+ for (size_t i = 0; i < faces.size(); ++i) {
+ carve::mesh::MeshSet<3>::face_t *face = faces[i];
+
+ bool found = false;
+ for (size_t j = i + 1; j < faces.size() && found == false; ++j) {
+ MeshSet<3>::face_t *cur_face = faces[j];
+ if (cur_face->nEdges() == face->nEdges() &&
+ cur_face->edge->vert == face->edge->vert)
+ {
+
+ MeshSet<3>::edge_t *cur_edge = cur_face->edge,
+ *forward_edge = face->edge,
+ *backward_edge = face->edge;
+ bool forward_matches = true, backward_matches = true;
+
+ for (int a = 0; a < cur_face->nEdges(); ++a) {
+ if (forward_edge->vert != cur_edge->vert) {
+ forward_matches = false;
+ if (backward_matches == false) {
+ break;
+ }
+ }
+
+ if (backward_edge->vert != cur_edge->vert) {
+ backward_matches = false;
+ if (forward_matches == false) {
+ break;
+ }
+ }
+
+ cur_edge = cur_edge->next;
+ forward_edge = forward_edge->next;
+ backward_edge = backward_edge->prev;
+ }
+
+ if (forward_matches || backward_matches) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ duplicated_faces.push_back(face);
+ }
+ else {
+ out_faces.push_back(face);
+ }
+ }
+
+ for (int i = 0; i < duplicated_faces.size(); ++i) {
+ delete duplicated_faces[i];
+ }
+
+ std::swap(faces, out_faces);
+ }
+
+public:
+ virtual ~HoleResolver() {
+ }
+
+ virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
+ const MeshSet<3>::face_t *orig,
+ bool flipped) {
+ carve::csg::CarveHoleResolver::processOutputFace(faces, orig, flipped);
+ if (faces.size() > 1) {
+ removeDuplicatedFaces(faces);
+ }
+ }
+};
+
+template <typename Interpolator>
+void copyFaceEdgeAttrs(const MeshSet<3> *poly,
+ Interpolator *old_interpolator,
+ Interpolator *new_interpolator)
+{
+ for (MeshSet<3>::const_face_iter face_iter = poly->faceBegin();
+ face_iter != poly->faceEnd();
+ ++face_iter)
+ {
+ const MeshSet<3>::face_t *face = *face_iter;
+
+ for (int edge_index = 0;
+ edge_index < face->nEdges();
+ ++edge_index)
+ {
+ new_interpolator->copyAttribute(face,
+ edge_index,
+ old_interpolator);
+ }
+ }
+}
+
+template <typename Interpolator>
+void cleanupFaceEdgeAttrs(const MeshSet<3> *left,
+ const MeshSet<3> *right,
+ Interpolator *interpolator)
+{
+ Interpolator new_interpolator;
+ copyFaceEdgeAttrs(left, interpolator, &new_interpolator);
+ copyFaceEdgeAttrs(right, interpolator, &new_interpolator);
+ interpolator->swapAttributes(&new_interpolator);
+}
+
} // namespace
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
@@ -227,8 +587,8 @@ CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
int num_tessellated_polys = 0;
std::vector<int> face_indices;
face_indices.reserve(num_loops);
- mesh_descr->orig_loop_index_map.reserve(num_polys);
mesh_descr->orig_poly_index_map.reserve(num_polys);
+ TrianglesStorage triangles_storage;
for (int i = 0; i < num_polys; i++) {
int verts_per_poly =
mesh_importer->getNumPolyVerts(import_data, i);
@@ -255,31 +615,35 @@ CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
verts_per_poly,
verts_of_poly,
&axis_matrix)) {
- int num_triangles;
-
- num_triangles = carve_triangulatePoly(import_data,
- mesh_importer,
- i,
- loop_index,
- vertices,
- verts_per_poly,
- verts_of_poly,
- axis_matrix,
- &face_indices,
- &mesh_descr->orig_loop_index_map,
- &mesh_descr->orig_poly_index_map);
+ int num_triangles = carve_triangulatePoly(import_data,
+ mesh_importer,
+ vertices,
+ verts_per_poly,
+ verts_of_poly,
+ axis_matrix,
+ &face_indices,
+ &triangles_storage);
+
+ for (int j = 0; j < num_triangles; ++j) {
+ mesh_descr->orig_poly_index_map.push_back(i);
+ }
num_tessellated_polys += num_triangles;
}
else {
face_indices.push_back(verts_per_poly);
for (int j = 0; j < verts_per_poly; ++j) {
- mesh_descr->orig_loop_index_map.push_back(loop_index++);
face_indices.push_back(verts_of_poly[j]);
}
mesh_descr->orig_poly_index_map.push_back(i);
num_tessellated_polys++;
}
+
+ for (int j = 0; j < verts_per_poly; ++j) {
+ int v1 = verts_of_poly[j];
+ int v2 = verts_of_poly[(j + 1) % verts_per_poly];
+ edgeIndexMap_put(&mesh_descr->orig_loop_index_map, v1, v2, loop_index++);
+ }
}
if (verts_of_poly_dynamic != NULL) {
@@ -344,12 +708,20 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
initOrigIndexMapping(left_mesh, right_mesh,
&output_descr->orig_vert_mapping,
&output_descr->orig_face_edge_mapping,
+ &output_descr->face_edge_triangulated_flag,
&output_descr->orig_face_mapping);
carve::csg::CSG csg;
+ csg.hooks.registerHook(new HoleResolver,
+ carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
+
+ csg.hooks.registerHook(new EarClipper,
+ carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
+
output_descr->orig_vert_mapping.installHooks(csg);
output_descr->orig_face_edge_mapping.installHooks(csg);
+ output_descr->face_edge_triangulated_flag.installHooks(csg);
output_descr->orig_face_mapping.installHooks(csg);
// Prepare operands for actual boolean operation.
@@ -359,7 +731,15 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
// intersecting that meshes tessellation of operation result can't be
// done properly. The only way to make such situations working is to
// union intersecting meshes of the same operand.
- carve_unionIntersections(&csg, &left, &right);
+ if (carve_unionIntersections(&csg, &left, &right)) {
+ cleanupFaceEdgeAttrs(left,
+ right,
+ &output_descr->face_edge_triangulated_flag);
+ cleanupFaceEdgeAttrs(left,
+ right,
+ &output_descr->orig_face_edge_mapping);
+ }
+
left_mesh->poly = left;
right_mesh->poly = right;
@@ -377,8 +757,11 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
op,
NULL,
carve::csg::CSG::CLASSIFY_EDGE);
+
if (output_descr->poly) {
output_descr->poly->transform(rev_r);
+
+ dissolveTriangulatedEdges(output_descr);
}
}
catch (carve::exception e) {
@@ -393,33 +776,32 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
return output_descr->poly != NULL;
}
-static void exportMesh_handle_edges_list(MeshSet<3> *poly,
- const std::vector<MeshSet<3>::edge_t*> &edges,
- int start_edge_index,
- CarveMeshExporter *mesh_exporter,
- struct ExportMeshData *export_data,
- const std::unordered_map<VertexPair, OrigIndex> &edge_origindex_map,
- std::unordered_map<VertexPair, int> *edge_map)
+static int exportMesh_handle_edges_list(MeshSet<3> *poly,
+ const std::vector<MeshSet<3>::edge_t*> &edges,
+ int start_edge_index,
+ CarveMeshExporter *mesh_exporter,
+ struct ExportMeshData *export_data,
+ std::unordered_map<VertexPair, OrigIndex> &edge_origindex_map,
+ std::unordered_map<VertexPair, int> *edge_map)
{
+ int num_exported_edges = 0;
+
for (int i = 0, edge_index = start_edge_index;
i < edges.size();
- ++i, ++edge_index)
+ ++i)
{
MeshSet<3>::edge_t *edge = edges.at(i);
- MeshSet<3>::vertex_t *v1 = edge->vert;
- MeshSet<3>::vertex_t *v2 = edge->next->vert;
+ MeshSet<3>::vertex_t *v1 = edge->v1();
+ MeshSet<3>::vertex_t *v2 = edge->v2();
- OrigIndex orig_edge_index;
-
- if (!edgeIndexMap_get_if_exists(edge_origindex_map,
- v1,
- v2,
- &orig_edge_index))
- {
- orig_edge_index.first = CARVE_MESH_NONE;
- orig_edge_index.second = -1;
+ if (edgeIndexMap_exists(*edge_map, v1, v2)) {
+ continue;
}
+ const OrigIndex &orig_edge_index = edgeIndexMap_get(edge_origindex_map,
+ v1,
+ v2);
+
mesh_exporter->setEdge(export_data,
edge_index,
indexOf(v1, poly->vertex_storage),
@@ -428,7 +810,11 @@ static void exportMesh_handle_edges_list(MeshSet<3> *poly,
orig_edge_index.second);
edgeIndexMap_put(edge_map, v1, v2, edge_index);
+ ++edge_index;
+ ++num_exported_edges;
}
+
+ return num_exported_edges;
}
void carve_exportMesh(CarveMeshDescr *mesh_descr,
@@ -440,28 +826,6 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
int num_vertices = poly->vertex_storage.size();
int num_edges = 0, num_loops = 0, num_polys = 0;
- // Count edges from all manifolds.
- for (int i = 0; i < poly->meshes.size(); ++i) {
- carve::mesh::Mesh<3> *mesh = poly->meshes[i];
- num_edges += mesh->closed_edges.size() + mesh->open_edges.size();
- }
-
- // Count polys and loops from all manifolds.
- for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
- face_iter != poly->faceEnd();
- ++face_iter, ++num_polys)
- {
- MeshSet<3>::face_t *face = *face_iter;
- num_loops += face->n_edges;
- }
-
- // Initialize arrays for geometry in exported mesh.
- mesh_exporter->initGeomArrays(export_data,
- num_vertices,
- num_edges,
- num_loops,
- num_polys);
-
// Get mapping from edge denoted by vertex pair to original edge index,
//
// This is needed because internally Carve interpolates data for per-face
@@ -484,23 +848,45 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
edge_iter_index,
origindex_none);
- if (orig_loop_index.first != CARVE_MESH_NONE) {
- OrigIndex orig_edge_index;
+ OrigIndex orig_edge_index;
+ if (orig_loop_index.first != CARVE_MESH_NONE) {
orig_edge_index.first = orig_loop_index.first;
orig_edge_index.second =
mesh_exporter->mapLoopToEdge(export_data,
orig_loop_index.first,
orig_loop_index.second);
+ }
+ else {
+ orig_edge_index.first = CARVE_MESH_NONE;
+ orig_edge_index.second = -1;
+ }
- MeshSet<3>::vertex_t *v1 = edge.vert;
- MeshSet<3>::vertex_t *v2 = edge.next->vert;
+ MeshSet<3>::vertex_t *v1 = edge.v1();
+ MeshSet<3>::vertex_t *v2 = edge.v2();
- edgeIndexMap_put(&edge_origindex_map, v1, v2, orig_edge_index);
- }
+ edgeIndexMap_put(&edge_origindex_map, v1, v2, orig_edge_index);
}
}
+ num_edges = edge_origindex_map.size();
+
+ // Count polys and loops from all manifolds.
+ for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
+ face_iter != poly->faceEnd();
+ ++face_iter, ++num_polys)
+ {
+ MeshSet<3>::face_t *face = *face_iter;
+ num_loops += face->nEdges();
+ }
+
+ // Initialize arrays for geometry in exported mesh.
+ mesh_exporter->initGeomArrays(export_data,
+ num_vertices,
+ num_edges,
+ num_loops,
+ num_polys);
+
// Export all the vertices.
std::vector<MeshSet<3>::vertex_t>::iterator vertex_iter = poly->vertex_storage.begin();
for (int i = 0; vertex_iter != poly->vertex_storage.end(); ++i, ++vertex_iter) {
@@ -523,24 +909,22 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
for (int i = 0, edge_index = 0; i < poly->meshes.size(); ++i) {
carve::mesh::Mesh<3> *mesh = poly->meshes[i];
// Export closed edges.
- exportMesh_handle_edges_list(poly,
- mesh->closed_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
- edge_index += mesh->closed_edges.size();
+ edge_index += exportMesh_handle_edges_list(poly,
+ mesh->closed_edges,
+ edge_index,
+ mesh_exporter,
+ export_data,
+ edge_origindex_map,
+ &edge_map);
// Export open edges.
- exportMesh_handle_edges_list(poly,
- mesh->open_edges,
- edge_index,
- mesh_exporter,
- export_data,
- edge_origindex_map,
- &edge_map);
- edge_index += mesh->open_edges.size();
+ edge_index += exportMesh_handle_edges_list(poly,
+ mesh->open_edges,
+ edge_index,
+ mesh_exporter,
+ export_data,
+ edge_origindex_map,
+ &edge_map);
}
// Export all the loops and polys.
@@ -565,15 +949,15 @@ void carve_exportMesh(CarveMeshDescr *mesh_descr,
origindex_none);
mesh_exporter->setLoop(export_data,
- loop_index,
- indexOf(edge.vert, poly->vertex_storage),
- edgeIndexMap_get(edge_map, edge.vert, edge.next->vert),
- orig_loop_index.first,
- orig_loop_index.second);
+ loop_index,
+ indexOf(edge.vert, poly->vertex_storage),
+ edgeIndexMap_get(edge_map, edge.v1(), edge.v2()),
+ orig_loop_index.first,
+ orig_loop_index.second);
}
mesh_exporter->setPoly(export_data,
- poly_index, start_loop_index, face->n_edges,
+ poly_index, start_loop_index, face->nEdges(),
orig_face_index.first, orig_face_index.second);
}
}
diff --git a/extern/carve/carve-util.cc b/extern/carve/carve-util.cc
index b9b7fb1c03f..d02b786fd2a 100644
--- a/extern/carve/carve-util.cc
+++ b/extern/carve/carve-util.cc
@@ -39,6 +39,7 @@ using carve::geom3d::Vector;
using carve::math::Matrix3;
using carve::mesh::Face;
using carve::mesh::MeshSet;
+using carve::triangulate::tri_idx;
using carve::triangulate::triangulate;
typedef std::map< MeshSet<3>::mesh_t*, RTreeNode<3, Face<3> *> * > RTreeCache;
@@ -48,84 +49,53 @@ namespace {
// Functions adopted from BLI_math.h to use Carve Vector and Matrix.
-void axis_angle_normalized_to_mat3(const Vector &normal,
- const double angle,
- Matrix3 *matrix)
+void transpose_m3__bli(double mat[3][3])
{
- double nsi[3], co, si, ico;
-
- /* now convert this to a 3x3 matrix */
- co = cos(angle);
- si = sin(angle);
-
- ico = (1.0 - co);
- nsi[0] = normal[0] * si;
- nsi[1] = normal[1] * si;
- nsi[2] = normal[2] * si;
-
- matrix->m[0][0] = ((normal[0] * normal[0]) * ico) + co;
- matrix->m[0][1] = ((normal[0] * normal[1]) * ico) + nsi[2];
- matrix->m[0][2] = ((normal[0] * normal[2]) * ico) - nsi[1];
- matrix->m[1][0] = ((normal[0] * normal[1]) * ico) - nsi[2];
- matrix->m[1][1] = ((normal[1] * normal[1]) * ico) + co;
- matrix->m[1][2] = ((normal[1] * normal[2]) * ico) + nsi[0];
- matrix->m[2][0] = ((normal[0] * normal[2]) * ico) + nsi[1];
- matrix->m[2][1] = ((normal[1] * normal[2]) * ico) - nsi[0];
- matrix->m[2][2] = ((normal[2] * normal[2]) * ico) + co;
+ double t;
+
+ t = mat[0][1];
+ mat[0][1] = mat[1][0];
+ mat[1][0] = t;
+ t = mat[0][2];
+ mat[0][2] = mat[2][0];
+ mat[2][0] = t;
+ t = mat[1][2];
+ mat[1][2] = mat[2][1];
+ mat[2][1] = t;
}
-void axis_angle_to_mat3(const Vector &axis,
- const double angle,
- Matrix3 *matrix)
+void ortho_basis_v3v3_v3__bli(double r_n1[3], double r_n2[3], const double n[3])
{
- if (axis.length2() < FLT_EPSILON) {
- *matrix = Matrix3();
- return;
+ const double eps = FLT_EPSILON;
+ const double f = (n[0] * n[0]) + (n[1] * n[1]);
+
+ if (f > eps) {
+ const double d = 1.0f / sqrt(f);
+
+ r_n1[0] = n[1] * d;
+ r_n1[1] = -n[0] * d;
+ r_n1[2] = 0.0f;
+ r_n2[0] = -n[2] * r_n1[1];
+ r_n2[1] = n[2] * r_n1[0];
+ r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
+ }
+ else {
+ /* degenerate case */
+ r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
+ r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
+ r_n2[1] = 1.0f;
}
-
- Vector nor = axis;
- nor.normalize();
-
- axis_angle_normalized_to_mat3(nor, angle, matrix);
-}
-
-inline double saacos(double fac)
-{
- if (fac <= -1.0) return M_PI;
- else if (fac >= 1.0) return 0.0;
- else return acos(fac);
}
-bool axis_dominant_v3_to_m3(const Vector &normal,
- Matrix3 *matrix)
+void axis_dominant_v3_to_m3__bli(Matrix3 *r_mat, const Vector &normal)
{
- Vector up;
- Vector axis;
- double angle;
-
- up.x = 0.0;
- up.y = 0.0;
- up.z = 1.0;
-
- axis = carve::geom::cross(normal, up);
- angle = saacos(carve::geom::dot(normal, up));
-
- if (angle >= FLT_EPSILON) {
- if (axis.length2() < FLT_EPSILON) {
- axis[0] = 0.0;
- axis[1] = 1.0;
- axis[2] = 0.0;
- }
+ memcpy(r_mat->m[2], normal.v, sizeof(double[3]));
+ ortho_basis_v3v3_v3__bli(r_mat->m[0], r_mat->m[1], r_mat->m[2]);
- axis_angle_to_mat3(axis, angle, matrix);
- return true;
- }
- else {
- *matrix = Matrix3();
- return false;
- }
+ transpose_m3__bli(r_mat->m);
}
+
void meshset_minmax(const MeshSet<3> *mesh,
Vector *min,
Vector *max)
@@ -485,14 +455,15 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
// TODO(sergey): This function is to be totally re-implemented to make it
// more clear what's going on and hopefully optimize it as well.
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
MeshSet<3> **left_r,
MeshSet<3> **right_r)
{
MeshSet<3> *left = *left_r, *right = *right_r;
+ bool changed = false;
if (left->meshes.size() == 1 && right->meshes.size() == 0) {
- return;
+ return false;
}
MeshSet<3>::aabb_t leftAABB = left->getAABB();
@@ -502,14 +473,19 @@ void carve_unionIntersections(carve::csg::CSG *csg,
right = unionIntersectingMeshes(csg, right, leftAABB);
if (left != *left_r) {
+ changed = true;
delete *left_r;
}
- if (right != *right_r)
+ if (right != *right_r) {
+ changed = true;
delete *right_r;
+ }
*left_r = left;
*right_r = right;
+
+ return changed;
}
static inline void add_newell_cross_v3_v3v3(const Vector &v_prev,
@@ -574,7 +550,7 @@ bool carve_checkPolyPlanarAndGetNormal(const std::vector<Vector> &vertices,
double magnitude = normal.length2();
normal.normalize();
- axis_dominant_v3_to_m3(normal, axis_matrix_r);
+ axis_dominant_v3_to_m3__bli(axis_matrix_r, normal);
Vector first_projected = *axis_matrix_r * vertices[verts_of_poly[0]];
double min_z = first_projected[2], max_z = first_projected[2];
@@ -607,7 +583,7 @@ int triangulateNGon_carveTriangulator(const std::vector<Vector> &vertices,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
- std::vector<carve::triangulate::tri_idx> *triangles)
+ std::vector<tri_idx> *triangles)
{
// Project vertices to 2D plane.
Vector projected;
@@ -619,6 +595,7 @@ int triangulateNGon_carveTriangulator(const std::vector<Vector> &vertices,
}
carve::triangulate::triangulate(poly_2d, *triangles);
+ carve::triangulate::improve(poly_2d, *triangles);
return triangles->size();
}
@@ -629,7 +606,7 @@ int triangulateNGon_importerTriangulator(struct ImportMeshData *import_data,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
- std::vector<carve::triangulate::tri_idx> *triangles)
+ std::vector<tri_idx> *triangles)
{
typedef float Vector2D[2];
typedef unsigned int Triangle[3];
@@ -652,10 +629,9 @@ int triangulateNGon_importerTriangulator(struct ImportMeshData *import_data,
triangles->reserve(num_triangles);
for (int i = 0; i < num_triangles; ++i) {
- triangles->push_back(
- carve::triangulate::tri_idx(api_triangles[i][0],
- api_triangles[i][1],
- api_triangles[i][2]));
+ triangles->push_back(tri_idx(api_triangles[i][0],
+ api_triangles[i][1],
+ api_triangles[i][2]));
}
delete [] poly_2d;
@@ -664,19 +640,52 @@ int triangulateNGon_importerTriangulator(struct ImportMeshData *import_data,
return num_triangles;
}
+template <typename T>
+void sortThreeNumbers(T &a, T &b, T &c)
+{
+ if (a > b)
+ std::swap(a, b);
+ if (b > c)
+ std::swap(b, c);
+ if (a > b)
+ std::swap(a, b);
+}
+
+bool pushTriangle(int v1, int v2, int v3,
+ std::vector<int> *face_indices,
+ TrianglesStorage *triangles_storage)
+{
+
+ tri_idx triangle(v1, v2, v3);
+ sortThreeNumbers(triangle.a, triangle.b, triangle.c);
+
+ assert(triangle.a < triangle.b);
+ assert(triangle.b < triangle.c);
+
+ if (triangles_storage->find(triangle) == triangles_storage->end()) {
+ face_indices->push_back(3);
+ face_indices->push_back(v1);
+ face_indices->push_back(v2);
+ face_indices->push_back(v3);
+
+ triangles_storage->insert(triangle);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
} // namespace
int carve_triangulatePoly(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer,
- int poly_index,
- int start_loop_index,
const std::vector<Vector> &vertices,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
std::vector<int> *face_indices,
- std::vector<int> *orig_loop_index_map,
- std::vector<int> *orig_poly_index_map)
+ TrianglesStorage *triangles_storage)
{
int num_triangles = 0;
@@ -689,57 +698,51 @@ int carve_triangulatePoly(struct ImportMeshData *import_data,
// TODO(sergey): Consider using shortest diagonal here. However
// display code in Blende use static 1-3 split, so some experiments
// are needed here.
- face_indices->push_back(3);
- face_indices->push_back(verts_of_poly[0]);
- face_indices->push_back(verts_of_poly[1]);
- face_indices->push_back(verts_of_poly[2]);
-
- orig_loop_index_map->push_back(start_loop_index);
- orig_loop_index_map->push_back(start_loop_index + 1);
- orig_loop_index_map->push_back(-1);
- orig_poly_index_map->push_back(poly_index);
-
- face_indices->push_back(3);
- face_indices->push_back(verts_of_poly[0]);
- face_indices->push_back(verts_of_poly[2]);
- face_indices->push_back(verts_of_poly[3]);
-
- orig_loop_index_map->push_back(-1);
- orig_loop_index_map->push_back(start_loop_index + 2);
- orig_loop_index_map->push_back(start_loop_index + 3);
- orig_poly_index_map->push_back(poly_index);
+ if (pushTriangle(verts_of_poly[0],
+ verts_of_poly[1],
+ verts_of_poly[2],
+ face_indices,
+ triangles_storage))
+ {
+ num_triangles++;
+ }
- num_triangles = 2;
+ if (pushTriangle(verts_of_poly[0],
+ verts_of_poly[2],
+ verts_of_poly[3],
+ face_indices,
+ triangles_storage))
+ {
+ num_triangles++;
+ }
}
else {
- std::vector<carve::triangulate::tri_idx> triangles;
+ std::vector<tri_idx> triangles;
triangles.reserve(verts_per_poly - 2);
// Make triangulator callback optional so we could do some tests
// in the future.
if (mesh_importer->triangulate2DPoly) {
- num_triangles =
- triangulateNGon_importerTriangulator(import_data,
- mesh_importer,
- vertices,
- verts_per_poly,
- verts_of_poly,
- axis_matrix,
- &triangles);
+ triangulateNGon_importerTriangulator(import_data,
+ mesh_importer,
+ vertices,
+ verts_per_poly,
+ verts_of_poly,
+ axis_matrix,
+ &triangles);
}
else {
- num_triangles =
- triangulateNGon_carveTriangulator(vertices,
- verts_per_poly,
- verts_of_poly,
- axis_matrix,
- &triangles);
+ triangulateNGon_carveTriangulator(vertices,
+ verts_per_poly,
+ verts_of_poly,
+ axis_matrix,
+ &triangles);
}
for (int i = 0; i < triangles.size(); ++i) {
- int v1 = triangles[i].c,
+ int v1 = triangles[i].a,
v2 = triangles[i].b,
- v3 = triangles[i].a;
+ v3 = triangles[i].c;
// Sanity check of the triangle.
assert(v1 != v2);
@@ -749,28 +752,14 @@ int carve_triangulatePoly(struct ImportMeshData *import_data,
assert(v2 < verts_per_poly);
assert(v3 < verts_per_poly);
- face_indices->push_back(3);
- face_indices->push_back(verts_of_poly[v3]);
- face_indices->push_back(verts_of_poly[v2]);
- face_indices->push_back(verts_of_poly[v1]);
-
-#define CHECK_TRIANGLE_LOOP_INDEX(v1, v2) \
- { \
- if (v2 == v1 + 1) { \
- orig_loop_index_map->push_back(start_loop_index + v1); \
- } \
- else { \
- orig_loop_index_map->push_back(-1); \
- } \
- } (void) 0
-
- CHECK_TRIANGLE_LOOP_INDEX(v1, v2);
- CHECK_TRIANGLE_LOOP_INDEX(v2, v3);
- CHECK_TRIANGLE_LOOP_INDEX(v3, v1);
-
-#undef CHECK_TRIANGLE_LOOP_INDEX
-
- orig_poly_index_map->push_back(poly_index);
+ if (pushTriangle(verts_of_poly[v1],
+ verts_of_poly[v2],
+ verts_of_poly[v3],
+ face_indices,
+ triangles_storage))
+ {
+ num_triangles++;
+ }
}
}
diff --git a/extern/carve/carve-util.h b/extern/carve/carve-util.h
index 07743de2d16..f650810e9e3 100644
--- a/extern/carve/carve-util.h
+++ b/extern/carve/carve-util.h
@@ -31,15 +31,46 @@
#include <carve/geom3d.hpp>
#include <carve/interpolator.hpp>
#include <carve/mesh.hpp>
+#include <carve/triangulator.hpp>
#include "carve-capi.h"
+struct TriIdxCompare {
+ bool operator() (const carve::triangulate::tri_idx &left,
+ const carve::triangulate::tri_idx &right) const {
+ if (left.a < right.a) {
+ return true;
+ }
+ else if (left.a > right.a) {
+ return false;
+ }
+
+ if (left.b < right.b) {
+ return true;
+ }
+ else if (left.b > right.b) {
+ return false;
+ }
+
+ if (left.c < right.c) {
+ return true;
+ }
+ else if (left.c > right.c) {
+ return false;
+ }
+
+ return false;
+ }
+};
+
+typedef std::set<carve::triangulate::tri_idx, TriIdxCompare> TrianglesStorage;
+
void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
const carve::mesh::MeshSet<3> *right,
carve::geom3d::Vector *min,
carve::geom3d::Vector *max);
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
carve::mesh::MeshSet<3> **left_r,
carve::mesh::MeshSet<3> **right_r);
@@ -50,15 +81,12 @@ bool carve_checkPolyPlanarAndGetNormal(const std::vector<carve::geom3d::Vector>
int carve_triangulatePoly(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer,
- int poly_index,
- int start_loop_index,
const std::vector<carve::geom3d::Vector> &vertices,
const int verts_per_poly,
const int *verts_of_poly,
const carve::math::Matrix3 &axis_matrix,
std::vector<int> *face_indices,
- std::vector<int> *orig_loop_index_map,
- std::vector<int> *orig_poly_index_map);
+ TrianglesStorage *triangles_storage);
namespace carve {
namespace interpolate {
@@ -87,8 +115,8 @@ namespace carve {
attrs.find(new_edge_iter->vert);
if (found == attrs.end()) {
for (const_edge_iter_t orig_edge_iter = orig_face->begin();
- orig_edge_iter != orig_face->end();
- ++orig_edge_iter)
+ orig_edge_iter != orig_face->end();
+ ++orig_edge_iter)
{
if ((orig_edge_iter->vert->v - new_edge_iter->vert->v).length2() < 1e-5) {
attrs[new_edge_iter->vert] = attrs[orig_edge_iter->vert];
@@ -116,6 +144,138 @@ namespace carve {
}
};
+ template<typename attr_t>
+ class SimpleFaceEdgeAttr : public Interpolator {
+ public:
+ typedef std::pair<const meshset_t::face_t *, unsigned> key_t;
+
+ protected:
+ typedef std::pair<const meshset_t::vertex_t *, const meshset_t::vertex_t *> vpair_t;
+
+ struct key_hash {
+ size_t operator()(const key_t &v) const {
+ return size_t(v.first) ^ size_t(v.second);
+ }
+ };
+ struct vpair_hash {
+ size_t operator()(const vpair_t &v) const {
+ return size_t(v.first) ^ size_t(v.second);
+ }
+ };
+
+ typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
+ typedef std::unordered_map<vpair_t, key_t, vpair_hash> edgedivmap_t;
+
+ attrmap_t attrs;
+
+ struct Hook : public Interpolator::Hook {
+ public:
+ virtual unsigned hookBits() const {
+ return carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT;
+ }
+ Hook(Interpolator *_interpolator, const carve::csg::CSG &_csg) : Interpolator::Hook(_interpolator, _csg) {
+ }
+ virtual ~Hook() {
+ }
+ };
+
+ virtual Interpolator::Hook *makeHook(carve::csg::CSG &csg) {
+ return new Hook(this, csg);
+ }
+
+ virtual void processOutputFace(const carve::csg::CSG &csg,
+ std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
+ const meshset_t::face_t *orig_face,
+ bool flipped) {
+ edgedivmap_t undiv;
+
+ for (meshset_t::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) {
+ key_t k(orig_face, e.idx());
+ typename attrmap_t::const_iterator attr_i = attrs.find(k);
+ if (attr_i == attrs.end()) {
+ continue;
+ } else {
+ undiv[vpair_t(e->v1(), e->v2())] = k;
+ }
+ }
+
+ for (size_t fnum = 0; fnum < new_faces.size(); ++fnum) {
+ const carve::mesh::MeshSet<3>::face_t *new_face = new_faces[fnum];
+ for (meshset_t::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) {
+ key_t k(new_face, e.idx());
+
+ vpair_t vp;
+ if (!flipped) {
+ vp = vpair_t(e->v1(), e->v2());
+ } else {
+ vp = vpair_t(e->v2(), e->v1());
+ }
+ typename edgedivmap_t::const_iterator vp_i;
+ if ((vp_i = undiv.find(vp)) != undiv.end()) {
+ attrs[k] = attrs[vp_i->second];
+ }
+ }
+ }
+ }
+
+ public:
+
+ bool hasAttribute(const meshset_t::face_t *f, unsigned e) {
+ return attrs.find(std::make_pair(f, e)) != attrs.end();
+ }
+
+ attr_t getAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &def = attr_t()) {
+ typename attrmap_t::const_iterator fv = attrs.find(std::make_pair(f, e));
+ if (fv != attrs.end()) {
+ return (*fv).second;
+ }
+ return def;
+ }
+
+ void setAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &attr) {
+ attrs[std::make_pair(f, e)] = attr;
+ }
+
+ void copyAttribute(const meshset_t::face_t *face,
+ unsigned edge,
+ SimpleFaceEdgeAttr<attr_t> *interpolator) {
+ key_t key(face, edge);
+ typename attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+ if (fv != interpolator->attrs.end()) {
+ attrs[key] = (*fv).second;
+ }
+ }
+
+ void swapAttributes(SimpleFaceEdgeAttr<attr_t> *interpolator) {
+ attrs.swap(interpolator->attrs);
+ }
+
+ SimpleFaceEdgeAttr() : Interpolator() {
+ }
+
+ virtual ~SimpleFaceEdgeAttr() {
+ }
+ };
+
+ template<typename attr_t>
+ class SwapableFaceEdgeAttr : public FaceEdgeAttr<attr_t> {
+ public:
+ typedef carve::mesh::MeshSet<3> meshset_t;
+
+ void copyAttribute(const meshset_t::face_t *face,
+ unsigned edge,
+ SwapableFaceEdgeAttr<attr_t> *interpolator) {
+ typename FaceEdgeAttr<attr_t>::key_t key(face, edge);
+ typename FaceEdgeAttr<attr_t>::attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+ if (fv != interpolator->attrs.end()) {
+ this->attrs[key] = (*fv).second;
+ }
+ }
+
+ void swapAttributes(SwapableFaceEdgeAttr<attr_t> *interpolator) {
+ this->attrs.swap(interpolator->attrs);
+ }
+ };
} // namespace interpolate
} // namespace carve
diff --git a/extern/carve/files.txt b/extern/carve/files.txt
index f7da6038692..5c02a04dfe2 100644
--- a/extern/carve/files.txt
+++ b/extern/carve/files.txt
@@ -1,6 +1,7 @@
include/carve/vertex_impl.hpp
include/carve/aabb_impl.hpp
include/carve/csg.hpp
+include/carve/triangle_intersection.hpp
include/carve/pointset_iter.hpp
include/carve/debug_hooks.hpp
include/carve/mesh.hpp
diff --git a/extern/carve/include/carve/config.h b/extern/carve/include/carve/config.h
index fdae2d2843f..3533c1a6710 100644
--- a/extern/carve/include/carve/config.h
+++ b/extern/carve/include/carve/config.h
@@ -10,3 +10,21 @@
# define HAVE_STDINT_H
#endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+// declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+# ifndef __NetBSD__
+# define HAVE_IS_HEAP
+# ifdef _LIBCPP_VERSION
+# define __is_heap is_heap
+# endif // _LIBCPP_VERSION
+# endif // !__NetBSD__
+#endif // __GNUC__
diff --git a/extern/carve/include/carve/csg_triangulator.hpp b/extern/carve/include/carve/csg_triangulator.hpp
index 5a40439271e..513f9a145b2 100644
--- a/extern/carve/include/carve/csg_triangulator.hpp
+++ b/extern/carve/include/carve/csg_triangulator.hpp
@@ -426,6 +426,7 @@ namespace carve {
findPerimeter(grp_tris, vloop, grp_perim);
out_faces.push_back(face->create(grp_perim.begin(), grp_perim.end(), false));
}
+ delete face;
}
std::swap(faces, out_faces);
}
diff --git a/extern/carve/include/carve/mesh_ops.hpp b/extern/carve/include/carve/mesh_ops.hpp
index 02b1bde4e45..3b71feb0e6c 100644
--- a/extern/carve/include/carve/mesh_ops.hpp
+++ b/extern/carve/include/carve/mesh_ops.hpp
@@ -580,7 +580,7 @@ namespace carve {
std::vector<VertexInfo *> queue;
void checkheap() {
-#ifdef __GNUC__
+#if defined(HAVE_IS_HEAP)
CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
#endif
}
diff --git a/extern/carve/include/carve/mesh_simplify.hpp b/extern/carve/include/carve/mesh_simplify.hpp
index 1c5169caf58..f0a0a965707 100644
--- a/extern/carve/include/carve/mesh_simplify.hpp
+++ b/extern/carve/include/carve/mesh_simplify.hpp
@@ -32,8 +32,6 @@
#include <algorithm>
#include <vector>
-#include "write_ply.hpp"
-
namespace carve {
namespace mesh {
@@ -1184,6 +1182,33 @@ namespace carve {
return modifications;
}
+ void dissolveMeshEdges(mesh_t *mesh, std::unordered_set<edge_t *> dissolve_edges) {
+ while (dissolve_edges.size()) {
+ MeshSet<3>::edge_t *edge = *dissolve_edges.begin();
+ if (edge->face == edge->rev->face) {
+ dissolve_edges.erase(edge);
+ continue;
+ }
+
+ MeshSet<3>::edge_t *removed = edge->mergeFaces();
+ if (removed == NULL) {
+ dissolve_edges.erase(edge);
+ } else {
+ MeshSet<3>::edge_t *e = removed;
+ do {
+ MeshSet<3>::edge_t *n = e->next;
+ dissolve_edges.erase(std::min(e, e->rev));
+ delete e->rev;
+ delete e;
+ e = n;
+ } while (e != removed);
+ }
+ }
+
+ removeRemnantFaces(mesh);
+ cleanFaceEdges(mesh);
+ mesh->cacheEdges();
+ }
size_t improveMesh(meshset_t *meshset,
@@ -1445,7 +1470,7 @@ namespace carve {
heapval_t last;
std::vector<heapval_t> heap;
- point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow(_base, _n_dp)), last(-1.0, _origin), heap() {
+ point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow((double)_base, _n_dp)), last(-1.0, _origin), heap() {
for (size_t i = 0; i < (1 << 3); ++i) {
vector_t t = origin;
for (size_t j = 0; j < 3; ++j) {
@@ -1502,7 +1527,7 @@ namespace carve {
}
aabb_t getAABB() const {
- std::set<face_t *>::iterator i = faces.begin();
+ std::set<face_t *>::const_iterator i = faces.begin();
aabb_t aabb = (*i)->getAABB();
while (++i != faces.end()) {
aabb.unionAABB((*i)->getAABB());
diff --git a/extern/carve/include/carve/triangle_intersection.hpp b/extern/carve/include/carve/triangle_intersection.hpp
new file mode 100644
index 00000000000..f1f4c2137f1
--- /dev/null
+++ b/extern/carve/include/carve/triangle_intersection.hpp
@@ -0,0 +1,53 @@
+// Begin License:
+// Copyright (C) 2006-2011 Tobias Sargeant (tobias.sargeant@gmail.com).
+// All rights reserved.
+//
+// This file is part of the Carve CSG Library (http://carve-csg.com/)
+//
+// This file may be used under the terms of the GNU General Public
+// License version 2.0 as published by the Free Software Foundation
+// and appearing in the file LICENSE.GPL2 included in the packaging of
+// this file.
+//
+// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE.
+// End:
+
+
+#pragma once
+
+#include <carve/carve.hpp>
+
+#include <carve/geom.hpp>
+
+namespace carve {
+ namespace geom {
+
+ enum TriangleIntType {
+ TR_TYPE_NONE = 0,
+ TR_TYPE_TOUCH = 1,
+ TR_TYPE_INT = 2
+ };
+
+ enum TriangleInt {
+ TR_INT_NONE = 0, // no intersection.
+ TR_INT_INT = 1, // intersection.
+ TR_INT_VERT = 2, // intersection due to shared vertex.
+ TR_INT_EDGE = 3, // intersection due to shared edge.
+ TR_INT_TRI = 4 // intersection due to identical triangle.
+ };
+
+ TriangleInt triangle_intersection(const vector<2> tri_a[3], const vector<2> tri_b[3]);
+ TriangleInt triangle_intersection(const vector<3> tri_a[3], const vector<3> tri_b[3]);
+
+ bool triangle_intersection_simple(const vector<2> tri_a[3], const vector<2> tri_b[3]);
+ bool triangle_intersection_simple(const vector<3> tri_a[3], const vector<3> tri_b[3]);
+
+ TriangleIntType triangle_intersection_exact(const vector<2> tri_a[3], const vector<2> tri_b[3]);
+ TriangleIntType triangle_intersection_exact(const vector<3> tri_a[3], const vector<3> tri_b[3]);
+
+ TriangleIntType triangle_linesegment_intersection_exact(const vector<2> tri_a[3], const vector<2> line_b[2]);
+ TriangleIntType triangle_point_intersection_exact(const vector<2> tri_a[3], const vector<2> &pt_b);
+ }
+}
diff --git a/extern/carve/lib/intersect_face_division.cpp b/extern/carve/lib/intersect_face_division.cpp
index ea82b7e89a3..0016724e16c 100644
--- a/extern/carve/lib/intersect_face_division.cpp
+++ b/extern/carve/lib/intersect_face_division.cpp
@@ -719,6 +719,10 @@ namespace {
unassigned--;
}
}
+
+ if (!removed.size())
+ throw carve::exception("Failed to merge holes");
+
for (std::set<int>::iterator f = removed.begin(); f != removed.end(); ++f) {
for (unsigned i = 0; i < containing_faces.size(); ++i) {
containing_faces[i].erase(std::remove(containing_faces[i].begin(),
@@ -1121,7 +1125,9 @@ namespace {
}
// copy up to the end of the path.
- std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
+ if (pos < e1_1) {
+ std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
+ }
CARVE_ASSERT(base_loop[e1_1] == p1.back());
std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out));
diff --git a/extern/carve/lib/triangulator.cpp b/extern/carve/lib/triangulator.cpp
index 820fed07db7..eb36e86af5d 100644
--- a/extern/carve/lib/triangulator.cpp
+++ b/extern/carve/lib/triangulator.cpp
@@ -27,24 +27,6 @@
#include <algorithm>
-// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-//
-// TODO(sergey): Move it some some more generic header with platform-specific
-// declarations.
-
-// Indicates whether __is_heap is available
-#undef HAVE_IS_HEAP
-
-#ifdef __GNUC__
-// NeyBSD doesn't have __is_heap
-# ifndef __NetBSD__
-# define HAVE_IS_HEAP
-# ifdef _LIBCPP_VERSION
-# define __is_heap is_heap
-# endif // _LIBCPP_VERSION
-# endif // !__NetBSD__
-#endif // __GNUC__
-
namespace {
// private code related to hole patching.
diff --git a/extern/carve/mkfiles.sh b/extern/carve/mkfiles.sh
index bd022666418..bd022666418 100755..100644
--- a/extern/carve/mkfiles.sh
+++ b/extern/carve/mkfiles.sh
diff --git a/extern/carve/patches/clang_is_heap_fix.patch b/extern/carve/patches/clang_is_heap_fix.patch
index a00710b9540..524a8e0420c 100644
--- a/extern/carve/patches/clang_is_heap_fix.patch
+++ b/extern/carve/patches/clang_is_heap_fix.patch
@@ -1,31 +1,27 @@
-diff -r 2e6e59022e6e lib/triangulator.cpp
---- a/lib/triangulator.cpp Fri Nov 09 09:35:35 2012 +1100
-+++ b/lib/triangulator.cpp Thu Jan 09 16:13:17 2014 +0600
-@@ -27,6 +27,23 @@
+diff -r e82d852e4fb0 include/carve/mesh_ops.hpp
+--- a/include/carve/mesh_ops.hpp Wed Jan 15 13:16:14 2014 +1100
++++ b/include/carve/mesh_ops.hpp Fri Mar 28 14:34:04 2014 +0600
+@@ -580,7 +580,7 @@
+ std::vector<VertexInfo *> queue;
- #include <algorithm>
+ void checkheap() {
+-#ifdef __GNUC__
++#if defined(HAVE_IS_HEAP)
+ CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
+ #endif
+ }
+diff -r e82d852e4fb0 lib/triangulator.cpp
+--- a/lib/triangulator.cpp Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/triangulator.cpp Fri Mar 28 14:34:04 2014 +0600
+@@ -27,7 +27,6 @@
-+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-+//
-+// TODO(sergey): Move it some some more generic header with platform-specific
-+// declarations.
-+
-+// Indicates whether __is_heap is available
-+#undef HAVE_IS_HEAP
-+
-+#ifdef __GNUC__
-+// NeyBSD doesn't have __is_heap
-+# ifndef __NetBSD__
-+# define HAVE_IS_HEAP
-+# ifdef _LIBCPP_VERSION
-+# define __is_heap is_heap
-+# endif // _LIBCPP_VERSION
-+# endif // !__NetBSD__
-+#endif // __GNUC__
+ #include <algorithm>
+-
namespace {
// private code related to hole patching.
-@@ -122,7 +139,7 @@
+
+@@ -122,7 +121,7 @@
std::vector<vertex_info *> queue;
void checkheap() {
diff --git a/extern/carve/patches/face_hole_merge_workaround.patch b/extern/carve/patches/face_hole_merge_workaround.patch
new file mode 100644
index 00000000000..834e03a4b12
--- /dev/null
+++ b/extern/carve/patches/face_hole_merge_workaround.patch
@@ -0,0 +1,14 @@
+diff -r e82d852e4fb0 lib/intersect_face_division.cpp
+--- a/lib/intersect_face_division.cpp Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect_face_division.cpp Thu Mar 13 15:39:26 2014 +0600
+@@ -719,6 +719,10 @@
+ unassigned--;
+ }
+ }
++
++ if (!removed.size())
++ throw carve::exception("Failed to merge holes");
++
+ for (std::set<int>::iterator f = removed.begin(); f != removed.end(); ++f) {
+ for (unsigned i = 0; i < containing_faces.size(); ++i) {
+ containing_faces[i].erase(std::remove(containing_faces[i].begin(),
diff --git a/extern/carve/patches/files/config.h b/extern/carve/patches/files/config.h
index fdae2d2843f..3533c1a6710 100644
--- a/extern/carve/patches/files/config.h
+++ b/extern/carve/patches/files/config.h
@@ -10,3 +10,21 @@
# define HAVE_STDINT_H
#endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+// declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+# ifndef __NetBSD__
+# define HAVE_IS_HEAP
+# ifdef _LIBCPP_VERSION
+# define __is_heap is_heap
+# endif // _LIBCPP_VERSION
+# endif // !__NetBSD__
+#endif // __GNUC__
diff --git a/extern/carve/patches/memory_leak_fix.patch b/extern/carve/patches/memory_leak_fix.patch
new file mode 100644
index 00000000000..c6aff1bf837
--- /dev/null
+++ b/extern/carve/patches/memory_leak_fix.patch
@@ -0,0 +1,11 @@
+diff -r e82d852e4fb0 include/carve/csg_triangulator.hpp
+--- a/include/carve/csg_triangulator.hpp Wed Jan 15 13:16:14 2014 +1100
++++ b/include/carve/csg_triangulator.hpp Wed Mar 05 14:43:56 2014 +0600
+@@ -426,6 +426,7 @@
+ findPerimeter(grp_tris, vloop, grp_perim);
+ out_faces.push_back(face->create(grp_perim.begin(), grp_perim.end(), false));
+ }
++ delete face;
+ }
+ std::swap(faces, out_faces);
+ }
diff --git a/extern/carve/patches/mesh_simplify_dissolve_edges.patch b/extern/carve/patches/mesh_simplify_dissolve_edges.patch
new file mode 100644
index 00000000000..27406a4912a
--- /dev/null
+++ b/extern/carve/patches/mesh_simplify_dissolve_edges.patch
@@ -0,0 +1,64 @@
+diff -r e82d852e4fb0 include/carve/mesh_simplify.hpp
+--- a/include/carve/mesh_simplify.hpp Wed Jan 15 13:16:14 2014 +1100
++++ b/include/carve/mesh_simplify.hpp Fri Feb 28 19:09:02 2014 +0600
+@@ -32,8 +32,6 @@
+ #include <algorithm>
+ #include <vector>
+
+-#include "write_ply.hpp"
+-
+
+ namespace carve {
+ namespace mesh {
+@@ -1184,6 +1182,33 @@
+ return modifications;
+ }
+
++ void dissolveMeshEdges(mesh_t *mesh, std::unordered_set<edge_t *> dissolve_edges) {
++ while (dissolve_edges.size()) {
++ MeshSet<3>::edge_t *edge = *dissolve_edges.begin();
++ if (edge->face == edge->rev->face) {
++ dissolve_edges.erase(edge);
++ continue;
++ }
++
++ MeshSet<3>::edge_t *removed = edge->mergeFaces();
++ if (removed == NULL) {
++ dissolve_edges.erase(edge);
++ } else {
++ MeshSet<3>::edge_t *e = removed;
++ do {
++ MeshSet<3>::edge_t *n = e->next;
++ dissolve_edges.erase(std::min(e, e->rev));
++ delete e->rev;
++ delete e;
++ e = n;
++ } while (e != removed);
++ }
++ }
++
++ removeRemnantFaces(mesh);
++ cleanFaceEdges(mesh);
++ mesh->cacheEdges();
++ }
+
+
+ size_t improveMesh(meshset_t *meshset,
+@@ -1445,7 +1470,7 @@
+ heapval_t last;
+ std::vector<heapval_t> heap;
+
+- point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow(_base, _n_dp)), last(-1.0, _origin), heap() {
++ point_enumerator_t(vector_t _origin, int _base, int _n_dp) : origin(_origin), rounding_fac(pow((double)_base, _n_dp)), last(-1.0, _origin), heap() {
+ for (size_t i = 0; i < (1 << 3); ++i) {
+ vector_t t = origin;
+ for (size_t j = 0; j < 3; ++j) {
+@@ -1502,7 +1527,7 @@
+ }
+
+ aabb_t getAABB() const {
+- std::set<face_t *>::iterator i = faces.begin();
++ std::set<face_t *>::const_iterator i = faces.begin();
+ aabb_t aabb = (*i)->getAABB();
+ while (++i != faces.end()) {
+ aabb.unionAABB((*i)->getAABB());
diff --git a/extern/carve/patches/msvc_fix.patch b/extern/carve/patches/msvc_fix.patch
new file mode 100644
index 00000000000..67431ecac75
--- /dev/null
+++ b/extern/carve/patches/msvc_fix.patch
@@ -0,0 +1,14 @@
+diff -r e82d852e4fb0 lib/intersect_face_division.cpp
+--- a/lib/intersect_face_division.cpp Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect_face_division.cpp Wed Mar 12 23:09:19 2014 +0600
+@@ -1121,7 +1121,9 @@
+ }
+
+ // copy up to the end of the path.
+- std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
++ if (pos < e1_1) {
++ std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
++ }
+
+ CARVE_ASSERT(base_loop[e1_1] == p1.back());
+ std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out));
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index 30937b4b9cf..529bf43a858 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -6,3 +6,7 @@ gcc46.patch
clang_is_heap_fix.patch
strict_flags.patch
interpolator_reorder.patch
+mesh_simplify_dissolve_edges.patch
+memory_leak_fix.patch
+msvc_fix.patch
+face_hole_merge_workaround.patch
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index 6c716b5752c..c3c5143cc16 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -44,6 +44,8 @@ if(WITH_LIBMV)
)
list(APPEND INC
+ third_party/gflags
+ third_party/glog/src
third_party/ceres/include
../../intern/guardedalloc
)
@@ -56,6 +58,8 @@ if(WITH_LIBMV)
list(APPEND SRC
libmv-capi.cc
+ libmv-util.cc
+ libmv/base/aligned_malloc.cc
libmv/image/array_nd.cc
libmv/image/convolve.cc
libmv/multiview/conditioning.cc
@@ -70,6 +74,7 @@ if(WITH_LIBMV)
libmv/simple_pipeline/bundle.cc
libmv/simple_pipeline/camera_intrinsics.cc
libmv/simple_pipeline/detect.cc
+ libmv/simple_pipeline/distortion_models.cc
libmv/simple_pipeline/initialize_reconstruction.cc
libmv/simple_pipeline/intersect.cc
libmv/simple_pipeline/keyframe_selection.cc
@@ -91,6 +96,8 @@ if(WITH_LIBMV)
third_party/gflags/gflags_completions.cc
third_party/gflags/gflags_reporting.cc
+ libmv-util.h
+ libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/scoped_ptr.h
libmv/base/vector.h
@@ -121,7 +128,9 @@ if(WITH_LIBMV)
libmv/simple_pipeline/bundle.h
libmv/simple_pipeline/callbacks.h
libmv/simple_pipeline/camera_intrinsics.h
+ libmv/simple_pipeline/camera_intrinsics_impl.h
libmv/simple_pipeline/detect.h
+ libmv/simple_pipeline/distortion_models.h
libmv/simple_pipeline/initialize_reconstruction.h
libmv/simple_pipeline/intersect.h
libmv/simple_pipeline/keyframe_selection.h
@@ -218,10 +227,6 @@ if(WITH_LIBMV)
third_party/glog/src/symbolize.h
third_party/glog/src/utilities.h
)
-
- list(APPEND INC
- third_party/glog/src
- )
endif()
else()
list(APPEND SRC
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 641d2518fb8..276fbb2ff0d 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,344 @@
+commit 0b7d83dc9627447dc7df64d7e3a468aefe9ddc13
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Apr 23 19:14:55 2014 +0600
+
+ Fix compilation on OSX after previous commit
+
+ EXPECT_EQ wasn't defined in the scope.
+
+commit d14049e00dabf8fdf49056779f0a3718fbb39e8f
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Apr 23 15:08:16 2014 +0600
+
+ Move aligned malloc implementation into own file
+
+ It was rather stupid having it in brute region tracker,
+ now it is in own file in base library (which was also
+ added in this commit, before this it consist of header
+ files only).
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D479
+
+commit 0ddf3851bfcb8de43660b119a25a77a25674200d
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Apr 21 14:14:03 2014 +0600
+
+ Optimization of PearsonProductMomentCorrelation
+
+ Pass the arrays by reference rather than by value,
+ should give some percent of speedup.
+
+ Also don't pass the dimensions to the function but
+ get them from the images themselves.
+
+ Hopefully this will give some %% of tracker speedup.
+
+commit f68fdbe5896a6c5bd8b500caeec61b876c5e44c6
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Apr 21 14:10:43 2014 +0600
+
+ Fix wrong assert in ResizeImage()
+
+ The assert didn't make any sense because ComputeBoundingBox()
+ is intended to return bounding box in the following way:
+ (xmin, xmax, ymin, ymax).
+
+commit 1d386b6775a71c499e9b8e4a288c0785c4937677
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Apr 17 18:42:43 2014 +0600
+
+ Add unit tests for buffer (un)distortion
+
+ Currently only uses identity camera intrinsics just to
+ see whether lookup grids are properly allocated.
+
+ Should prevent accidents like that one happened recently
+ with crashing Blender after Libmv re-integration.
+
+commit e1fe41b6604771ba769a9b15eb2f489fbf7af251
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Apr 17 17:52:23 2014 +0600
+
+ Fix offset array not being properly allocated
+
+ We really do need unit test for buffer (un)distortion,
+ didn't notice this bug for until new Libmv has been
+ integrated into Blender.
+
+commit ee21415a353396df67ef21e82adaffab2a8d2a0a
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Apr 17 16:26:12 2014 +0600
+
+ Support multiple distortion models, including a new division model
+
+ This commit makes it so CameraIntrinsics is no longer hardcoded
+ to use the traditional polynomial radial distortion model. Currently
+ the distortion code has generic logic which is shared between
+ different distortion models, but had no other models until now.
+
+ This moves everything specific to the polynomial radial distortion
+ to a subclass PolynomialDistortionCameraIntrinsics(), and adds a
+ new division distortion model suitable for cameras such as the
+ GoPro which have much stronger distortion due to their fisheye lens.
+
+ This also cleans up the internal API of CameraIntrinsics to make
+ it easier to understand and reduces old C-style code.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ CC: jta
+
+ Differential Revision: https://developer.blender.org/D335
+
+commit 313252083f6dfa69a93c287bed81dec616503c1b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Tue Apr 15 18:23:38 2014 +0600
+
+ Fix failure of the image transform linear test
+
+ Mainly was caused by the flakyness of image rotation in cases
+ when image has even size. The test was expecting the transform
+ code to rotate the image around pixel corner, which isn't a
+ common behavior in image processing applications. Rotation
+ is usually done around the pixel center.
+
+ So now made it so RotateImage() rotates the image around the
+ pixel center which gives 100% proper result for odd sized images
+ (i.e. center pixel stays untouched).
+
+ Also made the tests to use odd image sizes which are more
+ predictable by the humans. We can use even sized images in the
+ tests as well but their result wouldn't be so much spectacular.
+
+ Another issue with the tests was caused by RescaleImageTranslation
+ test which did expect things which are not happening in the
+ function.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D463
+
+commit 80d6945bf5f996b97cd41df0e422afce5e10e7f9
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Apr 14 00:01:32 2014 +0600
+
+ Unit tests for feature detector
+
+ Currently covers only simplest cases with synthetic images.
+ Also at this point mainly Harris detector is being testes,
+ other detectors behaves a bit unexpected on synthetic images
+ and this is to be investigated further.
+
+ Tests will be extended further later.
+
+ Additional change:
+
+ - Added constructor to Feature structure
+ - Added operator << for feature for easier debug dumps.
+
+ TODO: Some tests are not giving the result which i was expected
+ to. This is to be investigated further by finding the reference
+ detector implementation. For until then keeping that tests
+ commented out.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D316
+
+commit 397c3d3ed46eb4967eb285c8369cc125bea4b132
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Apr 4 16:17:57 2014 +0600
+
+ Compilation error fix
+
+ Not totally sure why this is needed, but multiview indeed
+ uses V3D library still, so it needs to be linked against it.
+
+ Patc by Martijn Berger, thanks!
+
+commit 1c36279239cbffe152493106eb04e55df7ebd649
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Apr 4 14:03:43 2014 +0600
+
+ Upgrade Eigen to 3.2.1 version
+
+ To main reasons for this:
+ - Probably this would solve strict compiler warnings
+ - It brings new stuff like sparse LU decomposition which
+ might be useful in the future.
+
+commit de698f442934f475478463445f78a00ea632e823
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Apr 3 15:08:26 2014 +0600
+
+ Fix compilation error when using make from the sources root
+
+ - Don't force flann to be static. It's a general rule on linux
+ to have dynamic libraries for all the bits instead of having
+ statically-linked dynamic libraries.
+
+ - Some weirdo stuff was happening around OpenExif, it was only
+ built on Apple, so don't link targets against this lib on
+ other platforms.
+
+ - Some libraries were missing for qt-tracker.
+
+commit 901b146f28825d3e05f4157ca2a34ae00261b91a
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Mar 26 17:44:09 2014 +0600
+
+ Fix bad memory write in BA code when having zero-weighted tracks
+
+ Issue was really stupid and caused by the wrong vector initialization.
+
+commit d14a372dfe09c7339f267c4904a541fbe2efec43
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Mar 21 16:02:41 2014 +0600
+
+ Attempt to fix compilation error with msvc2013
+
+commit 933531580b4dc4b65601d785cedc16506d615d7b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Mar 20 23:07:34 2014 +0600
+
+ Compilation fixes for MinGW
+
+ Many thanks to Antony Riakiotakis for the patch!
+
+commit f1aefcbf58fe04ea2967434f39f703bb486777c8
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Feb 27 16:21:19 2014 +0600
+
+ Implement separate BA step for tracks which have constant zero weight
+
+ This is needed to minimize their reprojection error over the footage.
+ Without this extra step positions of such tracks were calculated by
+ algebraic intersection code only, which doesn't give best precision.
+
+commit bcf7f9470b2ea33cf89a31a72037ec03be631637
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Feb 27 14:16:42 2014 +0600
+
+ Avoid zero-sized problem when doing euclidean intersection
+
+ Zero-sized problem might occur when intersecting track with
+ constant zero weight. For such tracks we'll just use result
+ of algebraic intersection.
+
+ TODO: We probably need to have a separate BA step to adjust
+ positions of tracks with constant zero weight.
+
+commit f884bb20a93189b8210639f3de939c64177d66b3
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Feb 26 18:00:40 2014 +0600
+
+ Ignore zero weighted markers in keyframe selection
+
+ It doesn't make sense to use zero-weighted tracks as a correspondences
+ in keyframe selection.
+
+ Such tracks are not guaranteed to be tracked accurately because their
+ purpose is to add reference points in 3D space without affecting the
+ solution.
+
+commit 74db5175cdbcabe673b82eef59c88fb7f342c43f
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Feb 26 13:23:02 2014 +0600
+
+ Tweaks to make bundling into Blender warning-less
+
+ Mainly issue i caused by conflicts in include directories,
+ so glog used to include config.h from gflags. It might be
+ fixed by splitting gflags/glog from Libmv in Blender build
+ system but that's not something fun to work on. Fixed by
+ making include directories bit more explicit.
+
+ Also solved no-previous-prototype warnings.
+
+commit bc4bc66af0115069562b79e837ccf4fd95c8f97e
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Feb 21 14:55:13 2014 +0600
+
+ Raise epsilon used for model solver test
+
+ It was too much small leading to false failure triggering
+ caused simply by precision issues.
+
+commit bf750590a6af4af3622c01fd1004c44da60484a7
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Tue Feb 18 23:35:52 2014 +0600
+
+ Made it possible to link against Ceres installed on the system
+
+ Main purpose of this is to get away from bundled Ceres library
+ which is not so trivial to re-bundle and takes some to do this
+ (not talking about CMake options conflicts and pollution).
+
+ Enabled by setting WITH_SYSTEM_CERES=ON. Default paths to search
+ Ceres library:
+
+ - /usr/local
+ - /sw
+ - /opt/local
+ - /opt/csw
+ - /opt/lib/ceres
+
+ You might also specify Ceres root directory using CERES_ROOT_DIR
+ variable (both CMake and environment variables are supported).
+
+ If your Ceres is build statically, you're to control all additional
+ libraries needed to link against using CMAKE_EXE_LINKER_FLAGS.
+
+commit c9156fbf80c86853806844b754b1e48f45c5ec11
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Tue Feb 18 19:38:22 2014 +0600
+
+ Remove .orig file which was added by accident
+
+commit 62597e3cf0f266a2fefec415c89759e502793e06
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Jan 2 16:02:08 2014 +0600
+
+ Upgrade glog to latest svn r139
+
+ The intention of this upgrade is to get rid of custom patches
+ we've been having to support compilation on different platforms
+ and compilers.
+
+commit 2452d5d42b390c7ab853e6fe60e58bdd7a01a004
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Tue Feb 18 18:46:08 2014 +0600
+
+ Tweak Ceres CMake to detect uninstall target properly on Windows
+
+commit 98a281d58ce2301f3dd239a97a448e53f48d0258
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Feb 14 00:36:44 2014 +0600
+
+ Fix order of third party libs compilation and options used by them
+
+ WITH_FAST_DETECTOR was defined too late and third_party folder
+ didn't see this option.
+
+commit 4962bccd643ec0f2aed3035170d5f20e8f6efc85
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Feb 13 23:55:03 2014 +0600
+
+ Disable Ceres unit tests and examples by default
+
+ Actually we're to switch to external Ceres rather than
+ bundled one, would make life much easier actually.
+
commit b1381540305d69c702eb2f051bd543fb5c1c3e2c
Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Thu Feb 6 18:01:58 2014 +0600
@@ -336,358 +677,3 @@ Date: Wed Sep 25 16:01:19 2013 +0600
that point".
Original patch by Keir Mierle made to Blender repository.
-
-commit 0d98e9bbde5d57f6cd9515ce8ff2786d322f29ea
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jun 18 19:24:07 2013 +0600
-
- Compilation error when using clang
-
- Where couple of issues:
-
- - Overloaded assignment operator usage ambiguity
- around some of the Eigen matrix assignment.
-
- - Using -O4 flag here on linux ended up in lots
- of cryptic linker issues, even when using recently
- release clang 3.3.
-
- Disabled forcing optimization flag for now.
- We could end up with something smarter in the
- future, but for now i'm not as much fan of
- forcing compiler's flag.
-
-commit 2b90b3915671cb629f7aabed30a88f28450294f8
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sat Jun 1 16:20:35 2013 +0600
-
- Pass vectors by a reference
-
- Saves couple of time which used to waste on copying objects,
- also solves win32 compilation errors caused by alignment.
-
-commit 994c02d0ec55e9ae14a93a3ada6e5d4939247fc3
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu May 30 18:00:03 2013 +0600
-
- Code cleanup
-
- - Made some arguments passing to detector const.
- - Remove unneeded include from track_region header.
-
-commit 7d0c5325a38e61929f44206761b8aa3565631af5
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon May 13 04:44:14 2013 +0600
-
- Pass ApplyRadialDistortionCameraIntrinsics input arguments by reference
-
- This shall save some CPU time on calling copy constructor and give
- some boost of bundle adjuster (where jet could take some time to
- be passed by value).
-
-commit eb2e567df4567a54887d602aa95d6744aa154d8b
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon May 13 04:22:05 2013 +0600
-
- Minor code style cleanup.
-
-commit ad3dbaaef10ea721230694311a359df152c7a44a
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sun May 12 22:34:54 2013 +0600
-
- Cleanup in simple pipeline's bundler
-
- - Better match Google's code style conventions.
- - Move evaluation part into own function, makes
- bundling itself easier to follow.
- - Made evaluation an optional parameter.
- - Removed note about unsupported camera intrinsics
- refining flags. Technically, all combinations
- are possible.
-
-commit 4432eb80f27e929f8750229aaada625d4f3ac5ee
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sun May 12 22:19:31 2013 +0600
-
- Remove check for zero focal length in BA cost functor
-
- This check is actually redundant, because empty intrinsics
- will have focal length of 1.0, which means original comment
- about BundleIntrinsics was not truth.
-
- It is possible that external user will send focal length of
- zero to be refined, but blender prevents this from happening.
-
-commit 34a91c9b8acb0dba3382866fbd29bb9884edb98a
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sat May 11 20:33:54 2013 +0600
-
- Fix compilation error with msvc2012
-
- Using change from glog's upstream for this.
-
-commit 87be4f030d025e4b29d9243d12bc458b2bb6762a
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sat May 11 19:50:57 2013 +0600
-
- Style cleanup, mainly pointed by Sameer in Ceres's codereview
-
-commit 7fa9c0b83d5e0fbd331add2952045076c2028d1b
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri May 10 18:30:40 2013 +0600
-
- Keyframe selection improvements
-
- Added additional criteria, which ignores
- keyframe pair if success intersection factor
- is lower than current candidate pair factor.
-
- This solves issue with keyframe pair at which
- most of the tracks are intersecting behind the
- camera is accepted (because variance in this
- case is really small),
-
- Also tweaked generalized inverse function,
- which now doesn't scale epsilon by maximal
- matrix element. This gave issues at really bad
- candidates with unstable covariance. In this
- case almost all eigen values getting zeroed
- on inverse leading to small expected error.
-
-commit 0477ef1aa8fc92848f03c45e32539210be583b80
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri May 10 17:59:40 2013 +0600
-
- Keyframe selection code cleanup
-
- - Updated comments in code.
- - Removed currently unused functions.
- Actually, they'd better be moved to some generic
- logging module, but we don't have it now so was
- lazy to create one now. Could happen later using
- code from git history
- - Renamed function to match better to what's going
- on in it.
-
-commit fee2d7cc6003942f628c9a24b74008fd491b85b9
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri May 10 17:44:49 2013 +0600
-
- Optimization for reconstruction variance
-
- Achieved by replacing SVD-based pseudo-inverse with
- an eigen solver pseudo inverse.
-
- New function works in the same way: it decomposes
- matrix to V*D*V^-1, then inverts diagonal of D
- and composes matrix back.
-
- The same way is used to deal with gauges - last
- 7 eigen values are getting zeroed.
-
- In own tests gives approx 2x boost, without
- visible affect on selected keyframe quality.
-
-commit b735649ead4d3d61f7896e46f35b1f7e0cecea3d
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Mar 14 14:53:42 2013 +0600
-
- Initial commit of reconstruction variance criteria
- which is an addition for GRIC-based keyframe selection.
-
- Uses paper Keyframe Selection for Camera Motion and Structure
- Estimation from Multiple Views,
- ftp://ftp.tnt.uni-hannover.de/pub/papers/2004/ECCV2004-TTHBAW.pdf
- as a basis.
-
- Currently implemented camera positions reconstructions,
- bundle positions estimation and bundle adjustment step.
-
- Covariance matrix is estimating using generalized inverse
- with 7 (by the number of gauge freedoms) zeroed eigen values
- of J^T * J.
-
- Additional changes:
- - Added utility function FundamentalToEssential to extract
- E from F matrix, used by both final reconstruction pipeline
- and reconstruction variance code.
-
- - Refactored bundler a bit, so now it's possible to return
- different evaluation data, such as number of cameras and
- points being minimized and also jacobian.
-
- Jacobian currently contains only camera and points columns,
- no intrinsics there yet. It is also currently converting to
- an Eigen dense matrix. A bit weak, but speed is nice for
- tests.
-
- Columns in jacobian are ordered in the following way:
- first columns are cameras (3 cols for rotation and 3 cols
- for translation), then goes 3D point columns.
-
- - Switched F and H refining to normalized space. Apparently,
- refining F in pixel space squeezes it a lot making it wrong.
-
- - EuclideanIntersect will not add point to reconstruction if
- it happened to be behind the camera.
-
- - Cleaned style a bit.
-
-commit 8bee982972a0b5bded3555b60e0987af685f85bd
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri May 10 13:27:21 2013 +0600
-
- Left extra debugging print in reconstruction scale by accident.
-
-commit 7971967d24e3d8d505bd6e54523161ab5dd5b728
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri May 10 12:23:03 2013 +0600
-
- Add check for points behind camera in euclidan BA cost functor
-
- In cases keyframes are no so good, algebraic two frames construction
- could produce result, for which more aggressive Ceres-based BA code
- will fall to a solution for which points goes behind the camera,
- which is not so nice.
-
- Seems in newer Ceres returning false from cost functor wouldn't
- abort solution, but will restrict solver from moving points behind
- the camera.
-
- Works fine in own tests, but requires more tests.
-
-commit f34e73f6bd0041a31f779a78e1c2324f9799a4a2
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Apr 24 22:06:38 2013 +0600
-
- Forgot to add reconstruction scale to CMakeLists
-
-commit de08cbaebe1b95673c4bc8f639aa0228414cf4a2
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Apr 24 19:40:39 2013 +0600
-
- Reconstructed scene scale ambiguity improvement
-
- Added a function EuclideanScaleToUnity() which is
- aimed to solve scale ambiguity by scaling solution
- in a way cameras centers variance in unity.
-
- Currently only available for euclidean pipeline,
- projective one is not finished anyway.
-
-commit 30ecb7dd075527c0e49220744bae65ec208dbdf5
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Apr 23 01:41:29 2013 +0600
-
- Use epsilon in modal solver test
-
- Default epsilon for isApprox was too small,
- leading to some false test failures.
-
-commit d03b303c171b0b0a33ed0b31c9a744c9676492a9
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Apr 23 01:35:56 2013 +0600
-
- Update Ceres to current HEAD
-
- Brings optimization for DENSE_NORMAL_CHOLESKY and
- also fixes threading issues with BLAS.
-
-commit 0a352686de0e87d59a2e37dbd0fddb351cbea2b7
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 15 05:35:33 2013 +0600
-
- Fix for bundle adjusting with motion restricted
-
- Was a bug introduced in previous commit, which
- was trying to set parameterization for non-existing
- camera->t parameter block.
-
- Replaced with subset parameterization.
-
- Also added basic synthetic unit test for modal solver.
-
-commit 1742515b89ad5da53be95bfc574cbeffc51dc0e2
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 8 23:33:20 2013 +0600
-
- Bundle adjustment improvements
-
- - Get rid of rotation matrix parameterization,
- use angle-axis instead.
-
- Also Joined rotation and translation into
- a single parameter block.
-
- This made minimization go significantly faster,
- like 1.3x times in average.
-
- - Fix first camera when bundling. This is to
- address orientation ambiguity.
-
- Reconstruction result could still vary in
- size, but that's another issue to be addressed
- later.
-
- Additional change:
-
- Split EuclideanBundleCommonIntrinsics into
- smaller functions, so it's now a bit easier
- to follow.
-
-commit 74bbeabf1c4570bfe04f3034afcde95134b3e161
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 8 23:31:57 2013 +0600
-
- Update Ceres to current HEAD
-
- Brings up some noticeable speed improvements. In particular
- the automatic differentiation and bundle adjustment solvers.
-
-commit e47519b0442527533ee046dd9881212d169561da
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 8 02:21:26 2013 +0600
-
- Corrected path to gflags
-
- Currently tools/track.cc is not used, but let's
- keep things a bit more up-to-date :)
-
-commit f617741b1f2a0ac7981dd71144eba187521d9ac4
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 8 02:17:16 2013 +0600
-
- Re-enable tests for multiview and image
-
- For as long code is in repo and used by some tools
- better to have it covered by tests.
-
- Some of them are failing tho, but that's completely
- different story to be addressed later.
-
-commit 7dbb5a37333fb6c5a729b8bafb317ea210735cbc
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 8 02:10:07 2013 +0600
-
- Do not modify cache's CMAKE_CXX_FLAGS_RELEASE when configuring Ceres
-
- Otherwise you'll have infinite appending of Ceres-specific flags
- on every saving of any CmakeLists.txt.
-
-commit b413d22280de2481a2e2acdcda8431f601d65448
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Sun Apr 7 21:53:23 2013 +0600
-
- Fixed compilation with BUILD_TOOLS enabled
-
- This commit mainly reverts parts of following commits:
- 0eebc21db831211738acc938566bbc29d68d45db
- d8109b7a4fede1660e0dbd73735f1a9e3fd79eec
- e59595806c045916ab4ef15ef7047c1a728b2da9
- 2d6cd58ee1cd7c5073980f358c71b2898ad16b4c
-
- They declared lots of stuff deprecated, but in
- fact it's not deprecated just a bit different
- usage pipeline. Anyway, deprecation shall not
- happen spontaneously as a part of other changes.
- And for sure shall not break anything.
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
index 544e5fda381..dc129501847 100644
--- a/extern/libmv/SConscript
+++ b/extern/libmv/SConscript
@@ -18,7 +18,8 @@ if env['WITH_BF_LIBMV']:
defs.append('WITH_LIBMV_GUARDED_ALLOC')
defs.append('LIBMV_NO_FAST_DETECTOR')
- src = env.Glob("libmv-capi.cc")
+ src = env.Glob('*.cc')
+ src += env.Glob('libmv/base/*.cc')
src += env.Glob('libmv/image/*.cc')
src += env.Glob('libmv/multiview/*.cc')
src += env.Glob('libmv/numeric/*.cc')
@@ -26,7 +27,7 @@ if env['WITH_BF_LIBMV']:
src += env.Glob('libmv/tracking/*.cc')
src += env.Glob('third_party/gflags/*.cc')
- incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc'
+ incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index 48d68435ef7..e8e698a89f2 100755..100644
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -132,6 +132,8 @@ if(WITH_LIBMV)
)
list(APPEND INC
+ third_party/gflags
+ third_party/glog/src
third_party/ceres/include
../../intern/guardedalloc
)
@@ -144,10 +146,12 @@ if(WITH_LIBMV)
list(APPEND SRC
libmv-capi.cc
+ libmv-util.cc
${sources}
${third_sources}
+ libmv-util.h
${headers}
${third_headers}
@@ -195,10 +199,6 @@ ${third_glog_sources}
${third_glog_headers}
)
-
- list(APPEND INC
- third_party/glog/src
- )
endif()
else()
list(APPEND SRC
@@ -234,10 +234,10 @@ if env['WITH_BF_LIBMV']:
defs.append('WITH_LIBMV_GUARDED_ALLOC')
defs.append('LIBMV_NO_FAST_DETECTOR')
- src = env.Glob("libmv-capi.cc")
+ src = env.Glob('*.cc')
$src
- incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc'
+ incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
index cb6546ae8ff..60a99307835 100644
--- a/extern/libmv/files.txt
+++ b/extern/libmv/files.txt
@@ -1,3 +1,5 @@
+libmv/base/aligned_malloc.cc
+libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/scoped_ptr.h
libmv/base/vector.h
@@ -41,8 +43,11 @@ libmv/simple_pipeline/bundle.h
libmv/simple_pipeline/callbacks.h
libmv/simple_pipeline/camera_intrinsics.cc
libmv/simple_pipeline/camera_intrinsics.h
+libmv/simple_pipeline/camera_intrinsics_impl.h
libmv/simple_pipeline/detect.cc
libmv/simple_pipeline/detect.h
+libmv/simple_pipeline/distortion_models.cc
+libmv/simple_pipeline/distortion_models.h
libmv/simple_pipeline/initialize_reconstruction.cc
libmv/simple_pipeline/initialize_reconstruction.h
libmv/simple_pipeline/intersect.cc
diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc
index 5bc159c64af..82143d50fbf 100644
--- a/extern/libmv/libmv-capi.cc
+++ b/extern/libmv/libmv-capi.cc
@@ -35,14 +35,10 @@
#undef DUMP_ALWAYS
#include "libmv-capi.h"
+#include "libmv-util.h"
-#include <cstdlib>
#include <cassert>
-#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
-# include <png.h>
-#endif
-
#include "libmv-capi_intern.h"
#include "libmv/logging/logging.h"
#include "libmv/multiview/homography.h"
@@ -58,27 +54,52 @@
#include "libmv/simple_pipeline/reconstruction_scale.h"
#include "libmv/simple_pipeline/keyframe_selection.h"
-#include "libmv/multiview/homography.h"
-
-#include "libmv/image/convolve.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 {
- libmv::EuclideanReconstruction reconstruction;
+ EuclideanReconstruction reconstruction;
/* used for per-track average error calculation after reconstruction */
- libmv::Tracks tracks;
- libmv::CameraIntrinsics intrinsics;
+ Tracks tracks;
+ CameraIntrinsics *intrinsics;
double error;
};
struct libmv_Features {
int count;
- libmv::Feature *features;
+ Feature *features;
};
/* ************ Logging ************ */
@@ -113,177 +134,6 @@ void libmv_setLoggingVerbosity(int verbosity)
google::SetCommandLineOption("v", val);
}
-/* ************ Utility ************ */
-
-static void byteBufToImage(const unsigned char *buf, int width, int height, int channels, libmv::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;
- }
- }
- }
-}
-
-static void floatBufToImage(const float *buf, int width, int height, int channels, libmv::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) = buf[a++];
- }
- }
- }
-}
-
-static void imageToFloatBuf(const libmv::FloatImage *image, int channels, float *buf)
-{
- int x, y, k, a = 0;
-
- for (y = 0; y < image->Height(); y++) {
- for (x = 0; x < image->Width(); x++) {
- for (k = 0; k < channels; k++) {
- buf[a++] = (*image)(y, x, k);
- }
- }
- }
-}
-
-#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
-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);
-}
-
-static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0)
-{
- int x, y;
- png_bytep *row_pointers;
-
- row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * image.Height());
-
- for (y = 0; y < image.Height(); y++) {
- row_pointers[y] = (png_bytep) malloc(sizeof(png_byte) * 4 * image.Width());
-
- for (x = 0; x < image.Width(); x++) {
- if (x0 == x && 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++) {
- free(row_pointers[y]);
- }
- free(row_pointers);
-}
-
-static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height)
-{
- int x, y;
- png_bytep *row_pointers;
-
- row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * height);
-
- for (y = 0; y < height; y++) {
- row_pointers[y] = (png_bytep) malloc(sizeof(png_byte) * 4 * width);
-
- for (x = 0; x < width; x++) {
- char pixel = data[width * y + x];
- row_pointers[y][x * 4 + 0] = pixel;
- row_pointers[y][x * 4 + 1] = pixel;
- row_pointers[y][x * 4 + 2] = pixel;
- row_pointers[y][x * 4 + 3] = 255;
- }
- }
-
- {
- static int a = 0;
- char buf[128];
- snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
- savePNGImage(row_pointers, width, height, 8, PNG_COLOR_TYPE_RGBA, buf);
- }
-
- for (y = 0; y < height; y++) {
- free(row_pointers[y]);
- }
- free(row_pointers);
-}
-#endif
-
/* ************ Planar tracker ************ */
/* TrackRegion */
@@ -306,13 +156,13 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
yy2[i] = y2[i];
}
- libmv::TrackRegionOptions track_region_options;
- libmv::FloatImage image1_mask;
+ TrackRegionOptions track_region_options;
+ FloatImage image1_mask;
switch (options->motion_model) {
#define LIBMV_CONVERT(the_model) \
- case libmv::TrackRegionOptions::the_model: \
- track_region_options.mode = libmv::TrackRegionOptions::the_model; \
+ case TrackRegionOptions::the_model: \
+ track_region_options.mode = TrackRegionOptions::the_model; \
break;
LIBMV_CONVERT(TRANSLATION)
LIBMV_CONVERT(TRANSLATION_ROTATION)
@@ -330,23 +180,40 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
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. */
- track_region_options.attempt_refine_before_brute = true;
+ * 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) {
- floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &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. */
- libmv::FloatImage old_patch, new_patch;
- floatBufToImage(image1, image1_width, image1_height, 1, &old_patch);
- floatBufToImage(image2, image2_width, image2_height, 1, &new_patch);
-
- libmv::TrackRegionResult track_region_result;
- libmv::TrackRegion(old_patch, new_patch, xx1, yy1, track_region_options, xx2, yy2, &track_region_result);
+ 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) {
@@ -355,78 +222,126 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
}
/* TODO(keir): Update the termination string with failure details. */
- if (track_region_result.termination == libmv::TrackRegionResult::CONVERGENCE ||
- track_region_result.termination == libmv::TrackRegionResult::NO_CONVERGENCE)
+ 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)
-#if defined(DUMP_ALWAYS)
{
-#else
- if (!tracking_result) {
-#endif
- saveImage("old_patch", old_patch, x1[4], y1[4]);
- saveImage("new_patch", new_patch, x2[4], y2[4]);
+ 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)
- saveImage("mask", image1_mask, 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,
+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)
+ 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;
- floatBufToImage(image, width, height, channels, &libmv_image);
+ libmv_byteBufferToImage(image, width, height, channels, &libmv_image);
if (mask) {
- floatBufToImage(mask, width, height, 1, &libmv_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::SamplePlanarPatch(libmv_image, xs, ys,
+ num_samples_x, num_samples_y,
+ libmv_mask_for_sample,
+ &libmv_patch,
+ warped_position_x,
+ warped_position_y);
- imageToFloatBuf(&libmv_patch, channels, patch);
+ libmv_imageToByteBuffer(libmv_patch, patch);
}
/* ************ Tracks ************ */
-struct libmv_Tracks *libmv_tracksNew(void)
+libmv_Tracks *libmv_tracksNew(void)
{
- libmv::Tracks *libmv_tracks = LIBMV_OBJECT_NEW(libmv::Tracks);
+ Tracks *libmv_tracks = LIBMV_OBJECT_NEW(Tracks);
- return (struct libmv_Tracks *)libmv_tracks;
+ return (libmv_Tracks *) libmv_tracks;
}
-void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks)
+void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
{
- using libmv::Tracks;
LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
}
-void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y, double weight)
+void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
+ int image, int track,
+ double x, double y,
+ double weight)
{
- ((libmv::Tracks*) libmv_tracks)->Insert(image, track, x, y, weight);
+ ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
}
/* ************ Reconstruction ************ */
-class ReconstructUpdateCallback : public libmv::ProgressUpdateCallback {
+namespace {
+
+class ReconstructUpdateCallback : public ProgressUpdateCallback {
public:
- ReconstructUpdateCallback(reconstruct_progress_update_cb progress_update_callback, void *callback_customdata)
+ ReconstructUpdateCallback(
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata)
{
progress_update_callback_ = progress_update_callback;
callback_customdata_ = callback_customdata;
@@ -443,13 +358,14 @@ protected:
void *callback_customdata_;
};
-static void libmv_solveRefineIntrinsics(const libmv::Tracks &tracks,
- const int refine_intrinsics,
- const int bundle_constraints,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata,
- libmv::EuclideanReconstruction *reconstruction,
- libmv::CameraIntrinsics *intrinsics)
+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;
@@ -469,61 +385,37 @@ static void libmv_solveRefineIntrinsics(const libmv::Tracks &tracks,
progress_update_callback(callback_customdata, 1.0, "Refining solution");
- libmv::EuclideanBundleCommonIntrinsics(tracks,
- bundle_intrinsics,
- bundle_constraints,
- reconstruction,
- intrinsics);
-}
-
-static void cameraIntrinsicsFromOptions(const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- libmv::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->SetRadialDistortion(camera_intrinsics_options->k1,
- camera_intrinsics_options->k2,
- camera_intrinsics_options->k3);
-
- camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
- camera_intrinsics_options->image_height);
+ EuclideanBundleCommonIntrinsics(tracks,
+ bundle_intrinsics,
+ bundle_constraints,
+ reconstruction,
+ intrinsics);
}
-static libmv::Tracks getNormalizedTracks(const libmv::Tracks &tracks, const libmv::CameraIntrinsics &camera_intrinsics)
+void finishReconstruction(
+ const Tracks &tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ libmv_Reconstruction *libmv_reconstruction,
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata)
{
- libmv::vector<libmv::Marker> markers = tracks.AllMarkers();
-
- for (int i = 0; i < markers.size(); ++i) {
- camera_intrinsics.InvertIntrinsics(markers[i].x, markers[i].y,
- &(markers[i].x), &(markers[i].y));
- }
-
- return libmv::Tracks(markers);
-}
-
-static void finishReconstruction(const libmv::Tracks &tracks, const libmv::CameraIntrinsics &camera_intrinsics,
- struct libmv_Reconstruction *libmv_reconstruction,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
-{
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
/* reprojection error calculation */
progress_update_callback(callback_customdata, 1.0, "Finishing solution");
libmv_reconstruction->tracks = tracks;
- libmv_reconstruction->error = libmv::EuclideanReprojectionError(tracks, reconstruction, camera_intrinsics);
+ libmv_reconstruction->error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
}
-static bool selectTwoKeyframesBasedOnGRICAndVariance(
- libmv::Tracks &tracks,
- libmv::Tracks &normalized_tracks,
- libmv::CameraIntrinsics &camera_intrinsics,
- int &keyframe1,
- int &keyframe2)
+bool selectTwoKeyframesBasedOnGRICAndVariance(
+ Tracks &tracks,
+ Tracks &normalized_tracks,
+ CameraIntrinsics &camera_intrinsics,
+ int &keyframe1,
+ int &keyframe2)
{
libmv::vector<int> keyframes;
@@ -553,25 +445,25 @@ static bool selectTwoKeyframesBasedOnGRICAndVariance(
int previous_keyframe = keyframes[0];
double best_error = std::numeric_limits<double>::max();
for (int i = 1; i < keyframes.size(); i++) {
- libmv::EuclideanReconstruction reconstruction;
+ EuclideanReconstruction reconstruction;
int current_keyframe = keyframes[i];
- libmv::vector<libmv::Marker> keyframe_markers =
+ libmv::vector<Marker> keyframe_markers =
normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
current_keyframe);
- libmv::Tracks keyframe_tracks(keyframe_markers);
+ Tracks keyframe_tracks(keyframe_markers);
/* get a solution from two keyframes only */
- libmv::EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- libmv::EuclideanBundle(keyframe_tracks, &reconstruction);
- libmv::EuclideanCompleteReconstruction(keyframe_tracks,
- &reconstruction, NULL);
+ EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
+ EuclideanBundle(keyframe_tracks, &reconstruction);
+ EuclideanCompleteReconstruction(keyframe_tracks,
+ &reconstruction,
+ NULL);
- double current_error =
- libmv::EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
+ double current_error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
LG << "Error between " << previous_keyframe
<< " and " << current_keyframe
@@ -589,26 +481,35 @@ static bool selectTwoKeyframesBasedOnGRICAndVariance(
return true;
}
-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)
+} // 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)
{
- struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
- libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
- libmv::CameraIntrinsics &camera_intrinsics = libmv_reconstruction->intrinsics;
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback, callback_customdata);
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
/* Retrieve reconstruction options from C-API to libmv API */
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ CameraIntrinsics *camera_intrinsics;
+ camera_intrinsics = libmv_reconstruction->intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(
+ libmv_camera_intrinsics_options);
/* Invert the camera intrinsics */
- libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
/* keyframe selection */
int keyframe1 = libmv_reconstruction_options->keyframe1,
@@ -621,7 +522,7 @@ struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks
selectTwoKeyframesBasedOnGRICAndVariance(tracks,
normalized_tracks,
- camera_intrinsics,
+ *camera_intrinsics,
keyframe1,
keyframe2);
@@ -633,95 +534,118 @@ struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks
/* actual reconstruction */
LG << "frames to init from: " << keyframe1 << " " << keyframe2;
- libmv::vector<libmv::Marker> keyframe_markers =
+ 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");
- libmv::EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- libmv::EuclideanBundle(normalized_tracks, &reconstruction);
- libmv::EuclideanCompleteReconstruction(normalized_tracks,
- &reconstruction, &update_callback);
+ 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);
+ 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 */
- libmv::EuclideanScaleToUnity(&reconstruction);
+ EuclideanScaleToUnity(&reconstruction);
/* finish reconstruction */
- finishReconstruction(tracks, camera_intrinsics, libmv_reconstruction,
- progress_update_callback, callback_customdata);
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
- return (struct libmv_Reconstruction *)libmv_reconstruction;
+ return (libmv_Reconstruction *) libmv_reconstruction;
}
-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)
+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)
{
- struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
- libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
- libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
- libmv::CameraIntrinsics &camera_intrinsics = libmv_reconstruction->intrinsics;
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback, callback_customdata);
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ /* 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. */
- libmv::Tracks normalized_tracks = getNormalizedTracks(tracks, camera_intrinsics);
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
/* Actual reconstruction. */
- libmv::ModalSolver(normalized_tracks, &reconstruction, &update_callback);
+ ModalSolver(normalized_tracks, &reconstruction, &update_callback);
- libmv::CameraIntrinsics empty_intrinsics;
- libmv::EuclideanBundleCommonIntrinsics(normalized_tracks,
- libmv::BUNDLE_NO_INTRINSICS,
- libmv::BUNDLE_NO_TRANSLATION,
- &reconstruction,
- &empty_intrinsics);
+ 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);
+ 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);
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
- return (struct libmv_Reconstruction *)libmv_reconstruction;
+ return (libmv_Reconstruction *) libmv_reconstruction;
}
-void libmv_reconstructionDestroy(struct 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 struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
+int libmv_reprojectionPointForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track,
+ double pos[3])
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(track);
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(track);
if (point) {
pos[0] = point->X[0];
@@ -734,35 +658,25 @@ int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction *libmv_rec
return 0;
}
-static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point,
- const libmv::EuclideanCamera &camera,
- const libmv::CameraIntrinsics &intrinsics)
-{
- libmv::Vec3 projected = camera.R * point.X + camera.t;
- projected /= projected(2);
-
- libmv::Marker reprojected_marker;
- intrinsics.ApplyIntrinsics(projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y);
-
- reprojected_marker.image = camera.image;
- reprojected_marker.track = point.track;
-
- return reprojected_marker;
-}
-
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track)
+double libmv_reprojectionErrorForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track)
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
- libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersForTrack(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 libmv::EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(markers[i].image);
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
if (!camera || !point || weight == 0.0) {
continue;
@@ -770,7 +684,8 @@ double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_
num_reprojected++;
- libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+ 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;
@@ -780,20 +695,26 @@ double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_
return total_error / num_reprojected;
}
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_reconstruction, int image)
+double libmv_reprojectionErrorForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image)
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
- libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersInImage(image);
- const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(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;
+ if (!camera) {
+ return 0.0;
+ }
for (int i = 0; i < markers.size(); ++i) {
- const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
if (!point) {
continue;
@@ -801,9 +722,10 @@ double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_
num_reprojected++;
- libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
- double ex = reprojected_marker.x - markers[i].x;
- double ey = reprojected_marker.y - markers[i].y;
+ 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);
}
@@ -811,11 +733,14 @@ double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_
return total_error / num_reprojected;
}
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_reconstruction,
- int image, double mat[4][4])
+int libmv_reprojectionCameraForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image, double mat[4][4])
{
- const libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
- const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(image);
if (camera) {
for (int j = 0; j < 3; ++j) {
@@ -845,25 +770,27 @@ int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_re
return 0;
}
-double libmv_reprojectionError(const struct libmv_Reconstruction *libmv_reconstruction)
+double libmv_reprojectionError(
+ const libmv_Reconstruction *libmv_reconstruction)
{
return libmv_reconstruction->error;
}
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_reconstruction)
+libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
+ libmv_Reconstruction *libmv_reconstruction)
{
- return (struct libmv_CameraIntrinsics *)&libmv_reconstruction->intrinsics;
+ return (libmv_CameraIntrinsics *) libmv_reconstruction->intrinsics;
}
/* ************ Feature detector ************ */
static libmv_Features *libmv_featuresFromVector(
- const libmv::vector<libmv::Feature> &features)
+ const libmv::vector<Feature> &features)
{
- struct libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
+ libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
int count = features.size();
if (count) {
- libmv_features->features = LIBMV_STRUCT_NEW(libmv::Feature, count);
+ libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
for (int i = 0; i < count; i++) {
libmv_features->features[i] = features.at(i);
@@ -879,12 +806,12 @@ static libmv_Features *libmv_featuresFromVector(
}
static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
- libmv::DetectOptions *detector_options)
+ DetectOptions *detector_options)
{
switch (options->detector) {
#define LIBMV_CONVERT(the_detector) \
case LIBMV_DETECTOR_ ## the_detector: \
- detector_options->type = libmv::DetectOptions::the_detector; \
+ detector_options->type = DetectOptions::the_detector; \
break;
LIBMV_CONVERT(FAST)
LIBMV_CONVERT(MORAVEC)
@@ -899,49 +826,52 @@ static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
detector_options->harris_threshold = options->harris_threshold;
}
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char *image_buffer,
- int width, int height, int channels,
- libmv_DetectOptions *options)
+libmv_Features *libmv_detectFeaturesByte(
+ const unsigned char *image_buffer,
+ int width, int height,
+ int channels,
+ libmv_DetectOptions *options)
{
// Prepare the image.
- libmv::FloatImage image;
- byteBufToImage(image_buffer, width, height, channels, &image);
+ FloatImage image;
+ libmv_byteBufferToImage(image_buffer, width, height, channels, &image);
// Configure detector.
- libmv::DetectOptions detector_options;
+ DetectOptions detector_options;
libmv_convertDetectorOptions(options, &detector_options);
// Run the detector.
- libmv::vector<libmv::Feature> detected_features;
- libmv::Detect(image, detector_options, &detected_features);
+ 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;
}
-struct libmv_Features *libmv_detectFeaturesFloat(const float *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)
{
// Prepare the image.
- libmv::FloatImage image;
- floatBufToImage(image_buffer, width, height, channels, &image);
+ FloatImage image;
+ libmv_floatBufferToImage(image_buffer, width, height, channels, &image);
// Configure detector.
- libmv::DetectOptions detector_options;
+ DetectOptions detector_options;
libmv_convertDetectorOptions(options, &detector_options);
// Run the detector.
- libmv::vector<libmv::Feature> detected_features;
- libmv::Detect(image, detector_options, &detected_features);
+ 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(struct libmv_Features *libmv_features)
+void libmv_featuresDestroy(libmv_Features *libmv_features)
{
if (libmv_features->features) {
LIBMV_STRUCT_DELETE(libmv_features->features);
@@ -950,14 +880,16 @@ void libmv_featuresDestroy(struct libmv_Features *libmv_features)
LIBMV_STRUCT_DELETE(libmv_features);
}
-int libmv_countFeatures(const struct libmv_Features *libmv_features)
+int libmv_countFeatures(const libmv_Features *libmv_features)
{
return libmv_features->count;
}
-void libmv_getFeature(const struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size)
+void libmv_getFeature(const libmv_Features *libmv_features,
+ int number,
+ double *x, double *y, double *score, double *size)
{
- libmv::Feature feature = libmv_features->features[number];
+ Feature &feature = libmv_features->features[number];
*x = feature.x;
*y = feature.y;
@@ -967,51 +899,67 @@ void libmv_getFeature(const struct libmv_Features *libmv_features, int number, d
/* ************ Camera intrinsics ************ */
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNewEmpty(void)
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
{
- libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
- return (struct libmv_CameraIntrinsics *) camera_intrinsics;
+ return (libmv_CameraIntrinsics *) camera_intrinsics;
}
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+ const libmv_CameraIntrinsics *libmvIntrinsics)
{
- libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, camera_intrinsics);
-
- return (struct libmv_CameraIntrinsics *) camera_intrinsics;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics *libmvIntrinsics)
-{
- libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
- libmv::CameraIntrinsics *new_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics, *orig_intrinsics);
+ 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 (struct libmv_CameraIntrinsics *) new_intrinsics;
+ return (libmv_CameraIntrinsics *) new_intrinsics;
}
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics *libmvIntrinsics)
{
- using libmv::CameraIntrinsics;
LIBMV_OBJECT_DELETE(libmvIntrinsics, CameraIntrinsics);
}
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- struct libmv_CameraIntrinsics *libmv_intrinsics)
+void libmv_cameraIntrinsicsUpdate(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ libmv_CameraIntrinsics *libmv_intrinsics)
{
- libmv::CameraIntrinsics *camera_intrinsics = (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;
- double k1 = libmv_camera_intrinsics_options->k1;
- double k2 = libmv_camera_intrinsics_options->k2;
- double k3 = libmv_camera_intrinsics_options->k3;
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 */
+ /* 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);
@@ -1022,105 +970,192 @@ void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_cam
camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
}
- if (camera_intrinsics->k1() != k1 ||
- camera_intrinsics->k2() != k2 ||
- camera_intrinsics->k3() != k3)
- {
- camera_intrinsics->SetRadialDistortion(k1, k2, k3);
- }
-
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(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads)
+void libmv_cameraIntrinsicsSetThreads(
+ libmv_CameraIntrinsics *libmv_intrinsics, int threads)
{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
camera_intrinsics->SetThreads(threads);
}
-void libmv_cameraIntrinsicsExtract(const struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length,
- double *principal_x, double *principal_y, double *k1, double *k2, double *k3,
- int *width, int *height)
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics *libmv_intrinsics,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
-
- *focal_length = camera_intrinsics->focal_length();
- *principal_x = camera_intrinsics->principal_point_x();
- *principal_y = camera_intrinsics->principal_point_y();
- *k1 = camera_intrinsics->k1();
- *k2 = camera_intrinsics->k2();
- *k3 = camera_intrinsics->k3();
-}
+ 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;
+ }
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
+ 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;
+ }
- camera_intrinsics->Undistort(src, dst, width, height, overscan, channels);
+ default:
+ assert(!"Uknown distortion model");
+ }
}
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsUndistortByte(
+ const libmv_CameraIntrinsics *libmv_intrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
-
- intrinsics->Undistort(src, dst, width, height, overscan, channels);
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ camera_intrinsics->UndistortBuffer(src,
+ width, height, overscan, channels,
+ dst);
}
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsUndistortFloat(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
- intrinsics->Distort(src, dst, width, height, overscan, channels);
+ CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
+ intrinsics->UndistortBuffer(src,
+ width, height, overscan, channels,
+ dst);
}
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
+void libmv_cameraIntrinsicsDistortByte(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
-
- intrinsics->Distort(src, dst, width, height, overscan, channels);
+ 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)
+void libmv_cameraIntrinsicsDistortFloat(
+ const libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height,
+ float overscan, int channels)
{
- libmv::CameraIntrinsics camera_intrinsics;
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
+ 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) {
- /* do a lens undistortion if focal length is non-zero only */
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+
+ camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
- 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)
+void libmv_cameraIntrinsicsInvert(
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ double x, double y, double *x1, double *y1)
{
- libmv::CameraIntrinsics camera_intrinsics;
-
- cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, &camera_intrinsics);
-
+ /* do a lens distortion if focal length is non-zero only */
if (libmv_camera_intrinsics_options->focal_length) {
- /* do a lens distortion if focal length is non-zero only */
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+
+ camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
- 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])
+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;
@@ -1137,7 +1172,10 @@ void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2],
LG << "x2: " << x2_mat;
libmv::EstimateHomographyOptions options;
- libmv::EstimateHomography2DFromCorrespondences(x1_mat, x2_mat, options, &H_mat);
+ libmv::EstimateHomography2DFromCorrespondences(x1_mat,
+ x2_mat,
+ options,
+ &H_mat);
LG << "H: " << H_mat;
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index d183bc4cd41..5cd9936723b 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -64,11 +64,22 @@ int libmv_trackRegion(const libmv_TrackRegionOptions *options,
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,
+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,
+ 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);
@@ -81,12 +92,24 @@ void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track,
#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;
- double k1, k2, k3;
- double p1, p2;
- int image_width, image_height;
+
+ /* 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 {
@@ -147,7 +170,6 @@ void libmv_getFeature(const struct libmv_Features *libmv_features, int number, d
double *size);
/* Camera intrinsics */
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNewEmpty(void);
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options);
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const struct libmv_CameraIntrinsics *libmv_intrinsics);
@@ -155,9 +177,9 @@ void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmv_intrinsi
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_cameraIntrinsicsExtract(const struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length,
- double *principal_x, double *principal_y, double *k1, double *k2, double *k3,
- int *width, int *height);
+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);
diff --git a/extern/libmv/libmv-capi_stub.cc b/extern/libmv/libmv-capi_stub.cc
index bd5d16c9077..36a3bc7ddee 100644
--- a/extern/libmv/libmv-capi_stub.cc
+++ b/extern/libmv/libmv-capi_stub.cc
@@ -68,11 +68,24 @@ int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/,
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)
+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 */
}
@@ -186,11 +199,6 @@ struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
return NULL;
}
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNewEmpty(void)
-{
- return NULL;
-}
-
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/)
{
@@ -215,17 +223,12 @@ void libmv_cameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics * /*libmv_in
{
}
-void libmv_cameraIntrinsicsExtract(const struct libmv_CameraIntrinsics * /*libmv_intrinsics*/, double * focal_length,
- double * principal_x, double *principal_y, double *k1, double *k2, double *k3,
- int *width, int *height)
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics */*libmv_intrinsics*/,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
{
- *focal_length = 1.0;
- *principal_x = 0.0;
- *principal_y = 0.0;
- *k1 = 0.0;
- *k2 = 0.0;
- *width = 0.0;
- *height = 0.0;
+ memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
+ camera_intrinsics_options->focal_length = 1.0;
}
void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics * /*libmv_intrinsics*/,
diff --git a/extern/libmv/libmv-util.cc b/extern/libmv/libmv-util.cc
new file mode 100644
index 00000000000..f969417d6c1
--- /dev/null
+++ b/extern/libmv/libmv-util.cc
@@ -0,0 +1,309 @@
+/*
+ * ***** 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
new file mode 100644
index 00000000000..d755f98d06d
--- /dev/null
+++ b/extern/libmv/libmv-util.h
@@ -0,0 +1,69 @@
+/*
+ * ***** 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/base/aligned_malloc.cc b/extern/libmv/libmv/base/aligned_malloc.cc
new file mode 100644
index 00000000000..9141186f196
--- /dev/null
+++ b/extern/libmv/libmv/base/aligned_malloc.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/base/aligned_malloc.h"
+#include "libmv/logging/logging.h"
+
+#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
+// Needed for memalign on Linux and _aligned_alloc on Windows.
+# ifdef FREE_WINDOWS
+/* make sure _aligned_malloc is included */
+# ifdef __MSVCRT_VERSION__
+# undef __MSVCRT_VERSION__
+# endif
+
+# define __MSVCRT_VERSION__ 0x0700
+# endif // FREE_WINDOWS
+
+# include <malloc.h>
+#else
+// Apple's malloc is 16-byte aligned, and does not have malloc.h, so include
+// stdilb instead.
+# include <cstdlib>
+#endif
+
+namespace libmv {
+
+void *aligned_malloc(int size, int alignment) {
+#ifdef _WIN32
+ return _aligned_malloc(size, alignment);
+#elif __APPLE__
+ // On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
+ // they work natively with SSE types with no further work.
+ CHECK_EQ(alignment, 16);
+ return malloc(size);
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+ void *result;
+
+ if (posix_memalign(&result, alignment, size)) {
+ // non-zero means allocation error
+ // either no allocation or bad alignment value
+ return NULL;
+ }
+ return result;
+#else // This is for Linux.
+ return memalign(alignment, size);
+#endif
+}
+
+void aligned_free(void *ptr) {
+#ifdef _WIN32
+ _aligned_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/base/aligned_malloc.h b/extern/libmv/libmv/base/aligned_malloc.h
new file mode 100644
index 00000000000..096ff6e2d7c
--- /dev/null
+++ b/extern/libmv/libmv/base/aligned_malloc.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_BASE_ALIGNED_MALLOC_H_
+#define LIBMV_BASE_ALIGNED_MALLOC_H_
+
+namespace libmv {
+
+// Allocate block of size bytes at least aligned to a given value.
+void *aligned_malloc(int size, int alignment);
+
+// Free memory allocated by aligned_malloc.
+void aligned_free(void *ptr);
+
+} // namespace libmv
+
+#endif // LIBMV_BASE_ALIGNED_MALLOC_H_
diff --git a/extern/libmv/libmv/image/correlation.h b/extern/libmv/libmv/image/correlation.h
index ac1f8edab49..c354f7e891e 100644
--- a/extern/libmv/libmv/image/correlation.h
+++ b/extern/libmv/libmv/image/correlation.h
@@ -27,34 +27,40 @@
namespace libmv {
inline double PearsonProductMomentCorrelation(
- Array3Df image_and_gradient1_sampled,
- Array3Df image_and_gradient2_sampled,
- int width) {
+ const FloatImage &image_and_gradient1_sampled,
+ const FloatImage &image_and_gradient2_sampled) {
+ assert(image_and_gradient1_sampled.Width() ==
+ image_and_gradient2_sampled.Width());
+ assert(image_and_gradient1_sampled.Height() ==
+ image_and_gradient2_sampled.Height());
+
+ const int width = image_and_gradient1_sampled.Width(),
+ height = image_and_gradient1_sampled.Height();
double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0;
- for (int r = 0; r < width; ++r) {
+ for (int r = 0; r < height; ++r) {
for (int c = 0; c < width; ++c) {
double x = image_and_gradient1_sampled(r, c, 0);
double y = image_and_gradient2_sampled(r, c, 0);
sX += x;
sY += y;
- sXX += x*x;
- sYY += y*y;
- sXY += x*y;
+ sXX += x * x;
+ sYY += y * y;
+ sXY += x * y;
}
}
// Normalize.
- double N = width * width;
+ double N = width * height;
sX /= N;
sY /= N;
sXX /= N;
sYY /= N;
sXY /= N;
- double var_x = sXX - sX*sX;
- double var_y = sYY - sY*sY;
- double covariance_xy = sXY - sX*sY;
+ double var_x = sXX - sX * sX;
+ double var_y = sYY - sY * sY;
+ double covariance_xy = sXY - sX * sY;
double correlation = covariance_xy / sqrt(var_x * var_y);
LG << "Covariance xy: " << covariance_xy
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc
index 9835248e7d5..fc1882a0b72 100644
--- a/extern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/extern/libmv/libmv/simple_pipeline/bundle.cc
@@ -32,6 +32,7 @@
#include "libmv/simple_pipeline/camera_intrinsics.h"
#include "libmv/simple_pipeline/reconstruction.h"
#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/distortion_models.h"
#ifdef _OPENMP
# include <omp.h>
@@ -42,16 +43,27 @@ namespace libmv {
// The intrinsics need to get combined into a single parameter block; use these
// enums to index instead of numeric constants.
enum {
+ // Camera calibration values.
OFFSET_FOCAL_LENGTH,
OFFSET_PRINCIPAL_POINT_X,
OFFSET_PRINCIPAL_POINT_Y,
+
+ // Distortion model coefficients.
OFFSET_K1,
OFFSET_K2,
OFFSET_K3,
OFFSET_P1,
OFFSET_P2,
+
+ // Maximal possible offset.
+ OFFSET_MAX,
};
+#define FIRST_DISTORTION_COEFFICIENT OFFSET_K1
+#define LAST_DISTORTION_COEFFICIENT OFFSET_P2
+#define NUM_DISTORTION_COEFFICIENTS \
+ (LAST_DISTORTION_COEFFICIENT - FIRST_DISTORTION_COEFFICIENT + 1)
+
namespace {
// Cost functor which computes reprojection error of 3D point X
@@ -60,10 +72,12 @@ namespace {
//
// This functor uses a radial distortion model.
struct OpenCVReprojectionError {
- OpenCVReprojectionError(const double observed_x,
+ OpenCVReprojectionError(const DistortionModelType distortion_model,
+ const double observed_x,
const double observed_y,
const double weight)
- : observed_x_(observed_x), observed_y_(observed_y),
+ : distortion_model_(distortion_model),
+ observed_x_(observed_x), observed_y_(observed_y),
weight_(weight) {}
template <typename T>
@@ -76,11 +90,6 @@ struct OpenCVReprojectionError {
const T& focal_length = intrinsics[OFFSET_FOCAL_LENGTH];
const T& principal_point_x = intrinsics[OFFSET_PRINCIPAL_POINT_X];
const T& principal_point_y = intrinsics[OFFSET_PRINCIPAL_POINT_Y];
- const T& k1 = intrinsics[OFFSET_K1];
- const T& k2 = intrinsics[OFFSET_K2];
- const T& k3 = intrinsics[OFFSET_K3];
- const T& p1 = intrinsics[OFFSET_P1];
- const T& p2 = intrinsics[OFFSET_P2];
// Compute projective coordinates: x = RX + t.
T x[3];
@@ -104,15 +113,44 @@ struct OpenCVReprojectionError {
// Apply distortion to the normalized points to get (xd, yd).
// TODO(keir): Do early bailouts for zero distortion; these are expensive
// jet operations.
- ApplyRadialDistortionCameraIntrinsics(focal_length,
- focal_length,
- principal_point_x,
- principal_point_y,
- k1, k2, k3,
- p1, p2,
- xn, yn,
- &predicted_x,
- &predicted_y);
+ switch (distortion_model_) {
+ case DISTORTION_MODEL_POLYNOMIAL:
+ {
+ const T& k1 = intrinsics[OFFSET_K1];
+ const T& k2 = intrinsics[OFFSET_K2];
+ const T& k3 = intrinsics[OFFSET_K3];
+ const T& p1 = intrinsics[OFFSET_P1];
+ const T& p2 = intrinsics[OFFSET_P2];
+
+ ApplyPolynomialDistortionModel(focal_length,
+ focal_length,
+ principal_point_x,
+ principal_point_y,
+ k1, k2, k3,
+ p1, p2,
+ xn, yn,
+ &predicted_x,
+ &predicted_y);
+ break;
+ }
+ case DISTORTION_MODEL_DIVISION:
+ {
+ const T& k1 = intrinsics[OFFSET_K1];
+ const T& k2 = intrinsics[OFFSET_K2];
+
+ ApplyDivisionDistortionModel(focal_length,
+ focal_length,
+ principal_point_x,
+ principal_point_y,
+ k1, k2,
+ xn, yn,
+ &predicted_x,
+ &predicted_y);
+ break;
+ }
+ default:
+ LOG(FATAL) << "Unknown distortion model";
+ }
// The error is the difference between the predicted and observed position.
residuals[0] = (predicted_x - T(observed_x_)) * weight_;
@@ -120,6 +158,7 @@ struct OpenCVReprojectionError {
return true;
}
+ const DistortionModelType distortion_model_;
const double observed_x_;
const double observed_y_;
const double weight_;
@@ -154,32 +193,38 @@ void BundleIntrinsicsLogMessage(const int bundle_intrinsics) {
// Pack intrinsics from object to an array for easier
// and faster minimization.
void PackIntrinisicsIntoArray(const CameraIntrinsics &intrinsics,
- double ceres_intrinsics[8]) {
+ double ceres_intrinsics[OFFSET_MAX]) {
ceres_intrinsics[OFFSET_FOCAL_LENGTH] = intrinsics.focal_length();
ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X] = intrinsics.principal_point_x();
ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y] = intrinsics.principal_point_y();
- ceres_intrinsics[OFFSET_K1] = intrinsics.k1();
- ceres_intrinsics[OFFSET_K2] = intrinsics.k2();
- ceres_intrinsics[OFFSET_K3] = intrinsics.k3();
- ceres_intrinsics[OFFSET_P1] = intrinsics.p1();
- ceres_intrinsics[OFFSET_P2] = intrinsics.p2();
+
+ int num_distortion_parameters = intrinsics.num_distortion_parameters();
+ assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
+
+ const double *distortion_parameters = intrinsics.distortion_parameters();
+ for (int i = 0; i < num_distortion_parameters; ++i) {
+ ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i] =
+ distortion_parameters[i];
+ }
}
// Unpack intrinsics back from an array to an object.
-void UnpackIntrinsicsFromArray(const double ceres_intrinsics[8],
- CameraIntrinsics *intrinsics) {
- intrinsics->SetFocalLength(ceres_intrinsics[OFFSET_FOCAL_LENGTH],
- ceres_intrinsics[OFFSET_FOCAL_LENGTH]);
+void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX],
+ CameraIntrinsics *intrinsics) {
+ intrinsics->SetFocalLength(ceres_intrinsics[OFFSET_FOCAL_LENGTH],
+ ceres_intrinsics[OFFSET_FOCAL_LENGTH]);
- intrinsics->SetPrincipalPoint(ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X],
- ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]);
+ intrinsics->SetPrincipalPoint(ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X],
+ ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]);
- intrinsics->SetRadialDistortion(ceres_intrinsics[OFFSET_K1],
- ceres_intrinsics[OFFSET_K2],
- ceres_intrinsics[OFFSET_K3]);
+ int num_distortion_parameters = intrinsics->num_distortion_parameters();
+ assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
- intrinsics->SetTangentialDistortion(ceres_intrinsics[OFFSET_P1],
- ceres_intrinsics[OFFSET_P2]);
+ double *distortion_parameters = intrinsics->distortion_parameters();
+ for (int i = 0; i < num_distortion_parameters; ++i) {
+ distortion_parameters[i] =
+ ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i];
+ }
}
// Get a vector of camera's rotations denoted by angle axis
@@ -321,35 +366,110 @@ void EuclideanBundlerPerformEvaluation(const Tracks &tracks,
}
}
+// This is an utility function to only bundle 3D position of
+// given markers list.
+//
+// Main purpose of this function is to adjust positions of tracks
+// which does have constant zero weight and so far only were using
+// algebraic intersection to obtain their 3D positions.
+//
+// At this point we only need to bundle points positions, cameras
+// are to be totally still here.
+void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
+ const vector<Marker> &markers,
+ vector<Vec6> &all_cameras_R_t,
+ double ceres_intrinsics[OFFSET_MAX],
+ EuclideanReconstruction *reconstruction) {
+ ceres::Problem::Options problem_options;
+ ceres::Problem problem(problem_options);
+ int num_residuals = 0;
+ for (int i = 0; i < markers.size(); ++i) {
+ const Marker &marker = markers[i];
+ EuclideanCamera *camera = reconstruction->CameraForImage(marker.image);
+ EuclideanPoint *point = reconstruction->PointForTrack(marker.track);
+ if (camera == NULL || point == NULL) {
+ continue;
+ }
+
+ // Rotation of camera denoted in angle axis followed with
+ // camera translaiton.
+ double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
+
+ problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
+ OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
+ new OpenCVReprojectionError(
+ distortion_model,
+ marker.x,
+ marker.y,
+ 1.0)),
+ NULL,
+ ceres_intrinsics,
+ current_camera_R_t,
+ &point->X(0));
+
+ problem.SetParameterBlockConstant(current_camera_R_t);
+ num_residuals++;
+ }
+
+ LG << "Number of residuals: " << num_residuals;
+ if (!num_residuals) {
+ LG << "Skipping running minimizer with zero residuals";
+ return;
+ }
+
+ problem.SetParameterBlockConstant(ceres_intrinsics);
+
+ // Configure the solver.
+ ceres::Solver::Options options;
+ options.use_nonmonotonic_steps = true;
+ options.preconditioner_type = ceres::SCHUR_JACOBI;
+ options.linear_solver_type = ceres::ITERATIVE_SCHUR;
+ options.use_inner_iterations = true;
+ options.max_num_iterations = 100;
+
+#ifdef _OPENMP
+ options.num_threads = omp_get_max_threads();
+ options.num_linear_solver_threads = omp_get_max_threads();
+#endif
+
+ // Solve!
+ ceres::Solver::Summary summary;
+ ceres::Solve(options, &problem, &summary);
+
+ LG << "Final report:\n" << summary.FullReport();
+
+}
+
} // namespace
void EuclideanBundle(const Tracks &tracks,
EuclideanReconstruction *reconstruction) {
- CameraIntrinsics intrinsics;
+ PolynomialCameraIntrinsics empty_intrinsics;
EuclideanBundleCommonIntrinsics(tracks,
BUNDLE_NO_INTRINSICS,
BUNDLE_NO_CONSTRAINTS,
reconstruction,
- &intrinsics,
+ &empty_intrinsics,
NULL);
}
-void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
- const int bundle_intrinsics,
- const int bundle_constraints,
- EuclideanReconstruction *reconstruction,
- CameraIntrinsics *intrinsics,
- BundleEvaluation *evaluation) {
+void EuclideanBundleCommonIntrinsics(
+ const Tracks &tracks,
+ const int bundle_intrinsics,
+ const int bundle_constraints,
+ EuclideanReconstruction *reconstruction,
+ CameraIntrinsics *intrinsics,
+ BundleEvaluation *evaluation) {
LG << "Original intrinsics: " << *intrinsics;
vector<Marker> markers = tracks.AllMarkers();
- ceres::Problem::Options problem_options;
- ceres::Problem problem(problem_options);
+ // N-th element denotes whether track N is a constant zero-weigthed track.
+ vector<bool> zero_weight_tracks_flags(tracks.MaxTrack() + 1, true);
// Residual blocks with 10 parameters are unwieldly with Ceres, so pack the
// intrinsics into a single block and rely on local parameterizations to
// control which intrinsics are allowed to vary.
- double ceres_intrinsics[8];
+ double ceres_intrinsics[OFFSET_MAX];
PackIntrinisicsIntoArray(*intrinsics, ceres_intrinsics);
// Convert cameras rotations to angle axis and merge with translation
@@ -375,6 +495,8 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
}
// Add residual blocks to the problem.
+ ceres::Problem::Options problem_options;
+ ceres::Problem problem(problem_options);
int num_residuals = 0;
bool have_locked_camera = false;
for (int i = 0; i < markers.size(); ++i) {
@@ -394,8 +516,9 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
// This way ceres is not gonna to go crazy.
if (marker.weight != 0.0) {
problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
- OpenCVReprojectionError, 2, 8, 6, 3>(
+ OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
new OpenCVReprojectionError(
+ intrinsics->GetDistortionModelType(),
marker.x,
marker.y,
marker.weight)),
@@ -414,6 +537,8 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
problem.SetParameterization(current_camera_R_t,
constant_translation_parameterization);
}
+
+ zero_weight_tracks_flags[marker.track] = false;
}
num_residuals++;
@@ -425,6 +550,12 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
return;
}
+ if (intrinsics->GetDistortionModelType() == DISTORTION_MODEL_DIVISION &&
+ (bundle_intrinsics & BUNDLE_TANGENTIAL) != 0) {
+ LOG(FATAL) << "Division model doesn't support bundling "
+ "of tangential distortion";
+ }
+
BundleIntrinsicsLogMessage(bundle_intrinsics);
if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
@@ -453,7 +584,7 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
constant_intrinsics.push_back(OFFSET_K3);
ceres::SubsetParameterization *subset_parameterization =
- new ceres::SubsetParameterization(8, constant_intrinsics);
+ new ceres::SubsetParameterization(OFFSET_MAX, constant_intrinsics);
problem.SetParameterization(ceres_intrinsics, subset_parameterization);
}
@@ -492,6 +623,29 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
EuclideanBundlerPerformEvaluation(tracks, reconstruction, &all_cameras_R_t,
&problem, evaluation);
}
+
+ // Separate step to adjust positions of tracks which are
+ // constant zero-weighted.
+ vector<Marker> zero_weight_markers;
+ for (int track = 0; track < tracks.MaxTrack(); ++track) {
+ if (zero_weight_tracks_flags[track]) {
+ vector<Marker> current_markers = tracks.MarkersForTrack(track);
+ zero_weight_markers.reserve(zero_weight_markers.size() +
+ current_markers.size());
+ for (int i = 0; i < current_markers.size(); ++i) {
+ zero_weight_markers.push_back(current_markers[i]);
+ }
+ }
+ }
+
+ if (zero_weight_markers.size()) {
+ LG << "Refining position of constant zero-weighted tracks";
+ EuclideanBundlePointsOnly(intrinsics->GetDistortionModelType(),
+ zero_weight_markers,
+ all_cameras_R_t,
+ ceres_intrinsics,
+ reconstruction);
+ }
}
void ProjectiveBundle(const Tracks & /*tracks*/,
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.h b/extern/libmv/libmv/simple_pipeline/bundle.h
index d19eec16d6d..781bd8476fe 100644
--- a/extern/libmv/libmv/simple_pipeline/bundle.h
+++ b/extern/libmv/libmv/simple_pipeline/bundle.h
@@ -114,12 +114,13 @@ enum BundleConstraints {
BUNDLE_NO_CONSTRAINTS = 0,
BUNDLE_NO_TRANSLATION = 1,
};
-void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
- const int bundle_intrinsics,
- const int bundle_constraints,
- EuclideanReconstruction *reconstruction,
- CameraIntrinsics *intrinsics,
- BundleEvaluation *evaluation = NULL);
+void EuclideanBundleCommonIntrinsics(
+ const Tracks &tracks,
+ const int bundle_intrinsics,
+ const int bundle_constraints,
+ EuclideanReconstruction *reconstruction,
+ CameraIntrinsics *intrinsics,
+ BundleEvaluation *evaluation = NULL);
/*!
Refine camera poses and 3D coordinates using bundle adjustment.
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
index ddbbec58def..5e4e07b3c4c 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
@@ -19,358 +19,226 @@
// IN THE SOFTWARE.
#include "libmv/simple_pipeline/camera_intrinsics.h"
-#include "libmv/numeric/levenberg_marquardt.h"
-namespace libmv {
+#include "libmv/logging/logging.h"
+#include "libmv/simple_pipeline/distortion_models.h"
-struct Offset {
- short ix, iy;
- unsigned char fx, fy;
-};
+namespace libmv {
-struct Grid {
- struct Offset *offset;
- int width, height;
- double overscan;
-};
+namespace internal {
-static struct Grid *copyGrid(struct Grid *from) {
- struct Grid *to = NULL;
+LookupWarpGrid::LookupWarpGrid()
+ : offset_(NULL),
+ width_(0),
+ height_(0),
+ overscan_(0.0),
+ threads_(1) {}
- if (from) {
- to = new Grid;
+LookupWarpGrid::LookupWarpGrid(const LookupWarpGrid &from)
+ : offset_(NULL),
+ width_(from.width_),
+ height_(from.height_),
+ overscan_(from.overscan_),
+ threads_(from.threads_) {
+ if (from.offset_) {
+ offset_ = new Offset[width_ * height_];
+ memcpy(offset_, from.offset_, sizeof(Offset) * width_ * height_);
+ }
+}
- to->width = from->width;
- to->height = from->height;
- to->overscan = from->overscan;
+LookupWarpGrid::~LookupWarpGrid() {
+ delete [] offset_;
+}
- to->offset = new Offset[to->width*to->height];
- memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height);
- }
+void LookupWarpGrid::Reset() {
+ delete [] offset_;
+ offset_ = NULL;
+}
- return to;
+// Set number of threads used for threaded buffer distortion/undistortion.
+void LookupWarpGrid::SetThreads(int threads) {
+ threads_ = threads;
}
+} // namespace internal
+
CameraIntrinsics::CameraIntrinsics()
- : K_(Mat3::Identity()),
- image_width_(0),
+ : image_width_(0),
image_height_(0),
- k1_(0),
- k2_(0),
- k3_(0),
- p1_(0),
- p2_(0),
- distort_(0),
- undistort_(0),
- threads_(1) {}
+ K_(Mat3::Identity()) {}
CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
- : K_(from.K_),
- image_width_(from.image_width_),
+ : image_width_(from.image_width_),
image_height_(from.image_height_),
- k1_(from.k1_),
- k2_(from.k2_),
- k3_(from.k3_),
- p1_(from.p1_),
- p2_(from.p2_),
- threads_(from.threads_) {
- distort_ = copyGrid(from.distort_);
- undistort_ = copyGrid(from.undistort_);
-}
+ K_(from.K_),
+ distort_(from.distort_),
+ undistort_(from.undistort_) {}
-CameraIntrinsics::~CameraIntrinsics() {
- FreeLookupGrid();
+// Set the image size in pixels.
+void CameraIntrinsics::SetImageSize(int width, int height) {
+ image_width_ = width;
+ image_height_ = height;
+ ResetLookupGrids();
}
-/// Set the entire calibration matrix at once.
+// Set the entire calibration matrix at once.
void CameraIntrinsics::SetK(const Mat3 new_k) {
K_ = new_k;
- FreeLookupGrid();
+ ResetLookupGrids();
}
-/// Set both x and y focal length in pixels.
-void CameraIntrinsics::SetFocalLength(double focal_x, double focal_y) {
+// Set both x and y focal length in pixels.
+void CameraIntrinsics::SetFocalLength(double focal_x,
+ double focal_y) {
K_(0, 0) = focal_x;
K_(1, 1) = focal_y;
- FreeLookupGrid();
+ ResetLookupGrids();
}
-void CameraIntrinsics::SetPrincipalPoint(double cx, double cy) {
+// Set principal point in pixels.
+void CameraIntrinsics::SetPrincipalPoint(double cx,
+ double cy) {
K_(0, 2) = cx;
K_(1, 2) = cy;
- FreeLookupGrid();
+ ResetLookupGrids();
}
-void CameraIntrinsics::SetImageSize(int width, int height) {
- image_width_ = width;
- image_height_ = height;
- FreeLookupGrid();
+// Set number of threads used for threaded buffer distortion/undistortion.
+void CameraIntrinsics::SetThreads(int threads) {
+ distort_.SetThreads(threads);
+ undistort_.SetThreads(threads);
}
-void CameraIntrinsics::SetRadialDistortion(double k1, double k2, double k3) {
- k1_ = k1;
- k2_ = k2;
- k3_ = k3;
- FreeLookupGrid();
+void CameraIntrinsics::ImageSpaceToNormalized(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const {
+ *normalized_x = (image_x - principal_point_x()) / focal_length_x();
+ *normalized_y = (image_y - principal_point_y()) / focal_length_y();
}
-void CameraIntrinsics::SetTangentialDistortion(double p1, double p2) {
- p1_ = p1;
- p2_ = p2;
- FreeLookupGrid();
+void CameraIntrinsics::NormalizedToImageSpace(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const {
+ *image_x = normalized_x * focal_length_x() + principal_point_x();
+ *image_y = normalized_y * focal_length_y() + principal_point_y();
}
-void CameraIntrinsics::SetThreads(int threads) {
- threads_ = threads;
+// Reset lookup grids after changing the distortion model.
+void CameraIntrinsics::ResetLookupGrids() {
+ distort_.Reset();
+ undistort_.Reset();
}
-void CameraIntrinsics::ApplyIntrinsics(double normalized_x,
- double normalized_y,
- double *image_x,
- double *image_y) const {
- ApplyRadialDistortionCameraIntrinsics(focal_length_x(),
- focal_length_y(),
- principal_point_x(),
- principal_point_y(),
- k1(), k2(), k3(),
- p1(), p2(),
- normalized_x,
- normalized_y,
- image_x,
- image_y);
+PolynomialCameraIntrinsics::PolynomialCameraIntrinsics()
+ : CameraIntrinsics() {
+ SetRadialDistortion(0.0, 0.0, 0.0);
+ SetTangentialDistortion(0.0, 0.0);
}
-struct InvertIntrinsicsCostFunction {
- public:
- typedef Vec2 FMatrixType;
- typedef Vec2 XMatrixType;
-
- InvertIntrinsicsCostFunction(const CameraIntrinsics &intrinsics,
- double image_x, double image_y)
- : intrinsics(intrinsics), x(image_x), y(image_y) {}
-
- Vec2 operator()(const Vec2 &u) const {
- double xx, yy;
- intrinsics.ApplyIntrinsics(u(0), u(1), &xx, &yy);
- Vec2 fx;
- fx << (xx - x), (yy - y);
- return fx;
- }
- const CameraIntrinsics &intrinsics;
- double x, y;
-};
-
-void CameraIntrinsics::InvertIntrinsics(double image_x,
- double image_y,
- double *normalized_x,
- double *normalized_y) const {
- // Compute the initial guess. For a camera with no distortion, this will also
- // be the final answer; the LM iteration will terminate immediately.
- Vec2 normalized;
- normalized(0) = (image_x - principal_point_x()) / focal_length_x();
- normalized(1) = (image_y - principal_point_y()) / focal_length_y();
-
- typedef LevenbergMarquardt<InvertIntrinsicsCostFunction> Solver;
-
- InvertIntrinsicsCostFunction intrinsics_cost(*this, image_x, image_y);
- Solver::SolverParameters params;
- Solver solver(intrinsics_cost);
-
- /*Solver::Results results =*/ solver.minimize(params, &normalized);
-
- // TODO(keir): Better error handling.
-
- *normalized_x = normalized(0);
- *normalized_y = normalized(1);
+PolynomialCameraIntrinsics::PolynomialCameraIntrinsics(
+ const PolynomialCameraIntrinsics &from)
+ : CameraIntrinsics(from) {
+ SetRadialDistortion(from.k1(), from.k2(), from.k3());
+ SetTangentialDistortion(from.p1(), from.p2());
}
-// TODO(MatthiasF): downsample lookup
-template<typename WarpFunction>
-void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height,
- double overscan) {
- double w = (double)width / (1 + overscan);
- double h = (double)height / (1 + overscan);
- double aspx = (double)w / image_width_;
- double aspy = (double)h / image_height_;
-#if defined(_OPENMP)
-# pragma omp parallel for schedule(dynamic) num_threads(threads_) \
- if (threads_ > 1 && height > 100)
-#endif
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- double src_x = (x - 0.5 * overscan * w) / aspx,
- src_y = (y - 0.5 * overscan * h) / aspy;
- double warp_x, warp_y;
- WarpFunction(this, src_x, src_y, &warp_x, &warp_y);
- warp_x = warp_x*aspx + 0.5 * overscan * w;
- warp_y = warp_y*aspy + 0.5 * overscan * h;
- int ix = int(warp_x), iy = int(warp_y);
- int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
- if (fx == 256) { fx = 0; ix++; } // NOLINT
- if (fy == 256) { fy = 0; iy++; } // NOLINT
- // Use nearest border pixel
- if (ix < 0) { ix = 0, fx = 0; } // NOLINT
- if (iy < 0) { iy = 0, fy = 0; } // NOLINT
- if (ix >= width - 2) ix = width-2;
- if (iy >= height - 2) iy = height-2;
-
- Offset offset = { (short)(ix-x), (short)(iy-y),
- (unsigned char)fx, (unsigned char)fy };
- grid->offset[y*width+x] = offset;
- }
- }
+void PolynomialCameraIntrinsics::SetRadialDistortion(double k1,
+ double k2,
+ double k3) {
+ parameters_[OFFSET_K1] = k1;
+ parameters_[OFFSET_K2] = k2;
+ parameters_[OFFSET_K3] = k3;
+ ResetLookupGrids();
}
-// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
-template<typename T>
-static void Warp(const Grid* grid, const T* src, T* dst,
- const int width, const int height, const int channels,
- const int threads) {
- (void) threads; // Ignored if OpenMP is disabled
-#if defined(_OPENMP)
-# pragma omp parallel for schedule(dynamic) num_threads(threads) \
- if (threads > 1 && height > 100)
-#endif
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- Offset offset = grid->offset[y*width+x];
- const T* s = &src[((y + offset.iy) * width + (x + offset.ix)) * channels];
- for (int i = 0; i < channels; i++) {
- // TODO(sergey): Finally wrap this into ultiple lines nicely.
- dst[(y*width+x)*channels+i] =
- ((s[ i] * (256-offset.fx) + s[ channels+i] * offset.fx) * (256-offset.fy) // NOLINT
- +(s[width*channels+i] * (256-offset.fx) + s[width*channels+channels+i] * offset.fx) * offset.fy) / (256*256); // NOLINT
- }
- }
- }
+void PolynomialCameraIntrinsics::SetTangentialDistortion(double p1,
+ double p2) {
+ parameters_[OFFSET_P1] = p1;
+ parameters_[OFFSET_P2] = p2;
+ ResetLookupGrids();
}
-void CameraIntrinsics::FreeLookupGrid() {
- if (distort_) {
- delete distort_->offset;
- delete distort_;
- distort_ = NULL;
- }
-
- if (undistort_) {
- delete undistort_->offset;
- delete undistort_;
- undistort_ = NULL;
- }
+void PolynomialCameraIntrinsics::ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const {
+ ApplyPolynomialDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ k1(), k2(), k3(),
+ p1(), p2(),
+ normalized_x,
+ normalized_y,
+ image_x,
+ image_y);
}
-// FIXME: C++ templates limitations makes thing complicated,
-// but maybe there is a simpler method.
-struct ApplyIntrinsicsFunction {
- ApplyIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y,
- double *warp_x, double *warp_y) {
- intrinsics->ApplyIntrinsics(
- (x-intrinsics->principal_point_x())/intrinsics->focal_length_x(),
- (y-intrinsics->principal_point_y())/intrinsics->focal_length_y(),
- warp_x, warp_y);
- }
-};
-struct InvertIntrinsicsFunction {
- InvertIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y,
- double *warp_x, double *warp_y) {
- intrinsics->InvertIntrinsics(x, y, warp_x, warp_y);
-
- *warp_x = *warp_x * intrinsics->focal_length_x() +
- intrinsics->principal_point_x();
-
- *warp_y = *warp_y * intrinsics->focal_length_y() +
- intrinsics->principal_point_y();
- }
-};
-
-void CameraIntrinsics::CheckDistortLookupGrid(int width, int height,
- double overscan) {
- if (distort_) {
- if (distort_->width != width || distort_->height != height ||
- distort_->overscan != overscan) {
- delete [] distort_->offset;
- distort_->offset = NULL;
- }
- } else {
- distort_ = new Grid;
- distort_->offset = NULL;
- }
-
- if (!distort_->offset) {
- distort_->offset = new Offset[width * height];
- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_, width,
- height, overscan);
- }
-
- distort_->width = width;
- distort_->height = height;
- distort_->overscan = overscan;
+void PolynomialCameraIntrinsics::InvertIntrinsics(
+ double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const {
+ InvertPolynomialDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ k1(), k2(), k3(),
+ p1(), p2(),
+ image_x,
+ image_y,
+ normalized_x,
+ normalized_y);
}
-void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height,
- double overscan) {
- if (undistort_) {
- if (undistort_->width != width || undistort_->height != height ||
- undistort_->overscan != overscan) {
- delete [] undistort_->offset;
- undistort_->offset = NULL;
- }
- } else {
- undistort_ = new Grid;
- undistort_->offset = NULL;
- }
-
- if (!undistort_->offset) {
- undistort_->offset = new Offset[width * height];
- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_, width,
- height, overscan);
- }
-
- undistort_->width = width;
- undistort_->height = height;
- undistort_->overscan = overscan;
+DivisionCameraIntrinsics::DivisionCameraIntrinsics()
+ : CameraIntrinsics() {
+ SetDistortion(0.0, 0.0);
}
-void CameraIntrinsics::Distort(const float* src, float* dst,
- int width, int height,
- double overscan,
- int channels) {
- assert(channels >= 1);
- assert(channels <= 4);
- CheckDistortLookupGrid(width, height, overscan);
- Warp<float>(distort_, src, dst, width, height, channels, threads_);
+DivisionCameraIntrinsics::DivisionCameraIntrinsics(
+ const DivisionCameraIntrinsics &from)
+ : CameraIntrinsics(from) {
+ SetDistortion(from.k1(), from.k1());
}
-void CameraIntrinsics::Distort(const unsigned char* src,
- unsigned char* dst,
- int width, int height,
- double overscan,
- int channels) {
- assert(channels >= 1);
- assert(channels <= 4);
- CheckDistortLookupGrid(width, height, overscan);
- Warp<unsigned char>(distort_, src, dst, width, height, channels, threads_);
+void DivisionCameraIntrinsics::SetDistortion(double k1,
+ double k2) {
+ parameters_[OFFSET_K1] = k1;
+ parameters_[OFFSET_K2] = k2;
+ ResetLookupGrids();
}
-void CameraIntrinsics::Undistort(const float* src, float* dst,
- int width, int height,
- double overscan,
- int channels) {
- assert(channels >= 1);
- assert(channels <= 4);
- CheckUndistortLookupGrid(width, height, overscan);
- Warp<float>(undistort_, src, dst, width, height, channels, threads_);
+void DivisionCameraIntrinsics::ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const {
+ ApplyDivisionDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ k1(), k2(),
+ normalized_x,
+ normalized_y,
+ image_x,
+ image_y);
}
-void CameraIntrinsics::Undistort(const unsigned char* src,
- unsigned char* dst,
- int width, int height,
- double overscan,
- int channels) {
- assert(channels >= 1);
- assert(channels <= 4);
- CheckUndistortLookupGrid(width, height, overscan);
- Warp<unsigned char>(undistort_, src, dst, width, height, channels, threads_);
+void DivisionCameraIntrinsics::InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const {
+ InvertDivisionDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ k1(), k2(),
+ image_x,
+ image_y,
+ normalized_x,
+ normalized_y);
}
std::ostream& operator <<(std::ostream &os,
@@ -386,11 +254,38 @@ std::ostream& operator <<(std::ostream &os,
<< " w=" << intrinsics.image_width()
<< " h=" << intrinsics.image_height();
- if (intrinsics.k1() != 0.0) { os << " k1=" << intrinsics.k1(); }
- if (intrinsics.k2() != 0.0) { os << " k2=" << intrinsics.k2(); }
- if (intrinsics.k3() != 0.0) { os << " k3=" << intrinsics.k3(); }
- if (intrinsics.p1() != 0.0) { os << " p1=" << intrinsics.p1(); }
- if (intrinsics.p2() != 0.0) { os << " p2=" << intrinsics.p2(); }
+#define PRINT_NONZERO_COEFFICIENT(intrinsics, coeff) \
+ { \
+ if (intrinsics->coeff() != 0.0) { \
+ os << " " #coeff "=" << intrinsics->coeff(); \
+ } \
+ } (void) 0
+
+ switch (intrinsics.GetDistortionModelType()) {
+ case DISTORTION_MODEL_POLYNOMIAL:
+ {
+ const PolynomialCameraIntrinsics *polynomial_intrinsics =
+ static_cast<const PolynomialCameraIntrinsics *>(&intrinsics);
+ PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k1);
+ PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k2);
+ PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k3);
+ PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p1);
+ PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p2);
+ break;
+ }
+ case DISTORTION_MODEL_DIVISION:
+ {
+ const DivisionCameraIntrinsics *division_intrinsics =
+ static_cast<const DivisionCameraIntrinsics *>(&intrinsics);
+ PRINT_NONZERO_COEFFICIENT(division_intrinsics, k1);
+ PRINT_NONZERO_COEFFICIENT(division_intrinsics, k2);
+ break;
+ }
+ default:
+ LOG(FATAL) << "Unknown distortion model.";
+ }
+
+#undef PRINT_NONZERO_COEFFICIENT
return os;
}
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
index 5a348899a11..6a3ade81089 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
@@ -26,181 +26,381 @@
#include <Eigen/Core>
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/distortion_models.h"
+
namespace libmv {
-typedef Eigen::Matrix<double, 3, 3> Mat3;
+class CameraIntrinsics;
-struct Grid;
+namespace internal {
-class CameraIntrinsics {
+// This class is responsible to store a lookup grid to perform
+// image warping using this lookup grid. Such a magic is needed
+// to make (un)distortion as fast as possible in cases multiple
+// images are to be processed.
+class LookupWarpGrid {
public:
- CameraIntrinsics();
- CameraIntrinsics(const CameraIntrinsics &from);
- ~CameraIntrinsics();
-
- const Mat3 &K() const { return K_; }
- double focal_length() const { return K_(0, 0); }
- double focal_length_x() const { return K_(0, 0); }
- double focal_length_y() const { return K_(1, 1); }
- double principal_point_x() const { return K_(0, 2); }
- double principal_point_y() const { return K_(1, 2); }
- int image_width() const { return image_width_; }
- int image_height() const { return image_height_; }
- double k1() const { return k1_; }
- double k2() const { return k2_; }
- double k3() const { return k3_; }
- double p1() const { return p1_; }
- double p2() const { return p2_; }
-
- /// Set the entire calibration matrix at once.
- void SetK(const Mat3 new_k);
-
- /// Set both x and y focal length in pixels.
- void SetFocalLength(double focal_x, double focal_y);
-
- /// Set principal point in pixels.
- void SetPrincipalPoint(double cx, double cy);
-
- /// Set the image size in pixels.
- void SetImageSize(int width, int height);
-
- void SetRadialDistortion(double k1, double k2, double k3 = 0);
-
- void SetTangentialDistortion(double p1, double p2);
-
- /// Set number of threads using for buffer distortion/undistortion
+ LookupWarpGrid();
+ LookupWarpGrid(const LookupWarpGrid &from);
+ ~LookupWarpGrid();
+
+ // Width and height og the image, measured in pixels.
+ int width() const { return width_; }
+ int height() const { return height_; }
+
+ // Overscan factor of the image, so that
+ // - 0.0 is overscan of 0 pixels,
+ // - 1.0 is overscan of image weight pixels in horizontal direction
+ // and image height pixels in vertical direction.
+ double overscan() const { return overscan_; }
+
+ // Update lookup grid in order to be sure it's calculated for
+ // given image width, height and overscan.
+ //
+ // See comment for CameraIntrinsics::DistortBuffer to get more
+ // details about what overscan is.
+ template<typename WarpFunction>
+ void Update(const CameraIntrinsics &intrinsics,
+ int width,
+ int height,
+ double overscan);
+
+ // Apply coordinate lookup grid on a giver input buffer.
+ //
+ // See comment for CameraIntrinsics::DistortBuffer to get more
+ // details about template type.
+ template<typename PixelType>
+ void Apply(const PixelType *input_buffer,
+ int width,
+ int height,
+ int channels,
+ PixelType *output_buffer);
+
+ // Reset lookup grids.
+ // This will tag the grid for update without re-computing it.
+ void Reset();
+
+ // Set number of threads used for threaded buffer distortion/undistortion.
void SetThreads(int threads);
- /*!
- Apply camera intrinsics to the normalized point to get image coordinates.
-
- This applies the lens distortion to a point which is in normalized
- camera coordinates (i.e. the principal point is at (0, 0)) to get image
- coordinates in pixels.
- */
- void ApplyIntrinsics(double normalized_x, double normalized_y,
- double *image_x, double *image_y) const;
+ private:
+ // This structure contains an offset in both x,y directions
+ // in an optimized way sawing some bytes per pixel in the memory.
+ //
+ // TODO(sergey): This is rather questionable optimizations, memory
+ // is cheap nowadays and storing offset in such a way implies much
+ // more operations comparing to using bare floats.
+ struct Offset {
+ // Integer part of the offset.
+ short ix, iy;
+
+ // Float part of an offset, to get a real float value divide this
+ // value by 255.
+ unsigned char fx, fy;
+ };
+
+ // Compute coordinate lookup grid using a giver warp functor.
+ //
+ // width and height corresponds to a size of buffer which will
+ // be warped later.
+ template<typename WarpFunction>
+ void Compute(const CameraIntrinsics &intrinsics,
+ int width,
+ int height,
+ double overscan);
+
+ // This is a buffer which contains per-pixel offset of the
+ // pixels from input buffer to correspond the warping function.
+ Offset *offset_;
+
+ // Dimensions of the image this lookup grid processes.
+ int width_, height_;
+
+ // Overscan of the image being processed by this grid.
+ double overscan_;
+
+ // Number of threads which will be used for buffer istortion/undistortion.
+ int threads_;
+};
- /*!
- Invert camera intrinsics on the image point to get normalized coordinates.
+} // namespace internal
- This reverses the effect of lens distortion on a point which is in image
- coordinates to get normalized camera coordinates.
- */
- void InvertIntrinsics(double image_x, double image_y,
- double *normalized_x, double *normalized_y) const;
+class CameraIntrinsics {
+ public:
+ CameraIntrinsics();
+ CameraIntrinsics(const CameraIntrinsics &from);
+ virtual ~CameraIntrinsics() {}
- /*!
- Distort an image using the current camera instrinsics
+ virtual DistortionModelType GetDistortionModelType() const = 0;
- The distorted image is computed in \a dst using samples from \a src.
- both buffers should be \a width x \a height x \a channels sized.
+ int image_width() const { return image_width_; }
+ int image_height() const { return image_height_; }
- \note This is the reference implementation using floating point images.
- */
- void Distort(const float* src, float* dst,
- int width, int height, double overscan, int channels);
+ const Mat3 &K() const { return K_; }
- /*!
- Distort an image using the current camera instrinsics
+ double focal_length() const { return K_(0, 0); }
+ double focal_length_x() const { return K_(0, 0); }
+ double focal_length_y() const { return K_(1, 1); }
- The distorted image is computed in \a dst using samples from \a src.
- both buffers should be \a width x \a height x \a channels sized.
+ double principal_point_x() const { return K_(0, 2); }
+ double principal_point_y() const { return K_(1, 2); }
- \note This version is much faster.
- */
- void Distort(const unsigned char* src, unsigned char* dst,
- int width, int height, double overscan, int channels);
+ virtual int num_distortion_parameters() const = 0;
+ virtual double *distortion_parameters() = 0;
+ virtual const double *distortion_parameters() const = 0;
- /*!
- Undistort an image using the current camera instrinsics
+ // Set the image size in pixels.
+ // Image is the size of image camera intrinsics were calibrated with.
+ void SetImageSize(int width, int height);
- The undistorted image is computed in \a dst using samples from \a src.
- both buffers should be \a width x \a height x \a channels sized.
+ // Set the entire calibration matrix at once.
+ void SetK(const Mat3 new_k);
- \note This is the reference implementation using floating point images.
- */
- void Undistort(const float* src, float* dst,
- int width, int height, double overscan, int channels);
+ // Set both x and y focal length in pixels.
+ void SetFocalLength(double focal_x, double focal_y);
- /*!
- Undistort an image using the current camera instrinsics
+ // Set principal point in pixels.
+ void SetPrincipalPoint(double cx, double cy);
- The undistorted image is computed in \a dst using samples from \a src.
- both buffers should be \a width x \a height x \a channels sized.
+ // Set number of threads used for threaded buffer distortion/undistortion.
+ void SetThreads(int threads);
- \note This version is much faster.
- */
- void Undistort(const unsigned char* src, unsigned char* dst,
- int width, int height, double overscan, int channels);
+ // Convert image space coordinates to normalized.
+ void ImageSpaceToNormalized(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const;
+
+ // Convert normalized coordinates to image space.
+ void NormalizedToImageSpace(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const;
+
+ // Apply camera intrinsics to the normalized point to get image coordinates.
+ //
+ // This applies the lens distortion to a point which is in normalized
+ // camera coordinates (i.e. the principal point is at (0, 0)) to get image
+ // coordinates in pixels.
+ virtual void ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const = 0;
+
+ // Invert camera intrinsics on the image point to get normalized coordinates.
+ //
+ // This reverses the effect of lens distortion on a point which is in image
+ // coordinates to get normalized camera coordinates.
+ virtual void InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const = 0;
+
+ // Distort an image using the current camera instrinsics
+ //
+ // The distorted image is computed in output_buffer using samples from
+ // input_buffer. Both buffers should be width x height x channels sized.
+ //
+ // Overscan is a percentage value of how much overcan the image have.
+ // For example overscal value of 0.2 means 20% of overscan in the
+ // buffers.
+ //
+ // Overscan is usually used in cases when one need to distort an image
+ // and don't have a barrel in the distorted buffer. For example, when
+ // one need to render properly distorted FullHD frame without barrel
+ // visible. For such cases renderers usually renders bigger images and
+ // crops them after the distortion.
+ //
+ // This method is templated to be able to distort byte and float buffers
+ // without having separate methods for this two types. So basically only
+ //
+ // But in fact PixelType might be any type for which multiplication by
+ // a scalar and addition are implemented. For example PixelType might be
+ // Vec3 as well.
+ template<typename PixelType>
+ void DistortBuffer(const PixelType *input_buffer,
+ int width,
+ int height,
+ double overscan,
+ int channels,
+ PixelType *output_buffer);
+
+ // Undistort an image using the current camera instrinsics
+ //
+ // The undistorted image is computed in output_buffer using samples from
+ // input_buffer. Both buffers should be width x height x channels sized.
+ //
+ // Overscan is a percentage value of how much overcan the image have.
+ // For example overscal value of 0.2 means 20% of overscan in the
+ // buffers.
+ //
+ // Overscan is usually used in cases when one need to distort an image
+ // and don't have a barrel in the distorted buffer. For example, when
+ // one need to render properly distorted FullHD frame without barrel
+ // visible. For such cases renderers usually renders bigger images and
+ // crops them after the distortion.
+ //
+ // This method is templated to be able to distort byte and float buffers
+ // without having separate methods for this two types. So basically only
+ //
+ // But in fact PixelType might be any type for which multiplication by
+ // a scalar and addition are implemented. For example PixelType might be
+ // Vec3 as well.
+ template<typename PixelType>
+ void UndistortBuffer(const PixelType *input_buffer,
+ int width,
+ int height,
+ double overscan,
+ int channels,
+ PixelType *output_buffer);
private:
- template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid,
- int width,
- int height,
- double overscan);
- void CheckUndistortLookupGrid(int width, int height, double overscan);
- void CheckDistortLookupGrid(int width, int height, double overscan);
- void FreeLookupGrid();
-
- // The traditional intrinsics matrix from x = K[R|t]X.
- Mat3 K_;
-
// This is the size of the image. This is necessary to, for example, handle
// the case of processing a scaled image.
int image_width_;
int image_height_;
+ // The traditional intrinsics matrix from x = K[R|t]X.
+ Mat3 K_;
+
+ // Coordinate lookup grids for distortion and undistortion.
+ internal::LookupWarpGrid distort_;
+ internal::LookupWarpGrid undistort_;
+
+ protected:
+ // Reset lookup grids after changing the distortion model.
+ void ResetLookupGrids();
+};
+
+class PolynomialCameraIntrinsics : public CameraIntrinsics {
+ public:
+ // This constants defines an offset of corresponding coefficients
+ // in the arameters_ array.
+ enum {
+ OFFSET_K1,
+ OFFSET_K2,
+ OFFSET_K3,
+ OFFSET_P1,
+ OFFSET_P2,
+
+ // This defines the size of array which we need to have in order
+ // to store all the coefficients.
+ NUM_PARAMETERS,
+ };
+
+ PolynomialCameraIntrinsics();
+ PolynomialCameraIntrinsics(const PolynomialCameraIntrinsics &from);
+
+ DistortionModelType GetDistortionModelType() const {
+ return DISTORTION_MODEL_POLYNOMIAL;
+ }
+
+ int num_distortion_parameters() const { return NUM_PARAMETERS; }
+ double *distortion_parameters() { return parameters_; };
+ const double *distortion_parameters() const { return parameters_; };
+
+ double k1() const { return parameters_[OFFSET_K1]; }
+ double k2() const { return parameters_[OFFSET_K2]; }
+ double k3() const { return parameters_[OFFSET_K3]; }
+ double p1() const { return parameters_[OFFSET_P1]; }
+ double p2() const { return parameters_[OFFSET_P2]; }
+
+ // Set radial distortion coeffcients.
+ void SetRadialDistortion(double k1, double k2, double k3);
+
+ // Set tangential distortion coeffcients.
+ void SetTangentialDistortion(double p1, double p2);
+
+ // Apply camera intrinsics to the normalized point to get image coordinates.
+ //
+ // This applies the lens distortion to a point which is in normalized
+ // camera coordinates (i.e. the principal point is at (0, 0)) to get image
+ // coordinates in pixels.
+ void ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const;
+
+ // Invert camera intrinsics on the image point to get normalized coordinates.
+ //
+ // This reverses the effect of lens distortion on a point which is in image
+ // coordinates to get normalized camera coordinates.
+ void InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const;
+
+ private:
// OpenCV's distortion model with third order polynomial radial distortion
// terms and second order tangential distortion. The distortion is applied to
// the normalized coordinates before the focal length, which makes them
// independent of image size.
- double k1_, k2_, k3_, p1_, p2_;
+ double parameters_[NUM_PARAMETERS];
+};
- struct Grid *distort_;
- struct Grid *undistort_;
+class DivisionCameraIntrinsics : public CameraIntrinsics {
+ public:
+ // This constants defines an offset of corresponding coefficients
+ // in the arameters_ array.
+ enum {
+ OFFSET_K1,
+ OFFSET_K2,
+
+ // This defines the size of array which we need to have in order
+ // to store all the coefficients.
+ NUM_PARAMETERS,
+ };
+
+ DivisionCameraIntrinsics();
+ DivisionCameraIntrinsics(const DivisionCameraIntrinsics &from);
+
+ DistortionModelType GetDistortionModelType() const {
+ return DISTORTION_MODEL_DIVISION;
+ }
+
+ int num_distortion_parameters() const { return NUM_PARAMETERS; }
+ double *distortion_parameters() { return parameters_; };
+ const double *distortion_parameters() const { return parameters_; };
+
+ double k1() const { return parameters_[OFFSET_K1]; }
+ double k2() const { return parameters_[OFFSET_K2]; }
+
+ // Set radial distortion coeffcients.
+ void SetDistortion(double k1, double k2);
+
+ // Apply camera intrinsics to the normalized point to get image coordinates.
+ //
+ // This applies the lens distortion to a point which is in normalized
+ // camera coordinates (i.e. the principal point is at (0, 0)) to get image
+ // coordinates in pixels.
+ void ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const;
+
+ // Invert camera intrinsics on the image point to get normalized coordinates.
+ //
+ // This reverses the effect of lens distortion on a point which is in image
+ // coordinates to get normalized camera coordinates.
+ void InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const;
- int threads_;
+ private:
+ // Double-parameter division distortion model.
+ double parameters_[NUM_PARAMETERS];
};
/// A human-readable representation of the camera intrinsic parameters.
std::ostream& operator <<(std::ostream &os,
const CameraIntrinsics &intrinsics);
-// Apply camera intrinsics to the normalized point to get image coordinates.
-// This applies the radial lens distortion to a point which is in normalized
-// camera coordinates (i.e. the principal point is at (0, 0)) to get image
-// coordinates in pixels. Templated for use with autodifferentiation.
-template <typename T>
-inline void ApplyRadialDistortionCameraIntrinsics(const T &focal_length_x,
- const T &focal_length_y,
- const T &principal_point_x,
- const T &principal_point_y,
- const T &k1,
- const T &k2,
- const T &k3,
- const T &p1,
- const T &p2,
- const T &normalized_x,
- const T &normalized_y,
- T *image_x,
- T *image_y) {
- T x = normalized_x;
- T y = normalized_y;
-
- // Apply distortion to the normalized points to get (xd, yd).
- T r2 = x*x + y*y;
- T r4 = r2 * r2;
- T r6 = r4 * r2;
- T r_coeff = (T(1) + k1*r2 + k2*r4 + k3*r6);
- T xd = x * r_coeff + T(2)*p1*x*y + p2*(r2 + T(2)*x*x);
- T yd = y * r_coeff + T(2)*p2*x*y + p1*(r2 + T(2)*y*y);
-
- // Apply focal length and principal point to get the final image coordinates.
- *image_x = focal_length_x * xd + principal_point_x;
- *image_y = focal_length_y * yd + principal_point_y;
-}
-
} // namespace libmv
+// Include implementation of all templated methods here,
+// so they're visible to the compiler.
+#include "libmv/simple_pipeline/camera_intrinsics_impl.h"
+
#endif // LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics_impl.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics_impl.h
new file mode 100644
index 00000000000..97abee7ab01
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics_impl.h
@@ -0,0 +1,192 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+namespace libmv {
+
+namespace {
+
+// FIXME: C++ templates limitations makes thing complicated,
+// but maybe there is a simpler method.
+struct ApplyIntrinsicsFunction {
+ ApplyIntrinsicsFunction(const CameraIntrinsics &intrinsics,
+ double x,
+ double y,
+ double *warp_x,
+ double *warp_y) {
+ double normalized_x, normalized_y;
+ intrinsics.ImageSpaceToNormalized(x, y, &normalized_x, &normalized_y);
+ intrinsics.ApplyIntrinsics(normalized_x, normalized_y, warp_x, warp_y);
+ }
+};
+
+struct InvertIntrinsicsFunction {
+ InvertIntrinsicsFunction(const CameraIntrinsics &intrinsics,
+ double x,
+ double y,
+ double *warp_x,
+ double *warp_y) {
+ double normalized_x, normalized_y;
+ intrinsics.InvertIntrinsics(x, y, &normalized_x, &normalized_y);
+ intrinsics.NormalizedToImageSpace(normalized_x, normalized_y, warp_x, warp_y);
+ }
+};
+
+} // namespace
+
+namespace internal {
+
+// TODO(MatthiasF): downsample lookup
+template<typename WarpFunction>
+void LookupWarpGrid::Compute(const CameraIntrinsics &intrinsics,
+ int width,
+ int height,
+ double overscan) {
+ double w = (double) width / (1.0 + overscan);
+ double h = (double) height / (1.0 + overscan);
+ double aspx = (double) w / intrinsics.image_width();
+ double aspy = (double) h / intrinsics.image_height();
+#if defined(_OPENMP)
+# pragma omp parallel for schedule(dynamic) num_threads(threads_) \
+ if (threads_ > 1 && height > 100)
+#endif
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ double src_x = (x - 0.5 * overscan * w) / aspx,
+ src_y = (y - 0.5 * overscan * h) / aspy;
+ double warp_x, warp_y;
+ WarpFunction(intrinsics, src_x, src_y, &warp_x, &warp_y);
+ warp_x = warp_x * aspx + 0.5 * overscan * w;
+ warp_y = warp_y * aspy + 0.5 * overscan * h;
+ int ix = int(warp_x), iy = int(warp_y);
+ int fx = round((warp_x - ix) * 256), fy = round((warp_y - iy) * 256);
+ if (fx == 256) { fx = 0; ix++; } // NOLINT
+ if (fy == 256) { fy = 0; iy++; } // NOLINT
+ // Use nearest border pixel
+ if (ix < 0) { ix = 0, fx = 0; } // NOLINT
+ if (iy < 0) { iy = 0, fy = 0; } // NOLINT
+ if (ix >= width - 2) ix = width - 2;
+ if (iy >= height - 2) iy = height - 2;
+
+ Offset offset = { (short) (ix - x),
+ (short) (iy - y),
+ (unsigned char) fx,
+ (unsigned char) fy };
+ offset_[y * width + x] = offset;
+ }
+ }
+}
+
+template<typename WarpFunction>
+void LookupWarpGrid::Update(const CameraIntrinsics &intrinsics,
+ int width,
+ int height,
+ double overscan) {
+ if (width_ != width ||
+ height_ != height ||
+ overscan_ != overscan) {
+ Reset();
+ }
+
+ if (offset_ == NULL) {
+ offset_ = new Offset[width * height];
+ Compute<WarpFunction>(intrinsics,
+ width,
+ height,
+ overscan);
+ }
+
+ width_ = width;
+ height_ = height;
+ overscan_ = overscan;
+}
+
+// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
+template<typename PixelType>
+void LookupWarpGrid::Apply(const PixelType *input_buffer,
+ int width,
+ int height,
+ int channels,
+ PixelType *output_buffer) {
+#if defined(_OPENMP)
+# pragma omp parallel for schedule(dynamic) num_threads(threads_) \
+ if (threads_ > 1 && height > 100)
+#endif
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ Offset offset = offset_[y * width + x];
+ const int pixel_index = ((y + offset.iy) * width +
+ (x + offset.ix)) * channels;
+ const PixelType *s = &input_buffer[pixel_index];
+ for (int i = 0; i < channels; i++) {
+ output_buffer[(y * width + x) * channels + i] =
+ ((s[i] * (256 - offset.fx) +
+ s[channels + i] * offset.fx) * (256 - offset.fy) +
+ (s[width * channels + i] * (256 - offset.fx) +
+ s[width * channels + channels + i] * offset.fx) * offset.fy)
+ / (256 * 256);
+ }
+ }
+ }
+}
+
+} // namespace internal
+
+template<typename PixelType>
+void CameraIntrinsics::DistortBuffer(const PixelType *input_buffer,
+ int width,
+ int height,
+ double overscan,
+ int channels,
+ PixelType *output_buffer) {
+ assert(channels >= 1);
+ assert(channels <= 4);
+ distort_.Update<InvertIntrinsicsFunction>(*this,
+ width,
+ height,
+ overscan);
+ distort_.Apply<PixelType>(input_buffer,
+ width,
+ height,
+ channels,
+ output_buffer);
+}
+
+template<typename PixelType>
+void CameraIntrinsics::UndistortBuffer(const PixelType *input_buffer,
+ int width,
+ int height,
+ double overscan,
+ int channels,
+ PixelType *output_buffer) {
+ assert(channels >= 1);
+ assert(channels <= 4);
+ undistort_.Update<ApplyIntrinsicsFunction>(*this,
+ width,
+ height,
+ overscan);
+
+ undistort_.Apply<PixelType>(input_buffer,
+ width,
+ height,
+ channels,
+ output_buffer);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc
index 4039c83210c..46599a4c49e 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.cc
+++ b/extern/libmv/libmv/simple_pipeline/detect.cc
@@ -45,6 +45,14 @@ namespace libmv {
namespace {
+// Default value for FAST minimal trackness in the DetectOptions structure.
+// TODO(sergey): Think of a better default value here.
+int kDefaultFastMinTrackness = 128;
+
+// Default value for Harris threshold in the DetectOptions structure.
+// TODO(sergey): Think of a better default value here.
+double kDefaultHarrisThreshold = 1e-5;
+
class FeatureComparison {
public:
bool operator() (const Feature &left, const Feature &right) const {
@@ -134,11 +142,10 @@ void DetectFAST(const FloatImage &grayscale_image,
if (num_features) {
vector<Feature> all_features;
for (int i = 0; i < num_features; ++i) {
- Feature new_feature = {(float)nonmax[i].x + margin,
- (float)nonmax[i].y + margin,
- (float)scores[i],
- 0};
- all_features.push_back(new_feature);
+ all_features.push_back(Feature((float)nonmax[i].x + margin,
+ (float)nonmax[i].y + margin,
+ (float)scores[i],
+ 9.0));
}
FilterFeaturesByDistance(all_features, min_distance, detected_features);
}
@@ -233,15 +240,24 @@ void DetectMORAVEC(const FloatImage &grayscale_image,
int min = 255, total = 0;
for (; min > 0; min--) {
int h = histogram[min];
- if (total+h > count) break;
+ if (total + h > count) {
+ break;
+ }
total += h;
}
- for (int y = 16; y < height-16; y++) {
- for (int x = 16; x < width-16; x++) {
- int s = scores[y*width+x];
- Feature f = { (float)x+8.0f, (float)y+8.0f, (float)s, 16 };
+ for (int y = 16; y < height - 16; y++) {
+ for (int x = 16; x < width - 16; x++) {
+ int s = scores[y * width + x];
if (s > min) {
- detected_features->push_back(f);
+ // Currently SAD works with the patterns of 16x16 pixels.
+ //
+ // Score calculation above uses top left corner of the
+ // patch as the origin, here we need to convert this value
+ // to a pattrn center by adding 8 pixels.
+ detected_features->push_back(Feature((float) x + 8.0f,
+ (float) y + 8.0f,
+ (float) s,
+ 16.0f));
}
}
}
@@ -288,8 +304,10 @@ void DetectHarris(const FloatImage &grayscale_image,
double traceA = A.trace();
double harris_function = detA - alpha * traceA * traceA;
if (harris_function > threshold) {
- Feature new_feature = {(float)x, (float)y, (float)harris_function, 0.0f};
- all_features.push_back(new_feature);
+ all_features.push_back(Feature((float) x,
+ (float) y,
+ (float) harris_function,
+ 5.0f));
}
}
}
@@ -303,10 +321,10 @@ DetectOptions::DetectOptions()
: type(DetectOptions::HARRIS),
margin(0),
min_distance(120),
- fast_min_trackness(128),
+ fast_min_trackness(kDefaultFastMinTrackness),
moravec_max_count(0),
moravec_pattern(NULL),
- harris_threshold(0.0) {}
+ harris_threshold(kDefaultHarrisThreshold) {}
void Detect(const FloatImage &image,
const DetectOptions &options,
@@ -332,4 +350,12 @@ void Detect(const FloatImage &image,
}
}
+std::ostream& operator <<(std::ostream &os,
+ const Feature &feature) {
+ os << "x: " << feature.x << ", y: " << feature.y;
+ os << ", score: " << feature.score;
+ os << ", size: " << feature.size;
+ return os;
+}
+
} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h
index 2c782294d1b..1035287bcf2 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.h
+++ b/extern/libmv/libmv/simple_pipeline/detect.h
@@ -25,6 +25,7 @@
#ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
#define LIBMV_SIMPLE_PIPELINE_DETECT_H_
+#include <iostream>
#include <vector>
#include "libmv/base/vector.h"
@@ -34,22 +35,27 @@ namespace libmv {
typedef unsigned char ubyte;
-/*!
- A Feature is the 2D location of a detected feature in an image.
-
- \a x, \a y is the position of the feature in pixels from the top left corner.
- \a score is an estimate of how well the feature will be tracked.
- \a size can be used as an initial pattern size to track the feature.
-
- \sa Detect
-*/
+// A Feature is the 2D location of a detected feature in an image.
struct Feature {
- /// Position in pixels (from top-left corner)
- /// \note libmv might eventually support subpixel precision.
+ Feature(float x, float y) : x(x), y(y) {}
+ Feature(float x, float y, float score, float size)
+ : x(x), y(y), score(score), size(size) {}
+
+ // Position of the feature in pixels from top-left corner.
+ // Note: Libmv detector might eventually support subpixel precision.
float x, y;
- /// Trackness of the feature
+
+ // An estimate of how well the feature will be tracked.
+ //
+ // Absolute values totally depends on particular detector type
+ // used for detection. It's only guaranteed that features with
+ // higher score from the same Detect() result will be tracked better.
float score;
- /// Size of the feature in pixels
+
+ // An approximate feature size in pixels.
+ //
+ // If the feature is approximately a 5x5 square region, then size will be 5.
+ // It can be used as an initial pattern size to track the feature.
float size;
};
@@ -99,6 +105,9 @@ void Detect(const FloatImage &image,
const DetectOptions &options,
vector<Feature> *detected_features);
+std::ostream& operator <<(std::ostream &os,
+ const Feature &feature);
+
} // namespace libmv
#endif
diff --git a/extern/libmv/libmv/simple_pipeline/distortion_models.cc b/extern/libmv/libmv/simple_pipeline/distortion_models.cc
new file mode 100644
index 00000000000..9b6dca2678a
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/distortion_models.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/simple_pipeline/distortion_models.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+
+namespace libmv {
+
+namespace {
+
+struct InvertPolynomialIntrinsicsCostFunction {
+ public:
+ typedef Vec2 FMatrixType;
+ typedef Vec2 XMatrixType;
+
+ InvertPolynomialIntrinsicsCostFunction(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double k3,
+ const double p1,
+ const double p2,
+ const double image_x,
+ const double image_y)
+ : focal_length_x_(focal_length_x),
+ focal_length_y_(focal_length_y),
+ principal_point_x_(principal_point_x),
+ principal_point_y_(principal_point_y),
+ k1_(k1), k2_(k2), k3_(k3),
+ p1_(p1), p2_(p2),
+ x_(image_x), y_(image_y) {}
+
+ Vec2 operator()(const Vec2 &u) const {
+ double xx, yy;
+
+ ApplyPolynomialDistortionModel(focal_length_x_,
+ focal_length_y_,
+ principal_point_x_,
+ principal_point_y_,
+ k1_, k2_, k3_,
+ p1_, p2_,
+ u(0), u(1),
+ &xx, &yy);
+
+ Vec2 fx;
+ fx << (xx - x_), (yy - y_);
+ return fx;
+ }
+ double focal_length_x_;
+ double focal_length_y_;
+ double principal_point_x_;
+ double principal_point_y_;
+ double k1_, k2_, k3_;
+ double p1_, p2_;
+ double x_, y_;
+};
+
+struct InvertDivisionIntrinsicsCostFunction {
+ public:
+ typedef Vec2 FMatrixType;
+ typedef Vec2 XMatrixType;
+
+ InvertDivisionIntrinsicsCostFunction(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double image_x,
+ const double image_y)
+ : focal_length_x_(focal_length_x),
+ focal_length_y_(focal_length_y),
+ principal_point_x_(principal_point_x),
+ principal_point_y_(principal_point_y),
+ k1_(k1), k2_(k2),
+ x_(image_x), y_(image_y) {}
+
+ Vec2 operator()(const Vec2 &u) const {
+ double xx, yy;
+
+ ApplyDivisionDistortionModel(focal_length_x_,
+ focal_length_y_,
+ principal_point_x_,
+ principal_point_y_,
+ k1_, k2_,
+ u(0), u(1),
+ &xx, &yy);
+
+ Vec2 fx;
+ fx << (xx - x_), (yy - y_);
+ return fx;
+ }
+ double focal_length_x_;
+ double focal_length_y_;
+ double principal_point_x_;
+ double principal_point_y_;
+ double k1_, k2_;
+ double x_, y_;
+};
+
+} // namespace
+
+void InvertPolynomialDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double k3,
+ const double p1,
+ const double p2,
+ const double image_x,
+ const double image_y,
+ double *normalized_x,
+ double *normalized_y) {
+ // Compute the initial guess. For a camera with no distortion, this will also
+ // be the final answer; the LM iteration will terminate immediately.
+ Vec2 normalized;
+ normalized(0) = (image_x - principal_point_x) / focal_length_x;
+ normalized(1) = (image_y - principal_point_y) / focal_length_y;
+
+ typedef LevenbergMarquardt<InvertPolynomialIntrinsicsCostFunction> Solver;
+
+ InvertPolynomialIntrinsicsCostFunction intrinsics_cost(focal_length_x,
+ focal_length_y,
+ principal_point_x,
+ principal_point_y,
+ k1, k2, k3,
+ p1, p2,
+ image_x, image_y);
+ Solver::SolverParameters params;
+ Solver solver(intrinsics_cost);
+
+ /*Solver::Results results =*/ solver.minimize(params, &normalized);
+
+ // TODO(keir): Better error handling.
+
+ *normalized_x = normalized(0);
+ *normalized_y = normalized(1);
+}
+
+void InvertDivisionDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double image_x,
+ const double image_y,
+ double *normalized_x,
+ double *normalized_y) {
+ // Compute the initial guess. For a camera with no distortion, this will also
+ // be the final answer; the LM iteration will terminate immediately.
+ Vec2 normalized;
+ normalized(0) = (image_x - principal_point_x) / focal_length_x;
+ normalized(1) = (image_y - principal_point_y) / focal_length_y;
+
+ // TODO(sergey): Use Ceres minimizer instead.
+ typedef LevenbergMarquardt<InvertDivisionIntrinsicsCostFunction> Solver;
+
+ InvertDivisionIntrinsicsCostFunction intrinsics_cost(focal_length_x,
+ focal_length_y,
+ principal_point_x,
+ principal_point_y,
+ k1, k2,
+ image_x, image_y);
+ Solver::SolverParameters params;
+ Solver solver(intrinsics_cost);
+
+ /*Solver::Results results =*/ solver.minimize(params, &normalized);
+
+ // TODO(keir): Better error handling.
+
+ *normalized_x = normalized(0);
+ *normalized_y = normalized(1);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/distortion_models.h b/extern/libmv/libmv/simple_pipeline/distortion_models.h
new file mode 100644
index 00000000000..4f8e2295a0e
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/distortion_models.h
@@ -0,0 +1,131 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
+#define LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
+
+namespace libmv {
+
+enum DistortionModelType {
+ DISTORTION_MODEL_POLYNOMIAL,
+ DISTORTION_MODEL_DIVISION
+};
+
+// Invert camera intrinsics on the image point to get normalized coordinates.
+// This inverts the radial lens distortion to a point which is in image pixel
+// coordinates to get normalized coordinates.
+void InvertPolynomialDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double k3,
+ const double p1,
+ const double p2,
+ const double image_x,
+ const double image_y,
+ double *normalized_x,
+ double *normalized_y);
+
+// Apply camera intrinsics to the normalized point to get image coordinates.
+// This applies the radial lens distortion to a point which is in normalized
+// camera coordinates (i.e. the principal point is at (0, 0)) to get image
+// coordinates in pixels. Templated for use with autodifferentiation.
+template <typename T>
+inline void ApplyPolynomialDistortionModel(const T &focal_length_x,
+ const T &focal_length_y,
+ const T &principal_point_x,
+ const T &principal_point_y,
+ const T &k1,
+ const T &k2,
+ const T &k3,
+ const T &p1,
+ const T &p2,
+ const T &normalized_x,
+ const T &normalized_y,
+ T *image_x,
+ T *image_y) {
+ T x = normalized_x;
+ T y = normalized_y;
+
+ // Apply distortion to the normalized points to get (xd, yd).
+ T r2 = x*x + y*y;
+ T r4 = r2 * r2;
+ T r6 = r4 * r2;
+ T r_coeff = (T(1) + k1*r2 + k2*r4 + k3*r6);
+ T xd = x * r_coeff + T(2)*p1*x*y + p2*(r2 + T(2)*x*x);
+ T yd = y * r_coeff + T(2)*p2*x*y + p1*(r2 + T(2)*y*y);
+
+ // Apply focal length and principal point to get the final image coordinates.
+ *image_x = focal_length_x * xd + principal_point_x;
+ *image_y = focal_length_y * yd + principal_point_y;
+}
+
+// Invert camera intrinsics on the image point to get normalized coordinates.
+// This inverts the radial lens distortion to a point which is in image pixel
+// coordinates to get normalized coordinates.
+//
+// Uses division distortion model.
+void InvertDivisionDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const double k1,
+ const double k2,
+ const double image_x,
+ const double image_y,
+ double *normalized_x,
+ double *normalized_y);
+
+// Apply camera intrinsics to the normalized point to get image coordinates.
+// This applies the radial lens distortion to a point which is in normalized
+// camera coordinates (i.e. the principal point is at (0, 0)) to get image
+// coordinates in pixels. Templated for use with autodifferentiation.
+//
+// Uses division distortion model.
+template <typename T>
+inline void ApplyDivisionDistortionModel(const T &focal_length_x,
+ const T &focal_length_y,
+ const T &principal_point_x,
+ const T &principal_point_y,
+ const T &k1,
+ const T &k2,
+ const T &normalized_x,
+ const T &normalized_y,
+ T *image_x,
+ T *image_y) {
+
+ T x = normalized_x;
+ T y = normalized_y;
+ T r2 = x*x + y*y;
+ T r4 = r2 * r2;
+
+ T xd = x / (T(1) + k1 * r2 + k2 * r4);
+ T yd = y / (T(1) + k1 * r2 + k2 * r4);
+
+ // Apply focal length and principal point to get the final image coordinates.
+ *image_x = focal_length_x * xd + principal_point_x;
+ *image_y = focal_length_y * yd + principal_point_y;
+}
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
diff --git a/extern/libmv/libmv/simple_pipeline/intersect.cc b/extern/libmv/libmv/simple_pipeline/intersect.cc
index 6a098da272d..ddb713684a4 100644
--- a/extern/libmv/libmv/simple_pipeline/intersect.cc
+++ b/extern/libmv/libmv/simple_pipeline/intersect.cc
@@ -100,6 +100,8 @@ bool EuclideanIntersect(const vector<Marker> &markers,
ceres::Problem problem;
+ // Add residual blocks to the problem.
+ int num_residuals = 0;
for (int i = 0; i < markers.size(); ++i) {
const Marker &marker = markers[i];
if (marker.weight != 0.0) {
@@ -113,9 +115,27 @@ bool EuclideanIntersect(const vector<Marker> &markers,
3>(new EuclideanIntersectCostFunctor(marker, camera)),
NULL,
&X(0));
+ num_residuals++;
}
}
+ // TODO(sergey): Once we'll update Ceres to the next version
+ // we wouldn't need this check anymore -- Ceres will deal with
+ // zero-sized problems nicely.
+ LG << "Number of residuals: " << num_residuals;
+ if (!num_residuals) {
+ LG << "Skipping running minimizer with zero residuals";
+
+ // We still add 3D point for the track regardless it was
+ // optimized or not. If track is a constant zero it'll use
+ // algebraic intersection result as a 3D coordinate.
+
+ Vec3 point = X.head<3>();
+ reconstruction->InsertPoint(markers[0].track, point);
+
+ return true;
+ }
+
// Configure the solve.
ceres::Solver::Options solver_options;
solver_options.linear_solver_type = ceres::DENSE_QR;
diff --git a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
index 6ab9e7eefb6..7b90c28bbca 100644
--- a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
+++ b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
@@ -33,22 +33,6 @@
namespace libmv {
namespace {
-Vec2 NorrmalizedToPixelSpace(const Vec2 &vec,
- const CameraIntrinsics &intrinsics) {
- Vec2 result;
-
- double focal_length_x = intrinsics.focal_length_x();
- double focal_length_y = intrinsics.focal_length_y();
-
- double principal_point_x = intrinsics.principal_point_x();
- double principal_point_y = intrinsics.principal_point_y();
-
- result(0) = vec(0) * focal_length_x + principal_point_x;
- result(1) = vec(1) * focal_length_y + principal_point_y;
-
- return result;
-}
-
Mat3 IntrinsicsNormalizationMatrix(const CameraIntrinsics &intrinsics) {
Mat3 T = Mat3::Identity(), S = Mat3::Identity();
@@ -131,17 +115,37 @@ Mat pseudoInverse(const Mat &matrix) {
return V * D * V.inverse();
}
+
+void filterZeroWeightMarkersFromTracks(const Tracks &tracks,
+ Tracks *filtered_tracks) {
+ vector<Marker> all_markers = tracks.AllMarkers();
+
+ for (int i = 0; i < all_markers.size(); ++i) {
+ Marker &marker = all_markers[i];
+ if (marker.weight != 0.0) {
+ filtered_tracks->Insert(marker.image,
+ marker.track,
+ marker.x,
+ marker.y,
+ marker.weight);
+ }
+ }
+}
+
} // namespace
-void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
- CameraIntrinsics &intrinsics,
+void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks,
+ const CameraIntrinsics &intrinsics,
vector<int> &keyframes) {
// Mirza Tahir Ahmed, Matthew N. Dailey
// Robust key frame extraction for 3D reconstruction from video streams
//
// http://www.cs.ait.ac.th/~mdailey/papers/Tahir-KeyFrame.pdf
- int max_image = tracks.MaxImage();
+ Tracks filtered_tracks;
+ filterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks);
+
+ int max_image = filtered_tracks.MaxImage();
int next_keyframe = 1;
int number_keyframes = 0;
@@ -173,11 +177,13 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
candidate_image++) {
// Conjunction of all markers from both keyframes
vector<Marker> all_markers =
- tracks.MarkersInBothImages(current_keyframe, candidate_image);
+ filtered_tracks.MarkersInBothImages(current_keyframe,
+ candidate_image);
// Match keypoints between frames current_keyframe and candidate_image
vector<Marker> tracked_markers =
- tracks.MarkersForTracksInBothImages(current_keyframe, candidate_image);
+ filtered_tracks.MarkersForTracksInBothImages(current_keyframe,
+ candidate_image);
// Correspondences in normalized space
Mat x1, x2;
@@ -234,10 +240,13 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
H_e.resize(x1.cols());
F_e.resize(x1.cols());
for (int i = 0; i < x1.cols(); i++) {
- Vec2 current_x1 =
- NorrmalizedToPixelSpace(Vec2(x1(0, i), x1(1, i)), intrinsics);
- Vec2 current_x2 =
- NorrmalizedToPixelSpace(Vec2(x2(0, i), x2(1, i)), intrinsics);
+ Vec2 current_x1, current_x2;
+
+ intrinsics.NormalizedToImageSpace(x1(0, i), x1(1, i),
+ &current_x1(0), &current_x1(1));
+
+ intrinsics.NormalizedToImageSpace(x2(0, i), x2(1, i),
+ &current_x2(0), &current_x2(1));
H_e(i) = SymmetricGeometricDistance(H, current_x1, current_x2);
F_e(i) = SymmetricEpipolarDistance(F, current_x1, current_x2);
@@ -356,7 +365,7 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
success_intersects_factor_best = success_intersects_factor;
Tracks two_frames_tracks(tracked_markers);
- CameraIntrinsics empty_intrinsics;
+ PolynomialCameraIntrinsics empty_intrinsics;
BundleEvaluation evaluation;
evaluation.evaluate_jacobian = true;
diff --git a/extern/libmv/libmv/simple_pipeline/keyframe_selection.h b/extern/libmv/libmv/simple_pipeline/keyframe_selection.h
index da131010d35..aa3eeaf193d 100644
--- a/extern/libmv/libmv/simple_pipeline/keyframe_selection.h
+++ b/extern/libmv/libmv/simple_pipeline/keyframe_selection.h
@@ -43,9 +43,10 @@ namespace libmv {
// \param intrinsics is camera intrinsics
// \param keyframes will contain all images number which are considered
// good to be used for reconstruction
-void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
- CameraIntrinsics &intrinsics,
- vector<int> &keyframes);
+void SelectKeyframesBasedOnGRICAndVariance(
+ const Tracks &tracks,
+ const CameraIntrinsics &intrinsics,
+ vector<int> &keyframes);
} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/brute_region_tracker.cc b/extern/libmv/libmv/tracking/brute_region_tracker.cc
index 234aaa6ed00..4a2aef63a96 100644
--- a/extern/libmv/libmv/tracking/brute_region_tracker.cc
+++ b/extern/libmv/libmv/tracking/brute_region_tracker.cc
@@ -21,27 +21,10 @@
#include "libmv/tracking/brute_region_tracker.h"
#ifdef __SSE2__
-#include <emmintrin.h>
-#endif
-
-#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
-// Needed for memalign on Linux and _aligned_alloc on Windows.
-#ifdef FREE_WINDOWS
-/* make sure _aligned_malloc is included */
-#ifdef __MSVCRT_VERSION__
-#undef __MSVCRT_VERSION__
-#endif
-
-#define __MSVCRT_VERSION__ 0x0700
-#endif
-
-#include <malloc.h>
-#else
-// Apple's malloc is 16-byte aligned, and does not have malloc.h, so include
-// stdilb instead.
-#include <cstdlib>
+# include <emmintrin.h>
#endif
+#include "libmv/base/aligned_malloc.h"
#include "libmv/image/image.h"
#include "libmv/image/convolve.h"
#include "libmv/image/correlation.h"
@@ -51,37 +34,6 @@
namespace libmv {
namespace {
-// TODO(keir): It's stupid that this is needed here. Push this somewhere else.
-void *aligned_malloc(int size, int alignment) {
-#ifdef _WIN32
- return _aligned_malloc(size, alignment);
-#elif __APPLE__
- // On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
- // they work natively with SSE types with no further work.
- CHECK_EQ(alignment, 16);
- return malloc(size);
-#elif defined(__FreeBSD__) || defined(__NetBSD__)
- void *result;
-
- if (posix_memalign(&result, alignment, size)) {
- // non-zero means allocation error
- // either no allocation or bad alignment value
- return NULL;
- }
- return result;
-#else // This is for Linux.
- return memalign(alignment, size);
-#endif
-}
-
-void aligned_free(void *ptr) {
-#ifdef _WIN32
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
-}
-
bool RegionIsInBounds(const FloatImage &image1,
double x, double y,
int half_window_size) {
@@ -364,8 +316,7 @@ bool BruteRegionTracker::Track(const FloatImage &image1,
// for sanity.
double correlation = PearsonProductMomentCorrelation(
image_and_gradient1_sampled,
- image_and_gradient2_sampled,
- pattern_width);
+ image_and_gradient2_sampled);
LG << "Final correlation: " << correlation;
diff --git a/extern/libmv/mkfiles.sh b/extern/libmv/mkfiles.sh
index c7c8c33f725..c7c8c33f725 100755..100644
--- a/extern/libmv/mkfiles.sh
+++ b/extern/libmv/mkfiles.sh
diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt
index 52e2246b13f..168326476c6 100644
--- a/extern/libmv/third_party/ceres/CMakeLists.txt
+++ b/extern/libmv/third_party/ceres/CMakeLists.txt
@@ -309,54 +309,24 @@ if(WITH_OPENMP)
)
endif()
-include(CheckIncludeFileCXX)
-CHECK_INCLUDE_FILE_CXX(unordered_map HAVE_STD_UNORDERED_MAP_HEADER)
+TEST_UNORDERED_MAP_SUPPORT()
if(HAVE_STD_UNORDERED_MAP_HEADER)
- # Even so we've found unordered_map header file it doesn't
- # mean unordered_map and unordered_set will be declared in
- # std namespace.
- #
- # Namely, MSVC 2008 have unordered_map header which declares
- # unordered_map class in std::tr1 namespace. In order to support
- # this, we do extra check to see which exactly namespace is
- # to be used.
-
- include(CheckCXXSourceCompiles)
- CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
- int main() {
- std::unordered_map<int, int> map;
- return 0;
- }"
- HAVE_UNURDERED_MAP_IN_STD_NAMESPACE)
- if(HAVE_UNURDERED_MAP_IN_STD_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
add_definitions(-DCERES_STD_UNORDERED_MAP)
- message(STATUS "Found unordered_map/set in std namespace.")
else()
- CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
- int main() {
- std::tr1::unordered_map<int, int> map;
- return 0;
- }"
- HAVE_UNURDERED_MAP_IN_TR1_NAMESPACE)
- if(HAVE_UNURDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
add_definitions(-DCERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
- message(STATUS "Found unordered_map/set in std::tr1 namespace.")
else()
- message(STATUS "Found <unordered_map> but cannot find either std::unordered_map "
- "or std::tr1::unordered_map.")
- message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
add_definitions(-DCERES_NO_UNORDERED_MAP)
+ message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
endif()
endif()
else()
- CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" UNORDERED_MAP_IN_TR1_NAMESPACE)
- if(UNORDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
add_definitions(-DCERES_TR1_UNORDERED_MAP)
- message(STATUS "Found unordered_map/set in std::tr1 namespace.")
else()
- message(STATUS "Unable to find <unordered_map> or <tr1/unordered_map>. ")
- message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
add_definitions(-DCERES_NO_UNORDERED_MAP)
+ message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
endif()
endif()
diff --git a/extern/libmv/third_party/ceres/SConscript b/extern/libmv/third_party/ceres/SConscript
index 2573a9742ad..406e1593ded 100644
--- a/extern/libmv/third_party/ceres/SConscript
+++ b/extern/libmv/third_party/ceres/SConscript
@@ -7,6 +7,8 @@
import sys
import os
+from unordered_map import test_unordered_map
+
Import('env')
src = []
@@ -27,35 +29,26 @@ defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
defs.append('CERES_USE_OPENMP')
-conf = Configure(env)
-if conf.CheckCXXHeader("unordered_map"):
- # Even so we've found unordered_map header file it doesn't
- # mean unordered_map and unordered_set will be declared in
- # std namespace.
- #
- # Namely, MSVC 2008 have unordered_map header which declares
- # unordered_map class in std::tr1 namespace. In order to support
- # this, we do extra check to see which exactly namespace is
- # to be used.
+def define_unordered_map(conf):
+ found, namespace, include_prefix = test_unordered_map(conf)
+ if found:
+ if not include_prefix:
+ if namespace == 'std':
+ defs.append('CERES_STD_UNORDERED_MAP')
+ return True
+ elif namespace == 'std::tr1':
+ defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
+ return True
+ else:
+ if namespace == 'std::tr1':
+ defs.append('CERES_TR1_UNORDERED_MAP')
+ return True
+ return False
- if conf.CheckType('std::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
- defs.append('CERES_STD_UNORDERED_MAP')
- print("-- Found unordered_map/set in std namespace.")
- elif conf.CheckType('std::tr1::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
- defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
- print("-- Found unordered_map/set in std::tr1 namespace.")
- else:
- print("-- Found <unordered_map> but can not find neither std::unordered_map nor std::tr1::unordered_map.")
- print("-- Replacing unordered_map/set with map/set (warning: slower!)")
- defs.append('CERES_NO_UNORDERED_MAP')
-elif conf.CheckCXXHeader("tr1/unordered_map"):
- defs.append('CERES_TR1_UNORDERED_MAP')
- print("-- Found unordered_map/set in std::tr1 namespace.")
-else:
- print("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
+conf = Configure(env)
+if not define_unordered_map(conf):
print("-- Replacing unordered_map/set with map/set (warning: slower!)")
defs.append('CERES_NO_UNORDERED_MAP')
-
env = conf.Finish()
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh
index d937ed46945..7cb6b9beefd 100755..100644
--- a/extern/libmv/third_party/ceres/bundle.sh
+++ b/extern/libmv/third_party/ceres/bundle.sh
@@ -174,54 +174,24 @@ if(WITH_OPENMP)
)
endif()
-include(CheckIncludeFileCXX)
-CHECK_INCLUDE_FILE_CXX(unordered_map HAVE_STD_UNORDERED_MAP_HEADER)
+TEST_UNORDERED_MAP_SUPPORT()
if(HAVE_STD_UNORDERED_MAP_HEADER)
- # Even so we've found unordered_map header file it doesn't
- # mean unordered_map and unordered_set will be declared in
- # std namespace.
- #
- # Namely, MSVC 2008 have unordered_map header which declares
- # unordered_map class in std::tr1 namespace. In order to support
- # this, we do extra check to see which exactly namespace is
- # to be used.
-
- include(CheckCXXSourceCompiles)
- CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
- int main() {
- std::unordered_map<int, int> map;
- return 0;
- }"
- HAVE_UNURDERED_MAP_IN_STD_NAMESPACE)
- if(HAVE_UNURDERED_MAP_IN_STD_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE)
add_definitions(-DCERES_STD_UNORDERED_MAP)
- message(STATUS "Found unordered_map/set in std namespace.")
else()
- CHECK_CXX_SOURCE_COMPILES("#include <unordered_map>
- int main() {
- std::tr1::unordered_map<int, int> map;
- return 0;
- }"
- HAVE_UNURDERED_MAP_IN_TR1_NAMESPACE)
- if(HAVE_UNURDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
add_definitions(-DCERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
- message(STATUS "Found unordered_map/set in std::tr1 namespace.")
else()
- message(STATUS "Found <unordered_map> but cannot find either std::unordered_map "
- "or std::tr1::unordered_map.")
- message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
add_definitions(-DCERES_NO_UNORDERED_MAP)
+ message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
endif()
endif()
else()
- CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" UNORDERED_MAP_IN_TR1_NAMESPACE)
- if(UNORDERED_MAP_IN_TR1_NAMESPACE)
+ if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE)
add_definitions(-DCERES_TR1_UNORDERED_MAP)
- message(STATUS "Found unordered_map/set in std::tr1 namespace.")
else()
- message(STATUS "Unable to find <unordered_map> or <tr1/unordered_map>. ")
- message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
add_definitions(-DCERES_NO_UNORDERED_MAP)
+ message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)")
endif()
endif()
@@ -238,6 +208,8 @@ cat > SConscript << EOF
import sys
import os
+from unordered_map import test_unordered_map
+
Import('env')
src = []
@@ -258,35 +230,26 @@ defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
defs.append('CERES_USE_OPENMP')
+def define_unordered_map(conf):
+ found, namespace, include_prefix = test_unordered_map(conf)
+ if found:
+ if not include_prefix:
+ if namespace == 'std':
+ defs.append('CERES_STD_UNORDERED_MAP')
+ return True
+ elif namespace == 'std::tr1':
+ defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
+ return True
+ else:
+ if namespace == 'std::tr1':
+ defs.append('CERES_TR1_UNORDERED_MAP')
+ return True
+ return False
+
conf = Configure(env)
-if conf.CheckCXXHeader("unordered_map"):
- # Even so we've found unordered_map header file it doesn't
- # mean unordered_map and unordered_set will be declared in
- # std namespace.
- #
- # Namely, MSVC 2008 have unordered_map header which declares
- # unordered_map class in std::tr1 namespace. In order to support
- # this, we do extra check to see which exactly namespace is
- # to be used.
-
- if conf.CheckType('std::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
- defs.append('CERES_STD_UNORDERED_MAP')
- print("-- Found unordered_map/set in std namespace.")
- elif conf.CheckType('std::tr1::unordered_map<int, int>', language = 'CXX', includes="#include <unordered_map>"):
- defs.append('CERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE')
- print("-- Found unordered_map/set in std::tr1 namespace.")
- else:
- print("-- Found <unordered_map> but can not find neither std::unordered_map nor std::tr1::unordered_map.")
- print("-- Replacing unordered_map/set with map/set (warning: slower!)")
- defs.append('CERES_NO_UNORDERED_MAP')
-elif conf.CheckCXXHeader("tr1/unordered_map"):
- defs.append('CERES_TR1_UNORDERED_MAP')
- print("-- Found unordered_map/set in std::tr1 namespace.")
-else:
- print("-- Unable to find <unordered_map> or <tr1/unordered_map>. ")
+if not define_unordered_map(conf):
print("-- Replacing unordered_map/set with map/set (warning: slower!)")
defs.append('CERES_NO_UNORDERED_MAP')
-
env = conf.Finish()
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
diff --git a/extern/libmv/third_party/ceres/mkfiles.sh b/extern/libmv/third_party/ceres/mkfiles.sh
index d335829aa2c..d335829aa2c 100755..100644
--- a/extern/libmv/third_party/ceres/mkfiles.sh
+++ b/extern/libmv/third_party/ceres/mkfiles.sh
diff --git a/extern/libmv/third_party/gflags/gflags/gflags_declare.h b/extern/libmv/third_party/gflags/gflags/gflags_declare.h
index e3013826d53..503b686657f 100644
--- a/extern/libmv/third_party/gflags/gflags/gflags_declare.h
+++ b/extern/libmv/third_party/gflags/gflags/gflags_declare.h
@@ -49,17 +49,17 @@
#endif
namespace google {
-#if 1 // the C99 format
+#if defined(__GNUC__) || defined(__MINGW32__) // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
-#elif 1 // the BSD format
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
-#elif 0 // the windows (vc7) format
+#elif defined(_MSC_VER) // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
diff --git a/extern/libmv/third_party/glog/ChangeLog b/extern/libmv/third_party/glog/ChangeLog
index 6ac0b0f0575..d1b42484416 100644
--- a/extern/libmv/third_party/glog/ChangeLog
+++ b/extern/libmv/third_party/glog/ChangeLog
@@ -1,3 +1,18 @@
+2013-02-01 Google Inc. <opensource@google.com>
+
+ * google-glog: version 0.3.3
+ * Add --disable-rtti option for configure.
+ * Visual Studio build and test fix.
+ * QNX build fix (thanks vanuan).
+ * Reduce warnings.
+ * Fixed LOG_SYSRESULT (thanks ukai).
+ * FreeBSD build fix (thanks yyanagisawa).
+ * Clang build fix.
+ * Now users can re-initialize glog after ShutdownGoogleLogging.
+ * Color output support by GLOG_colorlogtostderr (thanks alexs).
+ * Now glog's ABI around flags are compatible with gflags.
+ * Document mentions how to modify flags from user programs.
+
2012-01-12 Google Inc. <opensource@google.com>
* google-glog: version 0.3.2
diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv
index 345bc9f5969..eb4b2ea3379 100644
--- a/extern/libmv/third_party/glog/README.libmv
+++ b/extern/libmv/third_party/glog/README.libmv
@@ -1,25 +1,9 @@
Project: Google Logging
URL: http://code.google.com/p/google-glog/
License: New BSD
-Upstream version: 0.3.2
+Upstream version: 0.3.3, r139
Local modifications:
-
-Upgrading Notes
-* Replace <gflags/gflags.h> with "third_party/gflags/gflags/gflags.h" which is easier
- to setup things in libmv and also helps with setting up building libmv into
- external applications.
-* Replace "glog/logging.h" and "glog/logging.h" with <glog/logging.h> and <glog/logging.h>
- which is needed on Windows platform because otherwise files like logging.cc will be using
- relative path which points to headers used by linux instead of headers need to be used
- on Windows.
-* Replace _asm int 3 with __debugbreak(). Such assembler code is obsolete and doesn't work
- with 64bit versions of MSVC compilers.
-* Do not use stacktrace for MinGW and FreeBSD because it leads into issues accessing
- some specific data on this platforms.
-* Define HAVE_LIB_GFLAGS for Windows builds.
-* Do not define __declspec(dllimport) for MinGW platforms.
-* Setup proper includes and datatypes for int32, uint32, int64 and uint64 for MinGW
-* Do not define va_copy for MinGW platforms (it's already defined there).
-* Patch localtime_r to be working fine with MinGW, disable strerror_r for MinGW because
- of lack of needed functions.
-* Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
+* Added per-platform config.h files so no configuration-time
+ checks for functions and so are needed.
+* See glog_tweaks.patch to see other tweaks which are done
+ against glog upstream.
diff --git a/extern/libmv/third_party/glog/src/base/commandlineflags.h b/extern/libmv/third_party/glog/src/base/commandlineflags.h
index 483a96ee80b..529540ea461 100644
--- a/extern/libmv/third_party/glog/src/base/commandlineflags.h
+++ b/extern/libmv/third_party/glog/src/base/commandlineflags.h
@@ -48,56 +48,57 @@
#ifndef BASE_COMMANDLINEFLAGS_H__
#define BASE_COMMANDLINEFLAGS_H__
-#include "config.h"
+#include "../config.h"
#include <string>
#include <string.h> // for memchr
#include <stdlib.h> // for getenv
#ifdef HAVE_LIB_GFLAGS
-#include "third_party/gflags/gflags/gflags.h"
+#include <gflags/gflags.h>
#else
-#include <glog/logging.h>
+#include "glog/logging.h"
-#define DECLARE_VARIABLE(type, name, tn) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
- extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
-#define DEFINE_VARIABLE(type, name, value, meaning, tn) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
- GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \
- char FLAGS_no##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+#define DECLARE_VARIABLE(type, shorttype, name, tn) \
+ namespace fL##shorttype { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using fL##shorttype::FLAGS_##name
+#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \
+ namespace fL##shorttype { \
+ GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \
+ char FLAGS_no##name; \
+ } \
+ using fL##shorttype::FLAGS_##name
// bool specialization
#define DECLARE_bool(name) \
- DECLARE_VARIABLE(bool, name, bool)
+ DECLARE_VARIABLE(bool, B, name, bool)
#define DEFINE_bool(name, value, meaning) \
- DEFINE_VARIABLE(bool, name, value, meaning, bool)
+ DEFINE_VARIABLE(bool, B, name, value, meaning, bool)
// int32 specialization
#define DECLARE_int32(name) \
- DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, name, int32)
+ DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32)
#define DEFINE_int32(name, value, meaning) \
- DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, name, value, meaning, int32)
+ DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
-#define DECLARE_string(name) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
- extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
-#define DEFINE_string(name, value, meaning) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
- GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name(value); \
- char FLAGS_no##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#define DECLARE_string(name) \
+ namespace fLS { \
+ extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
+#define DEFINE_string(name, value, meaning) \
+ namespace fLS { \
+ std::string FLAGS_##name##_buf(value); \
+ GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \
+ char FLAGS_no##name; \
+ } \
+ using fLS::FLAGS_##name
#endif // HAVE_LIB_GFLAGS
diff --git a/extern/libmv/third_party/glog/src/base/mutex.h b/extern/libmv/third_party/glog/src/base/mutex.h
index 7ba88cb5a63..36fc55c4dcb 100644
--- a/extern/libmv/third_party/glog/src/base/mutex.h
+++ b/extern/libmv/third_party/glog/src/base/mutex.h
@@ -102,12 +102,14 @@
#ifndef GOOGLE_MUTEX_H_
#define GOOGLE_MUTEX_H_
-#include "config.h" // to figure out pthreads support
+#include "../config.h" // to figure out pthreads support
#if defined(NO_THREADS)
typedef int MutexType; // to keep a lock-count
#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
-# define WIN32_LEAN_AND_MEAN // We only need minimal includes
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN // We only need minimal includes
+# endif
# ifdef GMUTEX_TRYLOCK
// We need Windows NT or later for TryEnterCriticalSection(). If you
// don't need that functionality, you can remove these _WIN32_WINNT
@@ -117,9 +119,13 @@
# endif
# endif
// To avoid macro definition of ERROR.
-# define NOGDI
+# ifndef NOGDI
+# define NOGDI
+# endif
// To avoid macro definition of min/max.
-# define NOMINMAX
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
# include <windows.h>
typedef CRITICAL_SECTION MutexType;
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
diff --git a/extern/libmv/third_party/glog/src/config_freebsd.h b/extern/libmv/third_party/glog/src/config_freebsd.h
index a671a0080b3..a1fe76fe806 100644
--- a/extern/libmv/third_party/glog/src/config_freebsd.h
+++ b/extern/libmv/third_party/glog/src/config_freebsd.h
@@ -46,12 +46,18 @@
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
+/* Define if you have the 'pread' function */
+#define HAVE_PREAD 1
+
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
+/* Define if you have the 'pwrite' function */
+#define HAVE_PWRITE 1
+
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK 1
diff --git a/extern/libmv/third_party/glog/src/config_hurd.h b/extern/libmv/third_party/glog/src/config_hurd.h
index 47aefa423d6..81e8ed7bac3 100644
--- a/extern/libmv/third_party/glog/src/config_hurd.h
+++ b/extern/libmv/third_party/glog/src/config_hurd.h
@@ -46,12 +46,18 @@
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
+/* Define if you have the 'pread' function */
+#define HAVE_PREAD 1
+
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
+/* Define if you have the 'pwrite' function */
+#define HAVE_PWRITE 1
+
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK 1
diff --git a/extern/libmv/third_party/glog/src/config_linux.h b/extern/libmv/third_party/glog/src/config_linux.h
index 5877029882a..7741ddebb63 100644
--- a/extern/libmv/third_party/glog/src/config_linux.h
+++ b/extern/libmv/third_party/glog/src/config_linux.h
@@ -46,12 +46,18 @@
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
+/* Define if you have the 'pread' function */
+#define HAVE_PREAD 1
+
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
+/* Define if you have the 'pwrite' function */
+#define HAVE_PWRITE 1
+
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK 1
diff --git a/extern/libmv/third_party/glog/src/config_mac.h b/extern/libmv/third_party/glog/src/config_mac.h
index 9756fde22f3..1695472f031 100644
--- a/extern/libmv/third_party/glog/src/config_mac.h
+++ b/extern/libmv/third_party/glog/src/config_mac.h
@@ -46,12 +46,18 @@
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
+/* Define if you have the 'pread' function */
+#define HAVE_PREAD 1
+
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
+/* Define if you have the 'pwrite' function */
+#define HAVE_PWRITE 1
+
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK 1
diff --git a/extern/libmv/third_party/glog/src/glog/logging.h b/extern/libmv/third_party/glog/src/glog/logging.h
index 005649c17c2..247c0467b6a 100644
--- a/extern/libmv/third_party/glog/src/glog/logging.h
+++ b/extern/libmv/third_party/glog/src/glog/logging.h
@@ -33,24 +33,23 @@
// Pretty much everybody needs to #include this file so that they can
// log various happenings.
//
+#ifdef WIN32
+# include "windows/glog/logging.h"
+#else // WIN32
+
#ifndef _LOGGING_H_
#define _LOGGING_H_
#include <errno.h>
#include <string.h>
#include <time.h>
+#include <iosfwd>
+#include <ostream>
+#include <sstream>
#include <string>
#if 1
# include <unistd.h>
#endif
-#ifdef __DEPRECATED
-// Make GCC quiet.
-# undef __DEPRECATED
-# include <strstream>
-# define __DEPRECATED
-#else
-# include <strstream>
-#endif
#include <vector>
// Annoying stuff for windows -- makes sure clients can import these functions
@@ -61,6 +60,14 @@
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
+#if defined(_MSC_VER)
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
+ __pragma(warning(disable:n))
+#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
+#else
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
+#define GLOG_MSVC_POP_WARNING()
+#endif
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
@@ -79,7 +86,7 @@
#endif
#if 1
-#include "third_party/gflags/gflags/gflags.h"
+#include <gflags/gflags.h>
#endif
namespace google {
@@ -126,8 +133,12 @@ typedef unsigned __int64 uint64;
#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
#if 1
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#else
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#define GOOGLE_PREDICT_FALSE(x) x
+#define GOOGLE_PREDICT_TRUE(x) x
#endif
#endif
@@ -286,27 +297,27 @@ typedef unsigned __int64 uint64;
#ifndef DECLARE_VARIABLE
#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
-#define DECLARE_VARIABLE(type, name, tn) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
- extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+#define DECLARE_VARIABLE(type, shorttype, name, tn) \
+ namespace fL##shorttype { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using fL##shorttype::FLAGS_##name
// bool specialization
#define DECLARE_bool(name) \
- DECLARE_VARIABLE(bool, name, bool)
+ DECLARE_VARIABLE(bool, B, name, bool)
// int32 specialization
#define DECLARE_int32(name) \
- DECLARE_VARIABLE(google::int32, name, int32)
+ DECLARE_VARIABLE(google::int32, I, name, int32)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
-#define DECLARE_string(name) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
- extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#define DECLARE_string(name) \
+ namespace fLS { \
+ extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
#endif
// Set whether log messages go to stderr instead of logfiles
@@ -315,6 +326,9 @@ DECLARE_bool(logtostderr);
// Set whether log messages go to stderr in addition to logfiles.
DECLARE_bool(alsologtostderr);
+// Set color messages logged to stderr (if supported by terminal).
+DECLARE_bool(colorlogtostderr);
+
// Log messages at a level >= this flag are automatically sent to
// stderr in addition to log files.
DECLARE_int32(stderrthreshold);
@@ -447,15 +461,16 @@ DECLARE_bool(stop_logging_if_full_disk);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
// A very useful logging macro to log windows errors:
#define LOG_SYSRESULT(result) \
- if (FAILED(result)) { \
- LPTSTR message = NULL; \
- LPTSTR msg = reinterpret_cast<LPTSTR>(&message); \
- DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+ if (FAILED(HRESULT_FROM_WIN32(result))) { \
+ LPSTR message = NULL; \
+ LPSTR msg = reinterpret_cast<LPSTR>(&message); \
+ DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM, \
0, result, 0, msg, 100, NULL); \
if (message_length > 0) { \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \
- &google::LogMessage::SendToLog).stream() << message; \
+ &google::LogMessage::SendToLog).stream() \
+ << reinterpret_cast<const char*>(message); \
LocalFree(message); \
} \
}
@@ -597,18 +612,68 @@ inline std::ostream& operator<<(
namespace google {
-// Build the error message string.
-template<class t1, class t2>
-std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
- // It means that we cannot use stl_logging if compiler doesn't
- // support using expression for operator.
- // TODO(hamaji): Figure out a way to fix.
-#if 1
- using ::operator<<;
-#endif
- std::strstream ss;
- ss << names << " (" << v1 << " vs. " << v2 << ")";
- return new std::string(ss.str(), ss.pcount());
+// This formats a value for a failing CHECK_XX statement. Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+template <typename T>
+inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
+ (*os) << v;
+}
+
+// Overrides for char types provide readable values for unprintable
+// characters.
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const signed char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
+
+// Build the error message string. Specify no inlining for code size.
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
+ __attribute__ ((noinline));
+
+namespace base {
+namespace internal {
+
+// If "s" is less than base_logging::INFO, returns base_logging::INFO.
+// If "s" is greater than base_logging::FATAL, returns
+// base_logging::ERROR. Otherwise, returns "s".
+LogSeverity NormalizeSeverity(LogSeverity s);
+
+} // namespace internal
+
+// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
+// statement. See MakeCheckOpString for sample usage. Other
+// approaches were considered: use of a template method (e.g.,
+// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
+// base::Print<T2>, &v2), however this approach has complications
+// related to volatile arguments and function-pointer arguments).
+class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder {
+ public:
+ // Inserts "exprtext" and " (" to the stream.
+ explicit CheckOpMessageBuilder(const char *exprtext);
+ // Deletes "stream_".
+ ~CheckOpMessageBuilder();
+ // For inserting the first variable.
+ std::ostream* ForVar1() { return stream_; }
+ // For inserting the second variable (adds an intermediate " vs. ").
+ std::ostream* ForVar2();
+ // Get the result (inserts the closing ")").
+ std::string* NewString();
+
+ private:
+ std::ostringstream *stream_;
+};
+
+} // namespace base
+
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
+ base::CheckOpMessageBuilder comb(exprtext);
+ MakeCheckOpValueString(comb.ForVar1(), v1);
+ MakeCheckOpValueString(comb.ForVar2(), v2);
+ return comb.NewString();
}
// Helper functions for CHECK_OP macro.
@@ -616,26 +681,26 @@ std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
// will not instantiate the template version of the function on values of
// unnamed enum type - see comment below.
#define DEFINE_CHECK_OP_IMPL(name, op) \
- template <class t1, class t2> \
- inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
- const char* names) { \
- if (v1 op v2) return NULL; \
- else return MakeCheckOpString(v1, v2, names); \
+ template <typename T1, typename T2> \
+ inline std::string* name##Impl(const T1& v1, const T2& v2, \
+ const char* exprtext) { \
+ if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \
+ else return MakeCheckOpString(v1, v2, exprtext); \
} \
- inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
- return Check##name##Impl<int, int>(v1, v2, names); \
+ inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \
+ return name##Impl<int, int>(v1, v2, exprtext); \
}
-// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h
-// provides its own #defines for the simpler names EQ, NE, LE, etc.
+// We use the full name Check_EQ, Check_NE, etc. in case the file including
+// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
// This happens if, for example, those are used as token names in a
// yacc grammar.
-DEFINE_CHECK_OP_IMPL(_EQ, ==)
-DEFINE_CHECK_OP_IMPL(_NE, !=)
-DEFINE_CHECK_OP_IMPL(_LE, <=)
-DEFINE_CHECK_OP_IMPL(_LT, < )
-DEFINE_CHECK_OP_IMPL(_GE, >=)
-DEFINE_CHECK_OP_IMPL(_GT, > )
+DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)?
+DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead.
+DEFINE_CHECK_OP_IMPL(Check_LE, <=)
+DEFINE_CHECK_OP_IMPL(Check_LT, < )
+DEFINE_CHECK_OP_IMPL(Check_GE, >=)
+DEFINE_CHECK_OP_IMPL(Check_GT, > )
#undef DEFINE_CHECK_OP_IMPL
// Helper macro for binary operators.
@@ -940,52 +1005,65 @@ const LogSeverity GLOG_0 = GLOG_ERROR;
#define DLOG_ASSERT(condition) \
true ? (void) 0 : LOG_ASSERT(condition)
+// MSVC warning C4127: conditional expression is constant
#define DCHECK(condition) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK(condition)
+ GLOG_MSVC_POP_WARNING() CHECK(condition)
#define DCHECK_EQ(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_EQ(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_NE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_LE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_LT(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_GE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_GT(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
+// You may see warnings in release mode if you don't use the return
+// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
#define DCHECK_NOTNULL(val) (val)
#define DCHECK_STREQ(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STREQ(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
#define DCHECK_STRCASEEQ(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRCASEEQ(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
#define DCHECK_STRNE(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRNE(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
#define DCHECK_STRCASENE(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRCASENE(str1, str2)
-
+ GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
#endif // NDEBUG
@@ -1002,6 +1080,29 @@ const LogSeverity GLOG_0 = GLOG_ERROR;
#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+namespace base_logging {
+
+// LogMessage::LogStream is a std::ostream backed by this streambuf.
+// This class ignores overflow and leaves two bytes at the end of the
+// buffer to allow for a '\n' and '\0'.
+class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf {
+ public:
+ // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'.
+ LogStreamBuf(char *buf, int len) {
+ setp(buf, buf + len - 2);
+ }
+ // This effectively ignores overflow.
+ virtual int_type overflow(int_type ch) {
+ return ch;
+ }
+
+ // Legacy public ostrstream method.
+ size_t pcount() const { return pptr() - pbase(); }
+ char* pbase() const { return std::streambuf::pbase(); }
+};
+
+} // namespace base_logging
+
//
// This class more or less represents a particular log message. You
// create an instance of LogMessage and then stream stuff to it.
@@ -1031,22 +1132,30 @@ public:
#ifdef _MSC_VER
# pragma warning(disable: 4275)
#endif
- class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream {
+ class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream {
#ifdef _MSC_VER
# pragma warning(default: 4275)
#endif
public:
- LogStream(char *buf, int len, int ctr_in)
- : ostrstream(buf, len),
- ctr_(ctr_in) {
- self_ = this;
+ LogStream(char *buf, int len, int ctr)
+ : std::ostream(NULL),
+ streambuf_(buf, len),
+ ctr_(ctr),
+ self_(this) {
+ rdbuf(&streambuf_);
}
int ctr() const { return ctr_; }
- void set_ctr(int ctr_in) { ctr_ = ctr_in; }
+ void set_ctr(int ctr) { ctr_ = ctr; }
LogStream* self() const { return self_; }
+ // Legacy std::streambuf methods.
+ size_t pcount() const { return streambuf_.pcount(); }
+ char* pbase() const { return streambuf_.pbase(); }
+ char* str() const { return pbase(); }
+
private:
+ base_logging::LogStreamBuf streambuf_;
int ctr_; // Counter hack (for the LOG_EVERY_X() macro)
LogStream *self_; // Consistency check hack
};
@@ -1115,13 +1224,15 @@ public:
// Call abort() or similar to perform LOG(FATAL) crash.
static void Fail() __attribute__ ((noreturn));
- std::ostream& stream() { return *(data_->stream_); }
+ std::ostream& stream();
- int preserved_errno() const { return data_->preserved_errno_; }
+ int preserved_errno() const;
// Must be called without the log_mutex held. (L < log_mutex)
static int64 num_messages(int severity);
+ struct LogMessageData;
+
private:
// Fully internal SendMethod cases:
void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs
@@ -1143,41 +1254,6 @@ private:
// We keep the data in a separate struct so that each instance of
// LogMessage uses less stack space.
- struct GOOGLE_GLOG_DLL_DECL LogMessageData {
- LogMessageData() {};
-
- int preserved_errno_; // preserved errno
- char* buf_;
- char* message_text_; // Complete message text (points to selected buffer)
- LogStream* stream_alloc_;
- LogStream* stream_;
- char severity_; // What level is this LogMessage logged at?
- int line_; // line number where logging call is.
- void (LogMessage::*send_method_)(); // Call this in destructor to send
- union { // At most one of these is used: union to keep the size low.
- LogSink* sink_; // NULL or sink to send message to
- std::vector<std::string>* outvec_; // NULL or vector to push message onto
- std::string* message_; // NULL or string to write message into
- };
- time_t timestamp_; // Time of creation of LogMessage
- struct ::tm tm_time_; // Time of creation of LogMessage
- size_t num_prefix_chars_; // # of chars of prefix in this message
- size_t num_chars_to_log_; // # of chars of msg to send to log
- size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
- const char* basename_; // basename of file that called LOG
- const char* fullname_; // fullname of file that called LOG
- bool has_been_flushed_; // false => data has not been flushed
- bool first_fatal_; // true => this was first fatal msg
-
- ~LogMessageData();
- private:
- LogMessageData(const LogMessageData&);
- void operator=(const LogMessageData&);
- };
-
- static LogMessageData fatal_msg_data_exclusive_;
- static LogMessageData fatal_msg_data_shared_;
-
LogMessageData* allocated_;
LogMessageData* data_;
@@ -1456,8 +1532,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
// be set to an empty string, if this function failed. This means, in most
// cases, you do not need to check the error code and you can directly
// use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
// A class for which we define operator<<, which does nothing.
class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
@@ -1525,3 +1605,5 @@ GOOGLE_GLOG_DLL_DECL void InstallFailureWriter(
}
#endif // _LOGGING_H_
+
+#endif // WIN32
diff --git a/extern/libmv/third_party/glog/src/glog/raw_logging.h b/extern/libmv/third_party/glog/src/glog/raw_logging.h
index 65278f62803..b030f7f736d 100644
--- a/extern/libmv/third_party/glog/src/glog/raw_logging.h
+++ b/extern/libmv/third_party/glog/src/glog/raw_logging.h
@@ -33,6 +33,10 @@
// acquire any locks, and can therefore be used by low-level memory
// allocation and synchronization code.
+#ifdef WIN32
+# include "windows/glog/raw_logging.h"
+#else // WIN32
+
#ifndef BASE_RAW_LOGGING_H_
#define BASE_RAW_LOGGING_H_
@@ -183,3 +187,5 @@ GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs);
}
#endif // BASE_RAW_LOGGING_H_
+
+#endif // WIN32
diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc
index 57d5e24122c..5e2ce61c9c9 100644
--- a/extern/libmv/third_party/glog/src/logging.cc
+++ b/extern/libmv/third_party/glog/src/logging.cc
@@ -59,8 +59,8 @@
#include <errno.h> // for errno
#include <sstream>
#include "base/commandlineflags.h" // to get the program name
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
#include "base/googleinit.h"
#ifdef HAVE_STACKTRACE
@@ -69,7 +69,6 @@
using std::string;
using std::vector;
-using std::ostrstream;
using std::setw;
using std::setfill;
using std::hex;
@@ -77,7 +76,17 @@ using std::dec;
using std::min;
using std::ostream;
using std::ostringstream;
-using std::strstream;
+
+using std::FILE;
+using std::fwrite;
+using std::fclose;
+using std::fflush;
+using std::fprintf;
+using std::perror;
+
+#ifdef __QNX__
+using std::fdopen;
+#endif
// There is no thread annotation support.
#define EXCLUSIVE_LOCKS_REQUIRED(mu)
@@ -94,6 +103,8 @@ GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false),
"log messages go to stderr instead of logfiles");
GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
"log messages go to stderr in addition to logfiles");
+GLOG_DEFINE_bool(colorlogtostderr, false,
+ "color messages logged to stderr (if supported by terminal)");
#ifdef OS_LINUX
GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
"Logs can grow very quickly and they are rarely read before they "
@@ -169,6 +180,38 @@ GLOG_DEFINE_string(log_backtrace_at, "",
// TODO(hamaji): consider windows
#define PATH_SEPARATOR '/'
+#ifndef HAVE_PREAD
+static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
+ off_t orig_offset = lseek(fd, 0, SEEK_CUR);
+ if (orig_offset == (off_t)-1)
+ return -1;
+ if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
+ return -1;
+ ssize_t len = read(fd, buf, count);
+ if (len < 0)
+ return len;
+ if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
+ return -1;
+ return len;
+}
+#endif // !HAVE_PREAD
+
+#ifndef HAVE_PWRITE
+static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) {
+ off_t orig_offset = lseek(fd, 0, SEEK_CUR);
+ if (orig_offset == (off_t)-1)
+ return -1;
+ if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
+ return -1;
+ ssize_t len = write(fd, buf, count);
+ if (len < 0)
+ return len;
+ if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
+ return -1;
+ return len;
+}
+#endif // !HAVE_PWRITE
+
static void GetHostName(string* hostname) {
#if defined(HAVE_SYS_UTSNAME_H)
struct utsname buf;
@@ -191,13 +234,125 @@ static void GetHostName(string* hostname) {
#endif
}
+// Returns true iff terminal supports using colors in output.
+static bool TerminalSupportsColor() {
+ bool term_supports_color = false;
+#ifdef OS_WINDOWS
+ // on Windows TERM variable is usually not set, but the console does
+ // support colors.
+ term_supports_color = true;
+#else
+ // On non-Windows platforms, we rely on the TERM variable.
+ const char* const term = getenv("TERM");
+ if (term != NULL && term[0] != '\0') {
+ term_supports_color =
+ !strcmp(term, "xterm") ||
+ !strcmp(term, "xterm-color") ||
+ !strcmp(term, "xterm-256color") ||
+ !strcmp(term, "screen") ||
+ !strcmp(term, "linux") ||
+ !strcmp(term, "cygwin");
+ }
+#endif
+ return term_supports_color;
+}
+
_START_GOOGLE_NAMESPACE_
+enum GLogColor {
+ COLOR_DEFAULT,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_YELLOW
+};
+
+static GLogColor SeverityToColor(LogSeverity severity) {
+ assert(severity >= 0 && severity < NUM_SEVERITIES);
+ GLogColor color = COLOR_DEFAULT;
+ switch (severity) {
+ case GLOG_INFO:
+ color = COLOR_DEFAULT;
+ break;
+ case GLOG_WARNING:
+ color = COLOR_YELLOW;
+ break;
+ case GLOG_ERROR:
+ case GLOG_FATAL:
+ color = COLOR_RED;
+ break;
+ default:
+ // should never get here.
+ assert(false);
+ }
+ return color;
+}
+
+#ifdef OS_WINDOWS
+
+// Returns the character attribute for the given color.
+WORD GetColorAttribute(GLogColor color) {
+ switch (color) {
+ case COLOR_RED: return FOREGROUND_RED;
+ case COLOR_GREEN: return FOREGROUND_GREEN;
+ case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+ default: return 0;
+ }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.
+static const char* GetAnsiColorCode(GLogColor color) {
+ switch (color) {
+ case COLOR_RED: return "1";
+ case COLOR_GREEN: return "2";
+ case COLOR_YELLOW: return "3";
+ case COLOR_DEFAULT: return "";
+ };
+ return NULL; // stop warning about return type.
+}
+
+#endif // OS_WINDOWS
+
// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0
static int32 MaxLogSize() {
return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1);
}
+// An arbitrary limit on the length of a single log message. This
+// is so that streaming can be done more efficiently.
+const size_t LogMessage::kMaxLogMessageLen = 30000;
+
+struct LogMessage::LogMessageData {
+ LogMessageData();
+
+ int preserved_errno_; // preserved errno
+ // Buffer space; contains complete message text.
+ char message_text_[LogMessage::kMaxLogMessageLen+1];
+ LogStream stream_;
+ char severity_; // What level is this LogMessage logged at?
+ int line_; // line number where logging call is.
+ void (LogMessage::*send_method_)(); // Call this in destructor to send
+ union { // At most one of these is used: union to keep the size low.
+ LogSink* sink_; // NULL or sink to send message to
+ std::vector<std::string>* outvec_; // NULL or vector to push message onto
+ std::string* message_; // NULL or string to write message into
+ };
+ time_t timestamp_; // Time of creation of LogMessage
+ struct ::tm tm_time_; // Time of creation of LogMessage
+ size_t num_prefix_chars_; // # of chars of prefix in this message
+ size_t num_chars_to_log_; // # of chars of msg to send to log
+ size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
+ const char* basename_; // basename of file that called LOG
+ const char* fullname_; // fullname of file that called LOG
+ bool has_been_flushed_; // false => data has not been flushed
+ bool first_fatal_; // true => this was first fatal msg
+
+ private:
+ LogMessageData(const LogMessageData&);
+ void operator=(const LogMessageData&);
+};
+
// A mutex that allows only one thread to log at a time, to keep things from
// getting jumbled. Some other very uncommon logging operations (like
// changing the destination file for log messages of a given severity) also
@@ -279,7 +434,7 @@ class LogFileObject : public base::Logger {
// Actually create a logfile using the value of base_filename_ and the
// supplied argument time_pid_string
// REQUIRES: lock_ is held
- bool CreateLogfile(const char* time_pid_string);
+ bool CreateLogfile(const string& time_pid_string);
};
} // namespace
@@ -312,6 +467,9 @@ class LogDestination {
static const int kNetworkBytes = 1400;
static const string& hostname();
+ static const bool& terminal_supports_color() {
+ return terminal_supports_color_;
+ }
static void DeleteLogDestinations();
@@ -362,6 +520,7 @@ class LogDestination {
static LogSeverity email_logging_severity_;
static string addresses_;
static string hostname_;
+ static bool terminal_supports_color_;
// arbitrary global logging destinations.
static vector<LogSink*>* sinks_;
@@ -383,6 +542,7 @@ string LogDestination::hostname_;
vector<LogSink*>* LogDestination::sinks_ = NULL;
Mutex LogDestination::sink_mutex_;
+bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
/* static */
const string& LogDestination::hostname() {
@@ -503,6 +663,43 @@ inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
LogDestination::addresses_ = addresses;
}
+static void ColoredWriteToStderr(LogSeverity severity,
+ const char* message, size_t len) {
+ const GLogColor color =
+ (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ?
+ SeverityToColor(severity) : COLOR_DEFAULT;
+
+ // Avoid using cerr from this module since we may get called during
+ // exit code, and cerr may be partially or fully destroyed by then.
+ if (COLOR_DEFAULT == color) {
+ fwrite(message, len, 1, stderr);
+ return;
+ }
+#ifdef OS_WINDOWS
+ const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+
+ // Gets the current text color.
+ CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+ GetConsoleScreenBufferInfo(stderr_handle, &buffer_info);
+ const WORD old_color_attrs = buffer_info.wAttributes;
+
+ // We need to flush the stream buffers into the console before each
+ // SetConsoleTextAttribute call lest it affect the text that is already
+ // printed but has not yet reached the console.
+ fflush(stderr);
+ SetConsoleTextAttribute(stderr_handle,
+ GetColorAttribute(color) | FOREGROUND_INTENSITY);
+ fwrite(message, len, 1, stderr);
+ fflush(stderr);
+ // Restores the text color.
+ SetConsoleTextAttribute(stderr_handle, old_color_attrs);
+#else
+ fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color));
+ fwrite(message, len, 1, stderr);
+ fprintf(stderr, "\033[m"); // Resets the terminal to default.
+#endif // OS_WINDOWS
+}
+
static void WriteToStderr(const char* message, size_t len) {
// Avoid using cerr from this module since we may get called during
// exit code, and cerr may be partially or fully destroyed by then.
@@ -512,7 +709,7 @@ static void WriteToStderr(const char* message, size_t len) {
inline void LogDestination::MaybeLogToStderr(LogSeverity severity,
const char* message, size_t len) {
if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
- WriteToStderr(message, len);
+ ColoredWriteToStderr(severity, message, len);
#ifdef OS_WINDOWS
// On Windows, also output to the debugger
::OutputDebugStringA(string(message,len).c_str());
@@ -561,12 +758,12 @@ inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
const char* message,
size_t len) {
- if ( FLAGS_logtostderr ) // global flag: never log to file
- WriteToStderr(message, len);
- else
+ if ( FLAGS_logtostderr ) { // global flag: never log to file
+ ColoredWriteToStderr(severity, message, len);
+ } else {
for (int i = severity; i >= 0; --i)
LogDestination::MaybeLogToLogfile(i, timestamp, message, len);
-
+ }
}
inline void LogDestination::LogToSinks(LogSeverity severity,
@@ -691,7 +888,7 @@ void LogFileObject::FlushUnlocked(){
next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
}
-bool LogFileObject::CreateLogfile(const char* time_pid_string) {
+bool LogFileObject::CreateLogfile(const string& time_pid_string) {
string string_filename = base_filename_+filename_extension_+
time_pid_string;
const char* filename = string_filename.c_str();
@@ -724,8 +921,10 @@ bool LogFileObject::CreateLogfile(const char* time_pid_string) {
linkpath += linkname;
unlink(linkpath.c_str()); // delete old one if it exists
+#if defined(OS_WINDOWS)
+ // TODO(hamaji): Create lnk file on Windows?
+#elif defined(HAVE_UNISTD_H)
// We must have unistd.h.
-#ifdef HAVE_UNISTD_H
// Make the symlink be relative (in the same dir) so that if the
// entire log directory gets relocated the link is still valid.
const char *linkdest = slash ? (slash + 1) : filename;
@@ -779,24 +978,24 @@ void LogFileObject::Write(bool force_flush,
localtime_r(&timestamp, &tm_time);
// The logfile's filename will have the date/time & pid in it
- char time_pid_string[256]; // More than enough chars for time, pid, \0
- ostrstream time_pid_stream(time_pid_string, sizeof(time_pid_string));
+ ostringstream time_pid_stream;
time_pid_stream.fill('0');
time_pid_stream << 1900+tm_time.tm_year
- << setw(2) << 1+tm_time.tm_mon
- << setw(2) << tm_time.tm_mday
- << '-'
- << setw(2) << tm_time.tm_hour
- << setw(2) << tm_time.tm_min
- << setw(2) << tm_time.tm_sec
- << '.'
- << GetMainThreadPid()
- << '\0';
+ << setw(2) << 1+tm_time.tm_mon
+ << setw(2) << tm_time.tm_mday
+ << '-'
+ << setw(2) << tm_time.tm_hour
+ << setw(2) << tm_time.tm_min
+ << setw(2) << tm_time.tm_sec
+ << '.'
+ << GetMainThreadPid();
+ const string& time_pid_string = time_pid_stream.str();
if (base_filename_selected_) {
if (!CreateLogfile(time_pid_string)) {
perror("Could not create log file");
- fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", time_pid_string);
+ fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n",
+ time_pid_string.c_str());
return;
}
} else {
@@ -844,15 +1043,14 @@ void LogFileObject::Write(bool force_flush,
// If we never succeeded, we have to give up
if ( success == false ) {
perror("Could not create logging file");
- fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", time_pid_string);
+ fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!",
+ time_pid_string.c_str());
return;
}
}
// Write a header message into the log file
- char file_header_string[512]; // Enough chars for time and binary info
- ostrstream file_header_stream(file_header_string,
- sizeof(file_header_string));
+ ostringstream file_header_stream;
file_header_stream.fill('0');
file_header_stream << "Log file created at: "
<< 1900+tm_time.tm_year << '/'
@@ -865,10 +1063,11 @@ void LogFileObject::Write(bool force_flush,
<< "Running on machine: "
<< LogDestination::hostname() << '\n'
<< "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu "
- << "threadid file:line] msg" << '\n'
- << '\0';
- int header_len = strlen(file_header_string);
- fwrite(file_header_string, 1, header_len, file_);
+ << "threadid file:line] msg" << '\n';
+ const string& file_header_string = file_header_stream.str();
+
+ const int header_len = file_header_string.size();
+ fwrite(file_header_string.data(), 1, header_len, file_);
file_length_ += header_len;
bytes_since_flush_ += header_len;
}
@@ -916,9 +1115,6 @@ void LogFileObject::Write(bool force_flush,
} // namespace
-// An arbitrary limit on the length of a single log message. This
-// is so that streaming can be done more efficiently.
-const size_t LogMessage::kMaxLogMessageLen = 30000;
// Static log data space to avoid alloc failures in a LOG(FATAL)
//
@@ -929,55 +1125,55 @@ const size_t LogMessage::kMaxLogMessageLen = 30000;
static Mutex fatal_msg_lock;
static CrashReason crash_reason;
static bool fatal_msg_exclusive = true;
-static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1];
-static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1];
-static LogMessage::LogStream fatal_msg_stream_exclusive(
- fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0);
-static LogMessage::LogStream fatal_msg_stream_shared(
- fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0);
-LogMessage::LogMessageData LogMessage::fatal_msg_data_exclusive_;
-LogMessage::LogMessageData LogMessage::fatal_msg_data_shared_;
+static LogMessage::LogMessageData fatal_msg_data_exclusive;
+static LogMessage::LogMessageData fatal_msg_data_shared;
-LogMessage::LogMessageData::~LogMessageData() {
- delete[] buf_;
- delete stream_alloc_;
+LogMessage::LogMessageData::LogMessageData()
+ : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
}
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
- int ctr, void (LogMessage::*send_method)()) {
+ int ctr, void (LogMessage::*send_method)())
+ : allocated_(NULL) {
Init(file, line, severity, send_method);
- data_->stream_->set_ctr(ctr);
+ data_->stream_.set_ctr(ctr);
}
LogMessage::LogMessage(const char* file, int line,
- const CheckOpString& result) {
+ const CheckOpString& result)
+ : allocated_(NULL) {
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
stream() << "Check failed: " << (*result.str_) << " ";
}
-LogMessage::LogMessage(const char* file, int line) {
+LogMessage::LogMessage(const char* file, int line)
+ : allocated_(NULL) {
Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
}
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity) {
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
+ : allocated_(NULL) {
Init(file, line, severity, &LogMessage::SendToLog);
}
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
- LogSink* sink, bool also_send_to_log) {
+ LogSink* sink, bool also_send_to_log)
+ : allocated_(NULL) {
Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
&LogMessage::SendToSink);
data_->sink_ = sink; // override Init()'s setting to NULL
}
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
- vector<string> *outvec) {
+ vector<string> *outvec)
+ : allocated_(NULL) {
Init(file, line, severity, &LogMessage::SaveOrSendToLog);
data_->outvec_ = outvec; // override Init()'s setting to NULL
}
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
- string *message) {
+ string *message)
+ : allocated_(NULL) {
Init(file, line, severity, &LogMessage::WriteToStringAndLog);
data_->message_ = message; // override Init()'s setting to NULL
}
@@ -990,27 +1186,17 @@ void LogMessage::Init(const char* file,
if (severity != GLOG_FATAL || !exit_on_dfatal) {
allocated_ = new LogMessageData();
data_ = allocated_;
- data_->buf_ = new char[kMaxLogMessageLen+1];
- data_->message_text_ = data_->buf_;
- data_->stream_alloc_ =
- new LogStream(data_->message_text_, kMaxLogMessageLen, 0);
- data_->stream_ = data_->stream_alloc_;
data_->first_fatal_ = false;
} else {
MutexLock l(&fatal_msg_lock);
if (fatal_msg_exclusive) {
fatal_msg_exclusive = false;
- data_ = &fatal_msg_data_exclusive_;
- data_->message_text_ = fatal_msg_buf_exclusive;
- data_->stream_ = &fatal_msg_stream_exclusive;
+ data_ = &fatal_msg_data_exclusive;
data_->first_fatal_ = true;
} else {
- data_ = &fatal_msg_data_shared_;
- data_->message_text_ = fatal_msg_buf_shared;
- data_->stream_ = &fatal_msg_stream_shared;
+ data_ = &fatal_msg_data_shared;
data_->first_fatal_ = false;
}
- data_->stream_alloc_ = NULL;
}
stream().fill('0');
@@ -1051,7 +1237,7 @@ void LogMessage::Init(const char* file,
<< ' '
<< data_->basename_ << ':' << data_->line_ << "] ";
}
- data_->num_prefix_chars_ = data_->stream_->pcount();
+ data_->num_prefix_chars_ = data_->stream_.pcount();
if (!FLAGS_log_backtrace_at.empty()) {
char fileline[128];
@@ -1071,13 +1257,21 @@ LogMessage::~LogMessage() {
delete allocated_;
}
+int LogMessage::preserved_errno() const {
+ return data_->preserved_errno_;
+}
+
+ostream& LogMessage::stream() {
+ return data_->stream_;
+}
+
// Flush buffered message, called by the destructor, or any other function
// that needs to synchronize the log.
void LogMessage::Flush() {
if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel)
return;
- data_->num_chars_to_log_ = data_->stream_->pcount();
+ data_->num_chars_to_log_ = data_->stream_.pcount();
data_->num_chars_to_syslog_ =
data_->num_chars_to_log_ - data_->num_prefix_chars_;
@@ -1127,7 +1321,7 @@ void LogMessage::Flush() {
// Copy of first FATAL log message so that we can print it out again
// after all the stack traces. To preserve legacy behavior, we don't
-// use fatal_msg_buf_exclusive.
+// use fatal_msg_data_exclusive.
static time_t fatal_time;
static char fatal_message[256];
@@ -1135,7 +1329,7 @@ void ReprintFatalMessage() {
if (fatal_message[0]) {
const int n = strlen(fatal_message);
if (!FLAGS_logtostderr) {
- // Also write to stderr
+ // Also write to stderr (don't color to avoid terminal checks)
WriteToStderr(fatal_message, n);
}
LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n);
@@ -1164,7 +1358,8 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
// file if we haven't parsed the command line flags to get the
// program name.
if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) {
- WriteToStderr(data_->message_text_, data_->num_chars_to_log_);
+ ColoredWriteToStderr(data_->severity_,
+ data_->message_text_, data_->num_chars_to_log_);
// this could be protected by a flag if necessary.
LogDestination::LogToSinks(data_->severity_,
@@ -1236,10 +1431,10 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
void LogMessage::RecordCrashReason(
glog_internal_namespace_::CrashReason* reason) {
- reason->filename = fatal_msg_data_exclusive_.fullname_;
- reason->line_number = fatal_msg_data_exclusive_.line_;
- reason->message = fatal_msg_buf_exclusive +
- fatal_msg_data_exclusive_.num_prefix_chars_;
+ reason->filename = fatal_msg_data_exclusive.fullname_;
+ reason->line_number = fatal_msg_data_exclusive.line_;
+ reason->message = fatal_msg_data_exclusive.message_text_ +
+ fatal_msg_data_exclusive.num_prefix_chars_;
#ifdef HAVE_STACKTRACE
// Retrieve the stack trace, omitting the logging frames that got us here.
reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4);
@@ -1366,8 +1561,13 @@ int64 LogMessage::num_messages(int severity) {
// Output the COUNTER value. This is only valid if ostream is a
// LogStream.
ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
+#ifdef DISABLE_RTTI
+ LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
+#else
LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
- CHECK(log == log->self());
+#endif
+ CHECK(log && log == log->self())
+ << "You must not use COUNTER with non-glog ostream";
os << log->ctr();
return os;
}
@@ -1381,9 +1581,8 @@ ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
ErrnoLogMessage::~ErrnoLogMessage() {
// Don't access errno directly because it may have been altered
// while streaming the message.
- char buf[100];
- posix_strerror_r(preserved_errno(), buf, sizeof(buf));
- stream() << ": " << buf << " [" << preserved_errno() << "]";
+ stream() << ": " << StrError(preserved_errno()) << " ["
+ << preserved_errno() << "]";
}
void FlushLogFiles(LogSeverity min_severity) {
@@ -1465,9 +1664,7 @@ void LogToStderr() {
namespace base {
namespace internal {
-/* Put prototypes here to suppress strict compiler warnings */
-bool GetExitOnDFatal();
-void SetExitOnDFatal(bool value);
+namespace {
bool GetExitOnDFatal() {
MutexLock l(&log_mutex);
@@ -1489,6 +1686,8 @@ void SetExitOnDFatal(bool value) {
exit_on_dfatal = value;
}
+} // namespace
+
} // namespace internal
} // namespace base
@@ -1516,13 +1715,11 @@ static bool SendEmailInternal(const char*dest, const char *subject,
bool ok = pclose(pipe) != -1;
if ( !ok ) {
if ( use_logging ) {
- char buf[100];
- posix_strerror_r(errno, buf, sizeof(buf));
- LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf;
+ LOG(ERROR) << "Problems sending mail to " << dest << ": "
+ << StrError(errno);
} else {
- char buf[100];
- posix_strerror_r(errno, buf, sizeof(buf));
- fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf);
+ fprintf(stderr, "Problems sending mail to %s: %s\n",
+ dest, StrError(errno).c_str());
}
}
return ok;
@@ -1644,8 +1841,11 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) {
int64 read_offset, write_offset;
// Don't follow symlinks unless they're our own fd symlinks in /proc
int flags = O_RDWR;
+ // TODO(hamaji): Support other environments.
+#ifdef OS_LINUX
const char *procfd_prefix = "/proc/self/fd/";
if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW;
+#endif
int fd = open(path, flags);
if (fd == -1) {
@@ -1730,11 +1930,11 @@ void TruncateStdoutStderr() {
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
if (equal == expected) return NULL; \
else { \
- strstream ss; \
+ ostringstream ss; \
if (!s1) s1 = ""; \
if (!s2) s2 = ""; \
ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
- return new string(ss.str(), ss.pcount()); \
+ return new string(ss.str()); \
} \
}
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
@@ -1793,6 +1993,15 @@ int posix_strerror_r(int err, char *buf, size_t len) {
}
}
+string StrError(int err) {
+ char buf[100];
+ int rc = posix_strerror_r(err, buf, sizeof(buf));
+ if ((rc < 0) || (buf[0] == '\000')) {
+ snprintf(buf, sizeof(buf), "Error number %d", err);
+ }
+ return buf;
+}
+
LogMessageFatal::LogMessageFatal(const char* file, int line) :
LogMessage(file, line, GLOG_FATAL) {}
@@ -1805,6 +2014,56 @@ LogMessageFatal::~LogMessageFatal() {
LogMessage::Fail();
}
+namespace base {
+
+CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext)
+ : stream_(new ostringstream) {
+ *stream_ << exprtext << " (";
+}
+
+CheckOpMessageBuilder::~CheckOpMessageBuilder() {
+ delete stream_;
+}
+
+ostream* CheckOpMessageBuilder::ForVar2() {
+ *stream_ << " vs. ";
+ return stream_;
+}
+
+string* CheckOpMessageBuilder::NewString() {
+ *stream_ << ")";
+ return new string(stream_->str());
+}
+
+} // namespace base
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const char& v) {
+ if (v >= 32 && v <= 126) {
+ (*os) << "'" << v << "'";
+ } else {
+ (*os) << "char value " << (short)v;
+ }
+}
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const signed char& v) {
+ if (v >= 32 && v <= 126) {
+ (*os) << "'" << v << "'";
+ } else {
+ (*os) << "signed char value " << (short)v;
+ }
+}
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
+ if (v >= 32 && v <= 126) {
+ (*os) << "'" << v << "'";
+ } else {
+ (*os) << "unsigned char value " << (unsigned short)v;
+ }
+}
+
void InitGoogleLogging(const char* argv0) {
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
}
diff --git a/extern/libmv/third_party/glog/src/raw_logging.cc b/extern/libmv/third_party/glog/src/raw_logging.cc
index 42676cba5de..7a7409bbf34 100644
--- a/extern/libmv/third_party/glog/src/raw_logging.cc
+++ b/extern/libmv/third_party/glog/src/raw_logging.cc
@@ -42,8 +42,8 @@
#include <fcntl.h> // for open()
#include <time.h>
#include "config.h"
-#include <glog/logging.h> // To pick up flag settings etc.
-#include <glog/raw_logging.h>
+#include "glog/logging.h" // To pick up flag settings etc.
+#include "glog/raw_logging.h"
#include "base/commandlineflags.h"
#ifdef HAVE_STACKTRACE
diff --git a/extern/libmv/third_party/glog/src/signalhandler.cc b/extern/libmv/third_party/glog/src/signalhandler.cc
index e95e9e97274..cccd800d769 100644
--- a/extern/libmv/third_party/glog/src/signalhandler.cc
+++ b/extern/libmv/third_party/glog/src/signalhandler.cc
@@ -34,7 +34,7 @@
#include "utilities.h"
#include "stacktrace.h"
#include "symbolize.h"
-#include <glog/logging.h>
+#include "glog/logging.h"
#include <signal.h>
#include <time.h>
@@ -48,6 +48,9 @@
_START_GOOGLE_NAMESPACE_
+// TOOD(hamaji): Use signal instead of sigaction?
+#ifdef HAVE_SIGACTION
+
namespace {
// We'll install the failure signal handler for these signals. We could
@@ -330,7 +333,10 @@ void FailureSignalHandler(int signal_number,
} // namespace
+#endif // HAVE_SIGACTION
+
void InstallFailureSignalHandler() {
+#ifdef HAVE_SIGACTION
// Build the sigaction struct.
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
@@ -341,10 +347,13 @@ void InstallFailureSignalHandler() {
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
}
+#endif // HAVE_SIGACTION
}
void InstallFailureWriter(void (*writer)(const char* data, int size)) {
+#ifdef HAVE_SIGACTION
g_failure_writer = writer;
+#endif // HAVE_SIGACTION
}
_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h
index 46002c1b019..0dc14c6506e 100644
--- a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h
+++ b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h
@@ -37,7 +37,7 @@ extern "C" {
#define UNW_LOCAL_ONLY
#include <libunwind.h>
}
-#include <glog/raw_logging.h>
+#include "glog/raw_logging.h"
#include "stacktrace.h"
_START_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/symbolize.cc b/extern/libmv/third_party/glog/src/symbolize.cc
index d1831e4ea79..18bbccf3072 100644
--- a/extern/libmv/third_party/glog/src/symbolize.cc
+++ b/extern/libmv/third_party/glog/src/symbolize.cc
@@ -111,7 +111,7 @@ _END_GOOGLE_NAMESPACE_
#include "symbolize.h"
#include "config.h"
-#include <glog/raw_logging.h>
+#include "glog/raw_logging.h"
// Re-runs fn until it doesn't cause EINTR.
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
@@ -232,7 +232,7 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
}
char header_name[kMaxSectionNameLen];
if (sizeof(header_name) < name_len) {
- RAW_LOG(WARNING, "Section name '%s' is too long (%"PRIuS"); "
+ RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS "); "
"section will not be found (even if present).", name, name_len);
// No point in even trying.
return false;
diff --git a/extern/libmv/third_party/glog/src/symbolize.h b/extern/libmv/third_party/glog/src/symbolize.h
index 04e482bc315..1ebe4dd94a2 100644
--- a/extern/libmv/third_party/glog/src/symbolize.h
+++ b/extern/libmv/third_party/glog/src/symbolize.h
@@ -56,7 +56,7 @@
#include "utilities.h"
#include "config.h"
-#include <glog/logging.h>
+#include "glog/logging.h"
#ifdef HAVE_SYMBOLIZE
diff --git a/extern/libmv/third_party/glog/src/utilities.cc b/extern/libmv/third_party/glog/src/utilities.cc
index 159b094c170..1e8836d243f 100644
--- a/extern/libmv/third_party/glog/src/utilities.cc
+++ b/extern/libmv/third_party/glog/src/utilities.cc
@@ -136,6 +136,8 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
static void DumpStackTraceAndExit() {
DumpStackTrace(1, DebugWriteToStderr, NULL);
+ // TOOD(hamaji): Use signal instead of sigaction?
+#ifdef HAVE_SIGACTION
// Set the default signal handler for SIGABRT, to avoid invoking our
// own signal handler installed by InstallFailedSignalHandler().
struct sigaction sig_action;
@@ -143,6 +145,7 @@ static void DumpStackTraceAndExit() {
sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &sig_action, NULL);
+#endif // HAVE_SIGACTION
abort();
}
@@ -233,7 +236,7 @@ bool PidHasChanged() {
}
pid_t GetTID() {
- // On Linux and MACOSX , we try to use gettid().
+ // On Linux and MacOSX, we try to use gettid().
#if defined OS_LINUX || defined OS_MACOSX
#ifndef __NR_gettid
#ifdef OS_MACOSX
@@ -331,6 +334,7 @@ void InitGoogleLoggingUtilities(const char* argv0) {
void ShutdownGoogleLoggingUtilities() {
CHECK(IsGoogleLoggingInitialized())
<< "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
+ g_program_invocation_short_name = NULL;
#ifdef HAVE_SYSLOG_H
closelog();
#endif
diff --git a/extern/libmv/third_party/glog/src/utilities.h b/extern/libmv/third_party/glog/src/utilities.h
index c8215b73f33..4f41c92e434 100644
--- a/extern/libmv/third_party/glog/src/utilities.h
+++ b/extern/libmv/third_party/glog/src/utilities.h
@@ -79,7 +79,7 @@
#endif
#include "config.h"
-#include <glog/logging.h>
+#include "glog/logging.h"
// There are three different ways we can try to get the stack trace:
//
@@ -108,7 +108,7 @@
#elif !defined(NO_FRAME_POINTER)
# if defined(__i386__) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_x86-inl.h"
-# elif defined(__x86_64__) && __GNUC__ >= 2
+# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H
# define STACKTRACE_H "stacktrace_x86_64-inl.h"
# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_powerpc-inl.h"
diff --git a/extern/libmv/third_party/glog/src/vlog_is_on.cc b/extern/libmv/third_party/glog/src/vlog_is_on.cc
index 4396aa8d066..cd7fc19bca8 100644
--- a/extern/libmv/third_party/glog/src/vlog_is_on.cc
+++ b/extern/libmv/third_party/glog/src/vlog_is_on.cc
@@ -40,8 +40,8 @@
#include <cstdio>
#include <string>
#include "base/commandlineflags.h"
-#include <glog/logging.h>
-#include <glog/raw_logging.h>
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
#include "base/googleinit.h"
// glog doesn't have annotation
@@ -62,11 +62,7 @@ _START_GOOGLE_NAMESPACE_
namespace glog_internal_namespace_ {
-// Put protytype here to suppress strict compiler flags
-GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern,
- size_t patt_len,
- const char* str,
- size_t str_len);
+namespace {
// Implementation of fnmatch that does not need 0-termination
// of arguments and does not allocate any memory,
@@ -101,6 +97,8 @@ GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern,
}
}
+} // namespace
+
} // namespace glog_internal_namespace_
using glog_internal_namespace_::SafeFNMatch_;
diff --git a/extern/libmv/third_party/glog/src/windows/config.h b/extern/libmv/third_party/glog/src/windows/config.h
index 682a1b9309d..9fb3cc564d5 100644
--- a/extern/libmv/third_party/glog/src/windows/config.h
+++ b/extern/libmv/third_party/glog/src/windows/config.h
@@ -1,122 +1,10 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
-/* Namespace for Google classes */
-#define GOOGLE_NAMESPACE google
-
-/* Define if you have the `dladdr' function */
-#undef HAVE_DLADDR
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the <execinfo.h> header file. */
-#undef HAVE_EXECINFO_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <libunwind.h> header file. */
-#undef HAVE_LIBUNWIND_H
-
/* define if you have google gflags library */
#define HAVE_LIB_GFLAGS 1
-/* define if you have libunwind */
-#undef HAVE_LIB_UNWIND
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* define if the compiler implements namespaces */
-#undef HAVE_NAMESPACES
-
-/* Define if you have POSIX threads libraries and header files. */
-#undef HAVE_PTHREAD
-
-/* define if the compiler implements pthread_rwlock_* */
-#undef HAVE_RWLOCK
-
-/* Define if you have the `sigaltstack' function */
-#undef HAVE_SIGALTSTACK
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <syscall.h> header file. */
-#undef HAVE_SYSCALL_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/syscall.h> header file. */
-#undef HAVE_SYS_SYSCALL_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <ucontext.h> header file. */
-#undef HAVE_UCONTEXT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* define if the compiler supports using expression for operator */
-#undef HAVE_USING_OPERATOR
-
-/* define if your compiler has __attribute__ */
-#undef HAVE___ATTRIBUTE__
-
-/* define if your compiler has __builtin_expect */
-#undef HAVE___BUILTIN_EXPECT
-
-/* define if your compiler has __sync_val_compare_and_swap */
-#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* How to access the PC from a struct ucontext */
-#undef PC_FROM_UCONTEXT
-
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-#undef PTHREAD_CREATE_JOINABLE
-
-/* The size of `void *', as computed by sizeof. */
-#undef SIZEOF_VOID_P
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* the namespace where STL code like vector<> is defined */
-#undef STL_NAMESPACE
-
-/* Version number of package */
-#undef VERSION
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE google
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
diff --git a/extern/libmv/third_party/glog/src/windows/glog/logging.h b/extern/libmv/third_party/glog/src/windows/glog/logging.h
index f623cd9e793..6e9c9224f92 100644
--- a/extern/libmv/third_party/glog/src/windows/glog/logging.h
+++ b/extern/libmv/third_party/glog/src/windows/glog/logging.h
@@ -43,18 +43,13 @@
#include <errno.h>
#include <string.h>
#include <time.h>
+#include <iosfwd>
+#include <ostream>
+#include <sstream>
#include <string>
#if 0
# include <unistd.h>
#endif
-#ifdef __DEPRECATED
-// Make GCC quiet.
-# undef __DEPRECATED
-# include <strstream>
-# define __DEPRECATED
-#else
-# include <strstream>
-#endif
#include <vector>
// Annoying stuff for windows -- makes sure clients can import these functions
@@ -65,6 +60,14 @@
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
+#if defined(_MSC_VER)
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
+ __pragma(warning(disable:n))
+#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
+#else
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
+#define GLOG_MSVC_POP_WARNING()
+#endif
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
@@ -83,7 +86,7 @@
#endif
#if 1
-#include "third_party/gflags/gflags/gflags.h"
+#include <gflags/gflags.h>
#endif
#ifdef __MINGW32__
@@ -97,7 +100,7 @@
namespace google {
-#if 0 // the C99 format
+#if defined(__MINGW32__) // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
@@ -107,16 +110,11 @@ typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
-#elif defined(__MINGW32__)
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
@@ -144,8 +142,12 @@ typedef uint64_t uint64;
#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
#if 0
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#else
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#define GOOGLE_PREDICT_FALSE(x) x
+#define GOOGLE_PREDICT_TRUE(x) x
#endif
#endif
@@ -304,27 +306,27 @@ typedef uint64_t uint64;
#ifndef DECLARE_VARIABLE
#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
-#define DECLARE_VARIABLE(type, name, tn) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
- extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+#define DECLARE_VARIABLE(type, shorttype, name, tn) \
+ namespace fL##shorttype { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using fL##shorttype::FLAGS_##name
// bool specialization
#define DECLARE_bool(name) \
- DECLARE_VARIABLE(bool, name, bool)
+ DECLARE_VARIABLE(bool, B, name, bool)
// int32 specialization
#define DECLARE_int32(name) \
- DECLARE_VARIABLE(google::int32, name, int32)
+ DECLARE_VARIABLE(google::int32, I, name, int32)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
-#define DECLARE_string(name) \
- namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
- extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
- } \
- using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#define DECLARE_string(name) \
+ namespace fLS { \
+ extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \
+ } \
+ using fLS::FLAGS_##name
#endif
// Set whether log messages go to stderr instead of logfiles
@@ -333,6 +335,9 @@ DECLARE_bool(logtostderr);
// Set whether log messages go to stderr in addition to logfiles.
DECLARE_bool(alsologtostderr);
+// Set color messages logged to stderr (if supported by terminal).
+DECLARE_bool(colorlogtostderr);
+
// Log messages at a level >= this flag are automatically sent to
// stderr in addition to log files.
DECLARE_int32(stderrthreshold);
@@ -465,15 +470,16 @@ DECLARE_bool(stop_logging_if_full_disk);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
// A very useful logging macro to log windows errors:
#define LOG_SYSRESULT(result) \
- if (FAILED(result)) { \
- LPTSTR message = NULL; \
- LPTSTR msg = reinterpret_cast<LPTSTR>(&message); \
- DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+ if (FAILED(HRESULT_FROM_WIN32(result))) { \
+ LPSTR message = NULL; \
+ LPSTR msg = reinterpret_cast<LPSTR>(&message); \
+ DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM, \
0, result, 0, msg, 100, NULL); \
if (message_length > 0) { \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \
- &google::LogMessage::SendToLog).stream() << message; \
+ &google::LogMessage::SendToLog).stream() \
+ << reinterpret_cast<const char*>(message); \
LocalFree(message); \
} \
}
@@ -615,18 +621,68 @@ inline std::ostream& operator<<(
namespace google {
-// Build the error message string.
-template<class t1, class t2>
-std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
- // It means that we cannot use stl_logging if compiler doesn't
- // support using expression for operator.
- // TODO(hamaji): Figure out a way to fix.
-#if 1
- using ::operator<<;
-#endif
- std::strstream ss;
- ss << names << " (" << v1 << " vs. " << v2 << ")";
- return new std::string(ss.str(), ss.pcount());
+// This formats a value for a failing CHECK_XX statement. Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+template <typename T>
+inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
+ (*os) << v;
+}
+
+// Overrides for char types provide readable values for unprintable
+// characters.
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const signed char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
+
+// Build the error message string. Specify no inlining for code size.
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
+ ;
+
+namespace base {
+namespace internal {
+
+// If "s" is less than base_logging::INFO, returns base_logging::INFO.
+// If "s" is greater than base_logging::FATAL, returns
+// base_logging::ERROR. Otherwise, returns "s".
+LogSeverity NormalizeSeverity(LogSeverity s);
+
+} // namespace internal
+
+// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
+// statement. See MakeCheckOpString for sample usage. Other
+// approaches were considered: use of a template method (e.g.,
+// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
+// base::Print<T2>, &v2), however this approach has complications
+// related to volatile arguments and function-pointer arguments).
+class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder {
+ public:
+ // Inserts "exprtext" and " (" to the stream.
+ explicit CheckOpMessageBuilder(const char *exprtext);
+ // Deletes "stream_".
+ ~CheckOpMessageBuilder();
+ // For inserting the first variable.
+ std::ostream* ForVar1() { return stream_; }
+ // For inserting the second variable (adds an intermediate " vs. ").
+ std::ostream* ForVar2();
+ // Get the result (inserts the closing ")").
+ std::string* NewString();
+
+ private:
+ std::ostringstream *stream_;
+};
+
+} // namespace base
+
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
+ base::CheckOpMessageBuilder comb(exprtext);
+ MakeCheckOpValueString(comb.ForVar1(), v1);
+ MakeCheckOpValueString(comb.ForVar2(), v2);
+ return comb.NewString();
}
// Helper functions for CHECK_OP macro.
@@ -634,26 +690,26 @@ std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
// will not instantiate the template version of the function on values of
// unnamed enum type - see comment below.
#define DEFINE_CHECK_OP_IMPL(name, op) \
- template <class t1, class t2> \
- inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
- const char* names) { \
- if (v1 op v2) return NULL; \
- else return MakeCheckOpString(v1, v2, names); \
+ template <typename T1, typename T2> \
+ inline std::string* name##Impl(const T1& v1, const T2& v2, \
+ const char* exprtext) { \
+ if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \
+ else return MakeCheckOpString(v1, v2, exprtext); \
} \
- inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
- return Check##name##Impl<int, int>(v1, v2, names); \
+ inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \
+ return name##Impl<int, int>(v1, v2, exprtext); \
}
-// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h
-// provides its own #defines for the simpler names EQ, NE, LE, etc.
+// We use the full name Check_EQ, Check_NE, etc. in case the file including
+// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
// This happens if, for example, those are used as token names in a
// yacc grammar.
-DEFINE_CHECK_OP_IMPL(_EQ, ==)
-DEFINE_CHECK_OP_IMPL(_NE, !=)
-DEFINE_CHECK_OP_IMPL(_LE, <=)
-DEFINE_CHECK_OP_IMPL(_LT, < )
-DEFINE_CHECK_OP_IMPL(_GE, >=)
-DEFINE_CHECK_OP_IMPL(_GT, > )
+DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)?
+DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead.
+DEFINE_CHECK_OP_IMPL(Check_LE, <=)
+DEFINE_CHECK_OP_IMPL(Check_LT, < )
+DEFINE_CHECK_OP_IMPL(Check_GE, >=)
+DEFINE_CHECK_OP_IMPL(Check_GT, > )
#undef DEFINE_CHECK_OP_IMPL
// Helper macro for binary operators.
@@ -958,52 +1014,65 @@ const LogSeverity GLOG_0 = GLOG_ERROR;
#define DLOG_ASSERT(condition) \
true ? (void) 0 : LOG_ASSERT(condition)
+// MSVC warning C4127: conditional expression is constant
#define DCHECK(condition) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK(condition)
+ GLOG_MSVC_POP_WARNING() CHECK(condition)
#define DCHECK_EQ(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_EQ(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_NE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_LE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_LT(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_GE(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_GT(val1, val2)
+ GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
+// You may see warnings in release mode if you don't use the return
+// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
#define DCHECK_NOTNULL(val) (val)
#define DCHECK_STREQ(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STREQ(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
#define DCHECK_STRCASEEQ(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRCASEEQ(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
#define DCHECK_STRNE(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRNE(str1, str2)
+ GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
#define DCHECK_STRCASENE(str1, str2) \
+ GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) \
- CHECK_STRCASENE(str1, str2)
-
+ GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
#endif // NDEBUG
@@ -1020,6 +1089,29 @@ const LogSeverity GLOG_0 = GLOG_ERROR;
#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+namespace base_logging {
+
+// LogMessage::LogStream is a std::ostream backed by this streambuf.
+// This class ignores overflow and leaves two bytes at the end of the
+// buffer to allow for a '\n' and '\0'.
+class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf {
+ public:
+ // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'.
+ LogStreamBuf(char *buf, int len) {
+ setp(buf, buf + len - 2);
+ }
+ // This effectively ignores overflow.
+ virtual int_type overflow(int_type ch) {
+ return ch;
+ }
+
+ // Legacy public ostrstream method.
+ size_t pcount() const { return pptr() - pbase(); }
+ char* pbase() const { return std::streambuf::pbase(); }
+};
+
+} // namespace base_logging
+
//
// This class more or less represents a particular log message. You
// create an instance of LogMessage and then stream stuff to it.
@@ -1049,22 +1141,30 @@ public:
#ifdef _MSC_VER
# pragma warning(disable: 4275)
#endif
- class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream {
+ class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream {
#ifdef _MSC_VER
# pragma warning(default: 4275)
#endif
public:
- LogStream(char *buf, int len, int ctr_in)
- : ostrstream(buf, len),
- ctr_(ctr_in) {
- self_ = this;
+ LogStream(char *buf, int len, int ctr)
+ : std::ostream(NULL),
+ streambuf_(buf, len),
+ ctr_(ctr),
+ self_(this) {
+ rdbuf(&streambuf_);
}
int ctr() const { return ctr_; }
- void set_ctr(int ctr_in) { ctr_ = ctr_in; }
+ void set_ctr(int ctr) { ctr_ = ctr; }
LogStream* self() const { return self_; }
+ // Legacy std::streambuf methods.
+ size_t pcount() const { return streambuf_.pcount(); }
+ char* pbase() const { return streambuf_.pbase(); }
+ char* str() const { return pbase(); }
+
private:
+ base_logging::LogStreamBuf streambuf_;
int ctr_; // Counter hack (for the LOG_EVERY_X() macro)
LogStream *self_; // Consistency check hack
};
@@ -1133,13 +1233,15 @@ public:
// Call abort() or similar to perform LOG(FATAL) crash.
static void Fail() ;
- std::ostream& stream() { return *(data_->stream_); }
+ std::ostream& stream();
- int preserved_errno() const { return data_->preserved_errno_; }
+ int preserved_errno() const;
// Must be called without the log_mutex held. (L < log_mutex)
static int64 num_messages(int severity);
+ struct LogMessageData;
+
private:
// Fully internal SendMethod cases:
void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs
@@ -1161,41 +1263,6 @@ private:
// We keep the data in a separate struct so that each instance of
// LogMessage uses less stack space.
- struct GOOGLE_GLOG_DLL_DECL LogMessageData {
- LogMessageData() {};
-
- int preserved_errno_; // preserved errno
- char* buf_;
- char* message_text_; // Complete message text (points to selected buffer)
- LogStream* stream_alloc_;
- LogStream* stream_;
- char severity_; // What level is this LogMessage logged at?
- int line_; // line number where logging call is.
- void (LogMessage::*send_method_)(); // Call this in destructor to send
- union { // At most one of these is used: union to keep the size low.
- LogSink* sink_; // NULL or sink to send message to
- std::vector<std::string>* outvec_; // NULL or vector to push message onto
- std::string* message_; // NULL or string to write message into
- };
- time_t timestamp_; // Time of creation of LogMessage
- struct ::tm tm_time_; // Time of creation of LogMessage
- size_t num_prefix_chars_; // # of chars of prefix in this message
- size_t num_chars_to_log_; // # of chars of msg to send to log
- size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
- const char* basename_; // basename of file that called LOG
- const char* fullname_; // fullname of file that called LOG
- bool has_been_flushed_; // false => data has not been flushed
- bool first_fatal_; // true => this was first fatal msg
-
- ~LogMessageData();
- private:
- LogMessageData(const LogMessageData&);
- void operator=(const LogMessageData&);
- };
-
- static LogMessageData fatal_msg_data_exclusive_;
- static LogMessageData fatal_msg_data_shared_;
-
LogMessageData* allocated_;
LogMessageData* data_;
@@ -1474,8 +1541,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
// be set to an empty string, if this function failed. This means, in most
// cases, you do not need to check the error code and you can directly
// use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
// A class for which we define operator<<, which does nothing.
class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
diff --git a/extern/libmv/third_party/glog/src/windows/port.cc b/extern/libmv/third_party/glog/src/windows/port.cc
index 58e28b026c0..c16111a4b6d 100644
--- a/extern/libmv/third_party/glog/src/windows/port.cc
+++ b/extern/libmv/third_party/glog/src/windows/port.cc
@@ -55,7 +55,6 @@ int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
return _vsnprintf(str, size-1, format, ap);
}
-// MinGW64 defines
#ifndef __MINGW64__
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
diff --git a/extern/libmv/third_party/glog/src/windows/port.h b/extern/libmv/third_party/glog/src/windows/port.h
index e3e76ec29e0..4879cbf5f92 100644
--- a/extern/libmv/third_party/glog/src/windows/port.h
+++ b/extern/libmv/third_party/glog/src/windows/port.h
@@ -45,7 +45,10 @@
#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
+#endif
+
#include <windows.h>
#include <winsock.h> /* for gethostname */
#include <io.h> /* because we so often use open/close/etc */
@@ -59,6 +62,8 @@
* used by both C and C++ code, so we put all the C++ together.
*/
+#ifdef _MSC_VER
+
/* 4244: otherwise we get problems when substracting two size_t's to an int
* 4251: it's complaining about a private struct I've chosen not to dllexport
* 4355: we use this in a constructor, but we do it safely
@@ -111,9 +116,7 @@ extern int snprintf(char *str, size_t size,
extern int safe_vsnprintf(char *str, size_t size,
const char *format, va_list ap);
#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
-#if !defined(__MINGW32__)
#define va_copy(dst, src) (dst) = (src)
-#endif
/* Windows doesn't support specifying the number of buckets as a
* hash_map constructor arg, so we leave this blank.
@@ -123,11 +126,14 @@ extern int safe_vsnprintf(char *str, size_t size,
#define DEFAULT_TEMPLATE_ROOTDIR ".."
// ----------------------------------- SYSTEM/PROCESS
-#ifndef __MINGW64__
typedef int pid_t;
-#endif
#define getpid _getpid
+#include <BaseTsd.h>
+typedef SSIZE_T ssize_t;
+
+#endif // _MSC_VER
+
// ----------------------------------- THREADS
typedef DWORD pthread_t;
typedef DWORD pthread_key_t;
diff --git a/extern/libmv/third_party/glog/src/windows/preprocess.sh b/extern/libmv/third_party/glog/src/windows/preprocess.sh
index ea4352e8e3a..ea4352e8e3a 100755..100644
--- a/extern/libmv/third_party/glog/src/windows/preprocess.sh
+++ b/extern/libmv/third_party/glog/src/windows/preprocess.sh
diff --git a/extern/rangetree/range_tree.hh b/extern/rangetree/range_tree.hh
index a88c70281b6..919e0b04933 100644
--- a/extern/rangetree/range_tree.hh
+++ b/extern/rangetree/range_tree.hh
@@ -79,10 +79,6 @@ struct RangeTree {
TreeIter iter = tree.find(Range(t));
assert(iter != tree.end());
Range cur = *iter;
- TreeIter prev = iter;
- TreeIter next = iter;
- --prev;
- ++next;
/* Remove the original range (note that this does not
invalidate the prev/next iterators) */
diff --git a/intern/SConscript b/intern/SConscript
index 828c1adc20d..20803884a39 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -53,9 +53,6 @@ if env['WITH_BF_FLUID']:
if env['WITH_BF_CYCLES']:
SConscript(['cycles/SConscript'])
-if env['WITH_BF_BOOLEAN']:
- SConscript(['bsp/SConscript'])
-
if env['WITH_BF_INTERNATIONAL']:
SConscript(['locale/SConscript'])
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index c3877c2c9f2..d055c131183 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -994,7 +994,7 @@ void AUD_OpenALDevice::updateStreams()
if(info != AL_PLAYING)
{
// if it really stopped
- if(sound->m_eos)
+ if(sound->m_eos && info != AL_INITIAL)
{
if(sound->m_stop)
sound->m_stop(sound->m_stop_data);
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index d8f0d837fec..d30835da4e5 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -169,14 +169,29 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(!codec)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
+ if(codec->sample_fmts) {
+ // Check if the prefered sample format for this codec is supported.
+ const enum AVSampleFormat *p = codec->sample_fmts;
+ for(; *p != -1; p++) {
+ if(*p == m_stream->codec->sample_fmt)
+ break;
+ }
+ if(*p == -1) {
+ // Sample format incompatible with codec. Defaulting to a format known to work.
+ m_stream->codec->sample_fmt = codec->sample_fmts[0];
+ }
+ }
+
if(avcodec_open2(m_codecCtx, codec, NULL))
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
int samplesize = AUD_MAX(AUD_SAMPLE_SIZE(m_specs), AUD_DEVICE_SAMPLE_SIZE(m_specs));
- if(m_codecCtx->frame_size <= 1)
- m_input_size = 0;
+ if(m_codecCtx->frame_size <= 1) {
+ m_input_size = FF_MIN_BUFFER_SIZE * 8 / m_codecCtx->bits_per_coded_sample / m_codecCtx->channels;
+ m_input_buffer.resize(m_input_size * samplesize);
+ }
else
{
m_input_buffer.resize(m_codecCtx->frame_size * samplesize);
@@ -187,14 +202,21 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
m_frame = av_frame_alloc();
if (!m_frame)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
+ avcodec_get_frame_defaults(m_frame);
m_frame->linesize[0] = m_input_size * samplesize;
m_frame->format = m_codecCtx->sample_fmt;
+ m_frame->nb_samples = m_input_size;
# ifdef FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
m_frame->sample_rate = m_codecCtx->sample_rate;
# endif
# ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
m_frame->channel_layout = m_codecCtx->channel_layout;
# endif
+ m_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt);
+ m_frame_pts = 0;
+ m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+ if(m_deinterleave)
+ m_deinterleave_buffer.resize(m_input_size * m_codecCtx->channels * m_sample_size);
#endif
try
@@ -272,13 +294,31 @@ void AUD_FFMPEGWriter::encode(sample_t* data)
#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
int got_output, ret;
+ m_frame->pts = m_frame_pts / av_q2d(m_codecCtx->time_base);
+ m_frame_pts++;
+#ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
+ m_frame->channel_layout = m_codecCtx->channel_layout;
+#endif
+
+ if(m_deinterleave) {
+ for(int channel = 0; channel < m_codecCtx->channels; channel++) {
+ for(int i = 0; i < m_frame->nb_samples; i++) {
+ memcpy(reinterpret_cast<uint8_t*>(m_deinterleave_buffer.getBuffer()) + (i + channel * m_frame->nb_samples) * m_sample_size,
+ reinterpret_cast<uint8_t*>(data) + (m_codecCtx->channels * i + channel) * m_sample_size, m_sample_size);
+ }
+ }
+
+ data = m_deinterleave_buffer.getBuffer();
+ }
+
+ avcodec_fill_audio_frame(m_frame, m_codecCtx->channels, m_codecCtx->sample_fmt, reinterpret_cast<uint8_t*>(data),
+ m_frame->nb_samples * av_get_bytes_per_sample(m_codecCtx->sample_fmt) * m_codecCtx->channels, 1);
- m_frame->data[0] = reinterpret_cast<uint8_t*>(data);
ret = avcodec_encode_audio2(m_codecCtx, &packet, m_frame, &got_output);
- if (ret < 0)
+ if(ret < 0)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
- if (!got_output)
+ if(!got_output)
return;
#else
sample_t* outbuf = m_output_buffer.getBuffer();
@@ -290,10 +330,23 @@ void AUD_FFMPEGWriter::encode(sample_t* data)
packet.data = reinterpret_cast<uint8_t*>(outbuf);
#endif
+ if(packet.pts != AV_NOPTS_VALUE)
+ packet.pts = av_rescale_q(packet.pts, m_codecCtx->time_base, m_stream->time_base);
+ if(packet.dts != AV_NOPTS_VALUE)
+ packet.dts = av_rescale_q(packet.dts, m_codecCtx->time_base, m_stream->time_base);
+ if(packet.duration > 0)
+ packet.duration = av_rescale_q(packet.duration, m_codecCtx->time_base, m_stream->time_base);
+
packet.stream_index = m_stream->index;
- if(av_interleaved_write_frame(m_formatCtx, &packet))
+ packet.flags |= AV_PKT_FLAG_KEY;
+
+ if(av_interleaved_write_frame(m_formatCtx, &packet)) {
+ av_free_packet(&packet);
AUD_THROW(AUD_ERROR_FFMPEG, write_error);
+ }
+
+ av_free_packet(&packet);
}
void AUD_FFMPEGWriter::write(unsigned int length, sample_t* buffer)
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
index 310f69258ea..492aa35ff12 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
@@ -83,6 +83,23 @@ private:
AVFrame *m_frame;
/**
+ * PTS of next frame to write.
+ */
+ int m_frame_pts;
+
+ /**
+ * Number of bytes per sample.
+ */
+ int m_sample_size;
+
+ /**
+ * Need to de-interleave audio for planar sample formats.
+ */
+ bool m_deinterleave;
+
+ AUD_Buffer m_deinterleave_buffer;
+
+ /**
* The input buffer for the format converted data before encoding.
*/
AUD_Buffer m_input_buffer;
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
index 61adae4b34b..9f399a0b99f 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
@@ -47,6 +47,23 @@ AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
pthread_mutexattr_destroy(&attr);
}
+AUD_AnimateableProperty::AUD_AnimateableProperty(int count, float value) :
+ AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
+{
+ sample_t* buf = getBuffer();
+
+ for(int i = 0; i < count; i++)
+ buf[i] = value;
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&m_mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+}
+
void AUD_AnimateableProperty::updateUnknownCache(int start, int end)
{
float* buf = getBuffer();
@@ -104,7 +121,8 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count)
if(pos == 0)
{
- memset(buf, 0, position * m_count * sizeof(float));
+ for(int i = 0; i < position; i++)
+ memcpy(buf + i * m_count, data, m_count * sizeof(float));
}
else
updateUnknownCache(pos, position - 1);
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h
index 37eb8f84550..f07e5916b25 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.h
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.h
@@ -76,6 +76,13 @@ public:
AUD_AnimateableProperty(int count = 1);
/**
+ * Creates a new animateable property.
+ * \param count The count of floats for a single property.
+ * \param count The value that the property should get initialized with. All count floats will be initialized to the same value.
+ */
+ AUD_AnimateableProperty(int count, float value);
+
+ /**
* Destroys the animateable property.
*/
~AUD_AnimateableProperty();
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
index 1ffcf6c4ef0..7817ee88c07 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.h
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.h
@@ -34,12 +34,11 @@
#include <cstring>
#ifdef _MSC_VER
-#if (_MSC_VER < 1300)
+#if (_MSC_VER <= 1500)
typedef short int16_t;
typedef int int32_t;
#else
- typedef __int16 int16_t;
- typedef __int32 int32_t;
+# include <stdint.h>
#endif
#else
#include <stdint.h>
diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp
index c59c56a4479..6c5e48c73f0 100644
--- a/intern/audaspace/intern/AUD_Sequencer.cpp
+++ b/intern/audaspace/intern/AUD_Sequencer.cpp
@@ -42,6 +42,7 @@ AUD_Sequencer::AUD_Sequencer(AUD_Specs specs, float fps, bool muted) :
m_speed_of_sound(434),
m_doppler_factor(1),
m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
+ m_volume(1, 1.0f),
m_location(3),
m_orientation(4)
{
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.cpp b/intern/audaspace/intern/AUD_SequencerEntry.cpp
index 005557bbed1..6ef8479cdb8 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.cpp
+++ b/intern/audaspace/intern/AUD_SequencerEntry.cpp
@@ -53,6 +53,8 @@ AUD_SequencerEntry::AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, fl
m_cone_angle_outer(360),
m_cone_angle_inner(360),
m_cone_volume_outer(0),
+ m_volume(1, 1.0f),
+ m_pitch(1, 1.0f),
m_location(3),
m_orientation(4)
{
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 5c8d68b07ee..a1b0030491e 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -1,4 +1,3 @@
-
# Standalone or with Blender
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
set(CYCLES_INSTALL_PATH "")
@@ -13,8 +12,11 @@ include(cmake/external_libs.cmake)
# Build Flags
# todo: refactor this code to match scons
+# note: CXX_HAS_SSE is needed in case passing SSE flags fails altogether (gcc-arm)
if(WIN32 AND MSVC)
+ set(CXX_HAS_SSE TRUE)
+
# /arch:AVX for VC2012 and above
if(NOT MSVC_VERSION LESS 1700)
set(CYCLES_AVX_ARCH_FLAGS "/arch:AVX")
@@ -24,36 +26,49 @@ if(WIN32 AND MSVC)
# there is no /arch:SSE3, but intrinsics are available anyway
if(CMAKE_CL_64)
- set(CYCLES_SSE2_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_SSE3_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_SSE41_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+ set(CYCLES_SSE2_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_SSE41_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
else()
- set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_SSE41_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
- set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+ set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_SSE41_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
+ set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
endif()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox")
elseif(CMAKE_COMPILER_IS_GNUCC)
- set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
- set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse")
- set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mfpmath=sse")
- set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mfpmath=sse")
+ check_cxx_compiler_flag(-msse CXX_HAS_SSE)
+ if(CXX_HAS_SSE)
+ set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
+ set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse")
+ set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mfpmath=sse")
+ set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mfpmath=sse")
+ endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2")
- set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3")
- set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1")
- set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx")
+ check_cxx_compiler_flag(-msse CXX_HAS_SSE)
+ if(CXX_HAS_SSE)
+ set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2")
+ set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3")
+ set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1")
+ set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx")
+ endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
-add_definitions(-DWITH_KERNEL_SSE2 -DWITH_KERNEL_SSE3 -DWITH_KERNEL_SSE41 -DWITH_KERNEL_AVX)
+if(CXX_HAS_SSE)
+ add_definitions(
+ -DWITH_KERNEL_SSE2
+ -DWITH_KERNEL_SSE3
+ -DWITH_KERNEL_SSE41
+ -DWITH_KERNEL_AVX
+ )
+endif()
# for OSL
if(WIN32 AND MSVC)
@@ -64,10 +79,15 @@ endif()
# Definitions and Includes
-add_definitions(${BOOST_DEFINITIONS} ${OPENIMAGEIO_DEFINITIONS})
+add_definitions(
+ ${BOOST_DEFINITIONS}
+ ${OPENIMAGEIO_DEFINITIONS}
+)
-add_definitions(-DCCL_NAMESPACE_BEGIN=namespace\ ccl\ {)
-add_definitions(-DCCL_NAMESPACE_END=})
+add_definitions(
+ -DCCL_NAMESPACE_BEGIN=namespace\ ccl\ {
+ -DCCL_NAMESPACE_END=}
+)
if(WITH_CYCLES_NETWORK)
add_definitions(-DWITH_NETWORK)
@@ -91,9 +111,11 @@ if(WITH_CYCLES_OSL)
include_directories(${OSL_INCLUDES})
endif()
-add_definitions(-DWITH_OPENCL)
-add_definitions(-DWITH_CUDA)
-add_definitions(-DWITH_MULTI)
+add_definitions(
+ -DWITH_OPENCL
+ -DWITH_CUDA
+ -DWITH_MULTI
+)
include_directories(
SYSTEM
@@ -101,7 +123,16 @@ include_directories(
${OPENIMAGEIO_INCLUDE_DIRS}
${OPENIMAGEIO_INCLUDE_DIRS}/OpenImageIO
${OPENEXR_INCLUDE_DIR}
- ${OPENEXR_INCLUDE_DIRS})
+ ${OPENEXR_INCLUDE_DIRS}
+)
+
+
+# Warnings
+if(CMAKE_COMPILER_IS_GNUCXX)
+ ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
+ unset(_has_cxxflag_float_conversion)
+endif()
+
# Subdirectories
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index b8c731e3315..532238b9d7e 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -72,6 +72,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
else:
cxxflags.append('-ffast-math'.split())
+# Warnings
+# XXX Not supported by gcc < 4.9, since we do not have any 'supported flags' test as in cmake,
+# simpler to comment for now.
+#if env['C_COMPILER_ID'] == 'gcc':
+# cxxflags.append(['-Werror=float-conversion'])
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs.append(env['BF_PTHREADS_INC'])
@@ -81,12 +87,12 @@ kernel_flags = {}
if env['OURPLATFORM'] == 'win32-vc':
# there is no /arch:SSE3, but intrinsics are available anyway
- kernel_flags['sse2'] = '/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'
+ kernel_flags['sse2'] = '/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /GS-'
kernel_flags['sse3'] = kernel_flags['sse2']
elif env['OURPLATFORM'] == 'win64-vc':
# /arch:AVX only available from visual studio 2012
- kernel_flags['sse2'] = '-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'
+ kernel_flags['sse2'] = '-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /GS-'
kernel_flags['sse3'] = kernel_flags['sse2']
if env['MSVC_VERSION'] in ('11.0', '12.0'):
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index 230833802b0..7ea1ca2d8fb 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -46,7 +46,8 @@ struct Options {
int width, height;
SceneParams scene_params;
SessionParams session_params;
- bool quiet, show_help, interactive;
+ bool quiet;
+ bool show_help, interactive, pause;
} options;
static void session_print(const string& str)
@@ -114,15 +115,25 @@ static void session_init()
options.scene = NULL;
}
-static void scene_init(int width, int height)
+static void scene_init()
{
options.scene = new Scene(options.scene_params, options.session_params.device);
+
+ /* Read XML */
xml_read_file(options.scene, options.filepath.c_str());
- if (width == 0 || height == 0) {
+ /* Camera width/height override? */
+ if (!(options.width == 0 || options.height == 0)) {
+ options.scene->camera->width = options.width;
+ options.scene->camera->height = options.height;
+ }
+ else {
options.width = options.scene->camera->width;
options.height = options.scene->camera->height;
}
+
+ /* Calculate Viewplane */
+ options.scene->camera->compute_auto_viewplane();
}
static void session_exit()
@@ -166,8 +177,14 @@ static void display_info(Progress& progress)
interactive = options.interactive? "On":"Off";
- str = string_printf("%s Time: %.2f Latency: %.4f Sample: %d Average: %.4f Interactive: %s",
- status.c_str(), total_time, latency, sample, sample_time, interactive.c_str());
+ str = string_printf(
+ "%s"
+ " Time: %.2f"
+ " Latency: %.4f"
+ " Sample: %d"
+ " Average: %.4f"
+ " Interactive: %s",
+ status.c_str(), total_time, latency, sample, sample_time, interactive.c_str());
view_display_info(str.c_str());
@@ -177,7 +194,9 @@ static void display_info(Progress& progress)
static void display()
{
- options.session->draw(session_buffer_params());
+ static DeviceDrawParams draw_params = DeviceDrawParams();
+
+ options.session->draw(session_buffer_params(), draw_params);
display_info(options.session->progress);
}
@@ -195,11 +214,11 @@ static void motion(int x, int y, int button)
/* Rotate */
else if(button == 2) {
- float4 r1= make_float4(x * 0.1f, 0.0f, 1.0f, 0.0f);
- matrix = matrix * transform_rotate(r1.x * M_PI/180.0f, make_float3(r1.y, r1.z, r1.w));
+ float4 r1 = make_float4((float)x * 0.1f, 0.0f, 1.0f, 0.0f);
+ matrix = matrix * transform_rotate(DEG2RADF(r1.x), make_float3(r1.y, r1.z, r1.w));
- float4 r2 = make_float4(y * 0.1, 1.0f, 0.0f, 0.0f);
- matrix = matrix * transform_rotate(r2.x * M_PI/180.0f, make_float3(r2.y, r2.z, r2.w));
+ float4 r2 = make_float4(y * 0.1f, 1.0f, 0.0f, 0.0f);
+ matrix = matrix * transform_rotate(DEG2RADF(r2.x), make_float3(r2.y, r2.z, r2.w));
}
/* Update and Reset */
@@ -216,20 +235,64 @@ static void resize(int width, int height)
options.width = width;
options.height = height;
- if(options.session)
+ if(options.session) {
+ /* Update camera */
+ options.session->scene->camera->width = width;
+ options.session->scene->camera->height = height;
+ options.session->scene->camera->compute_auto_viewplane();
+ options.session->scene->camera->need_update = true;
+ options.session->scene->camera->need_device_update = true;
+
options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
}
static void keyboard(unsigned char key)
{
- if(key == 'r')
- options.session->reset(session_buffer_params(), options.session_params.samples);
- else if(key == 'h')
+ /* Toggle help */
+ if(key == 'h')
options.show_help = !(options.show_help);
- else if(key == 'i')
- options.interactive = !(options.interactive);
+
+ /* Reset */
+ else if(key == 'r')
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+
+ /* Cancel */
else if(key == 27) // escape
options.session->progress.set_cancel("Canceled");
+
+ /* Pause */
+ else if(key == 'p') {
+ options.pause = !options.pause;
+ options.session->set_pause(options.pause);
+ }
+
+ /* Interactive Mode */
+ else if(key == 'i')
+ options.interactive = !(options.interactive);
+
+ else if(options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
+ Transform matrix = options.session->scene->camera->matrix;
+ float3 translate;
+
+ if(key == 'w')
+ translate = make_float3(0.0f, 0.0f, 0.1f);
+ else if(key == 's')
+ translate = make_float3(0.0f, 0.0f, -0.1f);
+ else if(key == 'a')
+ translate = make_float3(-0.1f, 0.0f, 0.0f);
+ else if(key == 'd')
+ translate = make_float3(0.1f, 0.0f, 0.0f);
+
+ matrix = matrix * transform_translate(translate);
+
+ /* Update and Reset */
+ options.session->scene->camera->matrix = matrix;
+ options.session->scene->camera->need_update = true;
+ options.session->scene->camera->need_device_update = true;
+
+ options.session->reset(session_buffer_params(), options.session_params.samples);
+ }
}
#endif
@@ -314,15 +377,13 @@ static void options_parse(int argc, const char **argv)
else if(ssname == "svm")
options.scene_params.shadingsystem = SceneParams::SVM;
-#ifdef WITH_CYCLES_STANDALONE_GUI
- /* Progressive rendering for GUI */
- if(!options.session_params.background)
- options.session_params.progressive = true;
-#else
- /* When building without GUI, set background */
+#ifndef WITH_CYCLES_STANDALONE_GUI
options.session_params.background = true;
#endif
+ /* Use progressive rendering */
+ options.session_params.progressive = true;
+
/* find matching device */
DeviceType device_type = Device::type_from_string(devicename.c_str());
vector<DeviceInfo>& devices = Device::available_devices();
@@ -360,12 +421,12 @@ static void options_parse(int argc, const char **argv)
fprintf(stderr, "No file path specified\n");
exit(EXIT_FAILURE);
}
-
+
/* For smoother Viewport */
options.session_params.start_resolution = 64;
/* load scene */
- scene_init(options.width, options.height);
+ scene_init();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 14fe43115d5..d5ef30e5c6f 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -105,7 +105,7 @@ static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
pugi::xml_attribute attr = node.attribute(name);
if(attr) {
- *value = atof(attr.value());
+ *value = (float)atof(attr.value());
return true;
}
@@ -121,7 +121,7 @@ static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, cons
string_split(tokens, attr.value());
foreach(const string& token, tokens)
- value.push_back(atof(token.c_str()));
+ value.push_back((float)atof(token.c_str()));
return true;
}
@@ -219,6 +219,35 @@ static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, co
return false;
}
+static ShaderSocketType xml_read_socket_type(pugi::xml_node node, const char *name)
+{
+ pugi::xml_attribute attr = node.attribute(name);
+
+ if(attr) {
+ string value = attr.value();
+ if (string_iequals(value, "float"))
+ return SHADER_SOCKET_FLOAT;
+ else if (string_iequals(value, "int"))
+ return SHADER_SOCKET_INT;
+ else if (string_iequals(value, "color"))
+ return SHADER_SOCKET_COLOR;
+ else if (string_iequals(value, "vector"))
+ return SHADER_SOCKET_VECTOR;
+ else if (string_iequals(value, "point"))
+ return SHADER_SOCKET_POINT;
+ else if (string_iequals(value, "normal"))
+ return SHADER_SOCKET_NORMAL;
+ else if (string_iequals(value, "closure color"))
+ return SHADER_SOCKET_CLOSURE;
+ else if (string_iequals(value, "string"))
+ return SHADER_SOCKET_STRING;
+ else
+ fprintf(stderr, "Unknown shader socket type \"%s\" for attribute \"%s\".\n", value.c_str(), name);
+ }
+
+ return SHADER_SOCKET_UNDEFINED;
+}
+
/* Film */
static void xml_read_film(const XMLReadState& state, pugi::xml_node node)
@@ -251,6 +280,8 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node)
xml_read_int(&integrator->mesh_light_samples, node, "mesh_light_samples");
xml_read_int(&integrator->subsurface_samples, node, "subsurface_samples");
xml_read_int(&integrator->volume_samples, node, "volume_samples");
+ xml_read_bool(&integrator->sample_all_lights_direct, node, "sample_all_lights_direct");
+ xml_read_bool(&integrator->sample_all_lights_indirect, node, "sample_all_lights_indirect");
}
/* Bounces */
@@ -268,6 +299,7 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node)
xml_read_bool(&integrator->transparent_shadows, node, "transparent_shadows");
/* Volume */
+ xml_read_int(&integrator->volume_homogeneous_sampling, node, "volume_homogeneous_sampling");
xml_read_float(&integrator->volume_step_size, node, "volume_step_size");
xml_read_int(&integrator->volume_max_steps, node, "volume_max_steps");
@@ -289,23 +321,8 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
xml_read_int(&cam->width, node, "width");
xml_read_int(&cam->height, node, "height");
- float aspect = (float)cam->width/(float)cam->height;
-
- if(cam->width >= cam->height) {
- cam->viewplane.left = -aspect;
- cam->viewplane.right = aspect;
- cam->viewplane.bottom = -1.0f;
- cam->viewplane.top = 1.0f;
- }
- else {
- cam->viewplane.left = -1.0f;
- cam->viewplane.right = 1.0f;
- cam->viewplane.bottom = -1.0f/aspect;
- cam->viewplane.top = 1.0f/aspect;
- }
-
if(xml_read_float(&cam->fov, node, "fov"))
- cam->fov *= M_PI/180.0f;
+ cam->fov = DEG2RADF(cam->fov);
xml_read_float(&cam->nearclip, node, "nearclip");
xml_read_float(&cam->farclip, node, "farclip");
@@ -333,7 +350,6 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
xml_read_float(&cam->sensorwidth, node, "sensorwidth");
xml_read_float(&cam->sensorheight, node, "sensorheight");
-
cam->matrix = state.tfm;
cam->need_update = true;
@@ -392,24 +408,41 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
/* Source */
xml_read_string(&osl->filepath, node, "src");
- osl->filepath = path_join(state.base, osl->filepath);
-
- /* Outputs */
- string output = "", output_type = "";
- ShaderSocketType type = SHADER_SOCKET_FLOAT;
+ if(path_is_relative(osl->filepath)) {
+ osl->filepath = path_join(state.base, osl->filepath);
+ }
- xml_read_string(&output, node, "output");
- xml_read_string(&output_type, node, "output_type");
-
- if(output_type == "float")
- type = SHADER_SOCKET_FLOAT;
- else if(output_type == "closure color")
- type = SHADER_SOCKET_CLOSURE;
- else if(output_type == "color")
- type = SHADER_SOCKET_COLOR;
-
- osl->output_names.push_back(ustring(output));
- osl->add_output(osl->output_names.back().c_str(), type);
+ /* Generate inputs/outputs from node sockets
+ *
+ * Note: ShaderInput/ShaderOutput store shallow string copies only!
+ * Socket names must be stored in the extra lists instead. */
+ /* read input values */
+ for(pugi::xml_node param = node.first_child(); param; param = param.next_sibling()) {
+ if (string_iequals(param.name(), "input")) {
+ string name;
+ if (!xml_read_string(&name, param, "name"))
+ continue;
+
+ ShaderSocketType type = xml_read_socket_type(param, "type");
+ if (type == SHADER_SOCKET_UNDEFINED)
+ continue;
+
+ osl->input_names.push_back(ustring(name));
+ osl->add_input(osl->input_names.back().c_str(), type);
+ }
+ else if (string_iequals(param.name(), "output")) {
+ string name;
+ if (!xml_read_string(&name, param, "name"))
+ continue;
+
+ ShaderSocketType type = xml_read_socket_type(param, "type");
+ if (type == SHADER_SOCKET_UNDEFINED)
+ continue;
+
+ osl->output_names.push_back(ustring(name));
+ osl->add_output(osl->output_names.back().c_str(), type);
+ }
+ }
snode = osl;
}
@@ -616,6 +649,11 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
xml_read_ustring(&attr->attribute, node, "attribute");
snode = attr;
}
+ else if(string_iequals(node.name(), "uv_map")) {
+ UVMapNode *uvm = new UVMapNode();
+ xml_read_ustring(&uvm->attribute, node, "uv_map");
+ snode = uvm;
+ }
else if(string_iequals(node.name(), "camera")) {
snode = new CameraNode();
}
@@ -734,6 +772,9 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
case SHADER_SOCKET_NORMAL:
xml_read_float3(&in->value, node, attr.name());
break;
+ case SHADER_SOCKET_STRING:
+ xml_read_ustring( &in->value_string, node, attr.name() );
+ break;
default:
break;
}
@@ -765,6 +806,8 @@ static void xml_read_shader(const XMLReadState& state, pugi::xml_node node)
static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
{
Shader *shader = state.scene->shaders[state.scene->default_background];
+
+ xml_read_bool(&shader->heterogeneous_volume, node, "heterogeneous_volume");
xml_read_shader_graph(state, shader, node);
}
@@ -846,7 +889,7 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
SubdParams sdparams(mesh, shader, smooth);
xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
- DiagSplit dsplit(sdparams);;
+ DiagSplit dsplit(sdparams);
sdmesh.tessellate(&dsplit);
}
else {
@@ -944,6 +987,26 @@ static void xml_read_light(const XMLReadState& state, pugi::xml_node node)
{
Light *light = new Light();
light->shader = state.shader;
+
+ /* Light Type
+ * 0: Point, 1: Sun, 3: Area, 5: Spot */
+ int type = 0;
+ xml_read_int(&type, node, "type");
+ light->type = (LightType)type;
+
+ /* Spot Light */
+ xml_read_float(&light->spot_angle, node, "spot_angle");
+ xml_read_float(&light->spot_smooth, node, "spot_smooth");
+
+ /* Area Light */
+ xml_read_float(&light->sizeu, node, "sizeu");
+ xml_read_float(&light->sizev, node, "sizev");
+ xml_read_float3(&light->axisu, node, "axisu");
+ xml_read_float3(&light->axisv, node, "axisv");
+
+ /* Generic */
+ xml_read_float(&light->size, node, "size");
+ xml_read_float3(&light->dir, node, "dir");
xml_read_float3(&light->co, node, "P");
light->co = transform_point(&state.tfm, light->co);
@@ -969,7 +1032,7 @@ static void xml_read_transform(pugi::xml_node node, Transform& tfm)
if(node.attribute("rotate")) {
float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
xml_read_float4(&rotate, node, "rotate");
- tfm = tfm * transform_rotate(rotate.x*M_PI/180.0f, make_float3(rotate.y, rotate.z, rotate.w));
+ tfm = tfm * transform_rotate(DEG2RADF(rotate.x), make_float3(rotate.y, rotate.z, rotate.w));
}
if(node.attribute("scale")) {
diff --git a/intern/cycles/app/cycles_xml.h b/intern/cycles/app/cycles_xml.h
index 1e3ed411312..96bc79c35d8 100644
--- a/intern/cycles/app/cycles_xml.h
+++ b/intern/cycles/app/cycles_xml.h
@@ -14,8 +14,8 @@
* limitations under the License
*/
-#ifndef __CYCLES_XML__
-#define __CYCLES_XML__
+#ifndef __CYCLES_XML_H__
+#define __CYCLES_XML_H__
CCL_NAMESPACE_BEGIN
@@ -23,7 +23,10 @@ class Scene;
void xml_read_file(Scene *scene, const char *filepath);
-CCL_NAMESPACE_END
+/* macros for importing */
+#define RAD2DEGF(_rad) ((_rad) * (float)(180.0 / M_PI))
+#define DEG2RADF(_deg) ((_deg) * (float)(M_PI / 180.0))
-#endif /* __CYCLES_XML__ */
+CCL_NAMESPACE_END
+#endif /* __CYCLES_XML_H__ */
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index 6532315cf39..2772b9ac8a7 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -14,8 +14,8 @@
* limitations under the License
*/
-#ifndef CCL_API_H
-#define CCL_API_H
+#ifndef __CCL_API_H__
+#define __CCL_API_H__
#ifdef __cplusplus
extern "C" {
@@ -40,5 +40,4 @@ void *CCL_python_module_init(void);
}
#endif
-#endif /* CCL_API_H */
-
+#endif /* __CCL_API_H__ */
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 25f91a0caea..9a60152841e 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -49,6 +49,11 @@ add_definitions(-DGLEW_STATIC)
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}")
+# avoid link failure with clang 3.4 debug
+if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only")
+endif()
+
add_dependencies(bf_intern_cycles bf_rna)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${ADDON_FILES}" ${CYCLES_INSTALL_PATH})
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index afd26945d6c..27d986900c8 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -19,7 +19,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 67, 0),
+ "blender": (2, 70, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -67,6 +67,9 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, scene):
engine.render(self)
+ def bake(self, scene, obj, pass_type, pixel_array, num_pixels, depth, result):
+ engine.bake(self, obj, pass_type, pixel_array, num_pixels, depth, result)
+
# viewport render
def view_update(self, context):
if not self.session:
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index b9ce65588df..25a9e97a99b 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -59,6 +59,12 @@ def render(engine):
_cycles.render(engine.session)
+def bake(engine, obj, pass_type, pixel_array, num_pixels, depth, result):
+ import _cycles
+ session = getattr(engine, "session", None)
+ if session is not None:
+ _cycles.bake(engine.session, obj.as_pointer(), pass_type, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+
def reset(engine, data, scene):
import _cycles
data = data.as_pointer()
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index c80e8a3250c..7205a272395 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -108,6 +108,11 @@ enum_integrator = (
('PATH', "Path Tracing", "Pure path tracing integrator"),
)
+enum_volume_homogeneous_sampling = (
+ ('DISTANCE', "Distance", "Use Distance Sampling"),
+ ('EQUI_ANGULAR', "Equi-angular", "Use Equi-angular Sampling"),
+ )
+
class CyclesRenderSettings(bpy.types.PropertyGroup):
@classmethod
@@ -141,6 +146,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='PATH',
)
+ cls.volume_homogeneous_sampling = EnumProperty(
+ name="Homogeneous Sampling",
+ description="Sampling method to use for homogeneous volumes",
+ items=enum_volume_homogeneous_sampling,
+ default='DISTANCE',
+ )
+
cls.use_square_samples = BoolProperty(
name="Square Samples",
description="Square sampling values for easier artist control",
@@ -241,6 +253,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='USE',
)
+ cls.sample_all_lights_direct = BoolProperty(
+ name="Sample All Direct Lights",
+ description="Sample all lights (for direct samples), rather than randomly picking one",
+ default=True,
+ )
+
+ cls.sample_all_lights_indirect = BoolProperty(
+ name="Sample All Indirect Lights",
+ description="Sample all lights (for indirect samples), rather than randomly picking one",
+ default=True,
+ )
+
cls.no_caustics = BoolProperty(
name="No Caustics",
description="Leave out caustics, resulting in a darker image with less noise",
@@ -447,6 +471,33 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=False,
)
+ cls.bake_type = EnumProperty(
+ name="Bake Type",
+ default='COMBINED',
+ description="Type of pass to bake",
+ items = (
+ ('COMBINED', "Combined", ""),
+ ('AO', "Ambient Occlusion", ""),
+ ('SHADOW', "Shadow", ""),
+ ('NORMAL', "Normal", ""),
+ ('UV', "UV", ""),
+ ('EMIT', "Emit", ""),
+ ('ENVIRONMENT', "Environment", ""),
+ ('DIFFUSE_DIRECT', "Diffuse Direct", ""),
+ ('DIFFUSE_INDIRECT', "Diffuse Indirect", ""),
+ ('DIFFUSE_COLOR', "Diffuse Color", ""),
+ ('GLOSSY_DIRECT', "Glossy Direct", ""),
+ ('GLOSSY_INDIRECT', "Glossy Indirect", ""),
+ ('GLOSSY_COLOR', "Glossy Color", ""),
+ ('TRANSMISSION_DIRECT', "Transmission Direct", ""),
+ ('TRANSMISSION_INDIRECT', "Transmission Indirect", ""),
+ ('TRANSMISSION_COLOR', "Transmission Color", ""),
+ ('SUBSURFACE_DIRECT', "Subsurface Direct", ""),
+ ('SUBSURFACE_INDIRECT', "Subsurface Indirect", ""),
+ ('SUBSURFACE_COLOR', "Subsurface Color", ""),
+ ),
+ )
+
@classmethod
def unregister(cls):
del bpy.types.Scene.cycles
@@ -718,6 +769,41 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
del bpy.types.MetaBall.cycles
+class CyclesObjectBlurSettings(bpy.types.PropertyGroup):
+
+ @classmethod
+ def register(cls):
+
+ bpy.types.Object.cycles = PointerProperty(
+ name="Cycles Object Settings",
+ description="Cycles object settings",
+ type=cls,
+ )
+
+ cls.use_motion_blur = BoolProperty(
+ name="Use Motion Blur",
+ description="Use motion blur for this object",
+ default=True,
+ )
+
+ cls.use_deform_motion = BoolProperty(
+ name="Use Deformation Motion",
+ description="Use deformation motion blur for this object",
+ default=True,
+ )
+
+ cls.motion_steps = IntProperty(
+ name="Motion Steps",
+ description="Control accuracy of deformation motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
+ min=1, soft_max=8,
+ default=1,
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.Object.cycles
+
+
class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c0ce80426c0..5c8115b6612 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -49,6 +49,13 @@ class CyclesButtonsPanel():
return rd.engine in cls.COMPAT_ENGINES
+def use_cpu(context):
+ cscene = context.scene.cycles
+ device_type = context.user_preferences.system.compute_device_type
+
+ return (device_type == 'NONE' or cscene.device == 'CPU')
+
+
def draw_samples_info(layout, cscene):
integrator = cscene.progressive
@@ -103,7 +110,6 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
- device_type = context.user_preferences.system.compute_device_type
row = layout.row(align=True)
row.menu("CYCLES_MT_sampling_presets", text=bpy.types.CYCLES_MT_sampling_presets.bl_label)
@@ -133,6 +139,9 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
sub.label(text="AA Samples:")
sub.prop(cscene, "aa_samples", text="Render")
sub.prop(cscene, "preview_aa_samples", text="Preview")
+ sub.separator()
+ sub.prop(cscene, "sample_all_lights_direct")
+ sub.prop(cscene, "sample_all_lights_indirect")
col = split.column()
sub = col.column(align=True)
@@ -145,7 +154,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
sub.prop(cscene, "subsurface_samples", text="Subsurface")
sub.prop(cscene, "volume_samples", text="Volume")
- if cscene.feature_set == 'EXPERIMENTAL' and (device_type == 'NONE' or cscene.device == 'CPU'):
+ if cscene.feature_set == 'EXPERIMENTAL' and use_cpu(context):
layout.row().prop(cscene, "sampling_pattern", text="Pattern")
for rl in scene.render.layers:
@@ -167,9 +176,16 @@ class CyclesRender_PT_volume_sampling(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
- split = layout.split()
- split.prop(cscene, "volume_step_size")
- split.prop(cscene, "volume_max_steps")
+ split = layout.split(align=True)
+
+ sub = split.column(align=True)
+ sub.label("Heterogeneous:")
+ sub.prop(cscene, "volume_step_size")
+ sub.prop(cscene, "volume_max_steps")
+
+ sub = split.column(align=True)
+ sub.label("Homogeneous:")
+ sub.prop(cscene, "volume_homogeneous_sampling", text="")
class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel):
@@ -310,28 +326,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
col.prop(cscene, "debug_use_spatial_splits")
-class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel):
- bl_label = "OpenGL Render"
- bl_options = {'DEFAULT_CLOSED'}
-
- def draw(self, context):
- layout = self.layout
-
- rd = context.scene.render
-
- split = layout.split()
-
- col = split.column()
- col.prop(rd, "use_antialiasing")
- sub = col.row()
- sub.active = rd.use_antialiasing
- sub.prop(rd, "antialiasing_samples", expand=True)
-
- col = split.column()
- col.label(text="Alpha:")
- col.prop(rd, "alpha_mode", text="")
-
-
class CyclesRender_PT_layer_options(CyclesButtonsPanel, Panel):
bl_label = "Layer"
bl_context = "render_layer"
@@ -562,26 +556,48 @@ class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel):
layout.prop(cdata, "dicing_rate")
-class Cycles_PT_mesh_normals(CyclesButtonsPanel, Panel):
- bl_label = "Normals"
- bl_context = "data"
+class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
+ bl_label = "Motion Blur"
+ bl_context = "object"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
- return CyclesButtonsPanel.poll(context) and context.mesh
+ ob = context.object
+ return CyclesButtonsPanel.poll(context) and ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META'}
+
+ def draw_header(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+ scene = context.scene
+ # cscene = scene.cycles
+
+ layout.active = rd.use_motion_blur
+
+ ob = context.object
+ cob = ob.cycles
+
+ layout.prop(cob, "use_motion_blur", text="")
def draw(self, context):
layout = self.layout
- mesh = context.mesh
+ rd = context.scene.render
+ scene = context.scene
+ # cscene = scene.cycles
- split = layout.split()
+ ob = context.object
+ cob = ob.cycles
- col = split.column()
- col.prop(mesh, "show_double_sided")
+ layout.active = (rd.use_motion_blur and cob.use_motion_blur)
- col = split.column()
- col.label()
+ row = layout.row()
+ row.prop(cob, "use_deform_motion", text="Deformation")
+
+ sub = row.row()
+ sub.active = cob.use_deform_motion
+ sub.prop(cob, "motion_steps", text="Steps")
class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
@@ -593,7 +609,8 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
def poll(cls, context):
ob = context.object
return (CyclesButtonsPanel.poll(context) and
- ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'})
+ ob and ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'} or
+ ob and ob.dupli_type == 'GROUP' and ob.dupli_group)
def draw(self, context):
layout = self.layout
@@ -847,9 +864,10 @@ class CyclesWorld_PT_mist(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
if CyclesButtonsPanel.poll(context):
- for rl in context.scene.render.layers:
- if rl.use_pass_mist:
- return True
+ if context.world:
+ for rl in context.scene.render.layers:
+ if rl.use_pass_mist:
+ return True
return False
@@ -997,8 +1015,9 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
split = layout.split()
- col = split.column()
+ col = split.column(align=True)
col.prop(mat, "diffuse_color", text="Viewport Color")
+ col.prop(mat, "alpha")
col = split.column(align=True)
col.label()
@@ -1108,7 +1127,7 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
def poll(cls, context):
# node = context.texture_node
return False
- #return node and CyclesButtonsPanel.poll(context)
+ # return node and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
@@ -1176,7 +1195,7 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
scene = context.scene
- cscene = scene.cycles
+ # cscene = scene.cycles
psys = context.particle_system
return CyclesButtonsPanel.poll(context) and psys and psys.settings.type == 'HAIR'
@@ -1208,6 +1227,54 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
row.prop(ccscene, "maximum_width", text="Max Ext.")
+class CyclesRender_PT_bake(CyclesButtonsPanel, Panel):
+ bl_label = "Bake"
+ bl_context = "render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ cbk = scene.render.bake
+
+ layout.operator("object.bake", icon='RENDER_STILL').type = \
+ cscene.bake_type
+
+ col = layout.column()
+ col.prop(cscene, "bake_type")
+
+ col.separator()
+ split = layout.split()
+
+ sub = split.column()
+ sub.prop(cbk, "use_clear")
+ sub.prop(cbk, "margin")
+
+ sub = split.column()
+ sub.prop(cbk, "use_selected_to_active")
+ sub = sub.column()
+
+ sub.active = cbk.use_selected_to_active
+ sub.prop(cbk, "cage_extrusion", text="Distance")
+ sub.prop_search(cbk, "cage", scene, "objects")
+
+ if cscene.bake_type == 'NORMAL':
+ col.separator()
+ box = col.box()
+ box.label(text="Normal Settings:")
+ box.prop(cbk, "normal_space", text="Space")
+
+ row = box.row(align=True)
+ row.label(text = "Swizzle:")
+ row.prop(cbk, "normal_r", text="")
+ row.prop(cbk, "normal_g", text="")
+ row.prop(cbk, "normal_b", text="")
+
+
class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
bl_label = "Cycles Hair Settings"
bl_context = "particle"
@@ -1215,7 +1282,7 @@ class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
scene = context.scene
- cscene = scene.cycles
+ # cscene = scene.cycles
ccscene = scene.cycles_curves
psys = context.particle_system
use_curves = ccscene.use_curves and psys
@@ -1275,7 +1342,7 @@ def draw_device(self, context):
if device_type in {'CUDA', 'OPENCL', 'NETWORK'}:
layout.prop(cscene, "device")
- if engine.with_osl() and (cscene.device == 'CPU' or device_type == 'NONE'):
+ if engine.with_osl() and use_cpu(context):
layout.prop(cscene, "shading_system")
@@ -1316,6 +1383,7 @@ def get_panels():
"DATA_PT_context_camera",
"DATA_PT_context_lamp",
"DATA_PT_context_speaker",
+ "DATA_PT_normals",
"DATA_PT_texture_space",
"DATA_PT_curve_texture_space",
"DATA_PT_mball_texture_space",
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 4c6b42a9cbc..1a85561c6d5 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -212,8 +212,8 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
BoundBox2D *viewplane, float *aspectratio, float *sensor_size)
{
/* dimensions */
- float xratio = width*bcam->pixelaspect.x;
- float yratio = height*bcam->pixelaspect.y;
+ float xratio = (float)width*bcam->pixelaspect.x;
+ float yratio = (float)height*bcam->pixelaspect.y;
/* compute x/y aspect and ratio */
float xaspect, yaspect;
@@ -288,8 +288,8 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* panorama sensor */
if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
- float fit_xratio = bcam->full_width*bcam->pixelaspect.x;
- float fit_yratio = bcam->full_height*bcam->pixelaspect.y;
+ float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x;
+ float fit_yratio = (float)bcam->full_height*bcam->pixelaspect.y;
bool horizontal_fit;
float sensor_size;
@@ -386,7 +386,7 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
blender_camera_sync(cam, &bcam, width, height);
}
-void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
+void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
{
Camera *cam = scene->camera;
@@ -394,12 +394,14 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
tfm = blender_camera_matrix(tfm, cam->type);
if(tfm != cam->matrix) {
- if(motion == -1)
+ if(motion_time == -1.0f) {
cam->motion.pre = tfm;
- else
+ cam->use_motion = true;
+ }
+ else if(motion_time == 1.0f) {
cam->motion.post = tfm;
-
- cam->use_motion = true;
+ cam->use_motion = true;
+ }
}
}
@@ -563,10 +565,10 @@ BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Sce
if(use_border) {
/* border render */
- params.full_x = cam->border.left*width;
- params.full_y = cam->border.bottom*height;
- params.width = (int)(cam->border.right*width) - params.full_x;
- params.height = (int)(cam->border.top*height) - params.full_y;
+ params.full_x = (int)(cam->border.left * (float)width);
+ params.full_y = (int)(cam->border.bottom * (float)height);
+ params.width = (int)(cam->border.right * (float)width) - params.full_x;
+ params.height = (int)(cam->border.top * (float)height) - params.full_y;
/* survive in case border goes out of view or becomes too small */
params.width = max(params.width, 1);
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 92c51b0aad3..22de7b64273 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -588,7 +588,7 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- radius =0.0f;
+ radius = 0.0f;
mesh->add_curve_key(ickey_loc, radius);
if(attr_intercept)
@@ -612,16 +612,23 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
}
}
-static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int motion)
+static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int time_index)
{
+ /* find attribute */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ bool new_attribute = false;
+
+ /* add new attribute if it doesn't exist already */
+ if(!attr_mP) {
+ attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ new_attribute = true;
+ }
+
/* export motion vectors for curve keys */
- AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
- Attribute *attr_motion = mesh->curve_attributes.add(std);
- float3 *data_motion = attr_motion->data_float3();
- float3 *current_motion = data_motion;
- size_t size = mesh->curve_keys.size();
- size_t i = 0;
+ size_t numkeys = mesh->curve_keys.size();
+ float4 *mP = attr_mP->data_float4() + time_index*numkeys;
bool have_motion = false;
+ int i = 0;
for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
if(CData->psys_curvenum[sys] == 0)
@@ -633,15 +640,21 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
if(i < mesh->curve_keys.size()) {
- *current_motion = CData->curvekey_co[curvekey];
+ float3 ickey_loc = CData->curvekey_co[curvekey];
+ float time = CData->curvekey_time[curvekey]/CData->curve_length[curve];
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = 0.0f;
+
+ mP[i] = float3_to_float4(ickey_loc);
+ mP[i].w = radius;
/* unlike mesh coordinates, these tend to be slightly different
* between frames due to particle transforms into/out of object
* space, so we use an epsilon to detect actual changes */
- if(len_squared(*current_motion - mesh->curve_keys[i].co) > 1e-5f*1e-5f)
+ if(len_squared(mP[i] - mesh->curve_keys[i]) > 1e-5f*1e-5f)
have_motion = true;
-
- current_motion++;
}
i++;
@@ -649,8 +662,23 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
}
}
- if(i != size || !have_motion)
- mesh->curve_attributes.remove(std);
+ /* in case of new attribute, we verify if there really was any motion */
+ if(new_attribute) {
+ if(i != numkeys || !have_motion) {
+ /* no motion, remove attributes again */
+ mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ else if(time_index > 0) {
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ for(int step = 0; step < time_index; step++) {
+ float4 *mP = attr_mP->data_float4() + step*numkeys;
+
+ for(int key = 0; key < numkeys; key++)
+ mP[key] = mesh->curve_keys[key];
+ }
+ }
+ }
}
void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata)
@@ -796,7 +824,7 @@ void BlenderSync::sync_curve_settings()
curve_system_manager->tag_update(scene);
}
-void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int motion)
+void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index)
{
if(!motion) {
/* Clear stored curve data */
@@ -851,7 +879,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int
}
else {
if(motion)
- ExportCurveSegmentsMotion(scene, mesh, &CData, motion);
+ ExportCurveSegmentsMotion(scene, mesh, &CData, time_index);
else
ExportCurveSegments(scene, mesh, &CData);
}
@@ -876,7 +904,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int
size_t i = 0;
foreach(Mesh::Curve& curve, mesh->curves) {
- float3 co = mesh->curve_keys[curve.first_key].co;
+ float3 co = float4_to_float3(mesh->curve_keys[curve.first_key]);
generated[i++] = co*size - loc;
}
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 61c6ef6af1b..83514879477 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -206,6 +206,40 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
}
}
+/* Create Volume Attribute */
+
+static void create_mesh_volume_attribute(BL::Object b_ob, Mesh *mesh, ImageManager *image_manager, AttributeStandard std)
+{
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if(!b_domain)
+ return;
+
+ Attribute *attr = mesh->attributes.add(std);
+ VoxelAttribute *volume_data = attr->data_voxel();
+ bool is_float, is_linear;
+ bool animated = false;
+
+ volume_data->manager = image_manager;
+ volume_data->slot = image_manager->add_image(Attribute::standard_name(std),
+ b_ob.ptr.data, animated, is_float, is_linear, INTERPOLATION_LINEAR, true);
+}
+
+static void create_mesh_volume_attributes(Scene *scene, BL::Object b_ob, Mesh *mesh)
+{
+ /* for smoke volume rendering */
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY);
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR);
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME);
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT);
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
+ create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY);
+}
+
/* Create Mesh */
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
@@ -214,6 +248,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
int numverts = b_mesh.vertices.length();
int numfaces = b_mesh.tessfaces.length();
int numtris = 0;
+ bool use_loop_normals = b_mesh.use_auto_smooth();
BL::Mesh::vertices_iterator v;
BL::Mesh::tessfaces_iterator f;
@@ -236,6 +271,21 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
*N = get_float3(v->normal());
+ N = attr_N->data_float3();
+
+ /* create generated coordinates from undeformed coordinates */
+ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ float3 *generated = attr->data_float3();
+ size_t i = 0;
+
+ for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
+ generated[i++] = get_float3(v->undeformed_co())*size - loc;
+ }
/* create faces */
vector<int> nverts(numfaces);
@@ -248,9 +298,32 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
int shader = used_shaders[mi];
bool smooth = f->use_smooth();
+ /* split vertices if normal is different
+ *
+ * note all vertex attributes must have been set here so we can split
+ * and copy attributes in split_vertex without remapping later */
+ if(use_loop_normals) {
+ BL::Array<float, 12> loop_normals = f->split_normals();
+
+ for(int i = 0; i < n; i++) {
+ float3 loop_N = make_float3(loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
+
+ if(N[vi[i]] != loop_N) {
+ int new_vi = mesh->split_vertex(vi[i]);
+
+ /* set new normal and vertex index */
+ N = attr_N->data_float3();
+ N[new_vi] = loop_N;
+ vi[i] = new_vi;
+ }
+ }
+ }
+
+ /* create triangles */
if(n == 4) {
if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
- is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) {
+ is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
+ {
mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth);
mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth);
}
@@ -348,20 +421,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
}
}
- /* create generated coordinates from undeformed coordinates */
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
-
- float3 loc, size;
- mesh_texture_space(b_mesh, loc, size);
-
- float3 *generated = attr->data_float3();
- size_t i = 0;
-
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
- generated[i++] = get_float3(v->undeformed_co())*size - loc;
- }
-
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can
* probably only be done well with a volume grid mapping of coordinates */
@@ -414,7 +473,7 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerR
//sdparams.camera = scene->camera;
/* tesselate */
- DiagSplit dsplit(sdparams);;
+ DiagSplit dsplit(sdparams);
sdmesh.tessellate(&dsplit);
}
@@ -449,6 +508,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
Mesh *mesh;
if(!mesh_map.sync(&mesh, key)) {
+
/* if transform was applied to mesh, need full update */
if(object_updated && mesh->transform_applied);
/* test if shaders changed, these can be object level so mesh
@@ -481,7 +541,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
/* compares curve_keys rather than strands in order to handle quick hair
* adjustsments in dynamic BVH - other methods could probably do this better*/
- vector<Mesh::CurveKey> oldcurve_keys = mesh->curve_keys;
+ vector<float4> oldcurve_keys = mesh->curve_keys;
mesh->clear();
mesh->used_shaders = used_shaders;
@@ -500,10 +560,12 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
create_subd_mesh(scene, mesh, b_mesh, &cmesh, used_shaders);
else
create_mesh(scene, mesh, b_mesh, used_shaders);
+
+ create_mesh_volume_attributes(scene, b_ob, mesh);
}
if(render_layer.use_hair)
- sync_curves(mesh, b_mesh, b_ob, 0);
+ sync_curves(mesh, b_mesh, b_ob, false);
/* free derived mesh */
b_data.meshes.remove(b_mesh);
@@ -535,7 +597,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
if(oldcurve_keys.size() != mesh->curve_keys.size())
rebuild = true;
else if(oldcurve_keys.size()) {
- if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(Mesh::CurveKey)*oldcurve_keys.size()) != 0)
+ if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float4)*oldcurve_keys.size()) != 0)
rebuild = true;
}
@@ -544,46 +606,153 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
return mesh;
}
-void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
+void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time)
{
- /* todo: displacement, subdivision */
- size_t size = mesh->verts.size();
-
- /* skip objects without deforming modifiers. this is not a totally reliable,
- * would need a more extensive check to see which objects are animated */
- if(!size || !ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview))
- return;
-
/* ensure we only sync instanced meshes once */
+ Mesh *mesh = object->mesh;
+
if(mesh_motion_synced.find(mesh) != mesh_motion_synced.end())
return;
mesh_motion_synced.insert(mesh);
- /* get derived mesh */
- BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false);
+ /* for motion pass always compute, for motion blur it can be disabled */
+ int time_index = 0;
+
+ if(scene->need_motion() == Scene::MOTION_BLUR) {
+ if(!mesh->use_motion_blur)
+ return;
+
+ /* see if this mesh needs motion data at this time */
+ vector<float> object_times = object->motion_times();
+ bool found = false;
+
+ foreach(float object_time, object_times) {
+ if(motion_time == object_time) {
+ found = true;
+ break;
+ }
+ else
+ time_index++;
+ }
- if(b_mesh) {
- BL::Mesh::vertices_iterator v;
- AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
- Attribute *attr_M = mesh->attributes.add(std);
- float3 *M = attr_M->data_float3(), *cur_M;
- size_t i = 0;
+ if(!found)
+ return;
+ }
+ else {
+ if(motion_time == -1.0f)
+ time_index = 0;
+ else if(motion_time == 1.0f)
+ time_index = 1;
+ else
+ return;
+ }
+
+ /* skip empty meshes */
+ size_t numverts = mesh->verts.size();
+ size_t numkeys = mesh->curve_keys.size();
+
+ if(!numverts && !numkeys)
+ return;
+
+ /* skip objects without deforming modifiers. this is not totally reliable,
+ * would need a more extensive check to see which objects are animated */
+ BL::Mesh b_mesh(PointerRNA_NULL);
+
+ if(ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
+ /* get derived mesh */
+ b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false);
+ }
- for(b_mesh.vertices.begin(v), cur_M = M; v != b_mesh.vertices.end() && i < size; ++v, cur_M++, i++)
- *cur_M = get_float3(v->co());
+ if(!b_mesh) {
+ /* if we have no motion blur on this frame, but on other frames, copy */
+ if(numverts) {
+ /* triangles */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr_mP) {
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N)? attr_N->data_float3(): NULL;
+
+ memcpy(attr_mP->data_float3() + time_index*numverts, P, sizeof(float3)*numverts);
+ if(attr_mN)
+ memcpy(attr_mN->data_float3() + time_index*numverts, N, sizeof(float3)*numverts);
+ }
+ }
+
+ if(numkeys) {
+ /* curves */
+ Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr_mP) {
+ float4 *keys = &mesh->curve_keys[0];
+ memcpy(attr_mP->data_float4() + time_index*numkeys, keys, sizeof(float4)*numkeys);
+ }
+ }
+
+ return;
+ }
+
+ if(numverts) {
+ /* find attributes */
+ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ bool new_attribute = false;
+
+ /* add new attributes if they don't exist already */
+ if(!attr_mP) {
+ attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ if(attr_N)
+ attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
- /* if number of vertices changed, or if coordinates stayed the same, drop it */
- if(i != size || memcmp(M, &mesh->verts[0], sizeof(float3)*size) == 0)
- mesh->attributes.remove(std);
+ new_attribute = true;
+ }
+
+ /* load vertex data from mesh */
+ float3 *mP = attr_mP->data_float3() + time_index*numverts;
+ float3 *mN = (attr_mN)? attr_mN->data_float3() + time_index*numverts: NULL;
+
+ BL::Mesh::vertices_iterator v;
+ int i = 0;
- /* hair motion */
- if(render_layer.use_hair)
- sync_curves(mesh, b_mesh, b_ob, motion);
+ for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
+ mP[i] = get_float3(v->co());
+ if(mN)
+ mN[i] = get_float3(v->normal());
+ }
- /* free derived mesh */
- b_data.meshes.remove(b_mesh);
+ /* in case of new attribute, we verify if there really was any motion */
+ if(new_attribute) {
+ if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
+ /* no motion, remove attributes again */
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
+ if(attr_mN)
+ mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
+ }
+ else if(time_index > 0) {
+ /* motion, fill up previous steps that we might have skipped because
+ * they had no motion, but we need them anyway now */
+ float3 *P = &mesh->verts[0];
+ float3 *N = (attr_N)? attr_N->data_float3(): NULL;
+
+ for(int step = 0; step < time_index; step++) {
+ memcpy(attr_mP->data_float3() + step*numverts, P, sizeof(float3)*numverts);
+ if(attr_mN)
+ memcpy(attr_mN->data_float3() + step*numverts, N, sizeof(float3)*numverts);
+ }
+ }
+ }
}
+
+ /* hair motion */
+ if(numkeys)
+ sync_curves(mesh, b_mesh, b_ob, true, time_index);
+
+ /* free derived mesh */
+ b_data.meshes.remove(b_mesh);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index cc52717fdb6..167647608a5 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -38,7 +38,11 @@ CCL_NAMESPACE_BEGIN
bool BlenderSync::BKE_object_is_modified(BL::Object b_ob)
{
/* test if we can instance or if the object is modified */
- if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
+ if(b_ob.type() == BL::Object::type_META) {
+ /* multi-user and dupli metaballs are fused, can't instance */
+ return true;
+ }
+ else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
/* modifiers */
return true;
}
@@ -213,9 +217,11 @@ void BlenderSync::sync_background_light()
/* Object */
-Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, bool hide_tris)
+Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
+ bool motion = motion_time != 0.0f;
/* light is handled separately */
if(object_is_light(b_ob)) {
@@ -238,19 +244,22 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
if(motion) {
object = object_map.find(key);
- if(object) {
+ if(object && (scene->need_motion() == Scene::MOTION_PASS || object_use_motion(b_ob))) {
+ /* object transformation */
if(tfm != object->tfm) {
- if(motion == -1)
+ if(motion_time == -1.0f) {
object->motion.pre = tfm;
- else
+ object->use_motion = true;
+ }
+ else if(motion_time == 1.0f) {
object->motion.post = tfm;
-
- object->use_motion = true;
+ object->use_motion = true;
+ }
}
- /* mesh deformation blur not supported yet */
- if(!scene->integrator->motion_blur)
- sync_mesh_motion(b_ob, object->mesh, motion);
+ /* mesh deformation */
+ if(object->mesh)
+ sync_mesh_motion(b_ob, object, motion_time);
}
return object;
@@ -310,6 +319,24 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
object->motion.post = tfm;
object->use_motion = false;
+ /* motion blur */
+ if(scene->need_motion() == Scene::MOTION_BLUR && object->mesh) {
+ Mesh *mesh = object->mesh;
+
+ mesh->use_motion_blur = false;
+
+ if(object_use_motion(b_ob)) {
+ if(object_use_deform_motion(b_ob)) {
+ mesh->motion_steps = object_motion_steps(b_ob);
+ mesh->use_motion_blur = true;
+ }
+
+ vector<float> times = object->motion_times();
+ foreach(float time, times)
+ motion_times.insert(time);
+ }
+ }
+
/* random number */
object->random_id = hash_string(object->name.c_str());
@@ -408,10 +435,11 @@ static bool object_render_hide_duplis(BL::Object b_ob)
/* Object Loop */
-void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
+void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
{
/* layer data */
uint scene_layer = render_layer.scene_layer;
+ bool motion = motion_time != 0.0f;
if(!motion) {
/* prepare for sync */
@@ -420,36 +448,40 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
object_map.pre_sync();
mesh_synced.clear();
particle_system_map.pre_sync();
+ motion_times.clear();
}
else {
mesh_motion_synced.clear();
}
/* object loop */
- BL::Scene::objects_iterator b_ob;
+ BL::Scene::object_bases_iterator b_base;
BL::Scene b_sce = b_scene;
-
- /* global particle index counter */
- int particle_id = 1;
+ /* modifier result type (not exposed as enum in C++ API)
+ * 1 : eModifierMode_Realtime
+ * 2 : eModifierMode_Render
+ */
+ int dupli_settings = preview ? 1 : 2;
bool cancel = false;
for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
- for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end() && !cancel; ++b_ob) {
- bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
- uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), render_layer.use_localview, object_is_light(*b_ob));
+ for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
+ BL::Object b_ob = b_base->object();
+ bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
+ uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob));
hide = hide || !(ob_layer & scene_layer);
if(!hide) {
- progress.set_sync_status("Synchronizing object", (*b_ob).name());
+ progress.set_sync_status("Synchronizing object", b_ob.name());
- if(b_ob->is_duplicator() && !object_render_hide_duplis(*b_ob)) {
+ if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
/* dupli objects */
- b_ob->dupli_list_create(b_scene, 2);
+ b_ob.dupli_list_create(b_scene, dupli_settings);
BL::Object::dupli_list_iterator b_dup;
- for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
+ for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
Transform tfm = get_transform(b_dup->matrix());
BL::Object b_dup_ob = b_dup->object();
bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
@@ -462,32 +494,27 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
/* sync object and mesh or light data */
- Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion, hide_tris);
+ Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris);
/* sync possible particle data, note particle_id
* starts counting at 1, first is dummy particle */
- if(!motion && object && sync_dupli_particle(*b_ob, *b_dup, object)) {
- if(particle_id != object->particle_id) {
- object->particle_id = particle_id;
- scene->object_manager->tag_update(scene);
- }
-
- particle_id++;
+ if(!motion && object) {
+ sync_dupli_particle(b_ob, *b_dup, object);
}
}
}
- b_ob->dupli_list_clear();
+ b_ob.dupli_list_clear();
}
/* test if object needs to be hidden */
bool hide_tris;
- if(!object_render_hide(*b_ob, true, true, hide_tris)) {
+ if(!object_render_hide(b_ob, true, true, hide_tris)) {
/* object itself */
- Transform tfm = get_transform(b_ob->matrix_world());
- sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion, hide_tris);
+ Transform tfm = get_transform(b_ob.matrix_world());
+ sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris);
}
}
@@ -527,31 +554,46 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
b_cam = b_override;
Camera prevcam = *(scene->camera);
-
- /* go back and forth one frame */
- int frame = b_scene.frame_current();
- for(int motion = -1; motion <= 1; motion += 2) {
- /* we need to set the python thread state again because this
- * function assumes it is being executed from python and will
- * try to save the thread state */
+ int frame_center = b_scene.frame_current();
+
+ /* always sample these times for camera motion */
+ motion_times.insert(-1.0f);
+ motion_times.insert(1.0f);
+
+ /* note iteration over motion_times set happens in sorted order */
+ foreach(float relative_time, motion_times) {
+ /* fixed shutter time to get previous and next frame for motion pass */
+ float shuttertime;
+
+ if(scene->need_motion() == Scene::MOTION_PASS)
+ shuttertime = 2.0f;
+ else
+ shuttertime = scene->camera->shuttertime;
+
+ /* compute frame and subframe time */
+ float time = frame_center + relative_time * shuttertime * 0.5f;
+ int frame = (int)floorf(time);
+ float subframe = time - frame;
+
+ /* change frame */
python_thread_state_restore(python_thread_state);
- b_scene.frame_set(frame + motion, 0.0f);
+ b_scene.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
- /* camera object */
- if(b_cam)
- sync_camera_motion(b_cam, motion);
+ /* sync camera, only supports two times at the moment */
+ if(relative_time == -1.0f || relative_time == 1.0f)
+ sync_camera_motion(b_cam, relative_time);
- /* mesh objects */
- sync_objects(b_v3d, motion);
+ /* sync object */
+ sync_objects(b_v3d, relative_time);
}
/* we need to set the python thread state again because this
* function assumes it is being executed from python and will
* try to save the thread state */
python_thread_state_restore(python_thread_state);
- b_scene.frame_set(frame, 0.0f);
+ b_scene.frame_set(frame_center, 0.0f);
python_thread_state_save(python_thread_state);
/* tag camera for motion update */
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index ef832ed39c0..5b2782ec2ac 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -76,6 +76,11 @@ bool BlenderSync::sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Ob
psys->particles.push_back(pa);
+ if (object->particle_index != psys->particles.size() - 1)
+ scene->object_manager->tag_update(scene);
+ object->particle_system = psys;
+ object->particle_index = psys->particles.size() - 1;
+
/* return that this object has particle data */
return true;
}
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index e08b7980e78..872f891cc2a 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -147,6 +147,38 @@ static PyObject *render_func(PyObject *self, PyObject *value)
Py_RETURN_NONE;
}
+/* pixel_array and result passed as pointers */
+static PyObject *bake_func(PyObject *self, PyObject *args)
+{
+ PyObject *pysession, *pyobject;
+ PyObject *pypixel_array, *pyresult;
+ const char *pass_type;
+ int num_pixels, depth;
+
+ if(!PyArg_ParseTuple(args, "OOsOiiO", &pysession, &pyobject, &pass_type, &pypixel_array, &num_pixels, &depth, &pyresult))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+
+ BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA objectptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr);
+ BL::Object b_object(objectptr);
+
+ void *b_result = PyLong_AsVoidPtr(pyresult);
+
+ PointerRNA bakepixelptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
+ BL::BakePixel b_bake_pixel(bakepixelptr);
+
+ session->bake(b_object, pass_type, b_bake_pixel, num_pixels, depth, (float *)b_result);
+
+ Py_END_ALLOW_THREADS
+
+ Py_RETURN_NONE;
+}
+
static PyObject *draw_func(PyObject *self, PyObject *args)
{
PyObject *pysession, *pyv3d, *pyrv3d;
@@ -285,7 +317,8 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
}
else if(param->type.vecsemantics == TypeDesc::POINT ||
param->type.vecsemantics == TypeDesc::VECTOR ||
- param->type.vecsemantics == TypeDesc::NORMAL) {
+ param->type.vecsemantics == TypeDesc::NORMAL)
+ {
socket_type = "NodeSocketVector";
data_type = BL::NodeSocket::type_VECTOR;
@@ -418,6 +451,7 @@ static PyMethodDef methods[] = {
{"create", create_func, METH_VARARGS, ""},
{"free", free_func, METH_O, ""},
{"render", render_func, METH_O, ""},
+ {"bake", bake_func, METH_VARARGS, ""},
{"draw", draw_func, METH_VARARGS, ""},
{"sync", sync_func, METH_O, ""},
{"reset", reset_func, METH_VARARGS, ""},
@@ -493,7 +527,7 @@ void *CCL_python_module_init()
/* TODO(sergey): This gives us library we've been linking against.
* In theory with dynamic OSL library it might not be
* accurate, but there's nothing in OSL API which we
- * might use th get version in runtime.
+ * might use to get version in runtime.
*/
int curversion = OSL_LIBRARY_VERSION_CODE;
PyModule_AddObject(mod, "with_osl", Py_True);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index ef578493901..01a5acd8982 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -14,6 +14,8 @@
* limitations under the License
*/
+#include <stdlib.h>
+
#include "background.h"
#include "buffers.h"
#include "camera.h"
@@ -21,6 +23,8 @@
#include "integrator.h"
#include "film.h"
#include "light.h"
+#include "mesh.h"
+#include "object.h"
#include "scene.h"
#include "session.h"
#include "shader.h"
@@ -93,6 +97,11 @@ void BlenderSession::create_session()
/* create scene */
scene = new Scene(scene_params, session_params.device);
+ /* setup callbacks for builtin image support */
+ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
+
/* create session */
session = new Session(session_params);
session->scene = scene;
@@ -121,11 +130,6 @@ void BlenderSession::create_session()
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
-
- /* setup callbacks for builtin image support */
- scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6);
- scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
- scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
}
void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
@@ -259,6 +263,58 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_NONE;
}
+static ShaderEvalType get_shader_type(const string& pass_type)
+{
+ const char *shader_type = pass_type.c_str();
+
+ /* data passes */
+ if(strcmp(shader_type, "NORMAL")==0)
+ return SHADER_EVAL_NORMAL;
+ else if(strcmp(shader_type, "UV")==0)
+ return SHADER_EVAL_UV;
+ else if(strcmp(shader_type, "DIFFUSE_COLOR")==0)
+ return SHADER_EVAL_DIFFUSE_COLOR;
+ else if(strcmp(shader_type, "GLOSSY_COLOR")==0)
+ return SHADER_EVAL_GLOSSY_COLOR;
+ else if(strcmp(shader_type, "TRANSMISSION_COLOR")==0)
+ return SHADER_EVAL_TRANSMISSION_COLOR;
+ else if(strcmp(shader_type, "SUBSURFACE_COLOR")==0)
+ return SHADER_EVAL_SUBSURFACE_COLOR;
+ else if(strcmp(shader_type, "EMIT")==0)
+ return SHADER_EVAL_EMISSION;
+
+ /* light passes */
+ else if(strcmp(shader_type, "AO")==0)
+ return SHADER_EVAL_AO;
+ else if(strcmp(shader_type, "COMBINED")==0)
+ return SHADER_EVAL_COMBINED;
+ else if(strcmp(shader_type, "SHADOW")==0)
+ return SHADER_EVAL_SHADOW;
+ else if(strcmp(shader_type, "DIFFUSE_DIRECT")==0)
+ return SHADER_EVAL_DIFFUSE_DIRECT;
+ else if(strcmp(shader_type, "GLOSSY_DIRECT")==0)
+ return SHADER_EVAL_GLOSSY_DIRECT;
+ else if(strcmp(shader_type, "TRANSMISSION_DIRECT")==0)
+ return SHADER_EVAL_TRANSMISSION_DIRECT;
+ else if(strcmp(shader_type, "SUBSURFACE_DIRECT")==0)
+ return SHADER_EVAL_SUBSURFACE_DIRECT;
+ else if(strcmp(shader_type, "DIFFUSE_INDIRECT")==0)
+ return SHADER_EVAL_DIFFUSE_INDIRECT;
+ else if(strcmp(shader_type, "GLOSSY_INDIRECT")==0)
+ return SHADER_EVAL_GLOSSY_INDIRECT;
+ else if(strcmp(shader_type, "TRANSMISSION_INDIRECT")==0)
+ return SHADER_EVAL_TRANSMISSION_INDIRECT;
+ else if(strcmp(shader_type, "SUBSURFACE_INDIRECT")==0)
+ return SHADER_EVAL_SUBSURFACE_INDIRECT;
+
+ /* extra */
+ else if(strcmp(shader_type, "ENVIRONMENT")==0)
+ return SHADER_EVAL_ENVIRONMENT;
+
+ else
+ return SHADER_EVAL_BAKE;
+}
+
static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername)
{
return b_engine.begin_result(x, y, w, h, layername);
@@ -425,6 +481,105 @@ void BlenderSession::render()
sync = NULL;
}
+static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const int num_pixels)
+{
+ BL::BakePixel bp = pixel_array;
+
+ int i;
+ for(i=0; i < num_pixels; i++) {
+ data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
+ bp = bp.next();
+ }
+}
+
+static bool is_light_pass(ShaderEvalType type)
+{
+ switch (type) {
+ case SHADER_EVAL_AO:
+ case SHADER_EVAL_COMBINED:
+ case SHADER_EVAL_SHADOW:
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float result[])
+{
+ ShaderEvalType shader_type = get_shader_type(pass_type);
+ size_t object_index = OBJECT_NONE;
+ int tri_offset = 0;
+
+ if(shader_type == SHADER_EVAL_UV) {
+ /* force UV to be available */
+ Pass::add(PASS_UV, scene->film->passes);
+ }
+
+ if(is_light_pass(shader_type)) {
+ /* force use_light_pass to be true */
+ Pass::add(PASS_LIGHT, scene->film->passes);
+ }
+
+ /* create device and update scene */
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ /* update scene */
+ sync->sync_camera(b_render, b_engine.camera_override(), width, height);
+ sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+
+ /* get buffer parameters */
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+
+ scene->bake_manager->set_baking(true);
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
+ for(size_t i = 0; i < scene->objects.size(); i++) {
+ if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) {
+ object_index = i;
+ tri_offset = scene->objects[i]->mesh->tri_offset;
+ break;
+ }
+ }
+
+ /* when used, non-instanced convention: object = ~object */
+ int object = ~object_index;
+
+ BakeData *bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
+
+ populate_bake_data(bake_data, pixel_array, num_pixels);
+
+ /* set number of samples */
+ session->tile_manager.set_samples(session_params.samples);
+ session->reset(buffer_params, session_params.samples);
+ session->update_scene();
+
+ scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result);
+
+ /* free all memory used (host and device), so we wouldn't leave render
+ * engine with extra memory allocated
+ */
+
+ session->device_free();
+
+ delete sync;
+ sync = NULL;
+}
+
void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only)
{
RenderBuffers *buffers = rtile.buffers;
@@ -592,16 +747,14 @@ bool BlenderSession::draw(int w, int h)
/* draw */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ DeviceDrawParams draw_params;
- if(session->params.display_buffer_linear)
- b_engine.bind_display_space_shader(b_scene);
-
- bool draw_ok = !session->draw(buffer_params);
+ if(session->params.display_buffer_linear) {
+ draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
+ draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine);
+ }
- if(session->params.display_buffer_linear)
- b_engine.unbind_display_space_shader();
-
- return draw_ok;
+ return !session->draw(buffer_params, draw_params);
}
void BlenderSession::get_status(string& status, string& substatus)
@@ -726,85 +879,123 @@ int BlenderSession::builtin_image_frame(const string &builtin_name)
return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
}
-void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels)
+void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels)
{
+ /* empty image */
+ is_float = false;
+ width = 0;
+ height = 0;
+ depth = 0;
+ channels = 0;
+
+ if(!builtin_data)
+ return;
+
+ /* recover ID pointer */
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
+ BL::ID b_id(ptr);
+
+ if(b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
- if(b_image) {
is_float = b_image.is_float();
width = b_image.size()[0];
height = b_image.size()[1];
+ depth = 1;
channels = b_image.channels();
}
- else {
- is_float = false;
- width = 0;
- height = 0;
- channels = 0;
+ else if(b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if(!b_domain)
+ return;
+
+ if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME))
+ channels = 1;
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
+ channels = 4;
+ else
+ return;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
+
+ width = resolution.x * amplify;
+ height = resolution.y * amplify;
+ depth = resolution.z * amplify;
+
+ is_float = true;
}
}
bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
{
+ if(!builtin_data)
+ return false;
+
int frame = builtin_image_frame(builtin_name);
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
BL::Image b_image(ptr);
- if(b_image) {
- int width = b_image.size()[0];
- int height = b_image.size()[1];
- int channels = b_image.channels();
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
- unsigned char *image_pixels;
- image_pixels = image_get_pixels_for_frame(b_image, frame);
+ unsigned char *image_pixels;
+ image_pixels = image_get_pixels_for_frame(b_image, frame);
- if(image_pixels) {
- memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
- MEM_freeN(image_pixels);
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(unsigned char));
}
else {
- if(channels == 1) {
- memset(pixels, 0, width * height * sizeof(unsigned char));
- }
- else {
- unsigned char *cp = pixels;
- for(int i = 0; i < width * height; i++, cp += channels) {
- cp[0] = 255;
- cp[1] = 0;
- cp[2] = 255;
- if(channels == 4)
- cp[3] = 255;
- }
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if(channels == 4)
+ cp[3] = 255;
}
}
+ }
- /* premultiply, byte images are always straight for blender */
- unsigned char *cp = pixels;
- for(int i = 0; i < width * height; i++, cp += channels) {
- cp[0] = (cp[0] * cp[3]) >> 8;
- cp[1] = (cp[1] * cp[3]) >> 8;
- cp[2] = (cp[2] * cp[3]) >> 8;
- }
-
- return true;
+ /* premultiply, byte images are always straight for blender */
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = (cp[0] * cp[3]) >> 8;
+ cp[1] = (cp[1] * cp[3]) >> 8;
+ cp[2] = (cp[2] * cp[3]) >> 8;
}
- return false;
+ return true;
}
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels)
{
- int frame = builtin_image_frame(builtin_name);
+ if(!builtin_data)
+ return false;
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
+ BL::ID b_id(ptr);
+
+ if(b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+ int frame = builtin_image_frame(builtin_name);
- if(b_image) {
int width = b_image.size()[0];
int height = b_image.size()[1];
int channels = b_image.channels();
@@ -834,6 +1025,51 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
return true;
}
+ else if(b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if(!b_domain)
+ return false;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
+
+ int width = resolution.x * amplify;
+ int height = resolution.y * amplify;
+ int depth = resolution.z * amplify;
+
+ if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
+ SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth) {
+ SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
+ /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
+ * as 1500..3000 K with the first part faded to zero density */
+ SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth) {
+ SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
+ /* the RGB is "premultiplied" by density for better interpolation results */
+ SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth*4) {
+ SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+
+ fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
+ }
return false;
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 0568fb291d0..0e44493d674 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -20,6 +20,7 @@
#include "device.h"
#include "scene.h"
#include "session.h"
+#include "bake.h"
#include "util_vector.h"
@@ -51,6 +52,8 @@ public:
/* offline render */
void render();
+ void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float pixels[]);
+
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
void write_render_tile(RenderTile& rtile);
@@ -99,7 +102,7 @@ protected:
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
int builtin_image_frame(const string &builtin_name);
- void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels);
+ void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels);
bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels);
bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels);
};
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 6175c8ea399..ddbb40da7db 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -546,9 +546,11 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
}
image->animated = b_image_node.image_user().use_auto_refresh();
+ image->use_alpha = b_image.use_alpha();
}
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
+ image->interpolation = (InterpolationType)b_image_node.interpolation();
image->projection_blend = b_image_node.projection_blend();
get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
node = image;
@@ -573,6 +575,8 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
env->animated = b_env_node.image_user().use_auto_refresh();
env->builtin_data = NULL;
}
+
+ env->use_alpha = b_image.use_alpha();
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
@@ -667,6 +671,13 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
tangent->attribute = b_tangent_node.uv_map();
node = tangent;
}
+ else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
+ BL::ShaderNodeUVMap b_uvmap_node(b_node);
+ UVMapNode *uvm = new UVMapNode();
+ uvm->attribute = b_uvmap_node.uv_map();
+ uvm->from_dupli = b_uvmap_node.from_dupli();
+ node = uvm;
+ }
if(node)
graph->add(node);
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 8e2197a2aa6..1f5e32a1123 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -172,6 +172,7 @@ void BlenderSync::sync_integrator()
integrator->transparent_min_bounce = get_int(cscene, "transparent_min_bounces");
integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows");
+ integrator->volume_homogeneous_sampling = RNA_enum_get(&cscene, "volume_homogeneous_sampling");
integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
integrator->volume_step_size = get_float(cscene, "volume_step_size");
@@ -197,6 +198,9 @@ void BlenderSync::sync_integrator()
integrator->method = (Integrator::Method)get_enum(cscene, "progressive");
+ integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
+ integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
+
int diffuse_samples = get_int(cscene, "diffuse_samples");
int glossy_samples = get_int(cscene, "glossy_samples");
int transmission_samples = get_int(cscene, "transmission_samples");
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 205761ad302..9c4175ef690 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -71,7 +71,7 @@ private:
/* sync */
void sync_lamps(bool update_all);
void sync_materials(bool update_all);
- void sync_objects(BL::SpaceView3D b_v3d, int motion = 0);
+ void sync_objects(BL::SpaceView3D b_v3d, float motion_time = 0.0f);
void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state);
void sync_film();
void sync_view();
@@ -81,12 +81,13 @@ private:
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
- void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int motion);
- Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, bool hide_tris);
+ void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index = 0);
+ Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris);
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
void sync_background_light();
- void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
- void sync_camera_motion(BL::Object b_ob, int motion);
+ void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time);
+ void sync_camera_motion(BL::Object b_ob, float motion_time);
/* particles */
bool sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object);
@@ -109,6 +110,7 @@ private:
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
set<Mesh*> mesh_synced;
set<Mesh*> mesh_motion_synced;
+ std::set<float> motion_times;
void *world_map;
bool world_recalc;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 58e523d7fc2..35e417d8069 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -42,7 +42,14 @@ void python_thread_state_restore(void **python_thread_state);
static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render, bool calc_undeformed)
{
- return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true, calc_undeformed);
+ BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
+ if ((bool)me) {
+ if (me.use_auto_smooth()) {
+ me.calc_normals_split(me.auto_smooth_angle());
+ }
+ me.calc_tessface();
+ }
+ return me;
}
static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
@@ -50,7 +57,7 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size
for(int i = 0; i < size; i++) {
float color[4];
- ramp.evaluate(i/(float)(size-1), color);
+ ramp.evaluate((float)i/(float)(size-1), color);
data[i] = make_float4(color[0], color[1], color[2], color[3]);
}
}
@@ -67,7 +74,7 @@ static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *d
BL::CurveMap mapI = cumap.curves[3];
for(int i = 0; i < size; i++) {
- float t = i/(float)(size-1);
+ float t = (float)i/(float)(size-1);
data[i][0] = mapR.evaluate(mapI.evaluate(t));
data[i][1] = mapG.evaluate(mapI.evaluate(t));
@@ -76,7 +83,7 @@ static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *d
}
else {
for(int i = 0; i < size; i++) {
- float t = i/(float)(size-1);
+ float t = (float)i/(float)(size-1);
data[i][0] = mapR.evaluate(t);
data[i][1] = mapG.evaluate(t);
@@ -168,6 +175,11 @@ static inline float4 get_float4(BL::Array<float, 4> array)
return make_float4(array[0], array[1], array[2], array[3]);
}
+static inline int3 get_int3(BL::Array<int, 3> array)
+{
+ return make_int3(array[0], array[1], array[2]);
+}
+
static inline int4 get_int4(BL::Array<int, 4> array)
{
return make_int4(array[0], array[1], array[2], array[3]);
@@ -341,6 +353,52 @@ static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size
loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
}
+/* object used for motion blur */
+static inline bool object_use_motion(BL::Object b_ob)
+{
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_motion = get_boolean(cobject, "use_motion_blur");
+
+ return use_motion;
+}
+
+/* object motion steps */
+static inline uint object_motion_steps(BL::Object b_ob)
+{
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ uint steps = get_int(cobject, "motion_steps");
+
+ /* use uneven number of steps so we get one keyframe at the current frame,
+ * and ue 2^(steps - 1) so objects with more/fewer steps still have samples
+ * at the same times, to avoid sampling at many different times */
+ return (2 << (steps - 1)) + 1;
+}
+
+/* object uses deformation motion blur */
+static inline bool object_use_deform_motion(BL::Object b_ob)
+{
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+ bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
+
+ return use_deform_motion;
+}
+
+static inline BL::SmokeDomainSettings object_smoke_domain_find(BL::Object b_ob)
+{
+ BL::Object::modifiers_iterator b_mod;
+
+ for(b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
+ if (b_mod->is_a(&RNA_SmokeModifier)) {
+ BL::SmokeModifier b_smd(*b_mod);
+
+ if(b_smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN)
+ return b_smd.domain_settings();
+ }
+ }
+
+ return BL::SmokeDomainSettings(PointerRNA_NULL);
+}
+
/* ID Map
*
* Utility class to keep in sync with blender data.
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 6c636ac5c8d..3c0c5c021c8 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -77,13 +77,25 @@ bool BVH::cache_read(CacheData& key)
key.add(&params, sizeof(params));
foreach(Object *ob, objects) {
- key.add(ob->mesh->verts);
- key.add(ob->mesh->triangles);
- key.add(ob->mesh->curve_keys);
- key.add(ob->mesh->curves);
+ Mesh *mesh = ob->mesh;
+
+ key.add(mesh->verts);
+ key.add(mesh->triangles);
+ key.add(mesh->curve_keys);
+ key.add(mesh->curves);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
- key.add(&ob->mesh->transform_applied, sizeof(bool));
+ key.add(&mesh->transform_applied, sizeof(bool));
+
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if(attr)
+ key.add(attr->buffer);
+
+ attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if(attr)
+ key.add(attr->buffer);
+ }
}
CacheData value;
@@ -97,7 +109,7 @@ bool BVH::cache_read(CacheData& key)
value.read(pack.nodes);
value.read(pack.object_node);
value.read(pack.tri_woop);
- value.read(pack.prim_segment);
+ value.read(pack.prim_type);
value.read(pack.prim_visibility);
value.read(pack.prim_index);
value.read(pack.prim_object);
@@ -119,7 +131,7 @@ void BVH::cache_write(CacheData& key)
value.add(pack.nodes);
value.add(pack.object_node);
value.add(pack.tri_woop);
- value.add(pack.prim_segment);
+ value.add(pack.prim_type);
value.add(pack.prim_visibility);
value.add(pack.prim_index);
value.add(pack.prim_object);
@@ -165,11 +177,11 @@ void BVH::build(Progress& progress)
}
/* build nodes */
- vector<int> prim_segment;
+ vector<int> prim_type;
vector<int> prim_index;
vector<int> prim_object;
- BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
+ BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
BVHNode *root = bvh_build.run();
if(progress.get_cancel()) {
@@ -178,7 +190,7 @@ void BVH::build(Progress& progress)
}
/* todo: get rid of this copy */
- pack.prim_segment = prim_segment;
+ pack.prim_type = prim_type;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
@@ -238,9 +250,12 @@ void BVH::refit(Progress& progress)
void BVH::pack_triangle(int idx, float4 woop[3])
{
- /* create Woop triangle */
int tob = pack.prim_object[idx];
const Mesh *mesh = objects[tob]->mesh;
+
+ if(mesh->has_motion_blur())
+ return;
+
int tidx = pack.prim_index[idx];
const int *vidx = mesh->triangles[tidx].v;
const float3* vpos = &mesh->verts[0];
@@ -280,11 +295,11 @@ void BVH::pack_curve_segment(int idx, float4 woop[3])
int tob = pack.prim_object[idx];
const Mesh *mesh = objects[tob]->mesh;
int tidx = pack.prim_index[idx];
- int segment = pack.prim_segment[idx];
+ int segment = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[idx]);
int k0 = mesh->curves[tidx].first_key + segment;
int k1 = mesh->curves[tidx].first_key + segment + 1;
- float3 v0 = mesh->curve_keys[k0].co;
- float3 v1 = mesh->curve_keys[k1].co;
+ float3 v0 = float4_to_float3(mesh->curve_keys[k0]);
+ float3 v1 = float4_to_float3(mesh->curve_keys[k1]);
float3 d0 = v1 - v0;
float l = len(d0);
@@ -324,7 +339,7 @@ void BVH::pack_primitives()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- if(pack.prim_segment[i] != ~0)
+ if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
pack_curve_segment(i, woop);
else
pack_triangle(i, woop);
@@ -335,7 +350,7 @@ void BVH::pack_primitives()
Object *ob = objects[tob];
pack.prim_visibility[i] = ob->visibility;
- if(pack.prim_segment[i] != ~0)
+ if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
pack.prim_visibility[i] |= PATH_RAY_CURVE;
}
else {
@@ -359,7 +374,7 @@ void BVH::pack_instances(size_t nodes_size)
* meshes with transform applied and already in the top level BVH */
for(size_t i = 0; i < pack.prim_index.size(); i++)
if(pack.prim_index[i] != -1) {
- if(pack.prim_segment[i] != ~0)
+ if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
else
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
@@ -401,7 +416,7 @@ void BVH::pack_instances(size_t nodes_size)
mesh_map.clear();
pack.prim_index.resize(prim_index_size);
- pack.prim_segment.resize(prim_index_size);
+ pack.prim_type.resize(prim_index_size);
pack.prim_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.tri_woop.resize(tri_woop_size);
@@ -409,7 +424,7 @@ void BVH::pack_instances(size_t nodes_size)
pack.object_node.resize(objects.size());
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
- int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
+ int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
@@ -454,16 +469,16 @@ void BVH::pack_instances(size_t nodes_size)
if(bvh->pack.prim_index.size()) {
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
int *bvh_prim_index = &bvh->pack.prim_index[0];
- int *bvh_prim_segment = &bvh->pack.prim_segment[0];
+ int *bvh_prim_type = &bvh->pack.prim_type[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
for(size_t i = 0; i < bvh_prim_index_size; i++) {
- if(bvh->pack.prim_segment[i] != ~0)
+ if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
else
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
- pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
+ pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
pack_prim_index_offset++;
@@ -629,37 +644,51 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
/* primitives */
const Mesh *mesh = ob->mesh;
- if(pack.prim_segment[prim] != ~0) {
+ if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* curves */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
- int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
- int k1 = k0 + 1;
-
- float3 p[4];
- p[0] = mesh->curve_keys[max(k0 - 1,mesh->curves[pidx - str_offset].first_key)].co;
- p[1] = mesh->curve_keys[k0].co;
- p[2] = mesh->curve_keys[k1].co;
- p[3] = mesh->curve_keys[min(k1 + 1,mesh->curves[pidx - str_offset].first_key + mesh->curves[pidx - str_offset].num_keys - 1)].co;
- float3 lower;
- float3 upper;
- curvebounds(&lower.x, &upper.x, p, 0);
- curvebounds(&lower.y, &upper.y, p, 1);
- curvebounds(&lower.z, &upper.z, p, 2);
- float mr = max(mesh->curve_keys[k0].radius,mesh->curve_keys[k1].radius);
- bbox.grow(lower, mr);
- bbox.grow(upper, mr);
+ const Mesh::Curve& curve = mesh->curves[pidx - str_offset];
+ int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
+
+ curve.bounds_grow(k, &mesh->curve_keys[0], bbox);
visibility |= PATH_RAY_CURVE;
+
+ /* motion curves */
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float4 *key_steps = attr->data_float4();
+
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i*mesh_size, bbox);
+ }
+ }
}
else {
/* triangles */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- const int *vidx = mesh->triangles[pidx - tri_offset].v;
+ const Mesh::Triangle& triangle = mesh->triangles[pidx - tri_offset];
const float3 *vpos = &mesh->verts[0];
- bbox.grow(vpos[vidx[0]]);
- bbox.grow(vpos[vidx[1]]);
- bbox.grow(vpos[vidx[2]]);
+ triangle.bounds_grow(vpos, bbox);
+
+ /* motion triangles */
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr) {
+ size_t mesh_size = mesh->verts.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++)
+ triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
+ }
+ }
}
}
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index f2c96638b84..5fcaaaa988c 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -52,8 +52,8 @@ struct PackedBVH {
array<int> object_node;
/* precomputed triangle intersection data, one triangle is 4x float4 */
array<float4> tri_woop;
- /* primitive type - triangle or strand (should be moved to flag?) */
- array<int> prim_segment;
+ /* primitive type - triangle or strand */
+ array<int> prim_type;
/* visibility visibilitys for primitives */
array<uint> prim_visibility;
/* mapping from BVH primitive index to true primitive index, as primitives
diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp
index 05a674a47a7..bd37ffbcf38 100644
--- a/intern/cycles/bvh/bvh_binning.cpp
+++ b/intern/cycles/bvh/bvh_binning.cpp
@@ -83,14 +83,14 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
int4 bin1 = get_bin(prim1.bounds());
/* increase bounds for bins for even primitive */
- int b00 = extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds());
- int b01 = extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds());
- int b02 = extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds());
+ int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds());
+ int b01 = (int)extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds());
+ int b02 = (int)extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds());
/* increase bounds of bins for odd primitive */
- int b10 = extract<0>(bin1); bin_count[b10][0]++; bin_bounds[b10][0].grow(prim1.bounds());
- int b11 = extract<1>(bin1); bin_count[b11][1]++; bin_bounds[b11][1].grow(prim1.bounds());
- int b12 = extract<2>(bin1); bin_count[b12][2]++; bin_bounds[b12][2].grow(prim1.bounds());
+ int b10 = (int)extract<0>(bin1); bin_count[b10][0]++; bin_bounds[b10][0].grow(prim1.bounds());
+ int b11 = (int)extract<1>(bin1); bin_count[b11][1]++; bin_bounds[b11][1].grow(prim1.bounds());
+ int b12 = (int)extract<2>(bin1); bin_count[b12][2]++; bin_bounds[b12][2].grow(prim1.bounds());
}
/* for uneven number of primitives */
@@ -100,9 +100,9 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
int4 bin0 = get_bin(prim0.bounds());
/* increase bounds of bins */
- int b00 = extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds());
- int b01 = extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds());
- int b02 = extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds());
+ int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(prim0.bounds());
+ int b01 = (int)extract<1>(bin0); bin_count[b01][1]++; bin_bounds[b01][1].grow(prim0.bounds());
+ int b02 = (int)extract<2>(bin0); bin_count[b02][2]++; bin_bounds[b02][2].grow(prim0.bounds());
}
}
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index b21b20a87e5..eb4cca92b6b 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -49,10 +49,10 @@ public:
/* Constructor / Destructor */
BVHBuild::BVHBuild(const vector<Object*>& objects_,
- vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
+ vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
const BVHParams& params_, Progress& progress_)
: objects(objects_),
- prim_segment(prim_segment_),
+ prim_type(prim_type_),
prim_index(prim_index_),
prim_object(prim_object_),
params(params_),
@@ -70,45 +70,66 @@ BVHBuild::~BVHBuild()
void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
{
+ Attribute *attr_mP = NULL;
+
+ if(mesh->has_motion_blur())
+ attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
for(uint j = 0; j < mesh->triangles.size(); j++) {
Mesh::Triangle t = mesh->triangles[j];
BoundBox bounds = BoundBox::empty;
+ PrimitiveType type = PRIMITIVE_TRIANGLE;
+
+ t.bounds_grow(&mesh->verts[0], bounds);
- for(int k = 0; k < 3; k++) {
- float3 co = mesh->verts[t.v[k]];
- bounds.grow(co);
+ /* motion triangles */
+ if(attr_mP) {
+ size_t mesh_size = mesh->verts.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *vert_steps = attr_mP->data_float3();
+
+ for(size_t i = 0; i < steps; i++)
+ t.bounds_grow(vert_steps + i*mesh_size, bounds);
+
+ type = PRIMITIVE_MOTION_TRIANGLE;
}
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, ~0));
+ references.push_back(BVHReference(bounds, j, i, type));
root.grow(bounds);
center.grow(bounds.center2());
}
}
+ Attribute *curve_attr_mP = NULL;
+
+ if(mesh->has_motion_blur())
+ curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
for(uint j = 0; j < mesh->curves.size(); j++) {
Mesh::Curve curve = mesh->curves[j];
+ PrimitiveType type = PRIMITIVE_CURVE;
for(int k = 0; k < curve.num_keys - 1; k++) {
BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], bounds);
+
+ /* motion curve */
+ if(curve_attr_mP) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float4 *key_steps = curve_attr_mP->data_float4();
- float3 co[4];
- co[0] = mesh->curve_keys[max(curve.first_key + k - 1,curve.first_key)].co;
- co[1] = mesh->curve_keys[curve.first_key + k].co;
- co[2] = mesh->curve_keys[curve.first_key + k + 1].co;
- co[3] = mesh->curve_keys[min(curve.first_key + k + 2, curve.first_key + curve.num_keys - 1)].co;
-
- float3 lower;
- float3 upper;
- curvebounds(&lower.x, &upper.x, co, 0);
- curvebounds(&lower.y, &upper.y, co, 1);
- curvebounds(&lower.z, &upper.z, co, 2);
- float mr = max(mesh->curve_keys[curve.first_key + k].radius, mesh->curve_keys[curve.first_key + k + 1].radius);
- bounds.grow(lower, mr);
- bounds.grow(upper, mr);
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i*mesh_size, bounds);
+
+ type = PRIMITIVE_MOTION_CURVE;
+ }
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, k));
+ int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
+
+ references.push_back(BVHReference(bounds, j, i, packed_type));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -118,7 +139,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
{
- references.push_back(BVHReference(ob->bounds, -1, i, false));
+ references.push_back(BVHReference(ob->bounds, -1, i, 0));
root.grow(ob->bounds);
center.grow(ob->bounds.center2());
}
@@ -207,7 +228,7 @@ BVHNode* BVHBuild::run()
progress_total = references.size();
progress_original_total = progress_total;
- prim_segment.resize(references.size());
+ prim_type.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
@@ -277,18 +298,41 @@ void BVHBuild::thread_build_node(InnerNode *inner, int child, BVHObjectBinning *
}
}
+bool BVHBuild::range_within_max_leaf_size(const BVHRange& range)
+{
+ size_t size = range.size();
+ size_t max_leaf_size = max(params.max_triangle_leaf_size, params.max_curve_leaf_size);
+
+ if(size > max_leaf_size)
+ return false;
+
+ size_t num_triangles = 0;
+ size_t num_curves = 0;
+
+ for(int i = 0; i < size; i++) {
+ BVHReference& ref = references[range.start() + i];
+
+ if(ref.prim_type() & PRIMITIVE_ALL_CURVE)
+ num_curves++;
+ else if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE)
+ num_triangles++;
+ }
+
+ return (num_triangles < params.max_triangle_leaf_size) && (num_curves < params.max_curve_leaf_size);
+}
+
/* multithreaded binning builder */
BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level)
{
size_t size = range.size();
- float leafSAH = params.sah_triangle_cost * range.leafSAH;
- float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_triangle_cost * range.splitSAH;
+ float leafSAH = params.sah_primitive_cost * range.leafSAH;
+ float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_primitive_cost * range.splitSAH;
/* have at least one inner node on top level, for performance and correct
* visibility tests, since object instances do not check visibility flag */
if(!(range.size() > 0 && params.top_level && level == 0)) {
/* make leaf node when threshold reached or SAH tells us */
- if(params.small_enough_for_leaf(size, level) || (size <= params.max_leaf_size && leafSAH < splitSAH))
+ if(params.small_enough_for_leaf(size, level) || (range_within_max_leaf_size(range) && leafSAH < splitSAH))
return create_leaf_node(range);
}
@@ -373,12 +417,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
if(start == prim_index.size()) {
assert(params.use_spatial_split);
- prim_segment.push_back(ref->prim_segment());
+ prim_type.push_back(ref->prim_type());
prim_index.push_back(ref->prim_index());
prim_object.push_back(ref->prim_object());
}
else {
- prim_segment[start] = ref->prim_segment();
+ prim_type[start] = ref->prim_type();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
}
@@ -401,7 +445,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
{
- vector<int>& p_segment = prim_segment;
+ vector<int>& p_type = prim_type;
vector<int>& p_index = prim_index;
vector<int>& p_object = prim_object;
BoundBox bounds = BoundBox::empty;
@@ -415,12 +459,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
if(range.start() + num == prim_index.size()) {
assert(params.use_spatial_split);
- p_segment.push_back(ref.prim_segment());
+ p_type.push_back(ref.prim_type());
p_index.push_back(ref.prim_index());
p_object.push_back(ref.prim_object());
}
else {
- p_segment[range.start() + num] = ref.prim_segment();
+ p_type[range.start() + num] = ref.prim_type();
p_index[range.start() + num] = ref.prim_index();
p_object[range.start() + num] = ref.prim_object();
}
@@ -490,7 +534,7 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
/* find best rotation. we pick a target child of a first child, and swap
* this with an other child. we perform the best such swap. */
float best_cost = FLT_MAX;
- int best_child = -1, bets_target = -1, best_other = -1;
+ int best_child = -1, best_target = -1, best_other = -1;
for(size_t c = 0; c < 2; c++) {
/* ignore leaf nodes as we cannot descent into */
@@ -514,11 +558,11 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
if(cost0 < cost1) {
best_cost = cost0;
- bets_target = 0;
+ best_target = 0;
}
else {
best_cost = cost0;
- bets_target = 1;
+ best_target = 1;
}
}
}
@@ -527,10 +571,13 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
if(best_cost >= 0)
return;
+ assert(best_child == 0 || best_child == 1);
+ assert(best_target != -1);
+
/* perform the best found tree rotation */
InnerNode *child = (InnerNode*)parent->children[best_child];
- swap(parent->children[best_other], child->children[bets_target]);
+ swap(parent->children[best_other], child->children[best_target]);
child->m_bounds = merge(child->children[0]->m_bounds, child->children[1]->m_bounds);
}
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index 3df4da1739a..a6b9916de9b 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -44,7 +44,7 @@ public:
/* Constructor/Destructor */
BVHBuild(
const vector<Object*>& objects,
- vector<int>& prim_segment,
+ vector<int>& prim_type,
vector<int>& prim_index,
vector<int>& prim_object,
const BVHParams& params,
@@ -70,6 +70,8 @@ protected:
BVHNode *create_leaf_node(const BVHRange& range);
BVHNode *create_object_leaf_nodes(const BVHReference *ref, int start, int num);
+ bool range_within_max_leaf_size(const BVHRange& range);
+
/* threads */
enum { THREAD_TASK_SIZE = 4096 };
void thread_build_node(InnerNode *node, int child, BVHObjectBinning *range, int level);
@@ -88,7 +90,7 @@ protected:
int num_original_references;
/* output primitive indexes and objects */
- vector<int>& prim_segment;
+ vector<int>& prim_type;
vector<int>& prim_index;
vector<int>& prim_object;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index ad36bdfa326..ed67690a07f 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -33,11 +33,12 @@ public:
/* SAH costs */
float sah_node_cost;
- float sah_triangle_cost;
+ float sah_primitive_cost;
- /* number of triangles in leaf */
+ /* number of primitives in leaf */
int min_leaf_size;
- int max_leaf_size;
+ int max_triangle_leaf_size;
+ int max_curve_leaf_size;
/* object or mesh level bvh */
int top_level;
@@ -62,11 +63,14 @@ public:
use_spatial_split = true;
spatial_split_alpha = 1e-5f;
+ /* todo: see if splitting up primitive cost to be separate for triangles
+ * and curves can help. so far in tests it doesn't help, but why? */
sah_node_cost = 1.0f;
- sah_triangle_cost = 1.0f;
+ sah_primitive_cost = 1.0f;
min_leaf_size = 1;
- max_leaf_size = 8;
+ max_triangle_leaf_size = 8;
+ max_curve_leaf_size = 2;
top_level = false;
use_cache = false;
@@ -75,11 +79,11 @@ public:
}
/* SAH costs */
- __forceinline float cost(int num_nodes, int num_tris) const
- { return node_cost(num_nodes) + triangle_cost(num_tris); }
+ __forceinline float cost(int num_nodes, int num_primitives) const
+ { return node_cost(num_nodes) + primitive_cost(num_primitives); }
- __forceinline float triangle_cost(int n) const
- { return n*sah_triangle_cost; }
+ __forceinline float primitive_cost(int n) const
+ { return n*sah_primitive_cost; }
__forceinline float node_cost(int n) const
{ return n*sah_node_cost; }
@@ -98,22 +102,22 @@ class BVHReference
public:
__forceinline BVHReference() {}
- __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
+ __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
: rbounds(bounds_)
{
rbounds.min.w = __int_as_float(prim_index_);
rbounds.max.w = __int_as_float(prim_object_);
- segment = prim_segment;
+ type = prim_type;
}
__forceinline const BoundBox& bounds() const { return rbounds; }
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
- __forceinline int prim_segment() const { return segment; }
+ __forceinline int prim_type() const { return type; }
protected:
BoundBox rbounds;
- uint segment;
+ uint type;
};
/* BVH Range
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index d7dbae36336..3140bf23376 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -52,8 +52,8 @@ public:
else if(ra.prim_object() > rb.prim_object()) return false;
else if(ra.prim_index() < rb.prim_index()) return true;
else if(ra.prim_index() > rb.prim_index()) return false;
- else if(ra.prim_segment() < rb.prim_segment()) return true;
- else if(ra.prim_segment() > rb.prim_segment()) return false;
+ else if(ra.prim_type() < rb.prim_type()) return true;
+ else if(ra.prim_type() > rb.prim_type()) return false;
return false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 03ff69d7b6d..07c35c08c18 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -54,8 +54,8 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder, const BVHRange& range, float n
right_bounds = builder->spatial_right_bounds[i - 1];
float sah = nodeSAH +
- left_bounds.safe_area() * builder->params.triangle_cost(i) +
- right_bounds.safe_area() * builder->params.triangle_cost(range.size() - i);
+ left_bounds.safe_area() * builder->params.primitive_cost(i) +
+ right_bounds.safe_area() * builder->params.primitive_cost(range.size() - i);
if(sah < min_sah) {
min_sah = sah;
@@ -150,8 +150,8 @@ BVHSpatialSplit::BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float
rightNum -= builder->spatial_bins[dim][i - 1].exit;
float sah = nodeSAH +
- left_bounds.safe_area() * builder->params.triangle_cost(leftNum) +
- builder->spatial_right_bounds[i - 1].safe_area() * builder->params.triangle_cost(rightNum);
+ left_bounds.safe_area() * builder->params.primitive_cost(leftNum) +
+ builder->spatial_right_bounds[i - 1].safe_area() * builder->params.primitive_cost(rightNum);
if(sah < this->sah) {
this->sah = sah;
@@ -209,10 +209,10 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right,
ldb.grow(lref.bounds());
rdb.grow(rref.bounds());
- float lac = builder->params.triangle_cost(left_end - left_start);
- float rac = builder->params.triangle_cost(right_end - right_start);
- float lbc = builder->params.triangle_cost(left_end - left_start + 1);
- float rbc = builder->params.triangle_cost(right_end - right_start + 1);
+ float lac = builder->params.primitive_cost(left_end - left_start);
+ float rac = builder->params.primitive_cost(right_end - right_start);
+ float lbc = builder->params.primitive_cost(left_end - left_start + 1);
+ float rbc = builder->params.primitive_cost(right_end - right_start + 1);
float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac;
float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc;
@@ -253,7 +253,7 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
Object *ob = builder->objects[ref.prim_object()];
const Mesh *mesh = ob->mesh;
- if (ref.prim_segment() == ~0) {
+ if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
const int *inds = mesh->triangles[ref.prim_index()].v;
const float3 *verts = &mesh->verts[0];
const float3* v1 = &verts[inds[2]];
@@ -282,30 +282,32 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
}
else {
/* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
- const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
+ const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type());
const int k1 = k0 + 1;
- const float3* v0 = &mesh->curve_keys[k0].co;
- const float3* v1 = &mesh->curve_keys[k1].co;
+ const float4 key0 = mesh->curve_keys[k0];
+ const float4 key1 = mesh->curve_keys[k1];
+ const float3 v0 = float4_to_float3(key0);
+ const float3 v1 = float4_to_float3(key1);
- float v0p = (*v0)[dim];
- float v1p = (*v1)[dim];
+ float v0p = v0[dim];
+ float v1p = v1[dim];
/* insert vertex to the boxes it belongs to. */
if(v0p <= pos)
- left_bounds.grow(*v0);
+ left_bounds.grow(v0);
if(v0p >= pos)
- right_bounds.grow(*v0);
+ right_bounds.grow(v0);
if(v1p <= pos)
- left_bounds.grow(*v1);
+ left_bounds.grow(v1);
if(v1p >= pos)
- right_bounds.grow(*v1);
+ right_bounds.grow(v1);
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
left_bounds.grow(t);
right_bounds.grow(t);
}
@@ -318,8 +320,8 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
right_bounds.intersect(ref.bounds());
/* set references */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
+ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
+ right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h
index 1f4befbe8e2..5b739311e5f 100644
--- a/intern/cycles/bvh/bvh_split.h
+++ b/intern/cycles/bvh/bvh_split.h
@@ -77,7 +77,7 @@ public:
/* find split candidates. */
float area = range.bounds().safe_area();
- leafSAH = area * builder->params.triangle_cost(range.size());
+ leafSAH = area * builder->params.primitive_cost(range.size());
nodeSAH = area * builder->params.node_cost(2);
object = BVHObjectSplit(builder, range, nodeSAH);
@@ -92,7 +92,7 @@ public:
/* leaf SAH is the lowest => create leaf. */
minSAH = min(min(leafSAH, object.sah), spatial.sah);
- no_split = (minSAH == leafSAH && range.size() <= builder->params.max_leaf_size);
+ no_split = (minSAH == leafSAH && builder->range_within_max_leaf_size(range));
}
__forceinline void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 9d60d062b8e..d9e68742c53 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -53,7 +53,8 @@ void Device::pixels_free(device_memory& mem)
mem_free(mem);
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
pixels_copy_from(rgba, y, w, h);
@@ -80,6 +81,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
glEnable(GL_TEXTURE_2D);
+ if(draw_params.bind_display_space_shader_cb) {
+ draw_params.bind_display_space_shader_cb();
+ }
+
glPushMatrix();
glTranslatef(0.0f, (float)dy, 0.0f);
@@ -98,6 +103,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
glPopMatrix();
+ if(draw_params.unbind_display_space_shader_cb) {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glDeleteTextures(1, &texid);
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index bd309e35788..bcddd4f73e2 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -54,6 +54,7 @@ public:
bool display_device;
bool advanced_shading;
bool pack_images;
+ bool extended_images; /* flag for GPU and Multi device */
vector<DeviceInfo> multi_devices;
DeviceInfo()
@@ -64,11 +65,17 @@ public:
display_device = false;
advanced_shading = true;
pack_images = false;
+ extended_images = false;
}
};
/* Device */
+struct DeviceDrawParams {
+ boost::function<void(void)> bind_display_space_shader_cb;
+ boost::function<void(void)> unbind_display_space_shader_cb;
+};
+
class Device {
protected:
Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {}
@@ -100,7 +107,7 @@ public:
/* texture memory */
virtual void tex_alloc(const char *name, device_memory& mem,
- bool interpolation = false, bool periodic = false) {};
+ InterpolationType interpolation = INTERPOLATION_NONE, bool periodic = false) {};
virtual void tex_free(device_memory& mem) {};
/* pixel memory */
@@ -121,7 +128,8 @@ public:
/* opengl drawing */
virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int dy, int width, int height, bool transparent);
+ int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
/* networking */
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 76123fe44d2..c9cc7592028 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -103,9 +103,9 @@ public:
kernel_const_copy(&kernel_globals, name, host, size);
}
- void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+ void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic)
{
- kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height);
+ kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height, mem.data_depth, interpolation);
mem.device_pointer = mem.data_pointer;
stats.mem_alloc(mem.memory_size());
@@ -395,7 +395,7 @@ public:
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_avx_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
- if(task_pool.canceled())
+ if(task.get_cancel() || task_pool.canceled())
break;
}
}
@@ -406,7 +406,7 @@ public:
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_sse41_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
- if(task_pool.canceled())
+ if(task.get_cancel() || task_pool.canceled())
break;
}
}
@@ -417,7 +417,7 @@ public:
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
- if(task_pool.canceled())
+ if(task.get_cancel() || task_pool.canceled())
break;
}
}
@@ -428,7 +428,7 @@ public:
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
- if(task_pool.canceled())
+ if(task.get_cancel() || task_pool.canceled())
break;
}
}
@@ -438,7 +438,7 @@ public:
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
- if(task_pool.canceled())
+ if(task.get_cancel() || task_pool.canceled())
break;
}
}
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 107ca16c4d2..93b89dc38d9 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -48,6 +48,7 @@ public:
int cuDevArchitecture;
bool first_error;
bool use_texture_storage;
+ unsigned int target_update_frequency;
struct PixelMem {
GLuint cuPBO;
@@ -138,7 +139,7 @@ public:
/*cuda_abort();*/ \
cuda_error_documentation(); \
} \
- }
+ } (void)0
bool cuda_error_(CUresult result, const string& stmt)
{
@@ -165,7 +166,7 @@ public:
void cuda_push_context()
{
- cuda_assert(cuCtxSetCurrent(cuContext))
+ cuda_assert(cuCtxSetCurrent(cuContext));
}
void cuda_pop_context()
@@ -173,12 +174,14 @@ public:
cuda_assert(cuCtxSetCurrent(NULL));
}
- CUDADevice(DeviceInfo& info, Stats &stats, bool background_)
+ CUDADevice(DeviceInfo& info, Stats &stats, bool background_)
: Device(info, stats, background_)
{
first_error = true;
background = background_;
use_texture_storage = true;
+ /* we try an update / sync every 1000 ms */
+ target_update_frequency = 1000;
cuDevId = info.num;
cuDevice = 0;
@@ -209,8 +212,8 @@ public:
if(cuda_error_(result, "cuCtxCreate"))
return;
- cuda_assert(cuStreamCreate(&cuStream, 0))
- cuda_assert(cuEventCreate(&tileDone, 0x1))
+ cuda_assert(cuStreamCreate(&cuStream, 0));
+ cuda_assert(cuEventCreate(&tileDone, 0x1));
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
@@ -219,7 +222,7 @@ public:
/* In order to use full 6GB of memory on Titan cards, use arrays instead
* of textures. On earlier cards this seems slower, but on Titan it is
* actually slightly faster in tests. */
- use_texture_storage = (cuDevArchitecture < 350);
+ use_texture_storage = (cuDevArchitecture < 300);
cuda_pop_context();
}
@@ -228,21 +231,22 @@ public:
{
task_pool.stop();
- cuda_assert(cuEventDestroy(tileDone))
- cuda_assert(cuStreamDestroy(cuStream))
- cuda_assert(cuCtxDestroy(cuContext))
+ cuda_assert(cuEventDestroy(tileDone));
+ cuda_assert(cuStreamDestroy(cuStream));
+ cuda_assert(cuCtxDestroy(cuContext));
}
- bool support_device(bool experimental)
+ bool support_device(bool experimental, bool branched)
{
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
-
+
+ /* We only support sm_20 and above */
if(major < 2) {
cuda_error_message(string_printf("CUDA device supported only with compute capability 2.0 or up, found %d.%d.", major, minor));
return false;
}
-
+
return true;
}
@@ -293,28 +297,16 @@ public:
return "";
}
if(cuda_version < 50) {
- printf("Unsupported CUDA version %d.%d detected, you need CUDA 5.0.\n", cuda_version/10, cuda_version%10);
+ printf("Unsupported CUDA version %d.%d detected, you need CUDA 6.0.\n", cuda_version/10, cuda_version%10);
return "";
}
-
- else if(cuda_version > 50)
- printf("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported.\n", cuda_version/10, cuda_version%10);
+ else if(cuda_version != 60)
+ printf("CUDA version %d.%d detected, build may succeed but only CUDA 6.0 is officially supported.\n", cuda_version/10, cuda_version%10);
/* compile */
string kernel = path_join(kernel_path, "kernel.cu");
string include = kernel_path;
const int machine = system_cpu_bits();
- string arch_flags;
-
- /* CUDA 5.x build flags for different archs */
- if(major == 2) {
- /* sm_2x */
- arch_flags = "--maxrregcount=32 --use_fast_math";
- }
- else if(major == 3) {
- /* sm_3x */
- arch_flags = "--maxrregcount=32 --use_fast_math";
- }
double starttime = time_dt();
printf("Compiling CUDA kernel ...\n");
@@ -322,8 +314,8 @@ public:
path_create_directories(cubin);
string command = string_printf("\"%s\" -arch=sm_%d%d -m%d --cubin \"%s\" "
- "-o \"%s\" --ptxas-options=\"-v\" %s -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d",
- nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), arch_flags.c_str(), include.c_str(), cuda_version);
+ "-o \"%s\" --ptxas-options=\"-v\" -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d",
+ nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), include.c_str(), cuda_version);
printf("%s\n", command.c_str());
@@ -349,8 +341,8 @@ public:
if(cuContext == 0)
return false;
- /* check if GPU is supported with current feature set */
- if(!support_device(experimental))
+ /* check if GPU is supported */
+ if(!support_device(experimental, false))
return false;
/* get kernel */
@@ -383,7 +375,7 @@ public:
cuda_push_context();
CUdeviceptr device_pointer;
size_t size = mem.memory_size();
- cuda_assert(cuMemAlloc(&device_pointer, size))
+ cuda_assert(cuMemAlloc(&device_pointer, size));
mem.device_pointer = (device_ptr)device_pointer;
stats.mem_alloc(size);
cuda_pop_context();
@@ -393,7 +385,7 @@ public:
{
cuda_push_context();
if(mem.device_pointer)
- cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()))
+ cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()));
cuda_pop_context();
}
@@ -405,7 +397,7 @@ public:
cuda_push_context();
if(mem.device_pointer) {
cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
- (CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
+ (CUdeviceptr)((uchar*)mem.device_pointer + offset), size));
}
else {
memset((char*)mem.data_pointer + offset, 0, size);
@@ -419,7 +411,7 @@ public:
cuda_push_context();
if(mem.device_pointer)
- cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()))
+ cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()));
cuda_pop_context();
}
@@ -427,7 +419,7 @@ public:
{
if(mem.device_pointer) {
cuda_push_context();
- cuda_assert(cuMemFree(cuda_device_ptr(mem.device_pointer)))
+ cuda_assert(cuMemFree(cuda_device_ptr(mem.device_pointer)));
cuda_pop_context();
mem.device_pointer = 0;
@@ -442,19 +434,21 @@ public:
size_t bytes;
cuda_push_context();
- cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, name))
+ cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, name));
//assert(bytes == size);
- cuda_assert(cuMemcpyHtoD(mem, host, size))
+ cuda_assert(cuMemcpyHtoD(mem, host, size));
cuda_pop_context();
}
- void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+ void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic)
{
+ /* todo: support 3D textures, only CPU for now */
+
/* determine format */
CUarray_format_enum format;
size_t dsize = datatype_size(mem.data_type);
size_t size = mem.memory_size();
- bool use_texture = interpolation || use_texture_storage;
+ bool use_texture = (interpolation != INTERPOLATION_NONE) || use_texture_storage;
if(use_texture) {
@@ -469,14 +463,14 @@ public:
CUtexref texref = NULL;
cuda_push_context();
- cuda_assert(cuModuleGetTexRef(&texref, cuModule, name))
+ cuda_assert(cuModuleGetTexRef(&texref, cuModule, name));
if(!texref) {
cuda_pop_context();
return;
}
- if(interpolation) {
+ if(interpolation != INTERPOLATION_NONE) {
CUarray handle = NULL;
CUDA_ARRAY_DESCRIPTOR desc;
@@ -485,7 +479,7 @@ public:
desc.Format = format;
desc.NumChannels = mem.data_elements;
- cuda_assert(cuArrayCreate(&handle, &desc))
+ cuda_assert(cuArrayCreate(&handle, &desc));
if(!handle) {
cuda_pop_context();
@@ -503,15 +497,23 @@ public:
param.WidthInBytes = param.srcPitch;
param.Height = mem.data_height;
- cuda_assert(cuMemcpy2D(&param))
+ cuda_assert(cuMemcpy2D(&param));
}
else
- cuda_assert(cuMemcpyHtoA(handle, 0, (void*)mem.data_pointer, size))
+ cuda_assert(cuMemcpyHtoA(handle, 0, (void*)mem.data_pointer, size));
- cuda_assert(cuTexRefSetArray(texref, handle, CU_TRSA_OVERRIDE_FORMAT))
+ cuda_assert(cuTexRefSetArray(texref, handle, CU_TRSA_OVERRIDE_FORMAT));
- cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_LINEAR))
- cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES))
+ if(interpolation == INTERPOLATION_CLOSEST) {
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT));
+ }
+ else if (interpolation == INTERPOLATION_LINEAR) {
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_LINEAR));
+ }
+ else {/* CUBIC and SMART are unsupported for CUDA */
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_LINEAR));
+ }
+ cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES));
mem.device_pointer = (device_ptr)handle;
@@ -525,20 +527,20 @@ public:
cuda_push_context();
- cuda_assert(cuTexRefSetAddress(NULL, texref, cuda_device_ptr(mem.device_pointer), size))
- cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT))
- cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER))
+ cuda_assert(cuTexRefSetAddress(NULL, texref, cuda_device_ptr(mem.device_pointer), size));
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT));
+ cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER));
}
if(periodic) {
- cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP))
- cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP))
+ cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP));
+ cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP));
}
else {
- cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP))
- cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_CLAMP))
+ cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP));
+ cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_CLAMP));
}
- cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements))
+ cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements));
cuda_pop_context();
}
@@ -551,23 +553,23 @@ public:
CUdeviceptr cumem;
size_t cubytes;
- cuda_assert(cuModuleGetGlobal(&cumem, &cubytes, cuModule, name))
+ cuda_assert(cuModuleGetGlobal(&cumem, &cubytes, cuModule, name));
if(cubytes == 8) {
/* 64 bit device pointer */
uint64_t ptr = mem.device_pointer;
- cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes))
+ cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes));
}
else {
/* 32 bit device pointer */
uint32_t ptr = (uint32_t)mem.device_pointer;
- cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes))
+ cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes));
}
cuda_pop_context();
}
- tex_interp_map[mem.device_pointer] = interpolation;
+ tex_interp_map[mem.device_pointer] = (interpolation != INTERPOLATION_NONE);
}
void tex_free(device_memory& mem)
@@ -602,10 +604,12 @@ public:
CUdeviceptr d_rng_state = cuda_device_ptr(rtile.rng_state);
/* get kernel function */
- if(branched)
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"))
- else
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"))
+ if(branched && support_device(true, branched)) {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
+ }
if(have_error())
return;
@@ -613,49 +617,63 @@ public:
/* pass in parameters */
int offset = 0;
- cuda_assert(cuParamSetv(cuPathTrace, offset, &d_buffer, sizeof(d_buffer)))
+ cuda_assert(cuParamSetv(cuPathTrace, offset, &d_buffer, sizeof(d_buffer)));
offset += sizeof(d_buffer);
- cuda_assert(cuParamSetv(cuPathTrace, offset, &d_rng_state, sizeof(d_rng_state)))
+ cuda_assert(cuParamSetv(cuPathTrace, offset, &d_rng_state, sizeof(d_rng_state)));
offset += sizeof(d_rng_state);
offset = align_up(offset, __alignof(sample));
- cuda_assert(cuParamSeti(cuPathTrace, offset, sample))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, sample));
offset += sizeof(sample);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.x))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.x));
offset += sizeof(rtile.x);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.y))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.y));
offset += sizeof(rtile.y);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.w))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.w));
offset += sizeof(rtile.w);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.h))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.h));
offset += sizeof(rtile.h);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.offset))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.offset));
offset += sizeof(rtile.offset);
- cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.stride))
+ cuda_assert(cuParamSeti(cuPathTrace, offset, rtile.stride));
offset += sizeof(rtile.stride);
- cuda_assert(cuParamSetSize(cuPathTrace, offset))
+ cuda_assert(cuParamSetSize(cuPathTrace, offset));
+
+ /* launch kernel */
+ int threads_per_block;
+ cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuPathTrace));
+
+ /*int num_registers;
+ cuda_assert(cuFuncGetAttribute(&num_registers, CU_FUNC_ATTRIBUTE_NUM_REGS, cuPathTrace));
+
+ printf("threads_per_block %d\n", threads_per_block);
+ printf("num_registers %d\n", num_registers);*/
- /* launch kernel: todo find optimal size, cache config for fermi */
- int xthreads = 16;
- int ythreads = 16;
+ int xthreads = (int)sqrt((float)threads_per_block);
+ int ythreads = (int)sqrt((float)threads_per_block);
int xblocks = (rtile.w + xthreads - 1)/xthreads;
int yblocks = (rtile.h + ythreads - 1)/ythreads;
- cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1))
- cuda_assert(cuFuncSetBlockShape(cuPathTrace, xthreads, ythreads, 1))
- cuda_assert(cuLaunchGridAsync(cuPathTrace, xblocks, yblocks, cuStream))
+ cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetBlockShape(cuPathTrace, xthreads, ythreads, 1));
- cuda_assert(cuEventRecord(tileDone, cuStream ))
- cuda_assert(cuEventSynchronize(tileDone))
+ if(info.display_device) {
+ /* don't use async for device used for display, locks up UI too much */
+ cuda_assert(cuLaunchGrid(cuPathTrace, xblocks, yblocks));
+ cuda_assert(cuCtxSynchronize());
+ }
+ else {
+ cuda_assert(cuLaunchGridAsync(cuPathTrace, xblocks, yblocks, cuStream));
+ }
cuda_pop_context();
}
@@ -672,55 +690,60 @@ public:
CUdeviceptr d_buffer = cuda_device_ptr(buffer);
/* get kernel function */
- if(rgba_half)
- cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_half_float"))
- else
- cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_byte"))
+ if(rgba_half) {
+ cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_half_float"));
+ }
+ else {
+ cuda_assert(cuModuleGetFunction(&cuFilmConvert, cuModule, "kernel_cuda_convert_to_byte"));
+ }
/* pass in parameters */
int offset = 0;
- cuda_assert(cuParamSetv(cuFilmConvert, offset, &d_rgba, sizeof(d_rgba)))
+ cuda_assert(cuParamSetv(cuFilmConvert, offset, &d_rgba, sizeof(d_rgba)));
offset += sizeof(d_rgba);
- cuda_assert(cuParamSetv(cuFilmConvert, offset, &d_buffer, sizeof(d_buffer)))
+ cuda_assert(cuParamSetv(cuFilmConvert, offset, &d_buffer, sizeof(d_buffer)));
offset += sizeof(d_buffer);
float sample_scale = 1.0f/(task.sample + 1);
offset = align_up(offset, __alignof(sample_scale));
- cuda_assert(cuParamSetf(cuFilmConvert, offset, sample_scale))
+ cuda_assert(cuParamSetf(cuFilmConvert, offset, sample_scale));
offset += sizeof(sample_scale);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.x))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.x));
offset += sizeof(task.x);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.y))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.y));
offset += sizeof(task.y);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.w))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.w));
offset += sizeof(task.w);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.h))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.h));
offset += sizeof(task.h);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.offset))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.offset));
offset += sizeof(task.offset);
- cuda_assert(cuParamSeti(cuFilmConvert, offset, task.stride))
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.stride));
offset += sizeof(task.stride);
- cuda_assert(cuParamSetSize(cuFilmConvert, offset))
+ cuda_assert(cuParamSetSize(cuFilmConvert, offset));
+
+ /* launch kernel */
+ int threads_per_block;
+ cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuFilmConvert));
- /* launch kernel: todo find optimal size, cache config for fermi */
- int xthreads = 16;
- int ythreads = 16;
+ int xthreads = (int)sqrt((float)threads_per_block);
+ int ythreads = (int)sqrt((float)threads_per_block);
int xblocks = (task.w + xthreads - 1)/xthreads;
int yblocks = (task.h + ythreads - 1)/ythreads;
- cuda_assert(cuFuncSetCacheConfig(cuFilmConvert, CU_FUNC_CACHE_PREFER_L1))
- cuda_assert(cuFuncSetBlockShape(cuFilmConvert, xthreads, ythreads, 1))
- cuda_assert(cuLaunchGrid(cuFilmConvert, xblocks, yblocks))
+ cuda_assert(cuFuncSetCacheConfig(cuFilmConvert, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetBlockShape(cuFilmConvert, xthreads, ythreads, 1));
+ cuda_assert(cuLaunchGrid(cuFilmConvert, xblocks, yblocks));
unmap_pixels((rgba_byte)? rgba_byte: rgba_half);
@@ -734,40 +757,55 @@ public:
cuda_push_context();
- CUfunction cuDisplace;
+ CUfunction cuShader;
CUdeviceptr d_input = cuda_device_ptr(task.shader_input);
CUdeviceptr d_output = cuda_device_ptr(task.shader_output);
/* get kernel function */
- cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_shader"))
-
- /* pass in parameters */
- int offset = 0;
-
- cuda_assert(cuParamSetv(cuDisplace, offset, &d_input, sizeof(d_input)))
- offset += sizeof(d_input);
+ cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_shader"));
+
+ /* do tasks in smaller chunks, so we can cancel it */
+ const int shader_chunk_size = 65536;
+ const int start = task.shader_x;
+ const int end = task.shader_x + task.shader_w;
- cuda_assert(cuParamSetv(cuDisplace, offset, &d_output, sizeof(d_output)))
- offset += sizeof(d_output);
+ for(int shader_x = start; shader_x < end; shader_x += shader_chunk_size) {
+ if(task.get_cancel())
+ break;
- int shader_eval_type = task.shader_eval_type;
- offset = align_up(offset, __alignof(shader_eval_type));
+ /* pass in parameters */
+ int offset = 0;
- cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_eval_type))
- offset += sizeof(task.shader_eval_type);
+ cuda_assert(cuParamSetv(cuShader, offset, &d_input, sizeof(d_input)));
+ offset += sizeof(d_input);
- cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_x))
- offset += sizeof(task.shader_x);
+ cuda_assert(cuParamSetv(cuShader, offset, &d_output, sizeof(d_output)));
+ offset += sizeof(d_output);
- cuda_assert(cuParamSetSize(cuDisplace, offset))
+ int shader_eval_type = task.shader_eval_type;
+ offset = align_up(offset, __alignof(shader_eval_type));
- /* launch kernel: todo find optimal size, cache config for fermi */
- int xthreads = 16;
- int xblocks = (task.shader_w + xthreads - 1)/xthreads;
+ cuda_assert(cuParamSeti(cuShader, offset, task.shader_eval_type));
+ offset += sizeof(task.shader_eval_type);
- cuda_assert(cuFuncSetCacheConfig(cuDisplace, CU_FUNC_CACHE_PREFER_L1))
- cuda_assert(cuFuncSetBlockShape(cuDisplace, xthreads, 1, 1))
- cuda_assert(cuLaunchGrid(cuDisplace, xblocks, 1))
+ cuda_assert(cuParamSeti(cuShader, offset, shader_x));
+ offset += sizeof(shader_x);
+
+ cuda_assert(cuParamSetSize(cuShader, offset));
+
+ /* launch kernel */
+ int threads_per_block;
+ cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, cuShader));
+
+ int shader_w = min(shader_chunk_size, end - shader_x);
+ int xblocks = (shader_w + threads_per_block - 1)/threads_per_block;
+
+ cuda_assert(cuFuncSetCacheConfig(cuShader, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetBlockShape(cuShader, threads_per_block, 1, 1));
+ cuda_assert(cuLaunchGrid(cuShader, xblocks, 1));
+
+ cuda_assert(cuCtxSynchronize());
+ }
cuda_pop_context();
}
@@ -779,8 +817,8 @@ public:
CUdeviceptr buffer;
size_t bytes;
- cuda_assert(cuGraphicsMapResources(1, &pmem.cuPBOresource, 0))
- cuda_assert(cuGraphicsResourceGetMappedPointer(&buffer, &bytes, pmem.cuPBOresource))
+ cuda_assert(cuGraphicsMapResources(1, &pmem.cuPBOresource, 0));
+ cuda_assert(cuGraphicsResourceGetMappedPointer(&buffer, &bytes, pmem.cuPBOresource));
return buffer;
}
@@ -793,7 +831,7 @@ public:
if(!background) {
PixelMem pmem = pixel_mem_map[mem];
- cuda_assert(cuGraphicsUnmapResources(1, &pmem.cuPBOresource, 0))
+ cuda_assert(cuGraphicsUnmapResources(1, &pmem.cuPBOresource, 0));
}
}
@@ -882,7 +920,7 @@ public:
cuda_push_context();
- cuda_assert(cuGraphicsUnregisterResource(pmem.cuPBOresource))
+ cuda_assert(cuGraphicsUnregisterResource(pmem.cuPBOresource));
glDeleteBuffers(1, &pmem.cuPBO);
glDeleteTextures(1, &pmem.cuTexId);
@@ -900,7 +938,8 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent)
+ void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
if(!background) {
PixelMem pmem = pixel_mem_map[mem.device_pointer];
@@ -933,6 +972,10 @@ public:
glColor3f(1.0f, 1.0f, 1.0f);
+ if(draw_params.bind_display_space_shader_cb) {
+ draw_params.bind_display_space_shader_cb();
+ }
+
glPushMatrix();
glTranslatef(0.0f, (float)dy, 0.0f);
@@ -951,6 +994,10 @@ public:
glPopMatrix();
+ if(draw_params.unbind_display_space_shader_cb) {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
if(transparent) {
glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* reset blender default */
@@ -964,7 +1011,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, dy, width, height, transparent);
+ Device::draw_pixels(mem, y, w, h, dy, width, height, transparent, draw_params);
}
void thread_run(DeviceTask *task)
@@ -979,6 +1026,10 @@ public:
int start_sample = tile.start_sample;
int end_sample = tile.start_sample + tile.num_samples;
+ boost::posix_time::ptime start_time(boost::posix_time::microsec_clock::local_time());
+ boost::posix_time::ptime last_time = start_time;
+ int sync_sample = 10;
+
for(int sample = start_sample; sample < end_sample; sample++) {
if (task->get_cancel()) {
if(task->need_finish_queue == false)
@@ -988,8 +1039,28 @@ public:
path_trace(tile, sample, branched);
tile.sample = sample + 1;
-
task->update_progress(tile);
+
+ if(!info.display_device && sample == sync_sample) {
+ cuda_push_context();
+ cuda_assert(cuEventRecord(tileDone, cuStream));
+ cuda_assert(cuEventSynchronize(tileDone));
+
+ /* Do some time keeping to find out if we need to sync less */
+ boost::posix_time::ptime current_time(boost::posix_time::microsec_clock::local_time());
+ boost::posix_time::time_duration sample_duration = current_time - last_time;
+
+ long msec = sample_duration.total_milliseconds();
+ float scaling_factor = (float)target_update_frequency / (float)msec;
+
+ /* sync at earliest next sample and probably later */
+ sync_sample = (sample + 1) + sync_sample * (int)ceil(scaling_factor);
+
+ sync_sample = min(end_sample - 1, sync_sample); // make sure we sync the last sample always
+
+ last_time = current_time;
+ cuda_pop_context();
+ }
}
task->release_tile(tile);
@@ -999,7 +1070,7 @@ public:
shader(*task);
cuda_push_context();
- cuda_assert(cuCtxSynchronize())
+ cuda_assert(cuCtxSynchronize());
cuda_pop_context();
}
}
@@ -1020,7 +1091,7 @@ public:
film_convert(task, task.buffer, task.rgba_byte, task.rgba_half);
cuda_push_context();
- cuda_assert(cuCtxSynchronize())
+ cuda_assert(cuCtxSynchronize());
cuda_pop_context();
}
else {
@@ -1081,6 +1152,7 @@ void device_cuda_info(vector<DeviceInfo>& devices)
int major, minor;
cuDeviceComputeCapability(&major, &minor, num);
info.advanced_shading = (major >= 2);
+ info.extended_images = (major >= 3);
info.pack_images = false;
/* if device has a kernel timeout, assume it is used for display */
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 1427d12cba2..8d6f4a49a9c 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -169,6 +169,7 @@ public:
size_t data_size;
size_t data_width;
size_t data_height;
+ size_t data_depth;
/* device pointer */
device_ptr device_pointer;
@@ -195,6 +196,7 @@ public:
data_size = 0;
data_width = 0;
data_height = 0;
+ data_depth = 0;
assert(data_elements > 0);
@@ -204,20 +206,21 @@ public:
virtual ~device_vector() {}
/* vector functions */
- T *resize(size_t width, size_t height = 0)
+ T *resize(size_t width, size_t height = 0, size_t depth = 0)
{
- data_size = (height == 0)? width: width*height;
+ data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth);
data.resize(data_size);
data_pointer = (device_ptr)&data[0];
data_width = width;
data_height = height;
+ data_depth = depth;
return &data[0];
}
- T *copy(T *ptr, size_t width, size_t height = 0)
+ T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0)
{
- T *mem = resize(width, height);
+ T *mem = resize(width, height, depth);
memcpy(mem, ptr, memory_size());
return mem;
}
@@ -230,13 +233,14 @@ public:
}
}
- void reference(T *ptr, size_t width, size_t height = 0)
+ void reference(T *ptr, size_t width, size_t height = 0, size_t depth = 0)
{
data.clear();
- data_size = (height == 0)? width: width*height;
+ data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth);
data_pointer = (device_ptr)ptr;
data_width = width;
data_height = height;
+ data_depth = depth;
}
void clear()
@@ -245,6 +249,7 @@ public:
data_pointer = 0;
data_width = 0;
data_height = 0;
+ data_depth = 0;
data_size = 0;
}
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 27b9de0769e..c866ebaaea2 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -168,7 +168,7 @@ public:
sub.device->const_copy_to(name, host, size);
}
- void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+ void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic)
{
foreach(SubDevice& sub, devices) {
mem.device_pointer = 0;
@@ -233,7 +233,8 @@ public:
mem.device_pointer = tmp;
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+ void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+ const DeviceDrawParams &draw_params)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -247,7 +248,7 @@ public:
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
+ sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent, draw_params);
i++;
}
@@ -327,6 +328,7 @@ static bool device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool
info.advanced_shading = with_advanced_shading;
info.pack_images = false;
+ info.extended_images = true;
foreach(DeviceInfo& subinfo, devices) {
if(subinfo.type == type) {
@@ -350,6 +352,7 @@ static bool device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool
if(subinfo.display_device)
info.display_device = true;
info.pack_images = info.pack_images || subinfo.pack_images;
+ info.extended_images = info.extended_images && subinfo.extended_images;
num_added++;
}
}
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index bffd993818f..af051076009 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -162,7 +162,7 @@ public:
snd.write_buffer(host, size);
}
- void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+ void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic)
{
thread_scoped_lock lock(rpc_lock);
@@ -326,7 +326,7 @@ class DeviceServer {
public:
thread_mutex rpc_lock;
- void network_error(const string &message){
+ void network_error(const string &message) {
error_func.network_error(message);
}
@@ -366,7 +366,7 @@ protected:
{
/* create a new DataVector and insert it into mem_data */
pair<DataMap::iterator,bool> data_ins = mem_data.insert(
- DataMap::value_type(client_pointer, DataVector()));
+ DataMap::value_type(client_pointer, DataVector()));
/* make sure it was a unique insertion */
assert(data_ins.second);
@@ -559,7 +559,7 @@ protected:
else if(rcv.name == "tex_alloc") {
network_device_memory mem;
string name;
- bool interpolation;
+ InterpolationType interpolation;
bool periodic;
device_ptr client_pointer;
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index bf8f3c70c49..893841d1da7 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -118,7 +118,7 @@ public:
void add(const device_memory& mem)
{
archive & mem.data_type & mem.data_elements & mem.data_size;
- archive & mem.data_width & mem.data_height & mem.device_pointer;
+ archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer;
}
template<typename T> void add(const T& data)
@@ -209,7 +209,7 @@ public:
boost::system::error_code error;
size_t len = boost::asio::read(socket, boost::asio::buffer(header), error);
- if(error.value()){
+ if(error.value()) {
error_func->network_error(error.message());
}
@@ -261,7 +261,7 @@ public:
void read(network_device_memory& mem)
{
*archive & mem.data_type & mem.data_elements & mem.data_size;
- *archive & mem.data_width & mem.data_height & mem.device_pointer;
+ *archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer;
mem.data_pointer = 0;
}
@@ -276,7 +276,7 @@ public:
boost::system::error_code error;
size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size), error);
- if(error.value()){
+ if(error.value()) {
error_func->network_error(error.message());
}
@@ -391,7 +391,7 @@ private:
/* add address if it's not already in the list */
bool found = std::find(servers.begin(), servers.end(),
- address) != servers.end();
+ address) != servers.end();
if(!found)
servers.push_back(address);
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 9117b70d749..694ec9db036 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -101,9 +101,6 @@ static string opencl_kernel_build_options(const string& platform, const string *
if(opencl_kernel_use_debug())
build_options += "-D__KERNEL_OPENCL_DEBUG__ ";
-
- if(opencl_kernel_use_advanced_shading(platform))
- build_options += "-D__KERNEL_OPENCL_NEED_ADVANCED_SHADING__ ";
return build_options;
}
@@ -409,10 +406,22 @@ public:
fprintf(stderr, "%s\n", message.c_str());
}
- void opencl_assert(cl_int err)
+#define opencl_assert(stmt) \
+ { \
+ cl_int err = stmt; \
+ \
+ if(err != CL_SUCCESS) { \
+ string message = string_printf("OpenCL error: %s in %s", opencl_error_string(err), #stmt); \
+ if(error_msg == "") \
+ error_msg = message; \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ } \
+ } (void)0
+
+ void opencl_assert_err(cl_int err, const char* where)
{
if(err != CL_SUCCESS) {
- string message = string_printf("OpenCL error (%d): %s", err, opencl_error_string(err));
+ string message = string_printf("OpenCL error (%d): %s in %s", err, opencl_error_string(err), where);
if(error_msg == "")
error_msg = message;
fprintf(stderr, "%s\n", message.c_str());
@@ -452,8 +461,10 @@ public:
vector<cl_platform_id> platforms(num_platforms, NULL);
ciErr = clGetPlatformIDs(num_platforms, &platforms[0], NULL);
- if(opencl_error(ciErr))
+ if(opencl_error(ciErr)) {
+ fprintf(stderr, "clGetPlatformIDs failed \n");
return;
+ }
int num_base = 0;
int total_devices = 0;
@@ -478,8 +489,10 @@ public:
/* get devices */
vector<cl_device_id> device_ids(num_devices, NULL);
- if(opencl_error(clGetDeviceIDs(cpPlatform, opencl_device_type(), num_devices, &device_ids[0], NULL)))
+ if(opencl_error(clGetDeviceIDs(cpPlatform, opencl_device_type(), num_devices, &device_ids[0], NULL))) {
+ fprintf(stderr, "clGetDeviceIDs failed \n");
return;
+ }
cdDevice = device_ids[info.num - num_base];
@@ -515,8 +528,10 @@ public:
cxContext = clCreateContext(context_props, 1, &cdDevice,
context_notify_callback, cdDevice, &ciErr);
- if(opencl_error(ciErr))
+ if(opencl_error(ciErr)) {
+ opencl_error("OpenCL: clCreateContext failed");
return;
+ }
/* cache it */
OpenCLCache::store_context(cpPlatform, cdDevice, cxContext, cache_locker);
@@ -531,6 +546,7 @@ public:
if(opencl_error(ciErr))
return;
+ fprintf(stderr,"Device init succes\n");
device_initialized = true;
}
@@ -821,7 +837,7 @@ public:
mem.device_pointer = (device_ptr)clCreateBuffer(cxContext, mem_flag, size, mem_ptr, &ciErr);
- opencl_assert(ciErr);
+ opencl_assert_err(ciErr, "clCreateBuffer");
stats.mem_alloc(size);
}
@@ -830,8 +846,7 @@ public:
{
/* this is blocking */
size_t size = mem.memory_size();
- ciErr = clEnqueueWriteBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, 0, size, (void*)mem.data_pointer, 0, NULL, NULL);
- opencl_assert(ciErr);
+ opencl_assert(clEnqueueWriteBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, 0, size, (void*)mem.data_pointer, 0, NULL, NULL));
}
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
@@ -839,8 +854,7 @@ public:
size_t offset = elem*y*w;
size_t size = elem*w*h;
- ciErr = clEnqueueReadBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, offset, size, (uchar*)mem.data_pointer + offset, 0, NULL, NULL);
- opencl_assert(ciErr);
+ opencl_assert(clEnqueueReadBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, offset, size, (uchar*)mem.data_pointer + offset, 0, NULL, NULL));
}
void mem_zero(device_memory& mem)
@@ -854,9 +868,8 @@ public:
void mem_free(device_memory& mem)
{
if(mem.device_pointer) {
- ciErr = clReleaseMemObject(CL_MEM_PTR(mem.device_pointer));
+ opencl_assert(clReleaseMemObject(CL_MEM_PTR(mem.device_pointer)));
mem.device_pointer = 0;
- opencl_assert(ciErr);
stats.mem_free(mem.memory_size());
}
@@ -881,7 +894,7 @@ public:
mem_copy_to(*i->second);
}
- void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+ void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic)
{
mem_alloc(mem, MEM_READ_ONLY);
mem_copy_to(mem);
@@ -919,7 +932,7 @@ public:
CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t)*3, max_work_items, NULL);
/* try to divide evenly over 2 dimensions */
- size_t sqrt_workgroup_size = max(sqrt((double)workgroup_size), 1.0);
+ size_t sqrt_workgroup_size = max((size_t)sqrt((double)workgroup_size), 1);
size_t local_size[2] = {sqrt_workgroup_size, sqrt_workgroup_size};
/* some implementations have max size 1 on 2nd dimension */
@@ -931,8 +944,7 @@ public:
size_t global_size[2] = {global_size_round_up(local_size[0], w), global_size_round_up(local_size[1], h)};
/* run kernel */
- ciErr = clEnqueueNDRangeKernel(cqCommandQueue, kernel, 2, NULL, global_size, NULL, 0, NULL, NULL);
- opencl_assert(ciErr);
+ opencl_assert(clEnqueueNDRangeKernel(cqCommandQueue, kernel, 2, NULL, global_size, NULL, 0, NULL, NULL));
opencl_assert(clFlush(cqCommandQueue));
}
@@ -952,33 +964,29 @@ public:
/* sample arguments */
cl_uint narg = 0;
- ciErr = 0;
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_data), (void*)&d_data);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_buffer), (void*)&d_buffer);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_rng_state), (void*)&d_rng_state);
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_data), (void*)&d_data));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_buffer), (void*)&d_buffer));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_rng_state), (void*)&d_rng_state));
#define KERNEL_TEX(type, ttype, name) \
- ciErr |= set_kernel_arg_mem(ckPathTraceKernel, &narg, #name);
+ set_kernel_arg_mem(ckPathTraceKernel, &narg, #name);
#include "kernel_textures.h"
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_sample), (void*)&d_sample);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_x), (void*)&d_x);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_h), (void*)&d_h);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_offset), (void*)&d_offset);
- ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_stride), (void*)&d_stride);
-
- opencl_assert(ciErr);
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_sample), (void*)&d_sample));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_x), (void*)&d_x));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_h), (void*)&d_h));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_offset), (void*)&d_offset));
+ opencl_assert(clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_stride), (void*)&d_stride));
enqueue_kernel(ckPathTraceKernel, d_w, d_h);
}
- cl_int set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name)
+ void set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name)
{
cl_mem ptr;
- cl_int err = 0;
MemMap::iterator i = mem_map.find(name);
if(i != mem_map.end()) {
@@ -989,10 +997,7 @@ public:
ptr = CL_MEM_PTR(null_mem);
}
- err |= clSetKernelArg(kernel, (*narg)++, sizeof(ptr), (void*)&ptr);
- opencl_assert(err);
-
- return err;
+ opencl_assert(clSetKernelArg(kernel, (*narg)++, sizeof(ptr), (void*)&ptr));
}
void film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half)
@@ -1011,27 +1016,27 @@ public:
/* sample arguments */
cl_uint narg = 0;
- ciErr = 0;
+
cl_kernel ckFilmConvertKernel = (rgba_byte)? ckFilmConvertByteKernel: ckFilmConvertHalfFloatKernel;
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_data), (void*)&d_data);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_rgba), (void*)&d_rgba);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_buffer), (void*)&d_buffer);
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_data), (void*)&d_data));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_rgba), (void*)&d_rgba));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_buffer), (void*)&d_buffer));
#define KERNEL_TEX(type, ttype, name) \
- ciErr |= set_kernel_arg_mem(ckFilmConvertKernel, &narg, #name);
+ set_kernel_arg_mem(ckFilmConvertKernel, &narg, #name);
#include "kernel_textures.h"
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_sample_scale), (void*)&d_sample_scale);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_x), (void*)&d_x);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_w), (void*)&d_w);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_h), (void*)&d_h);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_offset), (void*)&d_offset);
- ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_stride), (void*)&d_stride);
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_sample_scale), (void*)&d_sample_scale));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_x), (void*)&d_x));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_w), (void*)&d_w));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_h), (void*)&d_h));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_offset), (void*)&d_offset));
+ opencl_assert(clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_stride), (void*)&d_stride));
+
- opencl_assert(ciErr);
enqueue_kernel(ckFilmConvertKernel, d_w, d_h);
}
@@ -1048,21 +1053,18 @@ public:
/* sample arguments */
cl_uint narg = 0;
- ciErr = 0;
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_data), (void*)&d_data);
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_input), (void*)&d_input);
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_output), (void*)&d_output);
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_data), (void*)&d_data));
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_input), (void*)&d_input));
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_output), (void*)&d_output));
#define KERNEL_TEX(type, ttype, name) \
- ciErr |= set_kernel_arg_mem(ckShaderKernel, &narg, #name);
+ set_kernel_arg_mem(ckShaderKernel, &narg, #name);
#include "kernel_textures.h"
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_eval_type), (void*)&d_shader_eval_type);
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_x), (void*)&d_shader_x);
- ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_w), (void*)&d_shader_w);
-
- opencl_assert(ciErr);
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_eval_type), (void*)&d_shader_eval_type));
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_x), (void*)&d_shader_x));
+ opencl_assert(clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_w), (void*)&d_shader_w));
enqueue_kernel(ckShaderKernel, task.shader_w, 1);
}
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index cbe0d4b5d10..d18f4fa2998 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -12,10 +12,6 @@ set(INC_SYS
set(SRC
kernel.cpp
- kernel_sse2.cpp
- kernel_sse3.cpp
- kernel_sse41.cpp
- kernel_avx.cpp
kernel.cl
kernel.cu
)
@@ -23,14 +19,10 @@ set(SRC
set(SRC_HEADERS
kernel.h
kernel_accumulate.h
- kernel_bvh.h
- kernel_bvh_subsurface.h
- kernel_bvh_traversal.h
kernel_camera.h
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
- kernel_curve.h
kernel_differential.h
kernel_displace.h
kernel_emission.h
@@ -40,18 +32,15 @@ set(SRC_HEADERS
kernel_light.h
kernel_math.h
kernel_montecarlo.h
- kernel_object.h
kernel_passes.h
kernel_path.h
kernel_path_state.h
- kernel_primitive.h
kernel_projection.h
kernel_random.h
kernel_shader.h
kernel_shadow.h
kernel_subsurface.h
kernel_textures.h
- kernel_triangle.h
kernel_types.h
kernel_volume.h
)
@@ -118,6 +107,21 @@ set(SRC_SVM_HEADERS
svm/svm_wave.h
)
+set(SRC_GEOM_HEADERS
+ geom/geom.h
+ geom/geom_attribute.h
+ geom/geom_bvh.h
+ geom/geom_bvh_subsurface.h
+ geom/geom_bvh_traversal.h
+ geom/geom_curve.h
+ geom/geom_motion_curve.h
+ geom/geom_motion_triangle.h
+ geom/geom_object.h
+ geom/geom_primitive.h
+ geom/geom_triangle.h
+ geom/geom_volume.h
+)
+
set(SRC_UTIL_HEADERS
../util/util_color.h
../util/util_half.h
@@ -142,37 +146,45 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
# warn for other versions
- if(CUDA_VERSION MATCHES "50")
+ if(CUDA_VERSION MATCHES "60")
else()
- message(WARNING "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, build may succeed but only CUDA 5.0 is officially supported")
+ message(WARNING
+ "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
+ "build may succeed but only CUDA 6.0 is officially supported")
endif()
# build for each arch
- set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS})
+ set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_GEOM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS})
set(cuda_cubins)
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
set(cuda_cubin kernel_${arch}.cubin)
set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}")
-
- # CUDA 5.x build flags for different archs
- if(${arch} MATCHES "sm_2[0-9]")
- # sm_2x
- set(cuda_arch_flags "--maxrregcount=32")
- elseif(${arch} MATCHES "sm_3[0-9]")
- # sm_3x
- set(cuda_arch_flags "--maxrregcount=32")
- endif()
-
set(cuda_math_flags "--use_fast_math")
-
- if(CUDA_VERSION LESS 50 AND ${arch} MATCHES "sm_35")
+
+ if(CUDA_VERSION LESS 60 AND ${arch} MATCHES "sm_50")
+ message(WARNING "Can't build kernel for CUDA sm_50 architecture, skipping")
+ elseif(CUDA_VERSION LESS 50 AND ${arch} MATCHES "sm_35")
message(WARNING "Can't build kernel for CUDA sm_35 architecture, skipping")
else()
add_custom_command(
OUTPUT ${cuda_cubin}
- COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} ${cuda_version_flags} ${cuda_math_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC
+ COMMAND ${CUDA_NVCC_EXECUTABLE}
+ -arch=${arch}
+ -m${CUDA_BITS}
+ --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu
+ -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin}
+ --ptxas-options="-v"
+ ${cuda_arch_flags}
+ ${cuda_version_flags}
+ ${cuda_math_flags}
+ -I${CMAKE_CURRENT_SOURCE_DIR}/../util
+ -I${CMAKE_CURRENT_SOURCE_DIR}/svm
+ -DCCL_NAMESPACE_BEGIN=
+ -DCCL_NAMESPACE_END=
+ -DNVCC
+
DEPENDS ${cuda_sources})
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib)
@@ -195,12 +207,22 @@ endif()
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
-set_source_files_properties(kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
-set_source_files_properties(kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
-set_source_files_properties(kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
-set_source_files_properties(kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+if(CXX_HAS_SSE)
+ list(APPEND SRC
+ kernel_sse2.cpp
+ kernel_sse3.cpp
+ kernel_sse41.cpp
+ kernel_avx.cpp
+ )
+
+ set_source_files_properties(kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
+ set_source_files_properties(kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
+ set_source_files_properties(kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
+ set_source_files_properties(kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
+endif()
+
-add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_SVM_HEADERS})
+add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_SVM_HEADERS} ${SRC_GEOM_HEADERS})
if(WITH_CYCLES_CUDA)
add_dependencies(cycles_kernel cycles_kernel_cuda)
@@ -221,5 +243,6 @@ delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernel.cu" ${CYCLES_INSTALL_PATH}/k
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_CLOSURE_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel/closure)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_SVM_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel/svm)
+delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_GEOM_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel/geom)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_UTIL_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel)
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 5077d8c96b0..04e1bad7538 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -60,6 +60,7 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
kernel_file = os.path.join(source_dir, "kernel.cu")
util_dir = os.path.join(source_dir, "../util")
svm_dir = os.path.join(source_dir, "../svm")
+ geom_dir = os.path.join(source_dir, "../geom")
closure_dir = os.path.join(source_dir, "../closure")
# get CUDA version
@@ -68,37 +69,33 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
cuda_major_minor = re.findall(r'release (\d+).(\d+)', output)[0]
cuda_version = int(cuda_major_minor[0])*10 + int(cuda_major_minor[1])
- if cuda_version != 50:
- print("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported." % (cuda_version/10, cuda_version%10))
+ if cuda_version != 60:
+ print("CUDA version %d.%d detected, build may succeed but only CUDA 6.0 is officially supported." % (cuda_version/10, cuda_version%10))
# nvcc flags
nvcc_flags = "-m%s" % (bits)
nvcc_flags += " --cubin --ptxas-options=\"-v\""
nvcc_flags += " -D__KERNEL_CUDA_VERSION__=%d" % (cuda_version)
nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC"
- nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, closure_dir)
+ nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, geom_dir, closure_dir)
# dependencies
- dependencies = ['kernel.cu'] + kernel.Glob('*.h') + kernel.Glob('../util/*.h') + kernel.Glob('svm/*.h') + kernel.Glob('closure/*.h')
+ 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
# add command for each cuda architecture
for arch in cuda_archs:
- cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch)
+ if cuda_version < 60 and arch == "sm_50":
+ print("Can't build kernel for CUDA sm_50 architecture, skipping")
+ continue
- # CUDA 5.x build flags for different archs
- if arch.startswith("sm_2"):
- # sm_2x
- cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
- elif arch.startswith("sm_3"):
- # sm_3x
- cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
+ cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch)
if env['BF_CYCLES_CUDA_ENV']:
MS_SDK = "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\SetEnv.cmd"
- command = "\"%s\" & \"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (MS_SDK, nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file)
+ command = "\"%s\" & \"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (MS_SDK, nvcc, arch, nvcc_flags, kernel_file, cubin_file)
else:
- command = "\"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file)
+ command = "\"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, kernel_file, cubin_file)
kernel.Command(cubin_file, 'kernel.cu', command)
kernel.Depends(cubin_file, dependencies)
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index 163e7cc5ee2..19cdb773255 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -84,7 +84,7 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, con
float theta_i = M_PI_2_F - safe_acosf(omega_in_z);
float cosphi_i = dot(omega_in_y, locy);
- if(M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f){
+ if(M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
*pdf = 0.0f;
return make_float3(*pdf, *pdf, *pdf);
}
@@ -99,7 +99,7 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, con
float theta_h = (theta_i + theta_r) * 0.5f;
float t = theta_h - offset;
- float phi_pdf = cos(phi_i * 0.5f) * 0.25f / roughness2;
+ float phi_pdf = cosf(phi_i * 0.5f) * 0.25f / roughness2;
float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)* costheta_i);
*pdf = phi_pdf * theta_pdf;
@@ -140,7 +140,7 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc,
float theta_i = M_PI_2_F - safe_acosf(omega_in_z);
float phi_i = safe_acosf(dot(omega_in_y, locy));
- if(M_PI_2_F - fabsf(theta_i) < 0.001f){
+ if(M_PI_2_F - fabsf(theta_i) < 0.001f) {
*pdf = 0.0f;
return make_float3(*pdf, *pdf, *pdf);
}
@@ -191,7 +191,7 @@ ccl_device int bsdf_hair_reflection_sample(const ShaderClosure *sc, float3 Ng, f
float phi = 2 * safe_asinf(1 - 2 * randv) * roughness2;
- float phi_pdf = cos(phi * 0.5f) * 0.25f / roughness2;
+ float phi_pdf = cosf(phi * 0.5f) * 0.25f / roughness2;
float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)*costheta_i);
@@ -251,8 +251,8 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng,
float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
*omega_in =(cosf(phi) * costheta_i) * locy -
- (sinf(phi) * costheta_i) * locx +
- ( sintheta_i) * Tg;
+ (sinf(phi) * costheta_i) * locx +
+ ( sintheta_i) * Tg;
//differentials - TODO: find a better approximation for the transmission bounce
#ifdef __RAY_DIFFERENTIALS__
@@ -261,7 +261,7 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng,
#endif
*pdf = fabsf(phi_pdf * theta_pdf);
- if(M_PI_2_F - fabsf(theta_i) < 0.001f){
+ if(M_PI_2_F - fabsf(theta_i) < 0.001f) {
*pdf = 0.0f;
}
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index dfa8886c113..1ec35e444fe 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -154,8 +154,8 @@ ccl_device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, fl
float sinThetaM = cosThetaM * safe_sqrtf(tanThetaM2);
float phiM = M_2PI_F * randv;
float3 m = (cosf(phiM) * sinThetaM) * X +
- (sinf(phiM) * sinThetaM) * Y +
- cosThetaM * Z;
+ (sinf(phiM) * sinThetaM) * Y +
+ ( cosThetaM) * Z;
if(!m_refractive) {
float cosMO = dot(m, I);
if(cosMO > 0) {
@@ -383,8 +383,8 @@ ccl_device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 N
float sinThetaM = cosThetaM * tanThetaM;
float phiM = M_2PI_F * randv;
float3 m = (cosf(phiM) * sinThetaM) * X +
- (sinf(phiM) * sinThetaM) * Y +
- cosThetaM * Z;
+ (sinf(phiM) * sinThetaM) * Y +
+ ( cosThetaM) * Z;
if(!m_refractive) {
float cosMO = dot(m, I);
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 219c5aea159..2b4e1c68640 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -109,8 +109,8 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colo
float sinTheta2 = 1 - cosTheta * cosTheta;
float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
*omega_in = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- ( cosTheta) * R;
+ (sinf(phi) * sinTheta) * B +
+ ( cosTheta) * R;
if (dot(Ng, *omega_in) > 0.0f)
{
// common terms for pdf and eval
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index f6dceb3ca82..b3dcb9dcc38 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -35,14 +35,15 @@
CCL_NAMESPACE_BEGIN
-ccl_device float fresnel_dielectric(float eta, const float3 N,
- const float3 I, float3 *R, float3 *T,
+ccl_device float fresnel_dielectric(
+ float eta, const float3 N,
+ const float3 I, float3 *R, float3 *T,
#ifdef __RAY_DIFFERENTIALS__
- const float3 dIdx, const float3 dIdy,
- float3 *dRdx, float3 *dRdy,
- float3 *dTdx, float3 *dTdy,
+ const float3 dIdx, const float3 dIdy,
+ float3 *dRdx, float3 *dRdy,
+ float3 *dTdx, float3 *dTdy,
#endif
- bool *is_inside)
+ bool *is_inside)
{
float cos = dot(N, I), neta;
float3 Nn;
diff --git a/intern/cycles/kernel/closure/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h
index ca4c05e91fe..9dc1c00bb3d 100644
--- a/intern/cycles/kernel/closure/bsdf_westin.h
+++ b/intern/cycles/kernel/closure/bsdf_westin.h
@@ -96,10 +96,9 @@ ccl_device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng
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)
- {
+ (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
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
new file mode 100644
index 00000000000..9495a2541f9
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom.h
@@ -0,0 +1,44 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, 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.
+ */
+
+/* bottom-most stack entry, indicating the end of traversal */
+#define ENTRYPOINT_SENTINEL 0x76543210
+
+/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
+#define BVH_STACK_SIZE 192
+#define BVH_NODE_SIZE 4
+#define TRI_NODE_SIZE 3
+
+/* silly workaround for float extended precision that happens when compiling
+ * without sse support on x86, it results in different results for float ops
+ * that you would otherwise expect to compare correctly */
+#if !defined(__i386__) || defined(__SSE__)
+#define NO_EXTENDED_PRECISION
+#else
+#define NO_EXTENDED_PRECISION volatile
+#endif
+
+#include "geom_attribute.h"
+#include "geom_object.h"
+#include "geom_triangle.h"
+#include "geom_motion_triangle.h"
+#include "geom_motion_curve.h"
+#include "geom_curve.h"
+#include "geom_volume.h"
+#include "geom_primitive.h"
+#include "geom_bvh.h"
+
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
new file mode 100644
index 00000000000..63ce31c492f
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011-2013 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
+
+/* Attributes
+ *
+ * We support an arbitrary number of attributes on various mesh elements.
+ * On vertices, triangles, curve keys, curves, meshes and volume grids.
+ * Most of the code for attribute reading is in the primitive files.
+ *
+ * Lookup of attributes is different between OSL and SVM, as OSL is ustring
+ * based while for SVM we use integer ids. */
+
+/* Find attribute based on ID */
+
+ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
+{
+ if(sd->object == PRIM_NONE)
+ return (int)ATTR_STD_NOT_FOUND;
+
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
+#endif
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
+ return ATTR_STD_NOT_FOUND;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+}
+
+/* Transform matrix attribute on meshes */
+
+ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
+{
+ Transform tfm;
+
+ tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
+ tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
+ tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
+ tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
+
+ return tfm;
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
new file mode 100644
index 00000000000..dd7c25d581d
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -0,0 +1,318 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, 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.
+ */
+
+/* BVH
+ *
+ * Bounding volume hierarchy for ray tracing. We compile different variations
+ * of the same BVH traversal function for faster rendering when some types of
+ * primitives are not needed, using #includes to work around the lack of
+ * C++ templates in OpenCL.
+ *
+ * Originally based on "Understanding the Efficiency of Ray Traversal on GPUs",
+ * the code has been extended and modified to support more primitives and work
+ * with CPU/CUDA/OpenCL. */
+
+CCL_NAMESPACE_BEGIN
+
+/* BVH intersection function variations */
+
+#define BVH_INSTANCING 1
+#define BVH_MOTION 2
+#define BVH_HAIR 4
+#define BVH_HAIR_MINIMUM_WIDTH 8
+
+#define BVH_FUNCTION_NAME bvh_intersect
+#define BVH_FUNCTION_FEATURES 0
+#include "geom_bvh_traversal.h"
+
+#if defined(__INSTANCING__)
+#define BVH_FUNCTION_NAME bvh_intersect_instancing
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING
+#include "geom_bvh_traversal.h"
+#endif
+
+#if defined(__HAIR__)
+#define BVH_FUNCTION_NAME bvh_intersect_hair
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
+#include "geom_bvh_traversal.h"
+#endif
+
+#if defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+#include "geom_bvh_traversal.h"
+#endif
+
+#if defined(__HAIR__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_hair_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
+#include "geom_bvh_traversal.h"
+#endif
+
+#if defined(__SUBSURFACE__)
+#define BVH_FUNCTION_NAME bvh_intersect_subsurface
+#define BVH_FUNCTION_FEATURES 0
+#include "geom_bvh_subsurface.h"
+#endif
+
+#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
+#define BVH_FUNCTION_NAME bvh_intersect_subsurface_instancing
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING
+#include "geom_bvh_subsurface.h"
+#endif
+
+#if defined(__SUBSURFACE__) && defined(__HAIR__)
+#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
+#include "geom_bvh_subsurface.h"
+#endif
+
+#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+#include "geom_bvh_subsurface.h"
+#endif
+
+#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
+#include "geom_bvh_subsurface.h"
+#endif
+
+#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__)
+#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__)
+#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__)
+#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__)
+#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
+#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)
+#endif
+{
+#ifdef __OBJECT_MOTION__
+ if(kernel_data.bvh.have_motion) {
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_hair_motion(kg, ray, isect, visibility, lcg_state, difl, extmax);
+#endif /* __HAIR__ */
+
+ return bvh_intersect_motion(kg, ray, isect, visibility);
+ }
+#endif /* __OBJECT_MOTION__ */
+
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_hair(kg, ray, isect, visibility, lcg_state, difl, extmax);
+#endif /* __HAIR__ */
+
+#ifdef __KERNEL_CPU__
+
+#ifdef __INSTANCING__
+ if(kernel_data.bvh.have_instancing)
+ return bvh_intersect_instancing(kg, ray, isect, visibility);
+#endif /* __INSTANCING__ */
+
+ return bvh_intersect(kg, ray, isect, visibility);
+#else /* __KERNEL_CPU__ */
+
+#ifdef __INSTANCING__
+ return bvh_intersect_instancing(kg, ray, isect, visibility);
+#else
+ return bvh_intersect(kg, ray, isect, visibility);
+#endif /* __INSTANCING__ */
+
+#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)
+{
+#ifdef __OBJECT_MOTION__
+ if(kernel_data.bvh.have_motion) {
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#endif /* __HAIR__ */
+
+ return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+ }
+#endif /* __OBJECT_MOTION__ */
+
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#endif /* __HAIR__ */
+
+#ifdef __KERNEL_CPU__
+
+#ifdef __INSTANCING__
+ if(kernel_data.bvh.have_instancing)
+ return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#endif /* __INSTANCING__ */
+
+ return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#else /* __KERNEL_CPU__ */
+
+#ifdef __INSTANCING__
+ return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#else
+ return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
+#endif /* __INSTANCING__ */
+
+#endif /* __KERNEL_CPU__ */
+}
+#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)
+{
+#ifdef __OBJECT_MOTION__
+ if(kernel_data.bvh.have_motion) {
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_shadow_all_hair_motion(kg, ray, isect, max_hits, num_hits);
+#endif /* __HAIR__ */
+
+ return bvh_intersect_shadow_all_motion(kg, ray, isect, max_hits, num_hits);
+ }
+#endif /* __OBJECT_MOTION__ */
+
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ 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);
+#else /* __KERNEL_CPU__ */
+
+#ifdef __INSTANCING__
+ return bvh_intersect_shadow_all_instancing(kg, ray, isect, max_hits, num_hits);
+#else
+ return bvh_intersect_shadow_all(kg, ray, isect, max_hits, num_hits);
+#endif /* __INSTANCING__ */
+
+#endif /* __KERNEL_CPU__ */
+}
+#endif
+
+
+/* Ray offset to avoid self intersection.
+ *
+ * This function should be used to compute a modified ray start position for
+ * rays leaving from a surface. */
+
+ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
+{
+#ifdef __INTERSECTION_REFINE__
+ const float epsilon_f = 1e-5f;
+ /* ideally this should match epsilon_f, but instancing and motion blur
+ * precision makes it problematic */
+ const float epsilon_test = 1.0f;
+ const int epsilon_i = 32;
+
+ float3 res;
+
+ /* x component */
+ if(fabsf(P.x) < epsilon_test) {
+ res.x = P.x + Ng.x*epsilon_f;
+ }
+ else {
+ uint ix = __float_as_uint(P.x);
+ ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i;
+ res.x = __uint_as_float(ix);
+ }
+
+ /* y component */
+ if(fabsf(P.y) < epsilon_test) {
+ res.y = P.y + Ng.y*epsilon_f;
+ }
+ else {
+ uint iy = __float_as_uint(P.y);
+ iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i;
+ res.y = __uint_as_float(iy);
+ }
+
+ /* z component */
+ if(fabsf(P.z) < epsilon_test) {
+ res.z = P.z + Ng.z*epsilon_f;
+ }
+ else {
+ uint iz = __float_as_uint(P.z);
+ iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i;
+ res.z = __uint_as_float(iz);
+ }
+
+ return res;
+#else
+ const float epsilon_f = 1e-4f;
+ return P + epsilon_f*Ng;
+#endif
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h
new file mode 100644
index 00000000000..98bf82b3b2d
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h
@@ -0,0 +1,375 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2013, 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, 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_array, const uint max_hits, uint *num_hits)
+{
+ /* todo:
+ * - 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 */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
+
+#if FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+#if FEATURE(BVH_INSTANCING)
+ int num_hits_in_instance = 0;
+#endif
+
+ *num_hits = 0;
+ isect_array->t = tmax;
+
+#if defined(__KERNEL_SSE2__)
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+
+ const __m128 pn = _mm_castsi128_ps(_mm_set_epi32(0x80000000, 0x80000000, 0, 0));
+ __m128 Psplat[3], idirsplat[3];
+ shuffle_swap_t shufflexyz[3];
+
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ __m128 tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
+
+ 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) & PATH_RAY_SHADOW);
+ traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & PATH_RAY_SHADOW);
+#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 __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE;
+ const float4 cnodes = ((float4*)bvh_nodes)[3];
+
+ /* intersect ray against child nodes */
+ const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[0], shufflexyz[0]), Psplat[0]), idirsplat[0]);
+ const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[1], shufflexyz[1]), Psplat[1]), idirsplat[1]);
+ const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[2], shufflexyz[2]), Psplat[2]), idirsplat[2]);
+
+ /* calculate { c0min, c1min, -c0max, -c1max} */
+ __m128 minmax = _mm_max_ps(_mm_max_ps(tminmaxx, tminmaxy), _mm_max_ps(tminmaxz, tsplat));
+ const __m128 tminmax = _mm_xor_ps(minmax, pn);
+ const __m128 lrhit = _mm_cmple_ps(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 = (_mm_movemask_ps(lrhit) & 1) && (__float_as_uint(cnodes.z) & PATH_RAY_SHADOW);
+ traverseChild1 = (_mm_movemask_ps(lrhit) & 2) && (__float_as_uint(cnodes.w) & PATH_RAY_SHADOW);
+#else
+ traverseChild0 = (_mm_movemask_ps(lrhit) & 1);
+ traverseChild1 = (_mm_movemask_ps(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
+ union { __m128 m128; float v[4]; } uminmax;
+ uminmax.m128 = tminmax;
+ bool closestChild1 = uminmax.v[1] < uminmax.v[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 */
+ while(primAddr < primAddr2) {
+ bool hit;
+ uint type = kernel_tex_fetch(__prim_type, primAddr);
+
+ /* todo: specialized intersect functions which don't fill in
+ * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
+ * might give a few % performance improvement */
+
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ hit = triangle_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr);
+ break;
+ }
+#if FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, PATH_RAY_SHADOW, object, primAddr);
+ break;
+ }
+#endif
+#if FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ hit = bvh_cardinal_curve_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr, ray->time, type, NULL, 0, 0);
+ else
+ hit = bvh_curve_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr, ray->time, type, NULL, 0, 0);
+ break;
+ }
+#endif
+ default: {
+ hit = false;
+ break;
+ }
+ }
+
+ /* shadow ray early termination */
+ if(hit) {
+ /* detect if this surface has a shader with transparent shadows */
+
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+#endif
+ {
+ float4 Ns = kernel_tex_fetch(__tri_normal, prim);
+ shader = __float_as_int(Ns.w);
+ }
+#ifdef __HAIR__
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+#endif
+ int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
+
+ /* if no transparent shadows, all light is blocked */
+ if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if(*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
+#if FEATURE(BVH_INSTANCING)
+ num_hits_in_instance++;
+#endif
+
+ isect_array->t = isect_t;
+ }
+
+ primAddr++;
+ }
+ }
+#if FEATURE(BVH_INSTANCING)
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+
+#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
+
+ num_hits_in_instance = 0;
+
+#if defined(__KERNEL_SSE2__)
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ isect_array->t = isect_t;
+ tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
+
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif
+
+ ++stackPtr;
+ traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+#endif
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ if(num_hits_in_instance) {
+ float t_fac;
+
+#if FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+#else
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+#endif
+
+ /* scale isect->t to adjust for instancing */
+ for(int i = 0; i < num_hits_in_instance; i++)
+ (isect_array-i-1)->t *= t_fac;
+ }
+ else {
+ float ignore_t = FLT_MAX;
+
+#if FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
+#endif
+ }
+
+#if defined(__KERNEL_SSE2__)
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ isect_t = tmax;
+ isect_array->t = isect_t;
+ tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
+
+ 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 false;
+}
+
+#undef FEATURE
+#undef BVH_FUNCTION_NAME
+#undef BVH_FUNCTION_FEATURES
+
diff --git a/intern/cycles/kernel/kernel_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
index df82dda2435..a19f05dd371 100644
--- a/intern/cycles/kernel/kernel_bvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
@@ -48,12 +48,13 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
int nodeAddr = kernel_data.bvh.root;
/* ray parameters in registers */
- const float tmax = ray->t;
float3 P = ray->P;
- float3 idir = bvh_inverse_direction(ray->D);
- int object = ~0;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = ray->t;
- const uint visibility = ~0;
+ const uint visibility = PATH_RAY_ALL_VISIBILITY;
uint num_hits = 0;
#if FEATURE(BVH_MOTION)
@@ -72,7 +73,7 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
Psplat[1] = _mm_set_ps1(P.y);
Psplat[2] = _mm_set_ps1(P.z);
- __m128 tsplat = _mm_set_ps(-tmax, -tmax, 0.0f, 0.0f);
+ __m128 tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
@@ -89,7 +90,7 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
#if !defined(__KERNEL_SSE2__)
/* Intersect two child bounding boxes, non-SSE version */
- float t = tmax;
+ float t = isect_t;
/* fetch node data */
float4 node0 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+0);
@@ -130,8 +131,8 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
/* Intersect two child bounding boxes, SSE3 version adapted from Embree */
/* fetch node data */
- __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE;
- float4 cnodes = ((float4*)bvh_nodes)[3];
+ const __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE;
+ const float4 cnodes = ((float4*)bvh_nodes)[3];
/* intersect ray against child nodes */
const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[0], shufflexyz[0]), Psplat[0]), idirsplat[0]);
@@ -203,19 +204,29 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
/* primitive intersection */
for(; primAddr < primAddr2; primAddr++) {
-#if FEATURE(BVH_HAIR)
- uint segment = kernel_tex_fetch(__prim_segment, primAddr);
- if(segment != ~0)
- continue;
-#endif
-
/* only primitives from the same object */
- uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object;
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
- if(tri_object == subsurface_object) {
+ if(tri_object != subsurface_object)
+ continue;
- /* intersect ray against primitive */
- bvh_triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, tmax, &num_hits, lcg_state, max_hits);
+ /* intersect ray against primitive */
+ uint type = kernel_tex_fetch(__prim_type, primAddr);
+
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ triangle_intersect_subsurface(kg, isect_array, P, dir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+ break;
+ }
+#if FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ motion_triangle_intersect_subsurface(kg, isect_array, P, dir, ray->time, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+ break;
+ }
+#endif
+ default: {
+ break;
+ }
}
}
}
@@ -225,11 +236,10 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
if(subsurface_object == kernel_tex_fetch(__prim_object, -primAddr-1)) {
object = subsurface_object;
- float t_ignore = FLT_MAX;
#if FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &idir, &t_ignore, &ob_tfm, tmax);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
#else
- bvh_instance_push(kg, object, ray, &P, &idir, &t_ignore, tmax);
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
#if defined(__KERNEL_SSE2__)
@@ -237,7 +247,7 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
Psplat[1] = _mm_set_ps1(P.y);
Psplat[2] = _mm_set_ps1(P.z);
- tsplat = _mm_set_ps(-tmax, -tmax, 0.0f, 0.0f);
+ tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
@@ -259,14 +269,13 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
#if FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
- kernel_assert(object != ~0);
+ kernel_assert(object != OBJECT_NONE);
/* instance pop */
- float t_ignore = FLT_MAX;
#if FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &idir, &t_ignore, &ob_tfm, tmax);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
#else
- bvh_instance_pop(kg, object, ray, &P, &idir, &t_ignore, tmax);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
#if defined(__KERNEL_SSE2__)
@@ -274,12 +283,12 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
Psplat[1] = _mm_set_ps1(P.y);
Psplat[2] = _mm_set_ps1(P.z);
- tsplat = _mm_set_ps(-tmax, -tmax, 0.0f, 0.0f);
+ tsplat = _mm_set_ps(-isect_t, -isect_t, 0.0f, 0.0f);
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
- object = ~0;
+ object = OBJECT_NONE;
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
diff --git a/intern/cycles/kernel/kernel_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index bfd72b0aa16..9fd40f91471 100644
--- a/intern/cycles/kernel/kernel_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -41,7 +41,6 @@ ccl_device bool BVH_FUNCTION_NAME
* - test if pushing distance on the stack helps (for non shadow rays)
* - separate version for shadow rays
* - likely and unlikely for if() statements
- * - SSE for hair
* - test restrict attribute for pointers
*/
@@ -54,18 +53,18 @@ ccl_device bool BVH_FUNCTION_NAME
int nodeAddr = kernel_data.bvh.root;
/* ray parameters in registers */
- const float tmax = ray->t;
- ccl_align(16) float3 P = ray->P;
- ccl_align(16) float3 idir = bvh_inverse_direction(ray->D);
- int object = ~0;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
#if FEATURE(BVH_MOTION)
Transform ob_tfm;
#endif
- isect->t = tmax;
- isect->object = ~0;
- isect->prim = ~0;
+ isect->t = ray->t;
+ isect->object = OBJECT_NONE;
+ isect->prim = PRIM_NONE;
isect->u = 0.0f;
isect->v = 0.0f;
@@ -88,11 +87,9 @@ ccl_device bool BVH_FUNCTION_NAME
/* traversal loop */
do {
- do
- {
+ do {
/* traverse internal nodes */
- while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL)
- {
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
bool traverseChild0, traverseChild1;
int nodeAddrChild1;
@@ -250,26 +247,34 @@ ccl_device bool BVH_FUNCTION_NAME
/* primitive intersection */
while(primAddr < primAddr2) {
bool hit;
+ uint type = kernel_tex_fetch(__prim_type, primAddr);
- /* intersect ray against primitive */
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ hit = triangle_intersect(kg, isect, P, dir, visibility, object, primAddr);
+ break;
+ }
+#if FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
+ break;
+ }
+#endif
#if FEATURE(BVH_HAIR)
- uint segment = kernel_tex_fetch(__prim_segment, primAddr);
- if(segment != ~0) {
-
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
-#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
- else
- hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
-#else
- hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
- else
- hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ hit = bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ else
+ hit = bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ break;
+ }
#endif
+ default: {
+ hit = false;
+ break;
+ }
}
- else
-#endif
- hit = bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
#if defined(__KERNEL_SSE2__)
@@ -293,9 +298,9 @@ ccl_device bool BVH_FUNCTION_NAME
object = kernel_tex_fetch(__prim_object, -primAddr-1);
#if FEATURE(BVH_MOTION)
- bvh_instance_motion_push(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax);
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
- bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax);
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
#if defined(__KERNEL_SSE2__)
@@ -319,13 +324,13 @@ ccl_device bool BVH_FUNCTION_NAME
#if FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
- kernel_assert(object != ~0);
+ kernel_assert(object != OBJECT_NONE);
/* instance pop */
#if FEATURE(BVH_MOTION)
- bvh_instance_motion_pop(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax);
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
- bvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax);
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
#if defined(__KERNEL_SSE2__)
@@ -338,14 +343,14 @@ ccl_device bool BVH_FUNCTION_NAME
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
- object = ~0;
+ object = OBJECT_NONE;
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
#endif
} while(nodeAddr != ENTRYPOINT_SENTINEL);
- return (isect->prim != ~0);
+ return (isect->prim != PRIM_NONE);
}
#undef FEATURE
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
new file mode 100644
index 00000000000..e1d225436a6
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -0,0 +1,1035 @@
+/*
+ * 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
+
+/* Curve Primitive
+ *
+ * Curve primitive for rendering hair and fur. These can be render as flat ribbons
+ * or curves with actual thickness. The curve can also be rendered as line segments
+ * rather than curves for better performance */
+
+#ifdef __HAIR__
+
+/* Reading attributes on various curve elements */
+
+ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
+ float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = 0.0f;
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return 0.0f;
+ }
+}
+
+ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+/* Curve thickness */
+
+ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
+{
+ float r = 0.0f;
+
+ if(sd->type & PRIMITIVE_ALL_CURVE) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float4 P_curve[2];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
+
+ r = (P_curve[1].w - P_curve[0].w) * sd->u + P_curve[0].w;
+ }
+
+ return r*2.0f;
+}
+
+/* Curve location for motion pass, linear interpolation between keys and
+ * ignoring radius because we do the same for the motion keys */
+
+ccl_device float3 curve_motion_center_location(KernelGlobals *kg, ShaderData *sd)
+{
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float4 P_curve[2];
+
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+
+ return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u);
+}
+
+/* Curve tangent normal */
+
+ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 tgN = make_float3(0.0f,0.0f,0.0f);
+
+ if(sd->type & PRIMITIVE_ALL_CURVE) {
+
+ tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
+ tgN = normalize(tgN);
+
+ /* need to find suitable scaled gd for corrected normal */
+#if 0
+ tgN = normalize(tgN - gd * sd->dPdu);
+#endif
+ }
+
+ return tgN;
+}
+
+/* Curve bounds utility function */
+
+ccl_device_inline void curvebounds(float *lower, float *upper, float *extremta, float *extrema, float *extremtb, float *extremb, float p0, float p1, float p2, float p3)
+{
+ float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
+ float ta = -1.0f;
+ float tb = -1.0f;
+
+ *extremta = -1.0f;
+ *extremtb = -1.0f;
+ *upper = p0;
+ *lower = (p0 + p1) + (p2 + p3);
+ *extrema = *upper;
+ *extremb = *lower;
+
+ if(*lower >= *upper) {
+ *upper = *lower;
+ *lower = p0;
+ }
+
+ if(halfdiscroot >= 0) {
+ float inv3p3 = (1.0f/3.0f)/p3;
+ halfdiscroot = sqrtf(halfdiscroot);
+ ta = (-p2 - halfdiscroot) * inv3p3;
+ tb = (-p2 + halfdiscroot) * inv3p3;
+ }
+
+ float t2;
+ float t3;
+
+ if(ta > 0.0f && ta < 1.0f) {
+ t2 = ta * ta;
+ t3 = t2 * ta;
+ *extremta = ta;
+ *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
+
+ *upper = fmaxf(*extrema, *upper);
+ *lower = fminf(*extrema, *lower);
+ }
+
+ if(tb > 0.0f && tb < 1.0f) {
+ t2 = tb * tb;
+ t3 = t2 * tb;
+ *extremtb = tb;
+ *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
+
+ *upper = fmaxf(*extremb, *upper);
+ *lower = fminf(*extremb, *lower);
+ }
+}
+
+#ifdef __KERNEL_SSE2__
+ccl_device_inline __m128 transform_point_T3(const __m128 t[3], const __m128 &a)
+{
+ return fma(broadcast<0>(a), t[0], fma(broadcast<1>(a), t[1], _mm_mul_ps(broadcast<2>(a), t[2])));
+}
+#endif
+
+#ifdef __KERNEL_SSE2__
+/* Pass P and dir by reference to aligned vector */
+ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ const float3 &P, const float3 &dir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
+#else
+ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 dir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax)
+#endif
+{
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ float epsilon = 0.0f;
+ float r_st, r_en;
+
+ int depth = kernel_data.curve.subdivisions;
+ int flags = kernel_data.curve.curveflags;
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+
+#ifdef __KERNEL_SSE2__
+ __m128 vdir = load_m128(dir);
+ __m128 vcurve_coef[4];
+ const float3 *curve_coef = (float3 *)vcurve_coef;
+
+ {
+ __m128 dtmp = _mm_mul_ps(vdir, vdir);
+ __m128 d_ss = _mm_sqrt_ss(_mm_add_ss(dtmp, broadcast<2>(dtmp)));
+ __m128 rd_ss = _mm_div_ss(_mm_set_ss(1.0f), d_ss);
+
+ __m128i v00vec = _mm_load_si128((__m128i *)&kg->__curves.data[prim]);
+ int2 &v00 = (int2 &)v00vec;
+
+ int k0 = v00.x + segment;
+ int k1 = k0 + 1;
+ int ka = max(k0 - 1, v00.x);
+ int kb = min(k1 + 1, v00.x + v00.y - 1);
+
+ __m128 P_curve[4];
+
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = _mm_load_ps(&kg->__curve_keys.data[ka].x);
+ P_curve[1] = _mm_load_ps(&kg->__curve_keys.data[k0].x);
+ P_curve[2] = _mm_load_ps(&kg->__curve_keys.data[k1].x);
+ P_curve[3] = _mm_load_ps(&kg->__curve_keys.data[kb].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
+ }
+
+ __m128 rd_sgn = set_sign_bit<0, 1, 1, 1>(broadcast<0>(rd_ss));
+ __m128 mul_zxxy = _mm_mul_ps(shuffle<2, 0, 0, 1>(vdir), rd_sgn);
+ __m128 mul_yz = _mm_mul_ps(shuffle<1, 2, 1, 2>(vdir), mul_zxxy);
+ __m128 mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
+ __m128 vdir0 = _mm_and_ps(vdir, _mm_castsi128_ps(_mm_setr_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0)));
+
+ __m128 htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
+ __m128 htfm1 = shuffle<1, 0, 1, 3>(_mm_set_ss(_mm_cvtss_f32(d_ss)), vdir0);
+ __m128 htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
+
+ __m128 htfm[] = { htfm0, htfm1, htfm2 };
+ __m128 vP = load_m128(P);
+ __m128 p0 = transform_point_T3(htfm, _mm_sub_ps(P_curve[0], vP));
+ __m128 p1 = transform_point_T3(htfm, _mm_sub_ps(P_curve[1], vP));
+ __m128 p2 = transform_point_T3(htfm, _mm_sub_ps(P_curve[2], vP));
+ __m128 p3 = transform_point_T3(htfm, _mm_sub_ps(P_curve[3], vP));
+
+ float fc = 0.71f;
+ __m128 vfc = _mm_set1_ps(fc);
+ __m128 vfcxp3 = _mm_mul_ps(vfc, p3);
+
+ vcurve_coef[0] = p1;
+ vcurve_coef[1] = _mm_mul_ps(vfc, _mm_sub_ps(p2, p0));
+ vcurve_coef[2] = fma(_mm_set1_ps(fc * 2.0f), p0, fma(_mm_set1_ps(fc - 3.0f), p1, fms(_mm_set1_ps(3.0f - 2.0f * fc), p2, vfcxp3)));
+ vcurve_coef[3] = fms(_mm_set1_ps(fc - 2.0f), _mm_sub_ps(p2, p1), fms(vfc, p0, vfcxp3));
+
+ r_st = ((float4 &)P_curve[1]).w;
+ r_en = ((float4 &)P_curve[2]).w;
+ }
+#else
+ float3 curve_coef[4];
+
+ /* curve Intersection check */
+ /* obtain curve parameters */
+ {
+ /* ray transform created - this should be created at beginning of intersection loop */
+ Transform htfm;
+ float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
+ htfm = make_transform(
+ dir.z / d, 0, -dir.x /d, 0,
+ -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
+ dir.x, dir.y, dir.z, 0,
+ 0, 0, 0, 1);
+
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
+ float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
+ float3 p2 = transform_point(&htfm, float4_to_float3(P_curve[2]) - P);
+ float3 p3 = transform_point(&htfm, float4_to_float3(P_curve[3]) - P);
+
+ float fc = 0.71f;
+ curve_coef[0] = p1;
+ curve_coef[1] = -fc*p0 + fc*p2;
+ curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
+ curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
+ r_st = P_curve[1].w;
+ r_en = P_curve[2].w;
+ }
+#endif
+
+ float r_curr = max(r_st, r_en);
+
+ if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
+ epsilon = 2 * r_curr;
+
+ /* find bounds - this is slow for cubic curves */
+ float upper, lower;
+
+ float zextrem[4];
+ curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
+ if(lower - r_curr > isect->t || upper + r_curr < epsilon)
+ return false;
+
+ /* minimum width extension */
+ float mw_extension = min(difl * fabsf(upper), extmax);
+ float r_ext = mw_extension + r_curr;
+
+ float xextrem[4];
+ curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
+ if(lower > r_ext || upper < -r_ext)
+ return false;
+
+ float yextrem[4];
+ curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
+ if(lower > r_ext || upper < -r_ext)
+ return false;
+
+ /* setup recurrent loop */
+ int level = 1 << depth;
+ int tree = 0;
+ float resol = 1.0f / (float)level;
+ bool hit = false;
+
+ /* begin loop */
+ while(!(tree >> (depth))) {
+ float i_st = tree * resol;
+ float i_en = i_st + (level * resol);
+#ifdef __KERNEL_SSE2__
+ __m128 vi_st = _mm_set1_ps(i_st), vi_en = _mm_set1_ps(i_en);
+ __m128 vp_st = fma(fma(fma(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
+ __m128 vp_en = fma(fma(fma(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]), vi_en, vcurve_coef[0]);
+
+ __m128 vbmin = _mm_min_ps(vp_st, vp_en);
+ __m128 vbmax = _mm_max_ps(vp_st, vp_en);
+
+ float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
+ float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
+ float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
+ float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
+#else
+ float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
+ float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
+
+ float bminx = min(p_st.x, p_en.x);
+ float bmaxx = max(p_st.x, p_en.x);
+ float bminy = min(p_st.y, p_en.y);
+ float bmaxy = max(p_st.y, p_en.y);
+ float bminz = min(p_st.z, p_en.z);
+ float bmaxz = max(p_st.z, p_en.z);
+#endif
+
+ if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
+ bminx = min(bminx,xextrem[1]);
+ bmaxx = max(bmaxx,xextrem[1]);
+ }
+ if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
+ bminx = min(bminx,xextrem[3]);
+ bmaxx = max(bmaxx,xextrem[3]);
+ }
+ if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
+ bminy = min(bminy,yextrem[1]);
+ bmaxy = max(bmaxy,yextrem[1]);
+ }
+ if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
+ bminy = min(bminy,yextrem[3]);
+ bmaxy = max(bmaxy,yextrem[3]);
+ }
+ if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
+ bminz = min(bminz,zextrem[1]);
+ bmaxz = max(bmaxz,zextrem[1]);
+ }
+ if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
+ bminz = min(bminz,zextrem[3]);
+ bmaxz = max(bmaxz,zextrem[3]);
+ }
+
+ float r1 = r_st + (r_en - r_st) * i_st;
+ float r2 = r_st + (r_en - r_st) * i_en;
+ r_curr = max(r1, r2);
+
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ float r_ext = mw_extension + r_curr;
+ float coverage = 1.0f;
+
+ if (bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
+ /* the bounding box does not overlap the square centered at O */
+ tree += level;
+ level = tree & -tree;
+ }
+ else if (level == 1) {
+
+ /* the maximum recursion depth is reached.
+ * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
+ * dP* is reversed if necessary.*/
+ float t = isect->t;
+ float u = 0.0f;
+ float gd = 0.0f;
+
+ if(flags & CURVE_KN_RIBBONS) {
+ float3 tg = (p_en - p_st);
+ float w = tg.x * tg.x + tg.y * tg.y;
+ if (w == 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
+ w = clamp((float)w, 0.0f, 1.0f);
+
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+ r_curr = r_st + (r_en - r_st) * u;
+ /* compare x-y distances */
+ float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ if (dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+ if (dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ /* compute coverage */
+ float r_ext = r_curr;
+ coverage = 1.0f;
+ if(difl != 0.0f) {
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ r_ext = mw_extension + r_curr;
+ float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
+ float d0 = d - r_curr;
+ float d1 = d + r_curr;
+ float inv_mw_extension = 1.0f/mw_extension;
+ if (d0 >= 0)
+ coverage = (min(d1 * inv_mw_extension, 1.0f) - min(d0 * inv_mw_extension, 1.0f)) * 0.5f;
+ else // inside
+ coverage = (min(d1 * inv_mw_extension, 1.0f) + min(-d0 * inv_mw_extension, 1.0f)) * 0.5f;
+ }
+
+ if (p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon || isect->t < p_curr.z) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ t = p_curr.z;
+
+ /* stochastic fade from minimum width */
+ if(difl != 0.0f && lcg_state) {
+ if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ else {
+ float l = len(p_en - p_st);
+ /* minimum width extension */
+ float or1 = r1;
+ float or2 = r2;
+
+ if(difl != 0.0f) {
+ mw_extension = min(len(p_st - P) * difl, extmax);
+ or1 = r1 < mw_extension ? mw_extension : r1;
+ mw_extension = min(len(p_en - P) * difl, extmax);
+ or2 = r2 < mw_extension ? mw_extension : r2;
+ }
+ /* --- */
+ float invl = 1.0f/l;
+ float3 tg = (p_en - p_st) * invl;
+ gd = (or2 - or1) * invl;
+ float difz = -dot(p_st,tg);
+ float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
+ float invcyla = 1.0f/cyla;
+ float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + or1)));
+ float tcentre = -halfb*invcyla;
+ float zcentre = difz + (tg.z * tcentre);
+ float3 tdif = - p_st;
+ tdif.z += tcentre;
+ float tdifz = dot(tdif,tg);
+ float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
+ float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
+ float td = tb*tb - 4*cyla*tc;
+ if (td < 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float rootd = sqrtf(td);
+ float correction = (-tb - rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+
+ if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
+ correction = (-tb + rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+ }
+
+ if (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float w = (zcentre + (tg.z * correction)) * invl;
+ w = clamp((float)w, 0.0f, 1.0f);
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+
+ /* stochastic fade from minimum width */
+ if(difl != 0.0f && lcg_state) {
+ r_curr = r1 + (r2 - r1) * w;
+ r_ext = or1 + (or2 - or1) * w;
+ coverage = r_curr/r_ext;
+
+ if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ /* we found a new intersection */
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+ isect->u = u;
+ isect->v = gd;
+ /*isect->transparency = 1.0f - coverage; */
+ isect->t = t;
+ hit = true;
+ }
+
+ tree++;
+ level = tree & -tree;
+ }
+ else {
+ /* split the curve into two curves and process */
+ level = level >> 1;
+ }
+ }
+
+ return hit;
+}
+
+ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 direction, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
+{
+ /* define few macros to minimize code duplication for SSE */
+#ifndef __KERNEL_SSE2__
+#define len3_squared(x) len_squared(x)
+#define len3(x) len(x)
+#define dot3(x, y) dot(x, y)
+#endif
+
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ /* curve Intersection check */
+ int flags = kernel_data.curve.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int cnum = __float_as_int(v00.x);
+ int k0 = cnum + segment;
+ int k1 = k0 + 1;
+
+#ifndef __KERNEL_SSE2__
+ float4 P_curve[2];
+
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
+ }
+
+ float or1 = P_curve[0].w;
+ float or2 = P_curve[1].w;
+ float3 p1 = float4_to_float3(P_curve[0]);
+ float3 p2 = float4_to_float3(P_curve[1]);
+
+ /* minimum width extension */
+ float r1 = or1;
+ float r2 = or2;
+ float3 dif = P - p1;
+ float3 dif_second = P - p2;
+ if(difl != 0.0f) {
+ float pixelsize = min(len3(dif) * difl, extmax);
+ r1 = or1 < pixelsize ? pixelsize : or1;
+ pixelsize = min(len3(dif_second) * difl, extmax);
+ r2 = or2 < pixelsize ? pixelsize : or2;
+ }
+ /* --- */
+
+ float3 p21_diff = p2 - p1;
+ float3 sphere_dif1 = (dif + dif_second) * 0.5f;
+ float3 dir = direction;
+ float sphere_b_tmp = dot3(dir, sphere_dif1);
+ float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
+#else
+ __m128 P_curve[2];
+
+ if(type & PRIMITIVE_CURVE) {
+ P_curve[0] = _mm_load_ps(&kg->__curve_keys.data[k0].x);
+ P_curve[1] = _mm_load_ps(&kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4*)&P_curve);
+ }
+
+ const __m128 or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
+
+ __m128 r12 = or12;
+ const __m128 vP = load_m128(P);
+ const __m128 dif = _mm_sub_ps(vP, P_curve[0]);
+ const __m128 dif_second = _mm_sub_ps(vP, P_curve[1]);
+ if(difl != 0.0f) {
+ const __m128 len1_sq = len3_squared_splat(dif);
+ const __m128 len2_sq = len3_squared_splat(dif_second);
+ const __m128 len12 = _mm_sqrt_ps(shuffle<0, 0, 0, 0>(len1_sq, len2_sq));
+ const __m128 pixelsize12 = _mm_min_ps(_mm_mul_ps(len12, _mm_set1_ps(difl)), _mm_set1_ps(extmax));
+ r12 = _mm_max_ps(or12, pixelsize12);
+ }
+ float or1 = _mm_cvtss_f32(or12), or2 = _mm_cvtss_f32(broadcast<2>(or12));
+ float r1 = _mm_cvtss_f32(r12), r2 = _mm_cvtss_f32(broadcast<2>(r12));
+
+ const __m128 p21_diff = _mm_sub_ps(P_curve[1], P_curve[0]);
+ const __m128 sphere_dif1 = _mm_mul_ps(_mm_add_ps(dif, dif_second), _mm_set1_ps(0.5f));
+ const __m128 dir = load_m128(direction);
+ const __m128 sphere_b_tmp = dot3_splat(dir, sphere_dif1);
+ const __m128 sphere_dif2 = fnma(sphere_b_tmp, dir, sphere_dif1);
+#endif
+
+ float mr = max(r1, r2);
+ float l = len3(p21_diff);
+ float invl = 1.0f / l;
+ float sp_r = mr + 0.5f * l;
+
+ float sphere_b = dot3(dir, sphere_dif2);
+ float sdisc = sphere_b * sphere_b - len3_squared(sphere_dif2) + sp_r * sp_r;
+
+ if(sdisc < 0.0f)
+ return false;
+
+ /* obtain parameters and test midpoint distance for suitable modes */
+#ifndef __KERNEL_SSE2__
+ float3 tg = p21_diff * invl;
+#else
+ const __m128 tg = _mm_mul_ps(p21_diff, _mm_set1_ps(invl));
+#endif
+ float gd = (r2 - r1) * invl;
+
+ float dirz = dot3(dir, tg);
+ float difz = dot3(dif, tg);
+
+ float a = 1.0f - (dirz*dirz*(1 + gd*gd));
+
+ float halfb = dot3(dir, dif) - dirz*(difz + gd*(difz*gd + r1));
+
+ float tcentre = -halfb/a;
+ float zcentre = difz + (dirz * tcentre);
+
+ if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
+ return false;
+ if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
+ return false;
+
+ /* test minimum separation */
+#ifndef __KERNEL_SSE2__
+ float3 cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross(tg, dif));
+#else
+ const __m128 cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross_zxy(tg, dif));
+#endif
+ float cprodsq = len3_squared(cprod);
+ float distscaled = dot3(cprod, dif);
+
+ if(cprodsq == 0)
+ distscaled = cprod2sq;
+ else
+ distscaled = (distscaled*distscaled)/cprodsq;
+
+ if(distscaled > mr*mr)
+ return false;
+
+ /* calculate true intersection */
+#ifndef __KERNEL_SSE2__
+ float3 tdif = dif + tcentre * dir;
+#else
+ const __m128 tdif = fma(_mm_set1_ps(tcentre), dir, dif);
+#endif
+ float tdifz = dot3(tdif, tg);
+ float tdifma = tdifz*gd + r1;
+ float tb = 2*(dot3(dir, tdif) - dirz*(tdifz + gd*tdifma));
+ float tc = dot3(tdif, tdif) - tdifz*tdifz - tdifma*tdifma;
+ float td = tb*tb - 4*a*tc;
+
+ if (td < 0.0f)
+ return false;
+
+ float rootd = 0.0f;
+ float correction = 0.0f;
+ if(flags & CURVE_KN_ACCURATE) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ }
+
+ float t = tcentre + correction;
+
+ if(t < isect->t) {
+
+ if(flags & CURVE_KN_INTERSECTCORRECTION) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ t = tcentre + correction;
+ }
+
+ float z = zcentre + (dirz * correction);
+ // bool backface = false;
+
+ if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
+ // backface = true;
+ correction = ((-tb + rootd)/(2*a));
+ t = tcentre + correction;
+ z = zcentre + (dirz * correction);
+ }
+
+ /* stochastic fade from minimum width */
+ float adjradius = or1 + z * (or2 - or1) * invl;
+ adjradius = adjradius / (r1 + z * gd);
+ if(lcg_state && adjradius != 1.0f) {
+ if(lcg_step_float(lcg_state) > adjradius)
+ return false;
+ }
+ /* --- */
+
+ if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
+
+ if (flags & CURVE_KN_ENCLOSEFILTER) {
+ float enc_ratio = 1.01f;
+ if((difz > -r1 * enc_ratio) && (dot3(dif_second, tg) < r2 * enc_ratio)) {
+ float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
+ float c2 = dot3(dif, dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
+ if(a2*c2 < 0.0f)
+ return false;
+ }
+ }
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+ isect->u = z*invl;
+ isect->v = gd;
+ /*isect->transparency = 1.0f - adjradius;*/
+ isect->t = t;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+
+#ifndef __KERNEL_SSE2__
+#undef len3_squared
+#undef len3
+#undef dot3
+#endif
+}
+
+ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float fc = 0.71f;
+ float data[4];
+ float t2 = t * t;
+ data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
+ data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
+ data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
+ data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float data[4];
+ float fc = 0.71f;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
+{
+ int flag = kernel_data.curve.curveflags;
+ float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float3 tg;
+
+ if(flag & CURVE_KN_INTERPOLATE) {
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p[4];
+ p[0] = float4_to_float3(P_curve[0]);
+ p[1] = float4_to_float3(P_curve[1]);
+ p[2] = float4_to_float3(P_curve[2]);
+ p[3] = float4_to_float3(P_curve[3]);
+
+ P = P + D*t;
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = 0.0f;
+#endif
+
+ if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS) {
+ tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
+ sd->Ng = normalize(-(D - tg * (dot(tg, D))));
+ }
+ else {
+ /* direction from inside to surface of curve */
+ float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
+ sd->Ng = normalize(P - p_curr);
+
+ /* adjustment for changing radius */
+ float gd = isect->v;
+
+ if(gd != 0.0f) {
+ tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ /* todo: sometimes the normal is still so that this is detected as
+ * backfacing even if cull backfaces is enabled */
+
+ sd->N = sd->Ng;
+ }
+ else {
+ float4 P_curve[2];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
+
+ float l = 1.0f;
+ tg = normalize_len(float4_to_float3(P_curve[1] - P_curve[0]), &l);
+
+ P = P + D*t;
+
+ float3 dif = P - float4_to_float3(P_curve[0]);
+
+#ifdef __UV__
+ sd->u = dot(dif,tg)/l;
+ sd->v = 0.0f;
+#endif
+
+ if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->Ng = -(D - tg * dot(tg, D));
+ sd->Ng = normalize(sd->Ng);
+ }
+ else {
+ float gd = isect->v;
+
+ /* direction from inside to surface of curve */
+ sd->Ng = (dif - tg * sd->u * l) / (P_curve[0].w + sd->u * l * gd);
+
+ /* adjustment for changing radius */
+ if (gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ sd->N = sd->Ng;
+ }
+
+#ifdef __DPDU__
+ /* dPdu/dPdv */
+ sd->dPdu = tg;
+ sd->dPdv = cross(tg, sd->Ng);
+#endif
+
+ /*add fading parameter for minimum pixel width with transparency bsdf*/
+ /*sd->curve_transparency = isect->transparency;*/
+ /*sd->curve_radius = sd->u * gd * l + r1;*/
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h
new file mode 100644
index 00000000000..1022a957b05
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -0,0 +1,148 @@
+/*
+ * 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
+
+/* Motion Curve Primitive
+ *
+ * These are stored as regular curves, plus extra positions and radii at times
+ * other than the frame center. Computing the curve keys at a given ray time is
+ * a matter of interpolation of the two steps between which the ray time lies.
+ *
+ * The extra curve keys are stored as ATTR_STD_MOTION_VERTEX_POSITION.
+ */
+
+#ifdef __HAIR__
+
+ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
+{
+ /* todo: find a better (faster) solution for this, maybe store offset per object */
+ uint attr_offset = object*kernel_data.bvh.attributes_map_stride + ATTR_PRIM_CURVE;
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+}
+
+ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, float4 keys[2])
+{
+ if(step == numsteps) {
+ /* center step: regular vertex location */
+ keys[0] = kernel_tex_fetch(__curve_keys, k0);
+ keys[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ /* center step not stored in this array */
+ if(step > numsteps)
+ step--;
+
+ offset += step*numkeys;
+
+ keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
+ keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
+ }
+}
+
+/* return 2 curve key locations */
+ccl_device_inline void motion_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2])
+{
+ /* get motion info */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps*2;
+ int step = min((int)(time*maxstep), maxstep-1);
+ float t = time*maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch key coordinates */
+ float4 next_keys[2];
+
+ motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, keys);
+ motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, next_keys);
+
+ /* interpolate between steps */
+ keys[0] = (1.0f - t)*keys[0] + t*next_keys[0];
+ keys[1] = (1.0f - t)*keys[1] + t*next_keys[1];
+}
+
+ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, int k2, int k3, float4 keys[4])
+{
+ if(step == numsteps) {
+ /* center step: regular vertex location */
+ keys[0] = kernel_tex_fetch(__curve_keys, k0);
+ keys[1] = kernel_tex_fetch(__curve_keys, k1);
+ keys[2] = kernel_tex_fetch(__curve_keys, k2);
+ keys[3] = kernel_tex_fetch(__curve_keys, k3);
+ }
+ else {
+ /* center step not store in this array */
+ if(step > numsteps)
+ step--;
+
+ offset += step*numkeys;
+
+ keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
+ keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
+ keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2);
+ keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3);
+ }
+}
+
+/* return 2 curve key locations */
+ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, int k2, int k3, float4 keys[4])
+{
+ /* get motion info */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps*2;
+ int step = min((int)(time*maxstep), maxstep-1);
+ float t = time*maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch key coordinates */
+ float4 next_keys[4];
+
+ motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
+ motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, k2, k3, next_keys);
+
+ /* interpolate between steps */
+ keys[0] = (1.0f - t)*keys[0] + t*next_keys[0];
+ keys[1] = (1.0f - t)*keys[1] + t*next_keys[1];
+ keys[2] = (1.0f - t)*keys[2] + t*next_keys[2];
+ keys[3] = (1.0f - t)*keys[3] + t*next_keys[3];
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
new file mode 100644
index 00000000000..73338bb6b3b
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -0,0 +1,392 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, 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.
+ */
+
+/* Motion Triangle Primitive
+ *
+ * These are stored as regular triangles, plus extra positions and normals at
+ * times other than the frame center. Computing the triangle vertex positions
+ * or normals at a given ray time is a matter of interpolation of the two steps
+ * between which the ray time lies.
+ *
+ * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
+ * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Time interpolation of vertex positions and normals */
+
+ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
+{
+ /* todo: find a better (faster) solution for this, maybe store offset per object */
+ uint attr_offset = object*kernel_data.bvh.attributes_map_stride;
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+}
+
+ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3])
+{
+ if(step == numsteps) {
+ /* center step: regular vertex location */
+ verts[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+ verts[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+ verts[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+ }
+ else {
+ /* center step not store in this array */
+ if(step > numsteps)
+ step--;
+
+ offset += step*numverts;
+
+ verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+ verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+ verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
+ }
+}
+
+ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
+{
+ if(step == numsteps) {
+ /* center step: regular vertex location */
+ normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)));
+ normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)));
+ normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
+ }
+ else {
+ /* center step not stored in this array */
+ if(step > numsteps)
+ step--;
+
+ offset += step*numverts;
+
+ normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+ normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+ normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
+ }
+}
+
+ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
+{
+ /* get motion info */
+ int numsteps, numverts;
+ object_motion_info(kg, object, &numsteps, &numverts, NULL);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps*2;
+ int step = min((int)(time*maxstep), maxstep-1);
+ float t = time*maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch vertex coordinates */
+ float3 next_verts[3];
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
+
+ /* interpolate between steps */
+ verts[0] = (1.0f - t)*verts[0] + t*next_verts[0];
+ verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
+ verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
+}
+
+/* Refine triangle intersection to more precise hit point. For rays that travel
+ * far the precision is often not so good, this reintersects the primitive from
+ * a closer distance. */
+
+ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float3 verts[3])
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ P = P + D*t;
+
+ /* compute refined intersection distance */
+ const float3 e1 = verts[0] - verts[2];
+ const float3 e2 = verts[1] - verts[2];
+ const float3 s1 = cross(D, e2);
+
+ const float invdivisor = 1.0f/dot(s1, e1);
+ const float3 d = P - verts[2];
+ const float3 s2 = cross(d, e1);
+ float rt = dot(e2, s2)*invdivisor;
+
+ /* compute refined position */
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+
+/* Same as above, except that isect->t is assumed to be in object space for instancing */
+
+#ifdef __SUBSURFACE__
+ccl_device_inline float3 motion_triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float3 verts[3])
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D);
+ D = normalize(D);
+ }
+
+ P = P + D*t;
+
+ /* compute refined intersection distance */
+ const float3 e1 = verts[0] - verts[2];
+ const float3 e2 = verts[1] - verts[2];
+ const float3 s1 = cross(D, e2);
+
+ const float invdivisor = 1.0f/dot(s1, e1);
+ const float3 d = P - verts[2];
+ const float3 s2 = cross(d, e1);
+ float rt = dot(e2, s2)*invdivisor;
+
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+#endif
+
+/* Setup of motion triangle specific parts of ShaderData, moved into this one
+ * function to more easily share computation of interpolated positions and
+ * normals */
+
+/* return 3 triangle vertex normals */
+ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface)
+{
+ /* get shader */
+ float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
+ sd->shader = __float_as_int(Ns.w);
+
+ /* get motion info */
+ int numsteps, numverts;
+ object_motion_info(kg, sd->object, &numsteps, &numverts, NULL);
+
+ /* figure out which steps we need to fetch and their interpolation factor */
+ int maxstep = numsteps*2;
+ int step = min((int)(sd->time*maxstep), maxstep-1);
+ float t = sd->time*maxstep - step;
+
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch vertex coordinates */
+ float3 verts[3], next_verts[3];
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
+
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
+ motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
+
+ /* interpolate between steps */
+ verts[0] = (1.0f - t)*verts[0] + t*next_verts[0];
+ verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
+ verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
+
+ /* compute refined position */
+#ifdef __SUBSURFACE__
+ if(!subsurface)
+#endif
+ sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
+#ifdef __SUBSURFACE__
+ else
+ sd->P = motion_triangle_refine_subsurface(kg, sd, isect, ray, verts);
+#endif
+
+ /* compute face normal */
+ float3 Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
+
+ sd->Ng = Ng;
+ sd->N = Ng;
+
+ /* compute derivatives of P w.r.t. uv */
+#ifdef __DPDU__
+ sd->dPdu = (verts[0] - verts[2]);
+ sd->dPdv = (verts[1] - verts[2]);
+#endif
+
+ /* compute smooth normal */
+ if(sd->shader & SHADER_SMOOTH_NORMAL) {
+ /* find attribute */
+ AttributeElement elem;
+ int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* fetch vertex coordinates */
+ float3 normals[3], next_normals[3];
+ motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
+ motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_normals);
+
+ /* interpolate between steps */
+ normals[0] = (1.0f - t)*normals[0] + t*next_normals[0];
+ normals[1] = (1.0f - t)*normals[1] + t*next_normals[1];
+ normals[2] = (1.0f - t)*normals[2] + t*next_normals[2];
+
+ /* interpolate between vertices */
+ float u = sd->u;
+ float v = sd->v;
+ float w = 1.0f - u - v;
+ sd->N = (u*normals[0] + v*normals[1] + w*normals[2]);
+ }
+}
+
+/* Ray intersection. We simply compute the vertex positions at the given ray
+ * time and do a ray intersection with the resulting triangle */
+
+ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 dir, float time, uint visibility, int object, int triAddr)
+{
+ /* primitive index for vertex location lookup */
+ int prim = kernel_tex_fetch(__prim_index, triAddr);
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, triAddr): object;
+
+ /* get vertex locations for intersection */
+ float3 verts[3];
+ motion_triangle_vertices(kg, fobject, prim, time, verts);
+
+ /* ray-triangle intersection, unoptimized */
+ float t, u, v;
+
+ if(ray_triangle_intersect_uv(P, dir, isect->t, verts[2], verts[0], verts[1], &u, &v, &t)) {
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_MOTION_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Special ray intersection routines for subsurface scattering. In that case we
+ * only want to intersect with primitives in the same object, and if case of
+ * multiple hits we pick a single random primitive as the intersection point. */
+
+#ifdef __SUBSURFACE__
+ccl_device_inline void motion_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
+ float3 P, float3 dir, float time, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
+{
+ /* primitive index for vertex location lookup */
+ int prim = kernel_tex_fetch(__prim_index, triAddr);
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, triAddr): object;
+
+ /* get vertex locations for intersection */
+ float3 verts[3];
+ motion_triangle_vertices(kg, fobject, prim, time, verts);
+
+ /* ray-triangle intersection, unoptimized */
+ float t, u, v;
+
+ if(ray_triangle_intersect_uv(P, dir, tmax, verts[2], verts[0], verts[1], &u, &v, &t)) {
+ (*num_hits)++;
+
+ int hit;
+
+ if(*num_hits <= max_hits) {
+ hit = *num_hits - 1;
+ }
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit = lcg_step_uint(lcg_state) % *num_hits;
+
+ if(hit >= max_hits)
+ return;
+ }
+
+ /* record intersection */
+ Intersection *isect = &isect_array[hit];
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_MOTION_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+ }
+}
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/geom/geom_object.h
index a66277e10cd..91edd5863ac 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -1,6 +1,4 @@
/*
- * Copyright 2011-2013 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
@@ -11,11 +9,23 @@
* 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
+ * limitations under the License.
*/
+/* Object Primitive
+ *
+ * All mesh and curve primitives are part of an object. The same mesh and curves
+ * may be instanced multiple times by different objects.
+ *
+ * If the mesh is not instanced multiple times, the object will not be explicitly
+ * stored as a primitive in the BVH, rather the bare triangles are curved are
+ * directly primitives in the BVH with world space locations applied, and the object
+ * ID is looked up afterwards. */
+
CCL_NAMESPACE_BEGIN
+/* Object attributes, for now a fixed size and contents */
+
enum ObjectTransform {
OBJECT_TRANSFORM = 0,
OBJECT_TRANSFORM_MOTION_PRE = 0,
@@ -30,6 +40,8 @@ enum ObjectVectorTransform {
OBJECT_VECTOR_MOTION_POST = 3
};
+/* Object to world space transformation */
+
ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
{
int offset = object*OBJECT_SIZE + (int)type;
@@ -43,6 +55,8 @@ ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object
return tfm;
}
+/* Object to world space transformation for motion vectors */
+
ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
{
int offset = object*OBJECT_VECTOR_SIZE + (int)type;
@@ -56,6 +70,8 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
return tfm;
}
+/* Motion blurred object transformations */
+
#ifdef __OBJECT_MOTION__
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
@@ -102,7 +118,9 @@ ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg
}
#endif
-ccl_device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
+/* Transform position from object to world space */
+
+ccl_device_inline void object_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
{
#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_tfm, *P);
@@ -112,7 +130,9 @@ ccl_device_inline void object_position_transform(KernelGlobals *kg, ShaderData *
#endif
}
-ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
+/* Transform position from world to object space */
+
+ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
{
#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_itfm, *P);
@@ -122,7 +142,9 @@ ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, Shad
#endif
}
-ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
+/* Transform normal from world to object space */
+
+ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
{
#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_tfm, *N));
@@ -132,7 +154,9 @@ ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, Shader
#endif
}
-ccl_device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
+/* Transform normal from object to world space */
+
+ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
{
#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
@@ -142,7 +166,9 @@ ccl_device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd
#endif
}
-ccl_device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
+/* Transform direction vector from object to world space */
+
+ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
{
#ifdef __OBJECT_MOTION__
*D = transform_direction(&sd->ob_tfm, *D);
@@ -152,7 +178,9 @@ ccl_device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, f
#endif
}
-ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
+/* Transform direction vector from world to object space */
+
+ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
{
#ifdef __OBJECT_MOTION__
*D = transform_direction(&sd->ob_itfm, *D);
@@ -162,9 +190,11 @@ ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, ShaderDat
#endif
}
-ccl_device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
+/* Object center position */
+
+ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd)
{
- if(sd->object == ~0)
+ if(sd->object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
#ifdef __OBJECT_MOTION__
@@ -175,6 +205,8 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
#endif
}
+/* Total surface area of object */
+
ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
{
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
@@ -182,9 +214,11 @@ ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
return f.x;
}
+/* Pass ID number of object */
+
ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
{
- if(object == ~0)
+ if(object == OBJECT_NONE)
return 0.0f;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
@@ -192,9 +226,11 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
return f.y;
}
+/* Per object random number for shader variation */
+
ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
{
- if(object == ~0)
+ if(object == OBJECT_NONE)
return 0.0f;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
@@ -202,9 +238,11 @@ ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
return f.z;
}
-ccl_device_inline uint object_particle_id(KernelGlobals *kg, int object)
+/* Particle ID from which this object was generated */
+
+ccl_device_inline int object_particle_id(KernelGlobals *kg, int object)
{
- if(object == ~0)
+ if(object == OBJECT_NONE)
return 0.0f;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
@@ -212,9 +250,11 @@ ccl_device_inline uint object_particle_id(KernelGlobals *kg, int object)
return __float_as_uint(f.w);
}
+/* Generated texture coordinate on surface from where object was instanced */
+
ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
{
- if(object == ~0)
+ if(object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
@@ -222,9 +262,11 @@ ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
return make_float3(f.x, f.y, f.z);
}
+/* UV texture coordinate on surface from where object was instanced */
+
ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
{
- if(object == ~0)
+ if(object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
@@ -232,12 +274,33 @@ ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
return make_float3(f.x, f.y, 0.0f);
}
+/* Information about mesh for motion blurred triangles and curves */
+
+ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
+{
+ int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
+
+ if(numkeys) {
+ float4 f = kernel_tex_fetch(__objects, offset);
+ *numkeys = __float_as_int(f.w);
+ }
+
+ float4 f = kernel_tex_fetch(__objects, offset + 1);
+ if(numsteps)
+ *numsteps = __float_as_int(f.z);
+ if(numverts)
+ *numverts = __float_as_int(f.w);
+}
+
+/* Pass ID for shader */
-ccl_device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
+ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
{
return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
}
+/* Particle data from which object was instanced */
+
ccl_device_inline float particle_index(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
@@ -296,5 +359,107 @@ ccl_device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
return make_float3(f3.z, f3.w, f4.x);
}
+/* Object intersection in BVH */
+
+ccl_device_inline float3 bvh_clamp_direction(float3 dir)
+{
+ /* clamp absolute values by exp2f(-80.0f) to avoid division by zero when calculating inverse direction */
+ float ooeps = 8.271806E-25f;
+ return make_float3((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x),
+ (fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y),
+ (fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z));
+}
+
+ccl_device_inline float3 bvh_inverse_direction(float3 dir)
+{
+ return 1.0f / dir;
+}
+
+/* Transform ray into object space to enter static object in BVH */
+
+ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t)
+{
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+
+ *P = transform_point(&tfm, ray->P);
+
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
+
+ if(*t != FLT_MAX)
+ *t *= len;
+}
+
+/* Transorm ray to exit static object in BVH */
+
+ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t)
+{
+ if(*t != FLT_MAX) {
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
+ }
+
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
+}
+
+/* Same as above, but returns scale factor to apply to multiple intersection distances */
+
+ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac)
+{
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ *t_fac = len(transform_direction(&tfm, 1.0f/(*idir)));
+
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
+}
+
+
+#ifdef __OBJECT_MOTION__
+/* Transform ray into object space to enter motion blurred object in BVH */
+
+ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, Transform *tfm)
+{
+ Transform itfm;
+ *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
+
+ *P = transform_point(&itfm, ray->P);
+
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
+
+ if(*t != FLT_MAX)
+ *t *= len;
+}
+
+/* Transorm ray to exit motion blurred object in BVH */
+
+ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, Transform *tfm)
+{
+ if(*t != FLT_MAX)
+ *t *= len(transform_direction(tfm, 1.0f/(*idir)));
+
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
+}
+
+/* Same as above, but returns scale factor to apply to multiple intersection distances */
+
+ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac, Transform *tfm)
+{
+ *t_fac = len(transform_direction(tfm, 1.0f/(*idir)));
+
+ *P = ray->P;
+ *dir = bvh_clamp_direction(ray->D);
+ *idir = bvh_inverse_direction(*dir);
+}
+
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index fa450c97cbf..533973621d7 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -14,82 +14,60 @@
* limitations under the License
*/
-#ifndef __KERNEL_ATTRIBUTE_CL__
-#define __KERNEL_ATTRIBUTE_CL__
+/* Primitive Utilities
+ *
+ * Generic functions to look up mesh, curve and volume primitive attributes for
+ * shading and render passes. */
CCL_NAMESPACE_BEGIN
-/* attribute lookup */
-
-ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
-{
- if(sd->object == ~0)
- return (int)ATTR_STD_NOT_FOUND;
-
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id, elem);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
-#ifdef __HAIR__
- attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
-#endif
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id) {
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
-
- *elem = (AttributeElement)attr_map.y;
-
- if(sd->prim == ~0 && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
- return ATTR_STD_NOT_FOUND;
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
-}
+/* Generic primitive attribute reading functions */
ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
-#ifdef __HAIR__
- if(sd->segment == ~0)
-#endif
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
#ifdef __HAIR__
- else
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
+#endif
+#ifdef __VOLUME__
+ else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
#endif
+ else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+ return 0.0f;
+ }
}
ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
-#ifdef __HAIR__
- if(sd->segment == ~0)
-#endif
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
#ifdef __HAIR__
- else
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
+#endif
+#ifdef __VOLUME__
+ else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
#endif
+ else {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
-ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
-{
- Transform tfm;
-
- tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
- tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
- tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
- tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
-
- return tfm;
-}
+/* Default UV coordinate */
ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
{
@@ -104,6 +82,8 @@ ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
return uv;
}
+/* Ptex coordinates */
+
ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id)
{
/* storing ptex data as attributes is not memory efficient but simple for tests */
@@ -123,10 +103,12 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in
return true;
}
+/* Surface tangent */
+
ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __HAIR__
- if(sd->segment != ~0)
+ if(sd->type & PRIMITIVE_ALL_CURVE)
#ifdef __DPDU__
return normalize(sd->dPdu);
#else
@@ -154,21 +136,39 @@ ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
}
}
-/* motion */
+/* Motion vector for motion pass */
ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
{
- float3 motion_pre = sd->P, motion_post = sd->P;
+ /* center position */
+ float3 center;
+
+ if(sd->type & PRIMITIVE_ALL_CURVE) {
+ center = curve_motion_center_location(kg, sd);
+
+ if(!(sd->flag & SD_TRANSFORM_APPLIED))
+ object_position_transform(kg, sd, &center);
+ }
+ else
+ center = sd->P;
+
+ float3 motion_pre = center, motion_post = center;
/* deformation motion */
- AttributeElement elem_pre, elem_post;
- int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE, &elem_pre);
- int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST, &elem_post);
+ AttributeElement elem;
+ int offset = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
+
+ if(offset != ATTR_STD_NOT_FOUND) {
+ /* get motion info */
+ int numverts, numkeys;
+ object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
- if(offset_pre != ATTR_STD_NOT_FOUND)
- motion_pre = primitive_attribute_float3(kg, sd, elem_pre, offset_pre, NULL, NULL);
- if(offset_post != ATTR_STD_NOT_FOUND)
- motion_post = primitive_attribute_float3(kg, sd, elem_post, offset_post, NULL, NULL);
+ /* lookup attributes */
+ int offset_next = (sd->type & PRIMITIVE_ALL_TRIANGLE)? offset + numverts: offset + numkeys;
+
+ motion_pre = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ motion_post = primitive_attribute_float3(kg, sd, elem, offset_next, NULL, NULL);
+ }
/* object motion. note that depending on the mesh having motion vectors, this
* transformation was set match the world/object space of motion_pre/post */
@@ -180,13 +180,13 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
motion_post = transform_point(&tfm, motion_post);
- float3 P;
+ float3 motion_center;
/* camera motion, for perspective/orthographic motion.pre/post will be a
* world-to-raster matrix, for panorama it's world-to-camera */
if (kernel_data.cam.type != CAMERA_PANORAMA) {
tfm = kernel_data.cam.worldtoraster;
- P = transform_perspective(&tfm, sd->P);
+ motion_center = transform_perspective(&tfm, center);
tfm = kernel_data.cam.motion.pre;
motion_pre = transform_perspective(&tfm, motion_pre);
@@ -196,10 +196,10 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
}
else {
tfm = kernel_data.cam.worldtocamera;
- P = normalize(transform_point(&tfm, sd->P));
- P = float2_to_float3(direction_to_panorama(kg, P));
- P.x *= kernel_data.cam.width;
- P.y *= kernel_data.cam.height;
+ motion_center = normalize(transform_point(&tfm, center));
+ motion_center = float2_to_float3(direction_to_panorama(kg, motion_center));
+ motion_center.x *= kernel_data.cam.width;
+ motion_center.y *= kernel_data.cam.height;
tfm = kernel_data.cam.motion.pre;
motion_pre = normalize(transform_point(&tfm, motion_pre));
@@ -214,12 +214,11 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
motion_post.y *= kernel_data.cam.height;
}
- motion_pre = motion_pre - P;
- motion_post = P - motion_post;
+ motion_pre = motion_pre - motion_center;
+ motion_post = motion_center - motion_post;
return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
}
CCL_NAMESPACE_END
-#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
new file mode 100644
index 00000000000..355e36fef0c
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -0,0 +1,379 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, 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.
+ */
+
+/* Triangle Primitive
+ *
+ * Basic triangle with 3 vertices is used to represent mesh surfaces. For BVH
+ * ray intersection we use a precomputed triangle storage to accelarate
+ * intersection at the cost of more memory usage */
+
+CCL_NAMESPACE_BEGIN
+
+/* Refine triangle intersection to more precise hit point. For rays that travel
+ * far the precision is often not so good, this reintersects the primitive from
+ * a closer distance. */
+
+ccl_device_inline float3 triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ P = P + D*t;
+
+ float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
+ float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
+ float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
+ float rt = Oz * invDz;
+
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+
+/* same as above, except that isect->t is assumed to be in object space for instancing */
+ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D);
+ D = normalize(D);
+ }
+
+ P = P + D*t;
+
+ float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
+ float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
+ float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
+ float rt = Oz * invDz;
+
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+
+/* point and normal on triangle */
+ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int prim, float u, float v, float3 *P, float3 *Ng, int *shader)
+{
+ /* load triangle vertices */
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+ float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+ float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+ float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+
+ /* compute point */
+ float t = 1.0f - u - v;
+ *P = (u*v0 + v*v1 + t*v2);
+
+ float4 Nm = kernel_tex_fetch(__tri_normal, prim);
+ *Ng = make_float3(Nm.x, Nm.y, Nm.z);
+ *shader = __float_as_int(Nm.w);
+}
+
+/* Triangle vertex locations */
+
+ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3])
+{
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+ P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+ P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+ P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+}
+
+/* Interpolate smooth vertex normal from vertices */
+
+ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, float u, float v)
+{
+ /* load triangle vertices */
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+ float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)));
+ float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)));
+ float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
+
+ return normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
+}
+
+/* Ray differentials on triangle */
+
+ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, float3 *dPdu, float3 *dPdv)
+{
+ /* fetch triangle vertex coordinates */
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
+
+ float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+ float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+ float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+
+ /* compute derivatives of P w.r.t. uv */
+ *dPdu = (p0 - p2);
+ *dPdv = (p1 - p2);
+}
+
+/* Reading attributes on various triangle elements */
+
+ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_FACE) {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) {
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x));
+ float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y));
+ float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+#endif
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
+ }
+ else if(elem == ATTR_ELEMENT_CORNER) {
+ int tri = offset + sd->prim*3;
+ float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
+ float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
+ float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+#endif
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
+ }
+ else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
+ return 0.0f;
+ }
+}
+
+ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == ATTR_ELEMENT_FACE) {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) {
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+#endif
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
+ }
+ else if(elem == ATTR_ELEMENT_CORNER) {
+ int tri = offset + sd->prim*3;
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+#endif
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
+ }
+ else {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+/* Ray-Triangle intersection for BVH traversal
+ *
+ * Based on Sven Woop's algorithm with precomputed triangle storage */
+
+ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 dir, uint visibility, int object, int triAddr)
+{
+ /* compute and check intersection t-value */
+ float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
+ float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
+
+ float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
+ float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
+ float t = Oz * invDz;
+
+ if(t > 0.0f && t < isect->t) {
+ /* compute and check barycentric u */
+ float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
+ float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
+ float u = Ox + t*Dx;
+
+ if(u >= 0.0f) {
+ /* compute and check barycentric v */
+ float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
+ float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
+ float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
+ float v = Oy + t*Dy;
+
+ if(v >= 0.0f && u + v <= 1.0f) {
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/* Special ray intersection routines for subsurface scattering. In that case we
+ * only want to intersect with primitives in the same object, and if case of
+ * multiple hits we pick a single random primitive as the intersection point. */
+
+#ifdef __SUBSURFACE__
+ccl_device_inline void triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
+ float3 P, float3 dir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
+{
+ /* compute and check intersection t-value */
+ float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
+ float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
+
+ float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
+ float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
+ float t = Oz * invDz;
+
+ if(t > 0.0f && t < tmax) {
+ /* compute and check barycentric u */
+ float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
+ float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
+ float u = Ox + t*Dx;
+
+ if(u >= 0.0f) {
+ /* compute and check barycentric v */
+ float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
+ float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
+ float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
+ float v = Oy + t*Dy;
+
+ if(v >= 0.0f && u + v <= 1.0f) {
+ (*num_hits)++;
+
+ int hit;
+
+ if(*num_hits <= max_hits) {
+ hit = *num_hits - 1;
+ }
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit = lcg_step_uint(lcg_state) % *num_hits;
+
+ if(hit >= max_hits)
+ return;
+ }
+
+ /* record intersection */
+ Intersection *isect = &isect_array[hit];
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = u;
+ isect->v = v;
+ isect->t = t;
+ }
+ }
+ }
+}
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
new file mode 100644
index 00000000000..963d6cbee9c
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011-2013 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
+ */
+
+/* Volume Primitive
+ *
+ * Volumes are just regions inside meshes with the mesh surface as boundaries.
+ * There isn't as much data to access as for surfaces, there is only a position
+ * to do lookups in 3D voxel or procedural textures.
+ *
+ * 3D voxel textures can be assigned as attributes per mesh, which means the
+ * same shader can be used for volume objects with different densities, etc. */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __VOLUME__
+
+/* Return position normalized to 0..1 in mesh bounds */
+
+ccl_device float3 volume_normalized_position(KernelGlobals *kg, const ShaderData *sd, float3 P)
+{
+ /* todo: optimize this so it's just a single matrix multiplication when
+ * possible (not motion blur), or perhaps even just translation + scale */
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
+
+ object_inverse_position_transform(kg, sd, &P);
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+}
+
+ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float *dx, float *dy)
+{
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+ if(dx) *dx = 0.0f;
+ if(dx) *dy = 0.0f;
+
+ /* todo: support float textures to lower memory usage for single floats */
+ return average(float4_to_float3(r));
+}
+
+ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float3 *dx, float3 *dy)
+{
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+ return float4_to_float3(r);
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index 6cd14d3c51c..173028d50c8 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -37,7 +37,7 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t s
assert(0);
}
-void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height)
+void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation)
{
if(0) {
}
@@ -61,8 +61,8 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
if(tex) {
tex->data = (float4*)mem;
- tex->width = width;
- tex->height = height;
+ tex->dimensions_set(width, height, depth);
+ tex->interpolation = interpolation;
}
}
else if(strstr(name, "__tex_image")) {
@@ -76,8 +76,8 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
if(tex) {
tex->data = (uchar4*)mem;
- tex->width = width;
- tex->height = height;
+ tex->dimensions_set(width, height, depth);
+ tex->interpolation = interpolation;
}
}
else
diff --git a/intern/cycles/kernel/kernel.cu b/intern/cycles/kernel/kernel.cu
index 5e6748c66fc..636e48b5456 100644
--- a/intern/cycles/kernel/kernel.cu
+++ b/intern/cycles/kernel/kernel.cu
@@ -24,7 +24,83 @@
#include "kernel_path.h"
#include "kernel_displace.h"
-extern "C" __global__ void kernel_cuda_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
+/* device data taken from CUDA occupancy calculator */
+
+#ifdef __CUDA_ARCH__
+
+/* 2.0 and 2.1 */
+#if __CUDA_ARCH__ == 200 || __CUDA_ARCH__ == 210
+#define CUDA_MULTIPRESSOR_MAX_REGISTERS 32768
+#define CUDA_MULTIPROCESSOR_MAX_BLOCKS 8
+#define CUDA_BLOCK_MAX_THREADS 1024
+#define CUDA_THREAD_MAX_REGISTERS 63
+
+/* tunable parameters */
+#define CUDA_THREADS_BLOCK_WIDTH 16
+#define CUDA_KERNEL_MAX_REGISTERS 32
+#define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 40
+
+/* 3.0 and 3.5 */
+#elif __CUDA_ARCH__ == 300 || __CUDA_ARCH__ == 350
+#define CUDA_MULTIPRESSOR_MAX_REGISTERS 65536
+#define CUDA_MULTIPROCESSOR_MAX_BLOCKS 16
+#define CUDA_BLOCK_MAX_THREADS 1024
+#define CUDA_THREAD_MAX_REGISTERS 63
+
+/* tunable parameters */
+#define CUDA_THREADS_BLOCK_WIDTH 16
+#define CUDA_KERNEL_MAX_REGISTERS 63
+#define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63
+
+/* 5.0 */
+#elif __CUDA_ARCH__ == 500
+#define CUDA_MULTIPRESSOR_MAX_REGISTERS 65536
+#define CUDA_MULTIPROCESSOR_MAX_BLOCKS 32
+#define CUDA_BLOCK_MAX_THREADS 1024
+#define CUDA_THREAD_MAX_REGISTERS 255
+
+/* tunable parameters */
+#define CUDA_THREADS_BLOCK_WIDTH 16
+#define CUDA_KERNEL_MAX_REGISTERS 63
+#define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63
+
+/* unknown architecture */
+#else
+#error "Unknown or unuspported CUDA architecture, can't determine launch bounds"
+#endif
+
+/* compute number of threads per block and minimum blocks per multiprocessor
+ * given the maximum number of registers per thread */
+
+#define CUDA_LAUNCH_BOUNDS(threads_block_width, thread_num_registers) \
+ __launch_bounds__( \
+ threads_block_width*threads_block_width, \
+ CUDA_MULTIPRESSOR_MAX_REGISTERS/(threads_block_width*threads_block_width*thread_num_registers) \
+ )
+
+/* sanity checks */
+
+#if CUDA_THREADS_BLOCK_WIDTH*CUDA_THREADS_BLOCK_WIDTH > CUDA_BLOCK_MAX_THREADS
+#error "Maximum number of threads per block exceeded"
+#endif
+
+#if CUDA_MULTIPRESSOR_MAX_REGISTERS/(CUDA_THREADS_BLOCK_WIDTH*CUDA_THREADS_BLOCK_WIDTH*CUDA_KERNEL_MAX_REGISTERS) > CUDA_MULTIPROCESSOR_MAX_BLOCKS
+#error "Maximum number of blocks per multiprocessor exceeded"
+#endif
+
+#if CUDA_KERNEL_MAX_REGISTERS > CUDA_THREAD_MAX_REGISTERS
+#error "Maximum number of registers per thread exceeded"
+#endif
+
+#if CUDA_KERNEL_BRANCHED_MAX_REGISTERS > CUDA_THREAD_MAX_REGISTERS
+#error "Maximum number of registers per thread exceeded"
+#endif
+
+/* kernels */
+
+extern "C" __global__ void
+CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
+kernel_cuda_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -34,7 +110,9 @@ extern "C" __global__ void kernel_cuda_path_trace(float *buffer, uint *rng_state
}
#ifdef __BRANCHED_PATH__
-extern "C" __global__ void kernel_cuda_branched_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
+extern "C" __global__ void
+CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_BRANCHED_MAX_REGISTERS)
+kernel_cuda_branched_path_trace(float *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -44,7 +122,9 @@ extern "C" __global__ void kernel_cuda_branched_path_trace(float *buffer, uint *
}
#endif
-extern "C" __global__ void kernel_cuda_convert_to_byte(uchar4 *rgba, float *buffer, float sample_scale, int sx, int sy, int sw, int sh, int offset, int stride)
+extern "C" __global__ void
+CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
+kernel_cuda_convert_to_byte(uchar4 *rgba, float *buffer, float sample_scale, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -53,7 +133,9 @@ extern "C" __global__ void kernel_cuda_convert_to_byte(uchar4 *rgba, float *buff
kernel_film_convert_to_byte(NULL, rgba, buffer, sample_scale, x, y, offset, stride);
}
-extern "C" __global__ void kernel_cuda_convert_to_half_float(uchar4 *rgba, float *buffer, float sample_scale, int sx, int sy, int sw, int sh, int offset, int stride)
+extern "C" __global__ void
+CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
+kernel_cuda_convert_to_half_float(uchar4 *rgba, float *buffer, float sample_scale, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
@@ -62,10 +144,14 @@ extern "C" __global__ void kernel_cuda_convert_to_half_float(uchar4 *rgba, float
kernel_film_convert_to_half_float(NULL, rgba, buffer, sample_scale, x, y, offset, stride);
}
-extern "C" __global__ void kernel_cuda_shader(uint4 *input, float4 *output, int type, int sx)
+extern "C" __global__ void
+CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
+kernel_cuda_shader(uint4 *input, float4 *output, int type, int sx)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
kernel_shader_evaluate(NULL, input, output, (ShaderEvalType)type, x);
}
+#endif
+
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 039dc791b08..c4a08646bab 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -32,7 +32,7 @@ void *kernel_osl_memory(KernelGlobals *kg);
bool kernel_osl_use(KernelGlobals *kg);
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
-void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height);
+void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation=INTERPOLATION_LINEAR);
void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
int sample, int x, int y, int offset, int stride);
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 582a220ab3c..b4f6dcdace9 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -407,5 +407,30 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi
return L_sum;
}
+ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
+{
+ float fac = 1.0f/num_samples;
+
+#ifdef __PASSES__
+ L->direct_diffuse += L_sample->direct_diffuse*fac;
+ L->direct_glossy += L_sample->direct_glossy*fac;
+ L->direct_transmission += L_sample->direct_transmission*fac;
+ L->direct_subsurface += L_sample->direct_subsurface*fac;
+
+ L->indirect_diffuse += L_sample->indirect_diffuse*fac;
+ L->indirect_glossy += L_sample->indirect_glossy*fac;
+ L->indirect_transmission += L_sample->indirect_transmission*fac;
+ L->indirect_subsurface += L_sample->indirect_subsurface*fac;
+
+ L->emission += L_sample->emission*fac;
+ L->background += L_sample->background*fac;
+ L->ao += L_sample->ao*fac;
+ L->shadow += L_sample->shadow*fac;
+ L->mist += L_sample->mist*fac;
+#else
+ *L += *L_sample * fac;
+#endif
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_avx.cpp b/intern/cycles/kernel/kernel_avx.cpp
index d2a7142c551..354214c406e 100644
--- a/intern/cycles/kernel/kernel_avx.cpp
+++ b/intern/cycles/kernel/kernel_avx.cpp
@@ -77,6 +77,6 @@ CCL_NAMESPACE_END
/* needed for some linkers in combination with scons making empty compilation unit in a library */
void __dummy_function_cycles_avx(void);
-void __dummy_function_cycles_avx(void){}
+void __dummy_function_cycles_avx(void) {}
#endif
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
deleted file mode 100644
index 93e546eaece..00000000000
--- a/intern/cycles/kernel/kernel_bvh.h
+++ /dev/null
@@ -1,1258 +0,0 @@
-/*
- * Adapted from code Copyright 2009-2010 NVIDIA Corporation
- * Modifications Copyright 2011, 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
-
-/*
- * "Persistent while-while kernel" used in:
- *
- * "Understanding the Efficiency of Ray Traversal on GPUs",
- * Timo Aila and Samuli Laine,
- * Proc. High-Performance Graphics 2009
- */
-
-/* bottom-most stack entry, indicating the end of traversal */
-#define ENTRYPOINT_SENTINEL 0x76543210
-
-/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
-#define BVH_STACK_SIZE 192
-#define BVH_NODE_SIZE 4
-#define TRI_NODE_SIZE 3
-
-/* silly workaround for float extended precision that happens when compiling
- * without sse support on x86, it results in different results for float ops
- * that you would otherwise expect to compare correctly */
-#if !defined(__i386__) || defined(__SSE__)
-#define NO_EXTENDED_PRECISION
-#else
-#define NO_EXTENDED_PRECISION volatile
-#endif
-
-ccl_device_inline float3 bvh_inverse_direction(float3 dir)
-{
- /* avoid divide by zero (ooeps = exp2f(-80.0f)) */
- float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f;
- float3 idir;
-
- idir.x = 1.0f/((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x));
- idir.y = 1.0f/((fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y));
- idir.z = 1.0f/((fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z));
-
- return idir;
-}
-
-ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
-{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
-
- *P = transform_point(&tfm, ray->P);
-
- float3 dir = transform_direction(&tfm, ray->D);
-
- float len;
- dir = normalize_len(dir, &len);
-
- *idir = bvh_inverse_direction(dir);
-
- if(*t != FLT_MAX)
- *t *= len;
-}
-
-ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
-{
- if(*t != FLT_MAX) {
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
- }
-
- *P = ray->P;
- *idir = bvh_inverse_direction(ray->D);
-}
-
-#ifdef __OBJECT_MOTION__
-ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
-{
- Transform itfm;
- *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
-
- *P = transform_point(&itfm, ray->P);
-
- float3 dir = transform_direction(&itfm, ray->D);
-
- float len;
- dir = normalize_len(dir, &len);
-
- *idir = bvh_inverse_direction(dir);
-
- if(*t != FLT_MAX)
- *t *= len;
-}
-
-ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
-{
- if(*t != FLT_MAX)
- *t *= len(transform_direction(tfm, 1.0f/(*idir)));
-
- *P = ray->P;
- *idir = bvh_inverse_direction(ray->D);
-}
-#endif
-
-/* Sven Woop's algorithm */
-ccl_device_inline bool bvh_triangle_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 idir, uint visibility, int object, int triAddr)
-{
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
- float3 dir = 1.0f/idir;
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < isect->t) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->prim = triAddr;
- isect->object = object;
- isect->u = u;
- isect->v = v;
- isect->t = t;
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-#ifdef __HAIR__
-ccl_device_inline void curvebounds(float *lower, float *upper, float *extremta, float *extrema, float *extremtb, float *extremb, float p0, float p1, float p2, float p3)
-{
- float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
- float ta = -1.0f;
- float tb = -1.0f;
- *extremta = -1.0f;
- *extremtb = -1.0f;
- *upper = p0;
- *lower = p0 + p1 + p2 + p3;
- *extrema = *upper;
- *extremb = *lower;
- if(*lower >= *upper) {
- *upper = *lower;
- *lower = p0;
- }
-
- if(halfdiscroot >= 0) {
- halfdiscroot = sqrt(halfdiscroot);
- ta = (-p2 - halfdiscroot) / (3 * p3);
- tb = (-p2 + halfdiscroot) / (3 * p3);
- }
-
- float t2;
- float t3;
- if(ta > 0.0f && ta < 1.0f) {
- t2 = ta * ta;
- t3 = t2 * ta;
- *extremta = ta;
- *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
- if(*extrema > *upper) {
- *upper = *extrema;
- }
- if(*extrema < *lower) {
- *lower = *extrema;
- }
- }
- if(tb > 0.0f && tb < 1.0f) {
- t2 = tb * tb;
- t3 = t2 * tb;
- *extremtb = tb;
- *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
- if(*extremb >= *upper) {
- *upper = *extremb;
- }
- if(*extremb <= *lower) {
- *lower = *extremb;
- }
- }
-}
-
-#ifdef __KERNEL_SSE2__
-ccl_device_inline __m128 transform_point_T3(const __m128 t[3], const __m128 &a)
-{
- return fma(broadcast<0>(a), t[0], fma(broadcast<1>(a), t[1], _mm_mul_ps(broadcast<2>(a), t[2])));
-}
-#endif
-
-#ifdef __KERNEL_SSE2__
-/* Pass P and idir by reference to aligned vector */
-ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
- const float3 &P, const float3 &idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
-#else
-ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
-#endif
-{
- float epsilon = 0.0f;
- float r_st, r_en;
-
- int depth = kernel_data.curve.subdivisions;
- int flags = kernel_data.curve.curveflags;
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
-
-#ifdef __KERNEL_SSE2__
- __m128 vdir = _mm_div_ps(_mm_set1_ps(1.0f), (__m128 &)idir);
- __m128 vcurve_coef[4];
- const float3 *curve_coef = (float3 *)vcurve_coef;
-
- {
- __m128 dtmp = _mm_mul_ps(vdir, vdir);
- __m128 d_ss = _mm_sqrt_ss(_mm_add_ss(dtmp, broadcast<2>(dtmp)));
- __m128 rd_ss = _mm_div_ss(_mm_set_ss(1.0f), d_ss);
-
- __m128i v00vec = _mm_load_si128((__m128i *)&kg->__curves.data[prim]);
- int2 &v00 = (int2 &)v00vec;
-
- int k0 = v00.x + segment;
- int k1 = k0 + 1;
- int ka = max(k0 - 1, v00.x);
- int kb = min(k1 + 1, v00.x + v00.y - 1);
-
- __m128 P0 = _mm_load_ps(&kg->__curve_keys.data[ka].x);
- __m128 P1 = _mm_load_ps(&kg->__curve_keys.data[k0].x);
- __m128 P2 = _mm_load_ps(&kg->__curve_keys.data[k1].x);
- __m128 P3 = _mm_load_ps(&kg->__curve_keys.data[kb].x);
-
- __m128 rd_sgn = set_sign_bit<0, 1, 1, 1>(broadcast<0>(rd_ss));
- __m128 mul_zxxy = _mm_mul_ps(shuffle<2, 0, 0, 1>(vdir), rd_sgn);
- __m128 mul_yz = _mm_mul_ps(shuffle<1, 2, 1, 2>(vdir), mul_zxxy);
- __m128 mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
- __m128 vdir0 = _mm_and_ps(vdir, _mm_castsi128_ps(_mm_setr_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0)));
-
- __m128 htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
- __m128 htfm1 = shuffle<1, 0, 1, 3>(_mm_set_ss(_mm_cvtss_f32(d_ss)), vdir0);
- __m128 htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
-
- __m128 htfm[] = { htfm0, htfm1, htfm2 };
- __m128 p0 = transform_point_T3(htfm, _mm_sub_ps(P0, (__m128 &)P));
- __m128 p1 = transform_point_T3(htfm, _mm_sub_ps(P1, (__m128 &)P));
- __m128 p2 = transform_point_T3(htfm, _mm_sub_ps(P2, (__m128 &)P));
- __m128 p3 = transform_point_T3(htfm, _mm_sub_ps(P3, (__m128 &)P));
-
- float fc = 0.71f;
- __m128 vfc = _mm_set1_ps(fc);
- __m128 vfcxp3 = _mm_mul_ps(vfc, p3);
-
- vcurve_coef[0] = p1;
- vcurve_coef[1] = _mm_mul_ps(vfc, _mm_sub_ps(p2, p0));
- vcurve_coef[2] = fma(_mm_set1_ps(fc * 2.0f), p0, fma(_mm_set1_ps(fc - 3.0f), p1, fms(_mm_set1_ps(3.0f - 2.0f * fc), p2, vfcxp3)));
- vcurve_coef[3] = fms(_mm_set1_ps(fc - 2.0f), _mm_sub_ps(p2, p1), fms(vfc, p0, vfcxp3));
-
- r_st = ((float4 &)P1).w;
- r_en = ((float4 &)P2).w;
- }
-#else
- float3 curve_coef[4];
-
- /* curve Intersection check */
- float3 dir = 1.0f/idir;
-
- /* obtain curve parameters */
- {
- /* ray transform created - this should be created at beginning of intersection loop */
- Transform htfm;
- float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
- htfm = make_transform(
- dir.z / d, 0, -dir.x /d, 0,
- -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
- dir.x, dir.y, dir.z, 0,
- 0, 0, 0, 1);
-
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + segment;
- int k1 = k0 + 1;
-
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P0 = kernel_tex_fetch(__curve_keys, ka);
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
- float4 P3 = kernel_tex_fetch(__curve_keys, kb);
-
- float3 p0 = transform_point(&htfm, float4_to_float3(P0) - P);
- float3 p1 = transform_point(&htfm, float4_to_float3(P1) - P);
- float3 p2 = transform_point(&htfm, float4_to_float3(P2) - P);
- float3 p3 = transform_point(&htfm, float4_to_float3(P3) - P);
-
- float fc = 0.71f;
- curve_coef[0] = p1;
- curve_coef[1] = -fc*p0 + fc*p2;
- curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
- curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
- r_st = P1.w;
- r_en = P2.w;
- }
-#endif
-
- float r_curr = max(r_st, r_en);
-
- if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
- epsilon = 2 * r_curr;
-
- /* find bounds - this is slow for cubic curves */
- float upper, lower;
-
- float zextrem[4];
- curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
- if(lower - r_curr > isect->t || upper + r_curr < epsilon)
- return false;
-
- /* minimum width extension */
- float mw_extension = min(difl * fabsf(upper), extmax);
- float r_ext = mw_extension + r_curr;
-
- float xextrem[4];
- curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- float yextrem[4];
- curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- /* setup recurrent loop */
- int level = 1 << depth;
- int tree = 0;
- float resol = 1.0f / (float)level;
- bool hit = false;
-
- /* begin loop */
- while(!(tree >> (depth))) {
- float i_st = tree * resol;
- float i_en = i_st + (level * resol);
-#ifdef __KERNEL_SSE2__
- __m128 vi_st = _mm_set1_ps(i_st), vi_en = _mm_set1_ps(i_en);
- __m128 vp_st = fma(fma(fma(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
- __m128 vp_en = fma(fma(fma(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]), vi_en, vcurve_coef[0]);
-
- __m128 vbmin = _mm_min_ps(vp_st, vp_en);
- __m128 vbmax = _mm_max_ps(vp_st, vp_en);
-
- float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
- float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
- float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
- float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
-#else
- float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
- float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
-
- float bminx = min(p_st.x, p_en.x);
- float bmaxx = max(p_st.x, p_en.x);
- float bminy = min(p_st.y, p_en.y);
- float bmaxy = max(p_st.y, p_en.y);
- float bminz = min(p_st.z, p_en.z);
- float bmaxz = max(p_st.z, p_en.z);
-#endif
-
- if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
- bminx = min(bminx,xextrem[1]);
- bmaxx = max(bmaxx,xextrem[1]);
- }
- if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
- bminx = min(bminx,xextrem[3]);
- bmaxx = max(bmaxx,xextrem[3]);
- }
- if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
- bminy = min(bminy,yextrem[1]);
- bmaxy = max(bmaxy,yextrem[1]);
- }
- if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
- bminy = min(bminy,yextrem[3]);
- bmaxy = max(bmaxy,yextrem[3]);
- }
- if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
- bminz = min(bminz,zextrem[1]);
- bmaxz = max(bmaxz,zextrem[1]);
- }
- if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
- bminz = min(bminz,zextrem[3]);
- bmaxz = max(bmaxz,zextrem[3]);
- }
-
- float r1 = r_st + (r_en - r_st) * i_st;
- float r2 = r_st + (r_en - r_st) * i_en;
- r_curr = max(r1, r2);
-
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- float r_ext = mw_extension + r_curr;
- float coverage = 1.0f;
-
- if (bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
- /* the bounding box does not overlap the square centered at O */
- tree += level;
- level = tree & -tree;
- }
- else if (level == 1) {
-
- /* the maximum recursion depth is reached.
- * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
- * dP* is reversed if necessary.*/
- float t = isect->t;
- float u = 0.0f;
- if(flags & CURVE_KN_RIBBONS) {
- float3 tg = (p_en - p_st);
- float w = tg.x * tg.x + tg.y * tg.y;
- if (w == 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
- w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
- w = clamp((float)w, 0.0f, 1.0f);
-
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
- r_curr = r_st + (r_en - r_st) * u;
- /* compare x-y distances */
- float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if (dot(tg, dp_st)< 0)
- dp_st *= -1;
- if (dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if (dot(tg, dp_en) < 0)
- dp_en *= -1;
- if (dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- /* compute coverage */
- float r_ext = r_curr;
- coverage = 1.0f;
- if(difl != 0.0f) {
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- r_ext = mw_extension + r_curr;
- float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
- float d0 = d - r_curr;
- float d1 = d + r_curr;
- if (d0 >= 0)
- coverage = (min(d1 / mw_extension, 1.0f) - min(d0 / mw_extension, 1.0f)) * 0.5f;
- else // inside
- coverage = (min(d1 / mw_extension, 1.0f) + min(-d0 / mw_extension, 1.0f)) * 0.5f;
- }
-
- if (p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon || isect->t < p_curr.z) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- t = p_curr.z;
- }
- else {
- float l = len(p_en - p_st);
- /* minimum width extension */
- float or1 = r1;
- float or2 = r2;
- if(difl != 0.0f) {
- mw_extension = min(len(p_st - P) * difl, extmax);
- or1 = r1 < mw_extension ? mw_extension : r1;
- mw_extension = min(len(p_en - P) * difl, extmax);
- or2 = r2 < mw_extension ? mw_extension : r2;
- }
- /* --- */
- float3 tg = (p_en - p_st) / l;
- float gd = (or2 - or1) / l;
- float difz = -dot(p_st,tg);
- float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
- float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + or1)));
- float tcentre = -halfb/cyla;
- float zcentre = difz + (tg.z * tcentre);
- float3 tdif = - p_st;
- tdif.z += tcentre;
- float tdifz = dot(tdif,tg);
- float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
- float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
- float td = tb*tb - 4*cyla*tc;
- if (td < 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float rootd = sqrtf(td);
- float correction = ((-tb - rootd)/(2*cyla));
- t = tcentre + correction;
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if (dot(tg, dp_st)< 0)
- dp_st *= -1;
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if (dot(tg, dp_en) < 0)
- dp_en *= -1;
-
- if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
- correction = ((-tb + rootd)/(2*cyla));
- t = tcentre + correction;
- }
-
- if (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float w = (zcentre + (tg.z * correction))/l;
- w = clamp((float)w, 0.0f, 1.0f);
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
- r_curr = r1 + (r2 - r1) * w;
- r_ext = or1 + (or2 - or1) * w;
- coverage = r_curr/r_ext;
-
- }
- /* we found a new intersection */
-
- /* stochastic fade from minimum width */
- if(lcg_state && coverage != 1.0f) {
- if(lcg_step_float(lcg_state) > coverage)
- return hit;
- }
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->prim = curveAddr;
- isect->segment = segment;
- isect->object = object;
- isect->u = u;
- isect->v = 0.0f;
- /*isect->v = 1.0f - coverage; */
- isect->t = t;
- hit = true;
- }
-
- tree++;
- level = tree & -tree;
- }
- else {
- /* split the curve into two curves and process */
- level = level >> 1;
- }
- }
-
- return hit;
-}
-
-ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
-{
- /* curve Intersection check */
- int flags = kernel_data.curve.curveflags;
-
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int cnum = __float_as_int(v00.x);
- int k0 = cnum + segment;
- int k1 = k0 + 1;
-
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
-
- float or1 = P1.w;
- float or2 = P2.w;
- float3 p1 = float4_to_float3(P1);
- float3 p2 = float4_to_float3(P2);
-
- /* minimum width extension */
- float r1 = or1;
- float r2 = or2;
- if(difl != 0.0f) {
- float pixelsize = min(len(p1 - P) * difl, extmax);
- r1 = or1 < pixelsize ? pixelsize : or1;
- pixelsize = min(len(p2 - P) * difl, extmax);
- r2 = or2 < pixelsize ? pixelsize : or2;
- }
- /* --- */
-
- float mr = max(r1,r2);
- float3 dif = P - p1;
- float3 dir = 1.0f/idir;
- float l = len(p2 - p1);
-
- float sp_r = mr + 0.5f * l;
- float3 sphere_dif = P - ((p1 + p2) * 0.5f);
- float sphere_b = dot(dir,sphere_dif);
- sphere_dif = sphere_dif - sphere_b * dir;
- sphere_b = dot(dir,sphere_dif);
- float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r;
- if(sdisc < 0.0f)
- return false;
-
- /* obtain parameters and test midpoint distance for suitable modes */
- float3 tg = (p2 - p1) / l;
- float gd = (r2 - r1) / l;
- float dirz = dot(dir,tg);
- float difz = dot(dif,tg);
-
- float a = 1.0f - (dirz*dirz*(1 + gd*gd));
- float halfb = dot(dir,dif) - dirz*(difz + gd*(difz*gd + r1));
-
- float tcentre = -halfb/a;
- float zcentre = difz + (dirz * tcentre);
-
- if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
- return false;
- if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
- return false;
-
- /* test minimum separation */
- float3 cprod = cross(tg, dir);
- float3 cprod2 = cross(tg, dif);
- float cprodsq = len_squared(cprod);
- float cprod2sq = len_squared(cprod2);
- float distscaled = dot(cprod,dif);
-
- if(cprodsq == 0)
- distscaled = cprod2sq;
- else
- distscaled = (distscaled*distscaled)/cprodsq;
-
- if(distscaled > mr*mr)
- return false;
-
- /* calculate true intersection */
- float3 tdif = P - p1 + tcentre * dir;
- float tdifz = dot(tdif,tg);
- float tb = 2*(dot(dir,tdif) - dirz*(tdifz + gd*(tdifz*gd + r1)));
- float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd;
- float td = tb*tb - 4*a*tc;
-
- if (td < 0.0f)
- return false;
-
- float rootd = 0.0f;
- float correction = 0.0f;
- if(flags & CURVE_KN_ACCURATE) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- }
-
- float t = tcentre + correction;
-
- if(t < isect->t) {
-
- if(flags & CURVE_KN_INTERSECTCORRECTION) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- t = tcentre + correction;
- }
-
- float z = zcentre + (dirz * correction);
- bool backface = false;
-
- if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
- backface = true;
- correction = ((-tb + rootd)/(2*a));
- t = tcentre + correction;
- z = zcentre + (dirz * correction);
- }
-
- /* stochastic fade from minimum width */
- float adjradius = or1 + z * (or2 - or1) / l;
- adjradius = adjradius / (r1 + z * gd);
- if(lcg_state && adjradius != 1.0f) {
- if(lcg_step_float(lcg_state) > adjradius)
- return false;
- }
- /* --- */
-
- if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
-
- if (flags & CURVE_KN_ENCLOSEFILTER) {
- float enc_ratio = 1.01f;
- if((dot(P - p1, tg) > -r1 * enc_ratio) && (dot(P - p2, tg) < r2 * enc_ratio)) {
- float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
- float c2 = dot(dif,dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
- if(a2*c2 < 0.0f)
- return false;
- }
- }
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->prim = curveAddr;
- isect->segment = segment;
- isect->object = object;
- isect->u = z/l;
- isect->v = td/(4*a*a);
- /*isect->v = 1.0f - adjradius;*/
- isect->t = t;
-
- if(backface)
- isect->u = -isect->u;
-
- return true;
- }
- }
- }
-
- return false;
-}
-#endif
-
-#ifdef __SUBSURFACE__
-/* Special ray intersection routines for subsurface scattering. In that case we
- * only want to intersect with primitives in the same object, and if case of
- * multiple hits we pick a single random primitive as the intersection point. */
-
-ccl_device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
- float3 P, float3 idir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
-{
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
- float3 dir = 1.0f/idir;
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < tmax) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
- (*num_hits)++;
-
- int hit;
-
- if(*num_hits <= max_hits) {
- hit = *num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit = lcg_step_uint(lcg_state) % *num_hits;
-
- if(hit >= max_hits)
- return;
- }
-
- /* record intersection */
- Intersection *isect = &isect_array[hit];
- isect->prim = triAddr;
- isect->object = object;
- isect->u = u;
- isect->v = v;
- isect->t = t;
- }
- }
- }
-}
-#endif
-
-/* BVH intersection function variations */
-
-#define BVH_INSTANCING 1
-#define BVH_MOTION 2
-#define BVH_HAIR 4
-#define BVH_HAIR_MINIMUM_WIDTH 8
-
-#define BVH_FUNCTION_NAME bvh_intersect
-#define BVH_FUNCTION_FEATURES 0
-#include "kernel_bvh_traversal.h"
-
-#if defined(__INSTANCING__)
-#define BVH_FUNCTION_NAME bvh_intersect_instancing
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING
-#include "kernel_bvh_traversal.h"
-#endif
-
-#if defined(__HAIR__)
-#define BVH_FUNCTION_NAME bvh_intersect_hair
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
-#include "kernel_bvh_traversal.h"
-#endif
-
-#if defined(__OBJECT_MOTION__)
-#define BVH_FUNCTION_NAME bvh_intersect_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
-#include "kernel_bvh_traversal.h"
-#endif
-
-#if defined(__HAIR__) && defined(__OBJECT_MOTION__)
-#define BVH_FUNCTION_NAME bvh_intersect_hair_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
-#include "kernel_bvh_traversal.h"
-#endif
-
-#if defined(__SUBSURFACE__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface
-#define BVH_FUNCTION_FEATURES 0
-#include "kernel_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_instancing
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING
-#include "kernel_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__HAIR__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
-#include "kernel_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
-#include "kernel_bvh_subsurface.h"
-#endif
-
-#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
-#define BVH_FUNCTION_NAME bvh_intersect_subsurface_hair_motion
-#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
-#include "kernel_bvh_subsurface.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
-#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)
-#endif
-{
-#ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
-#ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_hair_motion(kg, ray, isect, visibility, lcg_state, difl, extmax);
-#endif /* __HAIR__ */
-
- return bvh_intersect_motion(kg, ray, isect, visibility);
- }
-#endif /* __OBJECT_MOTION__ */
-
-#ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_hair(kg, ray, isect, visibility, lcg_state, difl, extmax);
-#endif /* __HAIR__ */
-
-#ifdef __KERNEL_CPU__
-
-#ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing)
- return bvh_intersect_instancing(kg, ray, isect, visibility);
-#endif /* __INSTANCING__ */
-
- return bvh_intersect(kg, ray, isect, visibility);
-#else /* __KERNEL_CPU__ */
-
-#ifdef __INSTANCING__
- return bvh_intersect_instancing(kg, ray, isect, visibility);
-#else
- return bvh_intersect(kg, ray, isect, visibility);
-#endif /* __INSTANCING__ */
-
-#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)
-{
-#ifdef __OBJECT_MOTION__
- if(kernel_data.bvh.have_motion) {
-#ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_subsurface_hair_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#endif /* __HAIR__ */
-
- return bvh_intersect_subsurface_motion(kg, ray, isect, subsurface_object, lcg_state, max_hits);
- }
-#endif /* __OBJECT_MOTION__ */
-
-#ifdef __HAIR__
- if(kernel_data.bvh.have_curves)
- return bvh_intersect_subsurface_hair(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#endif /* __HAIR__ */
-
-#ifdef __KERNEL_CPU__
-
-#ifdef __INSTANCING__
- if(kernel_data.bvh.have_instancing)
- return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#endif /* __INSTANCING__ */
-
- return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#else /* __KERNEL_CPU__ */
-
-#ifdef __INSTANCING__
- return bvh_intersect_subsurface_instancing(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#else
- return bvh_intersect_subsurface(kg, ray, isect, subsurface_object, lcg_state, max_hits);
-#endif /* __INSTANCING__ */
-
-#endif /* __KERNEL_CPU__ */
-}
-#endif
-
-/* Ray offset to avoid self intersection */
-
-ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
-{
-#ifdef __INTERSECTION_REFINE__
- const float epsilon_f = 1e-5f;
- /* ideally this should match epsilon_f, but instancing/mblur
- * precision makes it problematic */
- const float epsilon_test = 1.0f;
- const int epsilon_i = 32;
-
- float3 res;
-
- /* x component */
- if(fabsf(P.x) < epsilon_test) {
- res.x = P.x + Ng.x*epsilon_f;
- }
- else {
- uint ix = __float_as_uint(P.x);
- ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i;
- res.x = __uint_as_float(ix);
- }
-
- /* y component */
- if(fabsf(P.y) < epsilon_test) {
- res.y = P.y + Ng.y*epsilon_f;
- }
- else {
- uint iy = __float_as_uint(P.y);
- iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i;
- res.y = __uint_as_float(iy);
- }
-
- /* z component */
- if(fabsf(P.z) < epsilon_test) {
- res.z = P.z + Ng.z*epsilon_f;
- }
- else {
- uint iz = __float_as_uint(P.z);
- iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i;
- res.z = __uint_as_float(iz);
- }
-
- return res;
-#else
- const float epsilon_f = 1e-4f;
- return P + epsilon_f*Ng;
-#endif
-}
-
-/* Refine triangle intersection to more precise hit point. For rays that travel
- * far the precision is often not so good, this reintersects the primitive from
- * a closer distance. */
-
-ccl_device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
-
-#ifdef __INTERSECTION_REFINE__
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- P = P + D*t;
-
- float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
- float rt = Oz * invDz;
-
- P = P + D*rt;
-
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-#else
- return P + D*t;
-#endif
-}
-
-/* same as above, except that isect->t is assumed to be in object space for instancing */
-ccl_device_inline float3 bvh_triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
-
-#ifdef __INTERSECTION_REFINE__
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D);
- D = normalize(D);
- }
-
- P = P + D*t;
-
- float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
- float rt = Oz * invDz;
-
- P = P + D*rt;
-
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-#else
- return P + D*t;
-#endif
-}
-
-#ifdef __HAIR__
-
-ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
-{
- float fc = 0.71f;
- float data[4];
- float t2 = t * t;
- data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
- data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
- data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
- data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
-}
-
-ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
-{
- float data[4];
- float fc = 0.71f;
- float t2 = t * t;
- float t3 = t2 * t;
- data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
- data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
- data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
- data[3] = fc * t3 - fc * t2;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
-}
-
-ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- int flag = kernel_data.curve.curveflags;
- float t = isect->t;
- float3 P = ray->P;
- float3 D = ray->D;
-
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + isect->segment;
- int k1 = k0 + 1;
-
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
- float l = 1.0f;
- float3 tg = normalize_len(float4_to_float3(P2 - P1), &l);
- float r1 = P1.w;
- float r2 = P2.w;
- float gd = ((r2 - r1)/l);
-
- P = P + D*t;
-
- if(flag & CURVE_KN_INTERPOLATE) {
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P0 = kernel_tex_fetch(__curve_keys, ka);
- float4 P3 = kernel_tex_fetch(__curve_keys, kb);
-
- float3 p[4];
- p[0] = float4_to_float3(P0);
- p[1] = float4_to_float3(P1);
- p[2] = float4_to_float3(P2);
- p[3] = float4_to_float3(P3);
-
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = 0.0f;
-#endif
-
- tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
-
- if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS)
- sd->Ng = normalize(-(D - tg * (dot(tg, D))));
- else {
- float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
- sd->Ng = normalize(P - p_curr);
- sd->Ng = sd->Ng - gd * tg;
- sd->Ng = normalize(sd->Ng);
- }
- sd->N = sd->Ng;
- }
- else {
- float3 dif = P - float4_to_float3(P1);
-
-#ifdef __UV__
- sd->u = dot(dif,tg)/l;
- sd->v = 0.0f;
-#endif
-
- if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
- sd->Ng = -(D - tg * dot(tg, D));
- sd->Ng = normalize(sd->Ng);
- }
- else {
- sd->Ng = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
- if (gd != 0.0f) {
- sd->Ng = sd->Ng - gd * tg ;
- sd->Ng = normalize(sd->Ng);
- }
- }
-
- sd->N = sd->Ng;
- }
-
-#ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = tg;
- sd->dPdv = cross(tg, sd->Ng);
-#endif
-
- /*add fading parameter for minimum pixel width with transparency bsdf*/
- /*sd->curve_transparency = isect->v;*/
- /*sd->curve_radius = sd->u * gd * l + r1;*/
-
- if(isect->object != ~0) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-}
-#endif
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 887b1afddd4..7fc66a9fdee 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -229,7 +229,7 @@ ccl_device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, f
if(kernel_data.cam.shuttertime == -1.0f)
ray->time = TIME_INVALID;
else
- ray->time = 0.5f + 0.5f*(time - 0.5f)*kernel_data.cam.shuttertime;
+ ray->time = time;
#endif
/* sample */
@@ -266,7 +266,7 @@ ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd,
{
if(kernel_data.cam.type != CAMERA_PANORAMA) {
/* perspective / ortho */
- if(sd->object == ~0 && kernel_data.cam.type == CAMERA_PERSPECTIVE)
+ if(sd->object == PRIM_NONE && kernel_data.cam.type == CAMERA_PERSPECTIVE)
P += camera_position(kg);
Transform tfm = kernel_data.cam.worldtondc;
@@ -276,7 +276,7 @@ ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd,
/* panorama */
Transform tfm = kernel_data.cam.worldtocamera;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
P = normalize(transform_point(&tfm, P));
else
P = normalize(transform_direction(&tfm, P));
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index b213e91274d..d027bb62ebe 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -20,9 +20,9 @@
#define __KERNEL_CPU__
#include "util_debug.h"
-#include "util_half.h"
#include "util_math.h"
#include "util_simd.h"
+#include "util_half.h"
#include "util_types.h"
CCL_NAMESPACE_BEGIN
@@ -95,38 +95,128 @@ template<typename T> struct texture_image {
ccl_always_inline float4 interp(float x, float y, bool periodic = true)
{
- if(!data)
+ if(UNLIKELY(!data))
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
int ix, iy, nix, niy;
- float tx = frac(x*width - 0.5f, &ix);
- float ty = frac(y*height - 0.5f, &iy);
- if(periodic) {
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
+ if(interpolation == INTERPOLATION_CLOSEST) {
+ frac(x*(float)width, &ix);
+ frac(y*(float)height, &iy);
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ }
+ return read(data[ix + iy*width]);
}
else {
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
-
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
+ float tx = frac(x*(float)width - 0.5f, &ix);
+ float ty = frac(y*(float)height - 0.5f, &iy);
+
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ }
+
+ float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
+ r += (1.0f - ty)*tx*read(data[nix + iy*width]);
+ r += ty*(1.0f - tx)*read(data[ix + niy*width]);
+ r += ty*tx*read(data[nix + niy*width]);
+
+ return r;
}
+ }
+
+ ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false)
+ {
+ if(UNLIKELY(!data))
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
- r += (1.0f - ty)*tx*read(data[nix + iy*width]);
- r += ty*(1.0f - tx)*read(data[ix + niy*width]);
- r += ty*tx*read(data[nix + niy*width]);
+ int ix, iy, iz, nix, niy, niz;
+
+ if(interpolation == INTERPOLATION_CLOSEST) {
+ frac(x*(float)width, &ix);
+ frac(y*(float)height, &iy);
+ frac(z*(float)depth, &iz);
+
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+ }
+
+ return read(data[ix + iy*width + iz*width*height]);
+ }
+ else {
+ float tx = frac(x*(float)width - 0.5f, &ix);
+ float ty = frac(y*(float)height - 0.5f, &iy);
+ float tz = frac(z*(float)depth - 0.5f, &iz);
+
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ niz = wrap_periodic(iz+1, depth);
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ niz = wrap_clamp(iz+1, depth);
+ }
+
+ float4 r;
+
+ r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + iz*width*height]);
+ r += (1.0f - tz)*(1.0f - ty)*tx*read(data[nix + iy*width + iz*width*height]);
+ r += (1.0f - tz)*ty*(1.0f - tx)*read(data[ix + niy*width + iz*width*height]);
+ r += (1.0f - tz)*ty*tx*read(data[nix + niy*width + iz*width*height]);
+
+ r += tz*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + niz*width*height]);
+ r += tz*(1.0f - ty)*tx*read(data[nix + iy*width + niz*width*height]);
+ r += tz*ty*(1.0f - tx)*read(data[ix + niy*width + niz*width*height]);
+ r += tz*ty*tx*read(data[nix + niy*width + niz*width*height]);
+
+ return r;
+ }
+ }
- return r;
+ ccl_always_inline void dimensions_set(int width_, int height_, int depth_)
+ {
+ width = width_;
+ height = height_;
+ depth = depth_;
}
T *data;
- int width, height;
+ int interpolation;
+ int width, height, depth;
};
typedef texture<float4> texture_float4;
@@ -146,6 +236,7 @@ typedef texture_image<uchar4> texture_image_uchar4;
#define kernel_tex_fetch_m128i(tex, index) (kg->tex.fetch_m128i(index))
#define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size))
#define kernel_tex_image_interp(tex, x, y) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp(x, y) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp(x, y))
+#define kernel_tex_image_interp_3d(tex, x, y, z) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp_3d(x, y, z) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp_3d(x, y, z))
#define kernel_data (kg->__data)
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 15e7353ec38..e4c20d26ff1 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -60,7 +60,7 @@ typedef texture<uchar4, 2, cudaReadModeNormalizedFloat> texture_image_uchar4;
/* In order to use full 6GB of memory on Titan cards, use arrays instead
* of textures. On earlier cards this seems slower, but on Titan it is
* actually slightly faster in tests. */
-#if __CUDA_ARCH__ < 350
+#if __CUDA_ARCH__ < 300
#define __KERNEL_CUDA_TEX_STORAGE__
#endif
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index 4f4414cc298..8346b09619e 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -85,27 +85,36 @@
#define __float_as_uint(x) as_uint(x)
#define __int_as_float(x) as_float(x)
#define __float_as_int(x) as_int(x)
-#define sqrtf(x) sqrt(((float)x))
-#define cosf(x) cos(((float)x))
-#define sinf(x) sin(((float)x))
#define powf(x, y) pow(((float)x), ((float)y))
#define fabsf(x) fabs(((float)x))
#define copysignf(x, y) copysign(((float)x), ((float)y))
-#define cosf(x) cos(((float)x))
#define asinf(x) asin(((float)x))
#define acosf(x) acos(((float)x))
#define atanf(x) atan(((float)x))
-#define tanf(x) tan(((float)x))
-#define logf(x) log(((float)x))
#define floorf(x) floor(((float)x))
#define ceilf(x) ceil(((float)x))
-#define expf(x) exp(((float)x))
#define hypotf(x, y) hypot(((float)x), ((float)y))
#define atan2f(x, y) atan2(((float)x), ((float)y))
#define fmaxf(x, y) fmax(((float)x), ((float)y))
#define fminf(x, y) fmin(((float)x), ((float)y))
#define fmodf(x, y) fmod((float)x, (float)y)
+#ifndef __CL_USE_NATIVE__
+#define sinf(x) native_sin(((float)x))
+#define cosf(x) native_cos(((float)x))
+#define tanf(x) native_tan(((float)x))
+#define expf(x) native_exp(((float)x))
+#define sqrtf(x) native_sqrt(((float)x))
+#define logf(x) native_log(((float)x))
+#else
+#define sinf(x) sin(((float)x))
+#define cosf(x) cos(((float)x))
+#define tanf(x) tan(((float)x))
+#define expf(x) exp(((float)x))
+#define sqrtf(x) sqrt(((float)x))
+#define logf(x) log(((float)x))
+#endif
+
/* data lookup defines */
#define kernel_data (*kg->data)
#define kernel_tex_fetch(t, index) kg->t[index]
diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h
deleted file mode 100644
index 821ac50eaa9..00000000000
--- a/intern/cycles/kernel/kernel_curve.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2011-2013 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
-
-#ifdef __HAIR__
-
-/* curve attributes */
-
-ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
-{
- if(elem == ATTR_ELEMENT_CURVE) {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-#endif
-
- return kernel_tex_fetch(__attributes_float, offset + sd->prim);
- }
- else if(elem == ATTR_ELEMENT_CURVE_KEY) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + sd->segment;
- int k1 = k0 + 1;
-
- float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
- float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*(f1 - f0);
- if(dy) *dy = 0.0f;
-#endif
-
- return (1.0f - sd->u)*f0 + sd->u*f1;
- }
- else {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-#endif
-
- return 0.0f;
- }
-}
-
-ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
-{
- if(elem == ATTR_ELEMENT_CURVE) {
- /* idea: we can't derive any useful differentials here, but for tiled
- * mipmap image caching it would be useful to avoid reading the highest
- * detail level always. maybe a derivative based on the hair density
- * could be computed somehow? */
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
- }
- else if(elem == ATTR_ELEMENT_CURVE_KEY) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + sd->segment;
- int k1 = k0 + 1;
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*(f1 - f0);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return (1.0f - sd->u)*f0 + sd->u*f1;
- }
- else {
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-}
-
-/* hair info node functions */
-
-ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
-{
- float r = 0.0f;
-
- if(sd->segment != ~0) {
- float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
- int k0 = __float_as_int(curvedata.x) + sd->segment;
- int k1 = k0 + 1;
-
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
- r = (P2.w - P1.w) * sd->u + P1.w;
- }
-
- return r*2.0f;
-}
-
-ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
-{
- float3 tgN = make_float3(0.0f,0.0f,0.0f);
-
- if(sd->segment != ~0) {
-
- tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
- tgN = normalize(tgN);
-
- /* need to find suitable scaled gd for corrected normal */
-#if 0
- tgN = normalize(tgN - gd * sd->dPdu);
-#endif
- }
-
- return tgN;
-}
-
-#endif
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index c50e2166660..b8c64af658f 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -16,8 +16,308 @@
CCL_NAMESPACE_BEGIN
+ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng,
+ bool is_combined, bool is_ao, bool is_sss)
+{
+ int samples = kernel_data.integrator.aa_samples;
+
+ /* initialize master radiance accumulator */
+ kernel_assert(kernel_data.film.use_light_pass);
+ path_radiance_init(L, kernel_data.film.use_light_pass);
+
+ /* take multiple samples */
+ for(int sample = 0; sample < samples; sample++) {
+ PathRadiance L_sample;
+ PathState state;
+ Ray ray;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+
+ /* init radiance */
+ path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
+
+ /* init path state */
+ path_state_init(kg, &state, &rng, sample);
+ state.num_samples = samples;
+
+ /* evaluate surface shader */
+ float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF);
+ shader_eval_surface(kg, sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
+
+ /* TODO, disable the closures we won't need */
+
+ /* sample ambient occlusion */
+ if(is_combined || is_ao) {
+ kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
+ }
+
+ /* sample subsurface scattering */
+ if((is_combined || is_sss) && (sd->flag & SD_BSSRDF)) {
+#ifdef __SUBSURFACE__
+ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+ if (kernel_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, &throughput))
+ is_sss = true;
+#endif
+ }
+
+ /* sample light and BSDF */
+ if((!is_sss) && (!is_ao)) {
+ if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
+#ifdef __LAMP_MIS__
+ state.ray_t = 0.0f;
+#endif
+ /* compute indirect light */
+ kernel_path_indirect(kg, &rng, ray, throughput, state.num_samples, state, &L_sample);
+
+ /* sum and reset indirect light pass variables for the next samples */
+ path_radiance_sum_indirect(&L_sample);
+ path_radiance_reset_indirect(&L_sample);
+ }
+ }
+
+ /* accumulate into master L */
+ path_radiance_accum_sample(L, &L_sample, samples);
+ }
+}
+
+ccl_device bool is_light_pass(ShaderEvalType type)
+{
+ switch (type) {
+ case SHADER_EVAL_AO:
+ case SHADER_EVAL_COMBINED:
+ case SHADER_EVAL_SHADOW:
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i)
+{
+ ShaderData sd;
+ uint4 in = input[i * 2];
+ uint4 diff = input[i * 2 + 1];
+
+ float3 out;
+
+ int object = in.x;
+ int prim = in.y;
+
+ if(prim == -1)
+ return;
+
+ float u = __uint_as_float(in.z);
+ float v = __uint_as_float(in.w);
+
+ float dudx = __uint_as_float(diff.x);
+ float dudy = __uint_as_float(diff.y);
+ float dvdx = __uint_as_float(diff.z);
+ float dvdy = __uint_as_float(diff.w);
+
+ int shader;
+ float3 P, Ng;
+
+ triangle_point_normal(kg, prim, u, v, &P, &Ng, &shader);
+
+ /* dummy initilizations copied from SHADER_EVAL_DISPLACE */
+ float3 I = Ng;
+ float t = 0.0f;
+ float time = TIME_INVALID;
+ int bounce = 0;
+ int transparent_bounce = 0;
+
+ /* light passes */
+ PathRadiance L;
+
+ shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time, bounce, transparent_bounce);
+ sd.I = sd.N;
+
+ /* update differentials */
+ sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
+ sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
+ sd.du.dx = dudx;
+ sd.du.dy = dudy;
+ sd.dv.dx = dvdx;
+ sd.dv.dy = dvdy;
+
+ if(is_light_pass(type)) {
+ RNG rng = cmj_hash(i, 0);
+ compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_COMBINED),
+ (type == SHADER_EVAL_AO),
+ (type == SHADER_EVAL_SUBSURFACE_DIRECT ||
+ type == SHADER_EVAL_SUBSURFACE_INDIRECT));
+ }
+
+ switch (type) {
+ /* data passes */
+ case SHADER_EVAL_NORMAL:
+ {
+ /* compression: normal = (2 * color) - 1 */
+ out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
+ break;
+ }
+ case SHADER_EVAL_UV:
+ {
+ out = primitive_uv(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_diffuse(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_glossy(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_transmission(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_COLOR:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_subsurface(kg, &sd);
+#endif
+ break;
+ }
+ case SHADER_EVAL_EMISSION:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_EMISSION);
+ out = shader_emissive_eval(kg, &sd);
+ break;
+ }
+
+#ifdef __PASSES__
+ /* light passes */
+ case SHADER_EVAL_AO:
+ {
+ out = L.ao;
+ break;
+ }
+ case SHADER_EVAL_COMBINED:
+ {
+ out = path_radiance_clamp_and_sum(kg, &L);
+ break;
+ }
+ case SHADER_EVAL_SHADOW:
+ {
+ out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_diffuse, shader_bsdf_diffuse(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_glossy, shader_bsdf_glossy(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_transmission, shader_bsdf_transmission(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_subsurface, shader_bsdf_subsurface(kg, &sd));
+#endif
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_diffuse, shader_bsdf_diffuse(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_glossy, shader_bsdf_glossy(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_transmission, shader_bsdf_transmission(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_subsurface, shader_bsdf_subsurface(kg, &sd));
+#endif
+ break;
+ }
+#endif
+
+ /* extra */
+ case SHADER_EVAL_ENVIRONMENT:
+ {
+ /* setup ray */
+ Ray ray;
+
+ ray.P = make_float3(0.0f, 0.0f, 0.0f);
+ ray.D = normalize(P);
+ ray.t = 0.0f;
+#ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+#endif
+
+#ifdef __RAY_DIFFERENTIALS__
+ ray.dD = differential3_zero();
+ ray.dP = differential3_zero();
+#endif
+
+ /* setup shader data */
+ shader_setup_from_background(kg, &sd, &ray, 0, 0);
+
+ /* evaluate */
+ int flag = 0; /* we can't know which type of BSDF this is for */
+ out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
+ break;
+ }
+ default:
+ {
+ /* no real shader, returning the position of the verts for debugging */
+ out = normalize(P);
+ break;
+ }
+ }
+
+ /* write output */
+ output[i] = make_float4(out.x, out.y, out.z, 1.0f);
+ return;
+}
+
ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i)
{
+ if(type >= SHADER_EVAL_BAKE) {
+ kernel_bake_evaluate(kg, input, output, type, i);
+ return;
+ }
+
ShaderData sd;
uint4 in = input[i];
float3 out;
@@ -55,7 +355,7 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *inpu
#endif
/* setup shader data */
- shader_setup_from_background(kg, &sd, &ray, 0);
+ shader_setup_from_background(kg, &sd, &ray, 0, 0);
/* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 58bdc2b70ca..deffa7f2ba2 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -18,8 +18,8 @@ CCL_NAMESPACE_BEGIN
/* Direction Emission */
-ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
- LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce)
+ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
+ LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce)
{
/* setup shading at emitter */
ShaderData sd;
@@ -36,27 +36,20 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
#endif
ray.dP = differential3_zero();
ray.dD = dI;
-#ifdef __CAMERA_MOTION__
- ray.time = time;
-#endif
- shader_setup_from_background(kg, &sd, &ray, bounce+1);
+
+ shader_setup_from_background(kg, &sd, &ray, bounce+1, transparent_bounce);
eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
}
else
#endif
{
-#ifdef __HAIR__
- if(ls->type == LIGHT_STRAND)
- shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ls->prim);
- else
-#endif
- shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ~0);
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, transparent_bounce);
ls->Ng = sd.Ng;
/* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */
- shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
+ shader_eval_surface(kg, &sd, 0.0f, 0, SHADER_CONTEXT_EMISSION);
/* evaluate emissive closure */
if(sd.flag & SD_EMISSION)
@@ -71,13 +64,13 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
}
ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
- float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
- bool *is_lamp, int bounce)
+ float randt, float randu, float randv, Ray *ray, BsdfEval *eval,
+ bool *is_lamp, int bounce, int transparent_bounce)
{
LightSample ls;
#ifdef __BRANCHED_PATH__
- if(lindex != -1) {
+ if(lindex != LAMP_NONE) {
/* sample position on a specified light */
light_select(kg, lindex, randu, randv, sd->P, &ls);
}
@@ -95,7 +88,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
differential3 dD = differential3_zero();
/* evaluate closure */
- float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce);
+ float3 light_eval = direct_emissive_eval(kg, &ls, -ls.D, dD, ls.t, sd->time, bounce, transparent_bounce);
if(is_zero(light_eval))
return false;
@@ -104,7 +97,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
float bsdf_pdf;
#ifdef __VOLUME__
- if(sd->prim != ~0)
+ if(sd->prim != PRIM_NONE)
shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
else
shader_volume_phase_eval(kg, sd, ls.D, eval, &bsdf_pdf);
@@ -160,7 +153,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
}
/* return if it's a lamp for shadow pass */
- *is_lamp = (ls.prim == ~0 && ls.type != LIGHT_BACKGROUND);
+ *is_lamp = (ls.prim == PRIM_NONE && ls.type != LIGHT_BACKGROUND);
return true;
}
@@ -173,10 +166,11 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
float3 L = shader_emissive_eval(kg, sd);
#ifdef __HAIR__
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) {
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE))
#else
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) {
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
#endif
+ {
/* multiple importance sampling, get triangle light pdf,
* and compute weight with respect to BSDF pdf */
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
@@ -190,71 +184,75 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader
/* Indirect Lamp Emission */
-ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce)
+ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission)
{
- LightSample ls;
- int lamp = lamp_light_eval_sample(kg, randt);
+ bool hit_lamp = false;
- if(lamp == ~0)
- return false;
+ *emission = make_float3(0.0f, 0.0f, 0.0f);
- if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
- return false;
+ for(int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
+ LightSample ls;
+
+ if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
+ continue;
#ifdef __PASSES__
- /* use visibility flag to skip lights */
- if(ls.shader & SHADER_EXCLUDE_ANY) {
- if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
- ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (path_flag & PATH_RAY_GLOSSY)) ||
- ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)))
- return false;
- }
+ /* use visibility flag to skip lights */
+ if(ls.shader & SHADER_EXCLUDE_ANY) {
+ if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
+ ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
+ ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)))
+ continue;
+ }
#endif
- float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce);
+ float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, state->bounce, state->transparent_bounce);
- if(!(path_flag & PATH_RAY_MIS_SKIP)) {
- /* multiple importance sampling, get regular light pdf,
- * and compute weight with respect to BSDF pdf */
- float mis_weight = power_heuristic(bsdf_pdf, ls.pdf);
- L *= mis_weight;
+ if(!(state->flag & PATH_RAY_MIS_SKIP)) {
+ /* multiple importance sampling, get regular light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
+ L *= mis_weight;
+ }
+
+ *emission += L;
+ hit_lamp = true;
}
- *emission = L;
- return true;
+ return hit_lamp;
}
/* Indirect Background */
-ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce)
+ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *state, Ray *ray)
{
#ifdef __BACKGROUND__
int shader = kernel_data.background.surface_shader;
/* use visibility flag to skip lights */
if(shader & SHADER_EXCLUDE_ANY) {
- if(((shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
- ((shader & SHADER_EXCLUDE_GLOSSY) && (path_flag & PATH_RAY_GLOSSY)) ||
- ((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
- ((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)))
+ if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
+ ((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
+ ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
+ ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)))
return make_float3(0.0f, 0.0f, 0.0f);
}
/* evaluate background closure */
ShaderData sd;
- shader_setup_from_background(kg, &sd, ray, bounce+1);
+ shader_setup_from_background(kg, &sd, ray, state->bounce+1, state->transparent_bounce);
- float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
+ float3 L = shader_eval_background(kg, &sd, state->flag, SHADER_CONTEXT_EMISSION);
#ifdef __BACKGROUND_MIS__
/* check if background light exists or if we should skip pdf */
int res = kernel_data.integrator.pdf_background_res;
- if(!(path_flag & PATH_RAY_MIS_SKIP) && res) {
+ if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
/* multiple importance sampling, get background light pdf for ray
* direction, and compute weight with respect to BSDF pdf */
float pdf = background_light_pdf(kg, ray->D);
- float mis_weight = power_heuristic(bsdf_pdf, pdf);
+ float mis_weight = power_heuristic(state->ray_pdf, pdf);
return L*mis_weight;
}
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index cbd875e994c..dc5f6e7ce38 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -75,7 +75,7 @@ ccl_device void kernel_film_convert_to_half_float(KernelGlobals *kg,
float exposure = kernel_data.film.exposure;
- ccl_align(16) float4 rgba_in = *in;
+ float4 rgba_in = *in;
if(exposure != 1.0f) {
rgba_in.x *= exposure;
@@ -83,7 +83,7 @@ ccl_device void kernel_film_convert_to_half_float(KernelGlobals *kg,
rgba_in.z *= exposure;
}
- float4_store_half(out, &rgba_in, sample_scale);
+ float4_store_half(out, rgba_in, sample_scale);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index c32f0395744..ac432d3fe04 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -217,8 +217,8 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
ls->shader = __float_as_int(data1.x);
- ls->object = ~0;
- ls->prim = ~0;
+ ls->object = PRIM_NONE;
+ ls->prim = PRIM_NONE;
ls->lamp = lamp;
ls->u = randu;
ls->v = randv;
@@ -309,8 +309,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
ls->shader = __float_as_int(data1.x);
- ls->object = ~0;
- ls->prim = ~0;
+ ls->object = PRIM_NONE;
+ ls->prim = PRIM_NONE;
ls->lamp = lamp;
/* todo: missing texture coordinates */
ls->u = 0.0f;
@@ -421,7 +421,6 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
/* compute pdf */
if(ls->t != FLT_MAX)
ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
- ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
return true;
}
@@ -458,11 +457,10 @@ ccl_device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
v = randv*randu;
/* triangle, so get position, normal, shader */
- ls->P = triangle_point_MT(kg, prim, u, v);
- ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
+ triangle_point_normal(kg, prim, u, v, &ls->P, &ls->Ng, &ls->shader);
ls->object = object;
ls->prim = prim;
- ls->lamp = ~0;
+ ls->lamp = LAMP_NONE;
ls->shader |= SHADER_USE_MIS;
ls->t = 0.0f;
ls->u = u;
@@ -485,52 +483,6 @@ ccl_device float triangle_light_pdf(KernelGlobals *kg,
return t*t*pdf/cos_pi;
}
-/* Curve Light */
-
-#ifdef __HAIR__
-
-ccl_device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
- int segment, float randu, float randv, float time, LightSample *ls)
-{
- /* this strand code needs completion */
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + segment;
- int k1 = k0 + 1;
-
- float4 P1 = kernel_tex_fetch(__curve_keys, k0);
- float4 P2 = kernel_tex_fetch(__curve_keys, k1);
-
- float l = len(float4_to_float3(P2) - float4_to_float3(P1));
-
- float r1 = P1.w;
- float r2 = P2.w;
- float3 tg = (float4_to_float3(P2) - float4_to_float3(P1)) / l;
- float3 xc = make_float3(tg.x * tg.z, tg.y * tg.z, -(tg.x * tg.x + tg.y * tg.y));
- if (is_zero(xc))
- xc = make_float3(tg.x * tg.y, -(tg.x * tg.x + tg.z * tg.z), tg.z * tg.y);
- xc = normalize(xc);
- float3 yc = cross(tg, xc);
- float gd = ((r2 - r1)/l);
-
- /* normal currently ignores gradient */
- ls->Ng = sinf(M_2PI_F * randv) * xc + cosf(M_2PI_F * randv) * yc;
- ls->P = randu * l * tg + (gd * l + r1) * ls->Ng;
- ls->object = object;
- ls->prim = prim;
- ls->lamp = ~0;
- ls->t = 0.0f;
- ls->u = randu;
- ls->v = randv;
- ls->type = LIGHT_STRAND;
- ls->eval_fac = 1.0f;
- ls->shader = __float_as_int(v00.z) | SHADER_USE_MIS;
-
- object_transform_light_sample(kg, ls, object, time);
-}
-
-#endif
-
/* Light Distribution */
ccl_device int light_distribution_sample(KernelGlobals *kg, float randt)
@@ -573,21 +525,14 @@ ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float
if(prim >= 0) {
int object = __float_as_int(l.w);
-#ifdef __HAIR__
- int segment = __float_as_int(l.z) & SHADER_MASK;
-#endif
+ int shader_flag = __float_as_int(l.z);
-#ifdef __HAIR__
- if (segment != SHADER_MASK)
- curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
- else
-#endif
- triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls);
/* compute incoming direction, distance and pdf */
ls->D = normalize_len(ls->P - P, &ls->t);
ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
- ls->shader |= __float_as_int(l.z) & (~SHADER_MASK);
+ ls->shader |= shader_flag;
}
else {
int lamp = -prim-1;
@@ -620,7 +565,7 @@ ccl_device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
return lamp;
}
else
- return ~0;
+ return LAMP_NONE;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 92f3420a218..af7b727c1ba 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -131,6 +131,11 @@ ccl_device float power_heuristic_3(float a, float b, float c)
return (a*a)/(a*a + b*b + c*c);
}
+ccl_device float max_heuristic(float a, float b)
+{
+ return (a > b)? 1.0f: 0.0f;
+}
+
/* distribute uniform xy on [0,1] over unit disk [-1,1], with concentric mapping
* to better preserve stratification for some RNG sequences */
ccl_device float2 concentric_sample_disk(float u1, float u2)
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 9cdcb8c5229..b3b6fc02894 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -51,7 +51,8 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl
if(!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) {
if(!(sd->flag & SD_TRANSPARENT) ||
kernel_data.film.pass_alpha_threshold == 0.0f ||
- average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold) {
+ average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold)
+ {
if(sample == 0) {
if(flag & PASS_DEPTH) {
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 635201471e1..a80a0033712 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -18,18 +18,15 @@
#include "osl_shader.h"
#endif
-#include "kernel_differential.h"
-#include "kernel_montecarlo.h"
-#include "kernel_projection.h"
-#include "kernel_object.h"
-#include "kernel_triangle.h"
-#include "kernel_curve.h"
-#include "kernel_primitive.h"
-#include "kernel_projection.h"
#include "kernel_random.h"
-#include "kernel_bvh.h"
-#include "kernel_accumulate.h"
+#include "kernel_projection.h"
+#include "kernel_montecarlo.h"
+#include "kernel_differential.h"
#include "kernel_camera.h"
+
+#include "geom/geom.h"
+
+#include "kernel_accumulate.h"
#include "kernel_shader.h"
#include "kernel_light.h"
#include "kernel_emission.h"
@@ -59,11 +56,6 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
/* sample illumination from lights to find path contribution */
if(sd->flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
-#ifdef __MULTI_CLOSURE__
- float light_o = 0.0f;
-#else
- float light_o = path_state_rng_1D(kg, rng, state, PRNG_LIGHT_F);
-#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
@@ -75,7 +67,7 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
light_ray.time = sd->time;
#endif
- if(direct_emission(kg, sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+ if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@@ -133,7 +125,96 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__)
-ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer,
+ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, bool sample_all_lights)
+{
+ /* sample illumination from lights to find path contribution */
+ if(sd->flag & SD_BSDF_HAS_EVAL) {
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
+
+#ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+#endif
+
+ if(sample_all_lights) {
+ /* lamp sampling */
+ for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
+ float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
+ RNG lamp_rng = cmj_hash(*rng, i);
+
+ if(kernel_data.integrator.pdf_triangles != 0.0f)
+ num_samples_inv *= 0.5f;
+
+ for(int j = 0; j < num_samples; j++) {
+ float light_u, light_v;
+ path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ if(direct_emission(kg, sd, i, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+
+ /* mesh light sampling */
+ if(kernel_data.integrator.pdf_triangles != 0.0f) {
+ int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
+ float num_samples_inv = num_samples_adjust/num_samples;
+
+ if(kernel_data.integrator.num_all_lights)
+ num_samples_inv *= 0.5f;
+
+ for(int j = 0; j < num_samples; j++) {
+ float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT);
+ float light_u, light_v;
+ path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* only sample triangle lights */
+ if(kernel_data.integrator.num_all_lights)
+ light_t = 0.5f*light_t;
+
+ if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+ }
+ else {
+ float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* sample random light */
+ if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
float3 throughput, int num_samples, PathState state, PathRadiance *L)
{
/* path iteration */
@@ -161,17 +242,16 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
light_ray.dP = ray.dP;
/* intersect with lamp */
- float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
float3 emission;
- if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
+ if(indirect_lamp_emission(kg, &state, &light_ray, &emission))
path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
#ifdef __VOLUME__
/* volume attenuation, emission, scatter */
- if(state.volume_stack[0].shader != SHADER_NO_ID) {
+ if(state.volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = ray;
volume_ray.t = (hit)? isect.t: FLT_MAX;
@@ -191,7 +271,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
if(!hit) {
#ifdef __BACKGROUND__
/* sample background shader */
- float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+ float3 L_background = indirect_background(kg, &state, &ray);
path_radiance_accum_background(L, throughput, L_background, state.bounce);
#endif
@@ -200,7 +280,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
/* setup shading */
ShaderData sd;
- shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+ shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
#ifdef __BRANCHED_PATH__
@@ -300,38 +380,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
}
#endif
-#ifdef __EMISSION__
+#if defined(__EMISSION__) && defined(__BRANCHED_PATH__)
if(kernel_data.integrator.use_direct_light) {
- /* sample illumination from lights to find path contribution */
- if(sd.flag & SD_BSDF_HAS_EVAL) {
- float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
-#ifdef __MULTI_CLOSURE__
- float light_o = 0.0f;
-#else
- float light_o = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT_F);
-#endif
- float light_u, light_v;
- path_state_rng_2D(kg, rng, &state, PRNG_LIGHT_U, &light_u, &light_v);
-
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd.time;
-#endif
-
- /* sample random light */
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp);
- }
- }
- }
+ bool all = kernel_data.integrator.sample_all_lights_indirect;
+ kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all);
}
#endif
@@ -406,10 +458,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
}
}
-#endif
-
-#ifdef __SUBSURFACE__
-
ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rng,
ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
{
@@ -418,11 +466,6 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
/* sample illumination from lights to find path contribution */
if(sd->flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
-#ifdef __MULTI_CLOSURE__
- float light_o = 0.0f;
-#else
- float light_o = path_state_rng_1D(kg, rng, state, PRNG_LIGHT_F);
-#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
@@ -434,7 +477,7 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
light_ray.time = sd->time;
#endif
- if(direct_emission(kg, sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
+ if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@@ -524,6 +567,84 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
}
}
+ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput)
+{
+ /* todo: solve correlation */
+ float bsdf_u, bsdf_v;
+
+ path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+
+ float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
+ float3 ao_D;
+ float ao_pdf;
+ float3 ao_alpha = shader_bsdf_alpha(kg, sd);
+
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+
+ if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+ Ray light_ray;
+ float3 ao_shadow;
+
+ light_ray.P = ray_offset(sd->P, sd->Ng);
+ light_ray.D = ao_D;
+ light_ray.t = kernel_data.background.ao_distance;
+#ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+#endif
+ light_ray.dP = sd->dP;
+ light_ray.dD = differential3_zero();
+
+ if(!shadow_blocked(kg, state, &light_ray, &ao_shadow))
+ path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce);
+ }
+}
+
+#ifdef __SUBSURFACE__
+ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, Ray *ray, float3 *throughput)
+{
+ float bssrdf_probability;
+ ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability);
+
+ /* modify throughput for picking bssrdf or bsdf */
+ *throughput *= bssrdf_probability;
+
+ /* do bssrdf scatter step if we picked a bssrdf closure */
+ if(sc) {
+ uint lcg_state = lcg_state_init(rng, state, 0x68bc21eb);
+
+ ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
+ 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);
+
+ /* compute lighting with the BSDF closure */
+ for(int hit = 0; hit < num_hits; hit++) {
+ float3 tp = *throughput;
+ PathState hit_state = *state;
+ Ray hit_ray = *ray;
+
+ hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
+ hit_state.rng_offset += PRNG_BOUNCE_NUM;
+
+ if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, L, &hit_ray)) {
+#ifdef __LAMP_MIS__
+ hit_state.ray_t = 0.0f;
+#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
+ * for the next samples */
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
+ }
+ }
+ return true;
+ }
+ return false;
+}
#endif
ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer)
@@ -578,17 +699,16 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
light_ray.dP = ray.dP;
/* intersect with lamp */
- float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
float3 emission;
- if(indirect_lamp_emission(kg, &light_ray, state.flag, state.ray_pdf, light_t, &emission, state.bounce))
+ if(indirect_lamp_emission(kg, &state, &light_ray, &emission))
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
#ifdef __VOLUME__
/* volume attenuation, emission, scatter */
- if(state.volume_stack[0].shader != SHADER_NO_ID) {
+ if(state.volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = ray;
volume_ray.t = (hit)? isect.t: FLT_MAX;
@@ -618,7 +738,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __BACKGROUND__
/* sample background shader */
- float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+ float3 L_background = indirect_background(kg, &state, &ray);
path_radiance_accum_background(&L, throughput, L_background, state.bounce);
#endif
@@ -627,7 +747,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
/* setup shading */
ShaderData sd;
- shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+ shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
float rbsdf = path_state_rng_1D(kg, rng, &state, PRNG_BSDF);
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
@@ -694,35 +814,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
- /* todo: solve correlation */
- float bsdf_u, bsdf_v;
- path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
-
- float ao_factor = kernel_data.background.ao_factor;
- float3 ao_N;
- float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
- float3 ao_D;
- float ao_pdf;
- float3 ao_alpha = shader_bsdf_alpha(kg, &sd);
-
- sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
-
- if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
- Ray light_ray;
- float3 ao_shadow;
-
- light_ray.P = ray_offset(sd.P, sd.Ng);
- light_ray.D = ao_D;
- light_ray.t = kernel_data.background.ao_distance;
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd.time;
-#endif
- light_ray.dP = sd.dP;
- light_ray.dD = differential3_zero();
-
- if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
- path_radiance_accum_ao(&L, throughput, ao_alpha, ao_bsdf, ao_shadow, state.bounce);
- }
+ kernel_path_ao(kg, &sd, &L, &state, rng, throughput);
}
#endif
@@ -730,60 +822,18 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
/* bssrdf scatter to a different location on the same object, replacing
* the closures with a diffuse BSDF */
if(sd.flag & SD_BSSRDF) {
- float bssrdf_probability;
- ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability);
-
- /* modify throughput for picking bssrdf or bsdf */
- throughput *= bssrdf_probability;
-
- /* do bssrdf scatter step if we picked a bssrdf closure */
- if(sc) {
- uint lcg_state = lcg_state_init(rng, &state, 0x68bc21eb);
-
- ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
- 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);
-
- /* compute lighting with the BSDF closure */
- for(int hit = 0; hit < num_hits; hit++) {
- float3 tp = throughput;
- PathState hit_state = state;
- Ray hit_ray = ray;
-
- hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
- hit_state.rng_offset += PRNG_BOUNCE_NUM;
-
- if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, &L, &hit_ray)) {
-#ifdef __LAMP_MIS__
- hit_state.ray_t = 0.0f;
-#endif
-
- kernel_path_indirect(kg, rng, hit_ray, buffer, tp, state.num_samples, hit_state, &L);
-
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(&L);
- path_radiance_reset_indirect(&L);
- }
- }
+ if(kernel_path_subsurface_scatter(kg, &sd, &L, &state, rng, &ray, &throughput))
break;
- }
}
#endif
- /* The following code is the same as in kernel_path_integrate_lighting(),
+ /* Same as kernel_path_integrate_lighting(kg, rng, &sd, &throughput, &state, &L, &ray),
but for CUDA the function call is slower. */
#ifdef __EMISSION__
if(kernel_data.integrator.use_direct_light) {
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
-#ifdef __MULTI_CLOSURE__
- float light_o = 0.0f;
-#else
- float light_o = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT_F);
-#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, &state, PRNG_LIGHT_U, &light_u, &light_v);
@@ -795,7 +845,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
light_ray.time = sd.time;
#endif
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) {
+ if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce, state.transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@@ -898,69 +948,9 @@ ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *
PathState *state, PathRadiance *L, ccl_global float *buffer)
{
#ifdef __EMISSION__
- /* sample illumination from lights to find path contribution */
- if(sd->flag & SD_BSDF_HAS_EVAL) {
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
-
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd->time;
-#endif
-
- /* lamp sampling */
- for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
- int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
- float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
- RNG lamp_rng = cmj_hash(*rng, i);
-
- if(kernel_data.integrator.pdf_triangles != 0.0f)
- num_samples_inv *= 0.5f;
-
- for(int j = 0; j < num_samples; j++) {
- float light_u, light_v;
- path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
- }
- }
- }
- }
-
- /* mesh light sampling */
- if(kernel_data.integrator.pdf_triangles != 0.0f) {
- int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
- float num_samples_inv = num_samples_adjust/num_samples;
-
- if(kernel_data.integrator.num_all_lights)
- num_samples_inv *= 0.5f;
-
- for(int j = 0; j < num_samples; j++) {
- float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT);
- float light_u, light_v;
- path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
-
- /* only sample triangle lights */
- if(kernel_data.integrator.num_all_lights)
- light_t = 0.5f*light_t;
-
- if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) {
- /* trace shadow ray */
- float3 shadow;
-
- if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
- }
- }
- }
- }
+ if(kernel_data.integrator.use_direct_light) {
+ bool all = kernel_data.integrator.sample_all_lights_direct;
+ kernel_branched_path_integrate_direct_lighting(kg, rng, sd, state, throughput, num_samples_adjust, L, all);
}
#endif
@@ -1043,7 +1033,7 @@ ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *
ps.ray_t = 0.0f;
#endif
- kernel_path_indirect(kg, rng, bsdf_ray, buffer, tp*num_samples_inv, num_samples, ps, L);
+ kernel_path_indirect(kg, rng, bsdf_ray, tp*num_samples_inv, num_samples, ps, L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@@ -1092,13 +1082,66 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
#ifdef __VOLUME__
/* volume attenuation, emission, scatter */
- if(state.volume_stack[0].shader != SHADER_NO_ID) {
+ if(state.volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = ray;
volume_ray.t = (hit)? isect.t: FLT_MAX;
+#ifdef __KERNEL_CPU__
+ /* decoupled ray marching only supported on CPU */
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state.volume_stack);
+
+ /* cache steps along volume for repeated sampling */
+ VolumeSegment volume_segment;
+ ShaderData volume_sd;
+
+ shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce, state.transparent_bounce);
+ kernel_volume_decoupled_record(kg, &state,
+ &volume_ray, &volume_sd, &volume_segment, heterogeneous);
+
+ /* sample scattering */
+ int num_samples = kernel_data.integrator.volume_samples;
+ float num_samples_inv = 1.0f/num_samples;
+
+ for(int j = 0; j < num_samples; j++) {
+ /* workaround to fix correlation bug in T38710, can find better solution
+ * in random number generator later, for now this is done here to not impact
+ * performance of rendering without volumes */
+ RNG tmp_rng = cmj_hash(*rng, state.rng_offset);
+
+ PathState ps = state;
+ Ray pray = ray;
+ float3 tp = throughput;
+
+ /* branch RNG state */
+ path_state_branch(&ps, j, num_samples);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
+ &ps, &volume_ray, &volume_sd, &tp, &tmp_rng, &volume_segment);
+
+ if(result == VOLUME_PATH_SCATTERED) {
+ /* todo: use all-light sampling */
+ if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) {
+ kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(&L);
+ path_radiance_reset_indirect(&L);
+ }
+ }
+ }
+
+ /* emission and transmittance */
+ if(volume_segment.closure_flag & SD_EMISSION)
+ path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state.bounce);
+ throughput *= volume_segment.accum_transmittance;
+
+ /* free cached steps */
+ kernel_volume_decoupled_free(kg, &volume_segment);
+#else
+ /* GPU: no decoupled ray marching, scatter probalistically */
int num_samples = kernel_data.integrator.volume_samples;
float num_samples_inv = 1.0f/num_samples;
- float3 avg_tp = make_float3(0.0f, 0.0f, 0.0f);
/* todo: we should cache the shader evaluations from stepping
* through the volume, for now we redo them multiple times */
@@ -1118,7 +1161,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
if(result == VOLUME_PATH_SCATTERED) {
/* todo: use all-light sampling */
if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) {
- kernel_path_indirect(kg, rng, pray, buffer, tp*num_samples_inv, num_samples, ps, &L);
+ kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@@ -1126,11 +1169,11 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
path_radiance_reset_indirect(&L);
}
}
- else
- avg_tp += tp;
}
- throughput = avg_tp * num_samples_inv;
+ /* todo: avoid this calculation using decoupled ray marching */
+ kernel_volume_shadow(kg, &state, &volume_ray, &throughput);
+#endif
}
#endif
@@ -1147,7 +1190,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
#ifdef __BACKGROUND__
/* sample background shader */
- float3 L_background = indirect_background(kg, &ray, state.flag, state.ray_pdf, state.bounce);
+ float3 L_background = indirect_background(kg, &state, &ray);
path_radiance_accum_background(&L, throughput, L_background, state.bounce);
#endif
@@ -1156,7 +1199,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
/* setup shading */
ShaderData sd;
- shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce);
+ shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce);
shader_eval_surface(kg, &sd, 0.0f, state.flag, SHADER_CONTEXT_MAIN);
shader_merge_closures(&sd);
@@ -1270,21 +1313,21 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
/* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */
for(int j = 0; j < num_samples; j++) {
- ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
- 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);
+ ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
+ 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);
- /* compute lighting with the BSDF closure */
- for(int hit = 0; hit < num_hits; hit++) {
- PathState hit_state = state;
+ /* compute lighting with the BSDF closure */
+ for(int hit = 0; hit < num_hits; hit++) {
+ PathState hit_state = state;
- path_state_branch(&hit_state, j, num_samples);
+ path_state_branch(&hit_state, j, num_samples);
- kernel_branched_path_integrate_lighting(kg, rng,
- &bssrdf_sd[hit], throughput, num_samples_inv,
- &hit_state, &L, buffer);
- }
+ kernel_branched_path_integrate_lighting(kg, rng,
+ &bssrdf_sd[hit], throughput, num_samples_inv,
+ &hit_state, &L, buffer);
+ }
}
state.flag &= ~PATH_RAY_BSSRDF_ANCESTOR;
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index c3f617542a6..406654c1741 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -50,7 +50,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, PathState *state, RNG
state->rng_congruential = lcg_init(*rng + sample*0x51633e2d);
}
else {
- state->volume_stack[0].shader = SHADER_NO_ID;
+ state->volume_stack[0].shader = SHADER_NONE;
}
#endif
}
@@ -132,6 +132,9 @@ ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *s
/* for visibility, diffuse/glossy are for reflection only */
if(flag & PATH_RAY_TRANSMIT)
flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
+ /* todo: this is not supported as its own ray visibility yet */
+ if(state->flag & PATH_RAY_VOLUME_SCATTER)
+ flag |= PATH_RAY_DIFFUSE;
/* for camera visibility, use render layer flags */
if(flag & PATH_RAY_CAMERA)
flag |= kernel_data.integrator.layer_flag;
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index e2108604bc8..6744471d659 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -39,7 +39,7 @@ CCL_NAMESPACE_BEGIN
ccl_device float2 direction_to_spherical(float3 dir)
{
- float theta = acosf(dir.z);
+ float theta = safe_acosf(dir.z);
float phi = atan2f(dir.x, dir.y);
return make_float2(theta, phi);
@@ -97,7 +97,7 @@ ccl_device float3 fisheye_to_direction(float u, float v, float fov)
if(r > 1.0f)
return make_float3(0.0f, 0.0f, 0.0f);
- float phi = acosf((r != 0.0f)? u/r: 0.0f);
+ float phi = safe_acosf((r != 0.0f)? u/r: 0.0f);
float theta = r * fov * 0.5f;
if(v < 0.0f) phi = -phi;
@@ -111,7 +111,7 @@ ccl_device float3 fisheye_to_direction(float u, float v, float fov)
ccl_device float2 direction_to_fisheye_equisolid(float3 dir, float lens, float width, float height)
{
- float theta = acosf(dir.x);
+ float theta = safe_acosf(dir.x);
float r = 2.0f * lens * sinf(theta * 0.5f);
float phi = atan2f(dir.z, dir.y);
@@ -132,7 +132,7 @@ ccl_device float3 fisheye_equisolid_to_direction(float u, float v, float lens, f
if(r > rmax)
return make_float3(0.0f, 0.0f, 0.0f);
- float phi = acosf((r != 0.0f)? u/r: 0.0f);
+ float phi = safe_acosf((r != 0.0f)? u/r: 0.0f);
float theta = 2.0f * asinf(r/(2.0f * lens));
if(v < 0.0f) phi = -phi;
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index ef397269ec2..31cb6ff6abd 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -120,6 +120,9 @@ ccl_device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int
/* Cranly-Patterson rotation using rng seed */
float shift;
+ /* using the same *rng value to offset seems to give correlation issues,
+ * we could hash it with the dimension but this has a performance impact,
+ * we need to find a solution for this */
if(dimension & 1)
shift = (*rng >> 16) * (1.0f/(float)0xFFFF);
else
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index b113e906e9d..58cec090410 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -39,7 +39,7 @@ ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd
{
if(sd->flag & SD_OBJECT_MOTION) {
sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
- sd->ob_itfm= transform_quick_inverse(sd->ob_tfm);
+ sd->ob_itfm = transform_quick_inverse(sd->ob_tfm);
}
else {
sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
@@ -49,12 +49,13 @@ ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd
#endif
ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
- const Intersection *isect, const Ray *ray, int bounce)
+ const Intersection *isect, const Ray *ray, int bounce, int transparent_bounce)
{
#ifdef __INSTANCING__
- sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
+ sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
#endif
+ sd->type = isect->type;
sd->flag = kernel_tex_fetch(__object_flag, sd->object);
/* matrices and time */
@@ -66,37 +67,31 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
sd->ray_length = isect->t;
sd->ray_depth = bounce;
+ sd->transparent_depth = transparent_bounce;
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = isect->v;
+#endif
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
- /* Strand Shader setting*/
+ if(sd->type & PRIMITIVE_ALL_CURVE) {
+ /* curve */
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
sd->shader = __float_as_int(curvedata.z);
- sd->segment = isect->segment;
sd->P = bvh_curve_refine(kg, sd, isect, ray);
}
- else {
+ else
#endif
- /* fetch triangle data */
+ if(sd->type & PRIMITIVE_TRIANGLE) {
+ /* static triangle */
float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
sd->shader = __float_as_int(Ns.w);
-#ifdef __HAIR__
- sd->segment = ~0;
- /*elements for minimum hair width using transparency bsdf*/
- /*sd->curve_transparency = 0.0f;*/
- /*sd->curve_radius = 0.0f;*/
-#endif
-
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
-#endif
-
/* vectors */
- sd->P = bvh_triangle_refine(kg, sd, isect, ray);
+ sd->P = triangle_refine(kg, sd, isect, ray);
sd->Ng = Ng;
sd->N = Ng;
@@ -106,19 +101,20 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#ifdef __DPDU__
/* dPdu/dPdv */
- triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
#endif
-
-#ifdef __HAIR__
}
-#endif
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, false);
+ }
sd->I = -ray->D;
sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
#ifdef __INSTANCING__
- if(isect->object != ~0) {
+ if(isect->object != OBJECT_NONE) {
/* instance transform */
object_normal_transform(kg, sd, &sd->N);
object_normal_transform(kg, sd, &sd->Ng);
@@ -161,39 +157,41 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
/* object, matrices, time, ray_length stay the same */
sd->flag = kernel_tex_fetch(__object_flag, sd->object);
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
-
- /* fetch triangle data */
- float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
- float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
- sd->shader = __float_as_int(Ns.w);
-
-#ifdef __HAIR__
- sd->segment = ~0;
-#endif
+ sd->type = isect->type;
#ifdef __UV__
sd->u = isect->u;
sd->v = isect->v;
#endif
- /* vectors */
- sd->P = bvh_triangle_refine_subsurface(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
-
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+ /* fetch triangle data */
+ if(sd->type == PRIMITIVE_TRIANGLE) {
+ float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
+ float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
+ sd->shader = __float_as_int(Ns.w);
+
+ /* static triangle */
+ sd->P = triangle_refine_subsurface(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
+
+ if(sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
#endif
+ }
+ else {
+ /* motion triangle */
+ motion_triangle_shader_setup(kg, sd, isect, ray, true);
+ }
sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
#ifdef __INSTANCING__
- if(isect->object != ~0) {
+ if(isect->object != OBJECT_NONE) {
/* instance transform */
object_normal_transform(kg, sd, &sd->N);
object_normal_transform(kg, sd, &sd->Ng);
@@ -231,7 +229,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
- int shader, int object, int prim, float u, float v, float t, float time, int bounce, int segment)
+ int shader, int object, int prim, float u, float v, float t, float time, int bounce, int transparent_bounce)
{
/* vectors */
sd->P = P;
@@ -239,9 +237,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
sd->Ng = Ng;
sd->I = I;
sd->shader = shader;
-#ifdef __HAIR__
- sd->segment = segment;
-#endif
+ sd->type = (prim == PRIM_NONE)? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE;
/* primitive */
#ifdef __INSTANCING__
@@ -255,12 +251,13 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
sd->ray_length = t;
sd->ray_depth = bounce;
+ sd->transparent_depth = transparent_bounce;
/* detect instancing, for non-instanced the object index is -object-1 */
#ifdef __INSTANCING__
bool instanced = false;
- if(sd->prim != ~0) {
+ if(sd->prim != PRIM_NONE) {
if(sd->object >= 0)
instanced = true;
else
@@ -271,7 +268,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
- if(sd->object != -1) {
+ if(sd->object != OBJECT_NONE) {
sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
#ifdef __OBJECT_MOTION__
@@ -283,36 +280,20 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
}
#endif
- /* smooth normal */
-#ifdef __HAIR__
- if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
- sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
-#else
- if(sd->shader & SHADER_SMOOTH_NORMAL) {
- sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
-#endif
+ if(sd->type & PRIMITIVE_TRIANGLE) {
+ /* smooth normal */
+ if(sd->shader & SHADER_SMOOTH_NORMAL) {
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#ifdef __INSTANCING__
- if(instanced)
- object_normal_transform(kg, sd, &sd->N);
+ if(instanced)
+ object_normal_transform(kg, sd, &sd->N);
#endif
- }
+ }
+ /* dPdu/dPdv */
#ifdef __DPDU__
- /* dPdu/dPdv */
-#ifdef __HAIR__
- if(sd->prim == ~0 || sd->segment != ~0) {
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
- }
-#else
- if(sd->prim == ~0) {
- sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
- sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
- }
-#endif
- else {
- triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
#ifdef __INSTANCING__
if(instanced) {
@@ -320,11 +301,17 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
object_dir_transform(kg, sd, &sd->dPdv);
}
#endif
+#endif
}
+ else {
+#ifdef __DPDU__
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
#endif
+ }
/* backfacing test */
- if(sd->prim != ~0) {
+ if(sd->prim != PRIM_NONE) {
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
if(backfacing) {
@@ -355,20 +342,19 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
int shader;
- P = triangle_point_MT(kg, prim, u, v);
- Ng = triangle_normal_MT(kg, prim, &shader);
+ triangle_point_normal(kg, prim, u, v, &P, &Ng, &shader);
/* force smooth shading for displacement */
shader |= SHADER_SMOOTH_NORMAL;
/* watch out: no instance transform currently */
- shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, ~0);
+ shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, 0);
}
/* ShaderData setup from ray into background */
-ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
+ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
{
/* vectors */
sd->P = ray->D;
@@ -382,11 +368,12 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
#endif
sd->ray_length = 0.0f;
sd->ray_depth = bounce;
+ sd->transparent_depth = transparent_bounce;
#ifdef __INSTANCING__
- sd->object = ~0;
+ sd->object = PRIM_NONE;
#endif
- sd->prim = ~0;
+ sd->prim = PRIM_NONE;
#ifdef __UV__
sd->u = 0.0f;
sd->v = 0.0f;
@@ -411,28 +398,27 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
/* ShaderData setup from point inside volume */
-ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce)
+ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce)
{
/* vectors */
sd->P = ray->P;
sd->N = -ray->D;
sd->Ng = -ray->D;
sd->I = -ray->D;
- sd->shader = SHADER_NO_ID;
+ sd->shader = SHADER_NONE;
sd->flag = 0;
#ifdef __OBJECT_MOTION__
sd->time = ray->time;
#endif
sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
sd->ray_depth = bounce;
+ sd->transparent_depth = transparent_bounce;
#ifdef __INSTANCING__
- sd->object = ~0; /* todo: fill this for texture coordinates */
-#endif
- sd->prim = ~0;
-#ifdef __HAIR__
- sd->segment = ~0;
+ sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
#endif
+ sd->prim = PRIM_NONE;
+ sd->type = PRIMITIVE_NONE;
#ifdef __UV__
sd->u = 0.0f;
@@ -471,23 +457,32 @@ ccl_device void shader_merge_closures(ShaderData *sd)
ShaderClosure *scj = &sd->closure[j];
#ifdef __OSL__
- if(!sci->prim && !scj->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
-#else
- if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+ if(sci->prim || scj->prim)
+ continue;
#endif
- sci->weight += scj->weight;
- sci->sample_weight += scj->sample_weight;
-
- int size = sd->num_closure - (j+1);
- if(size > 0) {
- for(int k = 0; k < size; k++) {
- scj[k] = scj[k+1];
- }
- }
- sd->num_closure--;
- j--;
+ if(!(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1))
+ continue;
+
+ if(CLOSURE_IS_BSDF_OR_BSSRDF(sci->type)) {
+ if(sci->N != scj->N)
+ continue;
+ else if(CLOSURE_IS_BSDF_ANISOTROPIC(sci->type) && sci->T != scj->T)
+ continue;
}
+
+ sci->weight += scj->weight;
+ sci->sample_weight += scj->sample_weight;
+
+ int size = sd->num_closure - (j+1);
+ if(size > 0) {
+ for(int k = 0; k < size; k++) {
+ scj[k] = scj[k+1];
+ }
+ }
+
+ sd->num_closure--;
+ j--;
}
}
}
@@ -495,8 +490,6 @@ ccl_device void shader_merge_closures(ShaderData *sd)
/* BSDF */
-#ifdef __MULTI_CLOSURE__
-
ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
{
@@ -524,28 +517,18 @@ ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderDa
*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
}
-#endif
-
ccl_device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
const float3 omega_in, BsdfEval *eval, float *pdf)
{
-#ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
_shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
-#else
- const ShaderClosure *sc = &sd->closure;
-
- *pdf = 0.0f;
- *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
-#endif
}
ccl_device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
float randu, float randv, BsdfEval *bsdf_eval,
float3 *omega_in, differential3 *domega_in, float *pdf)
{
-#ifdef __MULTI_CLOSURE__
int sampled = 0;
if(sd->num_closure > 1) {
@@ -596,13 +579,6 @@ ccl_device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
}
return label;
-#else
- /* sample the single closure that we picked */
- *pdf = 0.0f;
- int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
- *bsdf_eval *= sd->closure.weight;
- return label;
-#endif
}
ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
@@ -623,21 +599,16 @@ ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *s
ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
-#ifdef __MULTI_CLOSURE__
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type))
bsdf_blur(kg, sc, roughness);
}
-#else
- bsdf_blur(kg, &sd->closure, roughness);
-#endif
}
ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -648,12 +619,6 @@ ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
}
return eval;
-#else
- if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
@@ -668,7 +633,6 @@ ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -679,17 +643,10 @@ ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
}
return eval;
-#else
- if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -700,17 +657,10 @@ ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
}
return eval;
-#else
- if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -721,17 +671,10 @@ ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
}
return eval;
-#else
- if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -742,17 +685,10 @@ ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
}
return eval;
-#else
- if(CLOSURE_IS_BSSRDF(sd->closure.type))
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
float3 N = make_float3(0.0f, 0.0f, 0.0f);
@@ -776,21 +712,10 @@ ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_fac
*N_ = N;
return eval;
-#else
- *N_ = sd->N;
-
- if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
- return sd->closure.weight*ao_factor;
- else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_blur_)
{
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
float3 N = make_float3(0.0f, 0.0f, 0.0f);
float texture_blur = 0.0f, weight_sum = 0.0f;
@@ -815,20 +740,6 @@ ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_b
*texture_blur_ = texture_blur/weight_sum;
return eval;
-#else
- if(CLOSURE_IS_BSSRDF(sd->closure.type)) {
- if(N_) *N_ = sd->closure.N;
- if(texture_blur_) *texture_blur_ = sd->closure.data1;
-
- return sd->closure.weight;
- }
- else {
- if(N_) *N_ = sd->N;
- if(texture_blur_) *texture_blur_ = 0.0f;
-
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-#endif
}
/* Emission */
@@ -841,7 +752,6 @@ ccl_device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure
ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{
float3 eval;
-#ifdef __MULTI_CLOSURE__
eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
@@ -850,9 +760,6 @@ ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
if(CLOSURE_IS_EMISSION(sc->type))
eval += emissive_eval(kg, sd, sc)*sc->weight;
}
-#else
- eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
-#endif
return eval;
}
@@ -861,7 +768,6 @@ ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MULTI_CLOSURE__
float3 weight = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
@@ -872,12 +778,6 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
}
return weight;
-#else
- if(sd->closure.type == CLOSURE_HOLDOUT_ID)
- return make_float3(1.0f, 1.0f, 1.0f);
-
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
}
/* Surface Evaluation */
@@ -885,12 +785,8 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
float randb, int path_flag, ShaderContext ctx)
{
-#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = randb;
-#else
- sd->closure.type = NBUILTIN_CLOSURES;
-#endif
#ifdef __OSL__
if(kg->osl)
@@ -899,7 +795,7 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
#endif
{
#ifdef __SVM__
- svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
+ 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;
@@ -912,12 +808,8 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
-#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = 0.0f;
-#else
- sd->closure.type = NBUILTIN_CLOSURES;
-#endif
#ifdef __OSL__
if(kg->osl) {
@@ -928,9 +820,8 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int
{
#ifdef __SVM__
- svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
+ svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag);
-#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@@ -942,13 +833,6 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int
return eval;
#else
- if(sd->closure.type == CLOSURE_BACKGROUND_ID)
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
-#else
return make_float3(0.8f, 0.8f, 0.8f);
#endif
}
@@ -1067,14 +951,10 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
{
/* reset closures once at the start, we will be accumulating the closures
* for all volumes in the stack into a single array of closures */
-#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
-#else
- sd->closure.type = NBUILTIN_CLOSURES;
-#endif
sd->flag = 0;
- for(int i = 0; stack[i].shader != SHADER_NO_ID; i++) {
+ for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
/* setup shaderdata from stack. it's mostly setup already in
* shader_setup_from_volume, this switching should be quick */
sd->object = stack[i].object;
@@ -1083,7 +963,7 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
sd->flag &= ~(SD_SHADER_FLAGS|SD_OBJECT_FLAGS);
sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
- if(sd->object != ~0) {
+ if(sd->object != OBJECT_NONE) {
sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
#ifdef __OBJECT_MOTION__
@@ -1102,7 +982,7 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
else
#endif
{
- svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, 0.0f, path_flag);
+ svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, path_flag);
}
#endif
@@ -1118,12 +998,8 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
-#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = 0.0f;
-#else
- sd->closure.type = NBUILTIN_CLOSURES;
-#endif
/* this will modify sd->P */
#ifdef __SVM__
@@ -1133,7 +1009,7 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, Shad
else
#endif
{
- svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
+ svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0);
}
#endif
}
@@ -1147,7 +1023,7 @@ ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect
int shader = 0;
#ifdef __HAIR__
- if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
+ if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
#endif
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
shader = __float_as_int(Ns.w);
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index 9b015c98c40..ab7524c411a 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -16,6 +16,178 @@
CCL_NAMESPACE_BEGIN
+#ifdef __SHADOW_RECORD_ALL__
+
+/* Shadow function to compute how much light is blocked, CPU variation.
+ *
+ * We trace a single ray. If it hits any opaque surface, or more than a given
+ * number of transparent surfaces is hit, then we consider the geometry to be
+ * entirely blocked. If not, all transparent surfaces will be recorded and we
+ * will shade them one by one to determine how much light is blocked. This all
+ * happens in one scene intersection function.
+ *
+ * Recording all hits works well in some cases but may be slower in others. If
+ * we have many semi-transparent hairs, one intersection may be faster because
+ * you'd be reinteresecting the same hairs a lot with each step otherwise. If
+ * however there is mostly binary transparency then we may be recording many
+ * unnecessary intersections when one of the first surfaces blocks all light.
+ *
+ * From tests in real scenes it seems the performance loss is either minimal,
+ * or there is a performance increase anyway due to avoiding the need to send
+ * two rays with transparent shadows.
+ *
+ * This is CPU only because of qsort, and malloc or high stack space usage to
+ * record all these intersections. */
+
+ccl_device_noinline int shadow_intersections_compare(const void *a, const void *b)
+{
+ const Intersection *isect_a = (const Intersection*)a;
+ const Intersection *isect_b = (const Intersection*)b;
+
+ if(isect_a->t < isect_b->t)
+ return -1;
+ else if(isect_a->t > isect_b->t)
+ return 1;
+ else
+ return 0;
+}
+
+#define STACK_MAX_HITS 64
+
+ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow)
+{
+ *shadow = make_float3(1.0f, 1.0f, 1.0f);
+
+ if(ray->t == 0.0f)
+ return false;
+
+ bool blocked;
+
+ if(kernel_data.integrator.transparent_shadows) {
+ /* intersect to find an opaque surface, or record all transparent surface hits */
+ Intersection hits_stack[STACK_MAX_HITS];
+ Intersection *hits;
+ uint max_hits = kernel_data.integrator.transparent_max_bounce - state->transparent_bounce - 1;
+
+ /* prefer to use stack but use dynamic allocation if too deep max hits
+ * we need max_hits + 1 storage space due to the logic in
+ * scene_intersect_shadow_all which will first store and then check if
+ * the limit is exceeded */
+ if(max_hits + 1 <= STACK_MAX_HITS)
+ hits = hits_stack;
+ else
+ hits = (Intersection*)malloc(sizeof(Intersection)*(max_hits + 1));
+
+ uint num_hits;
+ blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
+
+ /* if no opaque surface found but we did find transparent hits, shade them */
+ if(!blocked && num_hits > 0) {
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ float3 Pend = ray->P + ray->D*ray->t;
+ float last_t = 0.0f;
+ int bounce = state->transparent_bounce;
+ Intersection *isect = hits;
+#ifdef __VOLUME__
+ PathState ps = *state;
+#endif
+
+ qsort(hits, num_hits, sizeof(Intersection), shadow_intersections_compare);
+
+ for(int hit = 0; hit < num_hits; hit++, isect++) {
+ /* adjust intersection distance for moving ray forward */
+ float new_t = isect->t;
+ isect->t -= last_t;
+
+ /* skip hit if we did not move forward, step by step raytracing
+ * would have skipped it as well then */
+ if(last_t == new_t)
+ continue;
+
+ last_t = new_t;
+
+#ifdef __VOLUME__
+ /* attenuation between last surface and next surface */
+ if(ps.volume_stack[0].shader != SHADER_NONE) {
+ Ray segment_ray = *ray;
+ segment_ray.t = isect->t;
+ kernel_volume_shadow(kg, &ps, &segment_ray, &throughput);
+ }
+#endif
+
+ /* setup shader data at surface */
+ ShaderData sd;
+ shader_setup_from_ray(kg, &sd, isect, ray, state->bounce+1, bounce);
+
+ /* attenuation from transparent surface */
+ if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
+ shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
+ throughput *= shader_bsdf_transparency(kg, &sd);
+ }
+
+ /* stop if all light is blocked */
+ if(is_zero(throughput)) {
+ /* free dynamic storage */
+ if(hits != hits_stack)
+ free(hits);
+ return true;
+ }
+
+ /* move ray forward */
+ ray->P = sd.P;
+ if(ray->t != FLT_MAX)
+ ray->D = normalize_len(Pend - ray->P, &ray->t);
+
+#ifdef __VOLUME__
+ /* exit/enter volume */
+ kernel_volume_stack_enter_exit(kg, &sd, ps.volume_stack);
+#endif
+
+ bounce++;
+ }
+
+#ifdef __VOLUME__
+ /* attenuation for last line segment towards light */
+ if(ps.volume_stack[0].shader != SHADER_NONE)
+ kernel_volume_shadow(kg, &ps, ray, &throughput);
+#endif
+
+ *shadow *= throughput;
+ }
+
+ /* free dynamic storage */
+ if(hits != hits_stack)
+ free(hits);
+ }
+ 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__
+ if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
+ /* apply attenuation from current volume shader */
+ kernel_volume_shadow(kg, state, ray, shadow);
+ }
+#endif
+
+ return blocked;
+}
+
+#else
+
+/* Shadow function to compute how much light is blocked, GPU variation.
+ *
+ * Here we raytrace from one transparent surface to the next step by step.
+ * To minimize overhead in cases where we don't need transparent shadows, we
+ * first trace a regular shadow ray. We check if the hit primitive was
+ * potentially transparent, and only in that case start marching. this gives
+ * one extra ray cast for the cases were we do want transparency. */
+
ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow)
{
*shadow = make_float3(1.0f, 1.0f, 1.0f);
@@ -25,21 +197,13 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
Intersection isect;
#ifdef __HAIR__
- bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
+ bool blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
#else
- bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
+ bool blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
#endif
#ifdef __TRANSPARENT_SHADOWS__
- if(result && kernel_data.integrator.transparent_shadows) {
- /* transparent shadows work in such a way to try to minimize overhead
- * in cases where we don't need them. after a regular shadow ray is
- * cast we check if the hit primitive was potentially transparent, and
- * only in that case start marching. this gives on extra ray cast for
- * the cases were we do want transparency.
- *
- * also note that for this to work correct, multi close sampling must
- * be used, since we don't pass a random number to shader_eval_surface */
+ if(blocked && kernel_data.integrator.transparent_shadows) {
if(shader_transparent_shadow(kg, &isect)) {
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
float3 Pend = ray->P + ray->D*ray->t;
@@ -49,35 +213,24 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
#endif
for(;;) {
- if(bounce >= kernel_data.integrator.transparent_max_bounce) {
+ if(bounce >= kernel_data.integrator.transparent_max_bounce)
return true;
- }
- else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
- /* todo: get random number somewhere for probabilistic terminate */
-#if 0
- float probability = average(throughput);
- float terminate = 0.0f;
-
- if(terminate >= probability)
- return true;
-
- throughput /= probability;
-#endif
- }
#ifdef __HAIR__
- if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect, NULL, 0.0f, 0.0f)) {
+ 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)) {
+ if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect))
#endif
+ {
#ifdef __VOLUME__
/* attenuation for last line segment towards light */
- if(ps.volume_stack[0].shader != SHADER_NO_ID)
+ if(ps.volume_stack[0].shader != SHADER_NONE)
kernel_volume_shadow(kg, &ps, ray, &throughput);
#endif
*shadow *= throughput;
+
return false;
}
@@ -86,7 +239,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
#ifdef __VOLUME__
/* attenuation between last surface and next surface */
- if(ps.volume_stack[0].shader != SHADER_NO_ID) {
+ if(ps.volume_stack[0].shader != SHADER_NONE) {
Ray segment_ray = *ray;
segment_ray.t = isect.t;
kernel_volume_shadow(kg, &ps, &segment_ray, &throughput);
@@ -95,7 +248,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
/* setup shader data at surface */
ShaderData sd;
- shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1);
+ shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1, bounce);
/* attenuation from transparent surface */
if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
@@ -103,6 +256,9 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
throughput *= shader_bsdf_transparency(kg, &sd);
}
+ if(is_zero(throughput))
+ return true;
+
/* move ray forward */
ray->P = ray_offset(sd.P, -sd.Ng);
if(ray->t != FLT_MAX)
@@ -118,15 +274,17 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
}
}
#ifdef __VOLUME__
- else if(!result && state->volume_stack[0].shader != SHADER_NO_ID) {
+ else if(!blocked && state->volume_stack[0].shader != SHADER_NONE) {
/* apply attenuation from current volume shader */
kernel_volume_shadow(kg, state, ray, shadow);
}
#endif
#endif
- return result;
+ return blocked;
}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_sse2.cpp b/intern/cycles/kernel/kernel_sse2.cpp
index 6a2a7804146..2d5f6091908 100644
--- a/intern/cycles/kernel/kernel_sse2.cpp
+++ b/intern/cycles/kernel/kernel_sse2.cpp
@@ -75,6 +75,6 @@ CCL_NAMESPACE_END
/* needed for some linkers in combination with scons making empty compilation unit in a library */
void __dummy_function_cycles_sse2(void);
-void __dummy_function_cycles_sse2(void){}
+void __dummy_function_cycles_sse2(void) {}
#endif
diff --git a/intern/cycles/kernel/kernel_sse3.cpp b/intern/cycles/kernel/kernel_sse3.cpp
index 9d0abb93cc6..1062fd0c990 100644
--- a/intern/cycles/kernel/kernel_sse3.cpp
+++ b/intern/cycles/kernel/kernel_sse3.cpp
@@ -76,6 +76,6 @@ CCL_NAMESPACE_END
/* needed for some linkers in combination with scons making empty compilation unit in a library */
void __dummy_function_cycles_sse3(void);
-void __dummy_function_cycles_sse3(void){}
+void __dummy_function_cycles_sse3(void) {}
#endif
diff --git a/intern/cycles/kernel/kernel_sse41.cpp b/intern/cycles/kernel/kernel_sse41.cpp
index bc20de0ec20..ba3b4887650 100644
--- a/intern/cycles/kernel/kernel_sse41.cpp
+++ b/intern/cycles/kernel/kernel_sse41.cpp
@@ -77,6 +77,6 @@ CCL_NAMESPACE_END
/* needed for some linkers in combination with scons making empty compilation unit in a library */
void __dummy_function_cycles_sse41(void);
-void __dummy_function_cycles_sse41(void){}
+void __dummy_function_cycles_sse41(void) {}
#endif
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index f06fa119cfc..b07075c6c95 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -25,7 +25,7 @@
/* bvh */
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
KERNEL_TEX(float4, texture_float4, __tri_woop)
-KERNEL_TEX(uint, texture_uint, __prim_segment)
+KERNEL_TEX(uint, texture_uint, __prim_type)
KERNEL_TEX(uint, texture_uint, __prim_visibility)
KERNEL_TEX(uint, texture_uint, __prim_index)
KERNEL_TEX(uint, texture_uint, __prim_object)
@@ -174,6 +174,61 @@ KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_097)
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_098)
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_099)
+/* Kepler and above */
+#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 300)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_100)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_101)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_102)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_103)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_104)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_105)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_106)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_107)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_108)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_109)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_110)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_111)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_112)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_113)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_114)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_115)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_116)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_117)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_118)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_119)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_120)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_121)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_122)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_123)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_124)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_125)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_126)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_127)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_128)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_129)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_130)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_131)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_132)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_133)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_134)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_135)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_136)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_137)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_138)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_139)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_140)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_141)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_142)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_143)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_144)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_145)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_146)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_147)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_148)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_149)
+KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_150)
+#endif
+
/* packed image (opencl) */
KERNEL_TEX(uchar4, texture_uchar4, __tex_image_packed)
KERNEL_TEX(uint4, texture_uint4, __tex_image_packed_info)
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
deleted file mode 100644
index 0455df85961..00000000000
--- a/intern/cycles/kernel/kernel_triangle.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2011-2013 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
-
-/* Point on triangle for Moller-Trumbore triangles */
-ccl_device_inline float3 triangle_point_MT(KernelGlobals *kg, int tri_index, float u, float v)
-{
- /* load triangle vertices */
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
-
- float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
- float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
- float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
-
- /* compute point */
- float t = 1.0f - u - v;
- return (u*v0 + v*v1 + t*v2);
-}
-
-/* Normal for Moller-Trumbore triangles */
-ccl_device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int *shader)
-{
-#if 0
- /* load triangle vertices */
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
-
- float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
- float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
- float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
-
- /* compute normal */
- return normalize(cross(v2 - v0, v1 - v0));
-#else
- float4 Nm = kernel_tex_fetch(__tri_normal, tri_index);
- *shader = __float_as_int(Nm.w);
- return make_float3(Nm.x, Nm.y, Nm.z);
-#endif
-}
-
-/* Return 3 triangle vertex locations */
-ccl_device_inline void triangle_vertices(KernelGlobals *kg, int tri_index, float3 P[3])
-{
- /* load triangle vertices */
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
-
- P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
- P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
- P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
-}
-
-ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int tri_index, float u, float v)
-{
- /* load triangle vertices */
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
-
- float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)));
- float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)));
- float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
-
- return normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
-}
-
-ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, float3 *dPdu, float3 *dPdv, int tri)
-{
- /* fetch triangle vertex coordinates */
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri));
-
- float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
- float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
- float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
-
- /* compute derivatives of P w.r.t. uv */
- *dPdu = (p0 - p2);
- *dPdv = (p1 - p2);
-}
-
-/* attributes */
-
-ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
-{
- if(elem == ATTR_ELEMENT_FACE) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return kernel_tex_fetch(__attributes_float, offset + sd->prim);
- }
- else if(elem == ATTR_ELEMENT_VERTEX) {
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
-
- float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x));
- float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y));
- float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z));
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
-#endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(elem == ATTR_ELEMENT_CORNER) {
- int tri = offset + sd->prim*3;
- float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
- float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
- float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
-#endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return 0.0f;
- }
-}
-
-ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
-{
- if(elem == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
- }
- else if(elem == ATTR_ELEMENT_VERTEX) {
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
-#endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(elem == ATTR_ELEMENT_CORNER) {
- int tri = offset + sd->prim*3;
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
-
-#ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
-#endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 5ee25a6cb98..11445aa1c93 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -46,7 +46,10 @@ CCL_NAMESPACE_BEGIN
#define TEX_NUM_FLOAT_IMAGES 5
-#define SHADER_NO_ID -1
+#define SHADER_NONE (~0)
+#define OBJECT_NONE (~0)
+#define PRIM_NONE (~0)
+#define LAMP_NONE (~0)
#define VOLUME_STACK_SIZE 16
@@ -61,13 +64,17 @@ CCL_NAMESPACE_BEGIN
#define __SUBSURFACE__
#define __CMJ__
#define __VOLUME__
+#define __SHADOW_RECORD_ALL__
#endif
#ifdef __KERNEL_CUDA__
#define __KERNEL_SHADING__
#define __KERNEL_ADV_SHADING__
#define __BRANCHED_PATH__
+
+/* Experimental on GPU */
//#define __VOLUME__
+//#define __SUBSURFACE__
#endif
#ifdef __KERNEL_OPENCL__
@@ -85,26 +92,24 @@ CCL_NAMESPACE_BEGIN
#endif
#ifdef __KERNEL_OPENCL_AMD__
-#define __SVM__
-#define __EMISSION__
-#define __IMAGE_TEXTURES__
-#define __PROCEDURAL_TEXTURES__
-#define __EXTRA_NODES__
-#define __HOLDOUT__
-#define __NORMAL_MAP__
-//#define __BACKGROUND_MIS__
-//#define __LAMP_MIS__
-//#define __AO__
-//#define __ANISOTROPIC__
+#define __CL_USE_NATIVE__
+#define __KERNEL_SHADING__
+//__KERNEL_ADV_SHADING__
+#define __MULTI_CLOSURE__
+#define __TRANSPARENT_SHADOWS__
+#define __PASSES__
+#define __BACKGROUND_MIS__
+#define __LAMP_MIS__
+#define __AO__
+#define __ANISOTROPIC__
//#define __CAMERA_MOTION__
//#define __OBJECT_MOTION__
//#define __HAIR__
-//#define __MULTI_CLOSURE__
-//#define __TRANSPARENT_SHADOWS__
-//#define __PASSES__
+//end __KERNEL_ADV_SHADING__
#endif
#ifdef __KERNEL_OPENCL_INTEL_CPU__
+#define __CL_USE_NATIVE__
#define __KERNEL_SHADING__
#define __KERNEL_ADV_SHADING__
#endif
@@ -147,12 +152,6 @@ CCL_NAMESPACE_BEGIN
#define __HAIR__
#endif
-/* Sanity check */
-
-#if defined(__KERNEL_OPENCL_NEED_ADVANCED_SHADING__) && !defined(__MULTI_CLOSURE__)
-#error "OpenCL: mismatch between advanced shading flags in device_opencl.cpp and kernel_types.h"
-#endif
-
/* Random Numbers */
typedef uint RNG;
@@ -161,7 +160,35 @@ typedef uint RNG;
typedef enum ShaderEvalType {
SHADER_EVAL_DISPLACE,
- SHADER_EVAL_BACKGROUND
+ SHADER_EVAL_BACKGROUND,
+ /* bake types */
+ SHADER_EVAL_BAKE, /* no real shade, it's used in the code to
+ * differentiate the type of shader eval from the above
+ */
+ /* data passes */
+ SHADER_EVAL_NORMAL,
+ SHADER_EVAL_UV,
+ SHADER_EVAL_DIFFUSE_COLOR,
+ SHADER_EVAL_GLOSSY_COLOR,
+ SHADER_EVAL_TRANSMISSION_COLOR,
+ SHADER_EVAL_SUBSURFACE_COLOR,
+ SHADER_EVAL_EMISSION,
+
+ /* light passes */
+ SHADER_EVAL_AO,
+ SHADER_EVAL_COMBINED,
+ SHADER_EVAL_SHADOW,
+ SHADER_EVAL_DIFFUSE_DIRECT,
+ SHADER_EVAL_GLOSSY_DIRECT,
+ SHADER_EVAL_TRANSMISSION_DIRECT,
+ SHADER_EVAL_SUBSURFACE_DIRECT,
+ SHADER_EVAL_DIFFUSE_INDIRECT,
+ SHADER_EVAL_GLOSSY_INDIRECT,
+ SHADER_EVAL_TRANSMISSION_INDIRECT,
+ SHADER_EVAL_SUBSURFACE_INDIRECT,
+
+ /* extra */
+ SHADER_EVAL_ENVIRONMENT,
} ShaderEvalType;
/* Path Tracing
@@ -177,10 +204,8 @@ enum PathTraceDimension {
PRNG_UNUSED_0 = 5,
PRNG_UNUSED_1 = 6, /* for some reason (6, 7) is a bad sobol pattern */
PRNG_UNUSED_2 = 7, /* with a low number of samples (< 64) */
- PRNG_BASE_NUM = 8,
-#else
- PRNG_BASE_NUM = 4,
#endif
+ PRNG_BASE_NUM = 8,
PRNG_BSDF_U = 0,
PRNG_BSDF_V = 1,
@@ -188,7 +213,7 @@ enum PathTraceDimension {
PRNG_LIGHT = 3,
PRNG_LIGHT_U = 4,
PRNG_LIGHT_V = 5,
- PRNG_LIGHT_F = 6,
+ PRNG_UNUSED_3 = 6,
PRNG_TERMINATE = 7,
#ifdef __VOLUME__
@@ -220,7 +245,6 @@ enum PathRayFlag {
PATH_RAY_GLOSSY = 16,
PATH_RAY_SINGULAR = 32,
PATH_RAY_TRANSPARENT = 64,
- PATH_RAY_VOLUME_SCATTER = 128,
PATH_RAY_SHADOW_OPAQUE = 128,
PATH_RAY_SHADOW_TRANSPARENT = 256,
@@ -228,16 +252,17 @@ enum PathRayFlag {
PATH_RAY_CURVE = 512, /* visibility flag to define curve segments*/
+ /* note that these can use maximum 12 bits, the other are for layers */
PATH_RAY_ALL_VISIBILITY = (1|2|4|8|16|32|64|128|256|512),
PATH_RAY_MIS_SKIP = 1024,
PATH_RAY_DIFFUSE_ANCESTOR = 2048,
PATH_RAY_GLOSSY_ANCESTOR = 4096,
PATH_RAY_BSSRDF_ANCESTOR = 8192,
- PATH_RAY_SINGLE_PASS_DONE = 8192,
+ PATH_RAY_SINGLE_PASS_DONE = 16384,
+ PATH_RAY_VOLUME_SCATTER = 32768,
- /* this gives collisions with localview bits
- * see: blender_util.h, grr - Campbell */
+ /* we need layer member flags to be the 20 upper bits */
PATH_RAY_LAYER_SHIFT = (32-20)
};
@@ -282,7 +307,8 @@ typedef enum PassType {
PASS_MIST = 2097152,
PASS_SUBSURFACE_DIRECT = 4194304,
PASS_SUBSURFACE_INDIRECT = 8388608,
- PASS_SUBSURFACE_COLOR = 16777216
+ PASS_SUBSURFACE_COLOR = 16777216,
+ PASS_LIGHT = 33554432, /* no real pass, used to force use_light_pass */
} PassType;
#define PASS_ALL (~0)
@@ -418,9 +444,27 @@ typedef struct Intersection {
float t, u, v;
int prim;
int object;
- int segment;
+ int type;
} Intersection;
+/* Primitives */
+
+typedef enum PrimitiveType {
+ PRIMITIVE_NONE = 0,
+ PRIMITIVE_TRIANGLE = 1,
+ PRIMITIVE_MOTION_TRIANGLE = 2,
+ PRIMITIVE_CURVE = 4,
+ PRIMITIVE_MOTION_CURVE = 8,
+
+ PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE),
+ PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE),
+ PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE),
+ PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE)
+} PrimitiveType;
+
+#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << 16) | type)
+#define PRIMITIVE_UNPACK_SEGMENT(type) (type >> 16)
+
/* Attributes */
#define ATTR_PRIM_TYPES 2
@@ -432,9 +476,12 @@ typedef enum AttributeElement {
ATTR_ELEMENT_MESH,
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
+ ATTR_ELEMENT_VERTEX_MOTION,
ATTR_ELEMENT_CORNER,
ATTR_ELEMENT_CURVE,
- ATTR_ELEMENT_CURVE_KEY
+ ATTR_ELEMENT_CURVE_KEY,
+ ATTR_ELEMENT_CURVE_KEY_MOTION,
+ ATTR_ELEMENT_VOXEL
} AttributeElement;
typedef enum AttributeStandard {
@@ -448,12 +495,17 @@ typedef enum AttributeStandard {
ATTR_STD_GENERATED_TRANSFORM,
ATTR_STD_POSITION_UNDEFORMED,
ATTR_STD_POSITION_UNDISPLACED,
- ATTR_STD_MOTION_PRE,
- ATTR_STD_MOTION_POST,
+ ATTR_STD_MOTION_VERTEX_POSITION,
+ ATTR_STD_MOTION_VERTEX_NORMAL,
ATTR_STD_PARTICLE,
ATTR_STD_CURVE_INTERCEPT,
ATTR_STD_PTEX_FACE_ID,
ATTR_STD_PTEX_UV,
+ ATTR_STD_VOLUME_DENSITY,
+ ATTR_STD_VOLUME_COLOR,
+ ATTR_STD_VOLUME_FLAME,
+ ATTR_STD_VOLUME_HEAT,
+ ATTR_STD_VOLUME_VELOCITY,
ATTR_STD_NUM,
ATTR_STD_NOT_FOUND = ~0
@@ -461,15 +513,17 @@ typedef enum AttributeStandard {
/* Closure data */
+#ifdef __MULTI_CLOSURE__
#define MAX_CLOSURE 64
+#else
+#define MAX_CLOSURE 1
+#endif
typedef struct ShaderClosure {
ClosureType type;
float3 weight;
-#ifdef __MULTI_CLOSURE__
float sample_weight;
-#endif
float data0;
float data1;
@@ -561,13 +615,9 @@ typedef struct ShaderData {
/* primitive id if there is one, ~0 otherwise */
int prim;
-#ifdef __HAIR__
- /* for curves, segment number in curve, ~0 for triangles */
- int segment;
- /* variables for minimum hair width using transparency bsdf */
- /*float curve_transparency; */
- /*float curve_radius; */
-#endif
+ /* combined type and curve segment for hair */
+ int type;
+
/* parametric coordinates
* - barycentric weights for triangles */
float u, v;
@@ -583,6 +633,9 @@ typedef struct ShaderData {
/* ray bounce depth */
int ray_depth;
+ /* ray transparent depth */
+ int transparent_depth;
+
#ifdef __RAY_DIFFERENTIALS__
/* differential of P. these are orthogonal to Ng, not N */
differential3 dP;
@@ -605,15 +658,10 @@ typedef struct ShaderData {
Transform ob_itfm;
#endif
-#ifdef __MULTI_CLOSURE__
/* Closure data, we store a fixed array of closures */
ShaderClosure closure[MAX_CLOSURE];
int num_closure;
float randb_closure;
-#else
- /* Closure data, with a single sampled closure for low memory usage */
- ShaderClosure closure;
-#endif
/* ray start position, only set for backgrounds */
float3 ray_P;
@@ -824,25 +872,27 @@ typedef struct KernelIntegrator {
/* clamp */
float sample_clamp_direct;
float sample_clamp_indirect;
- float pad1, pad2, pad3;
/* branched path */
int branched;
- int aa_samples;
int diffuse_samples;
int glossy_samples;
int transmission_samples;
int ao_samples;
int mesh_light_samples;
int subsurface_samples;
-
+ int sample_all_lights_direct;
+ int sample_all_lights_indirect;
+
/* mis */
int use_lamp_mis;
/* sampler */
int sampling_pattern;
+ int aa_samples;
/* volume render */
+ int volume_homogeneous_sampling;
int use_volumes;
int volume_max_steps;
float volume_step_size;
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index dc2ddf1098e..faaa68e3309 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -16,6 +16,8 @@
CCL_NAMESPACE_BEGIN
+/* Events for probalistic scattering */
+
typedef enum VolumeIntegrateResult {
VOLUME_PATH_SCATTERED = 0,
VOLUME_PATH_ATTENUATED = 1,
@@ -92,14 +94,19 @@ ccl_device bool volume_shader_sample(KernelGlobals *kg, ShaderData *sd, PathStat
return true;
}
-ccl_device float3 volume_color_attenuation(float3 sigma, float t)
+ccl_device float3 volume_color_transmittance(float3 sigma, float t)
{
return make_float3(expf(-sigma.x * t), expf(-sigma.y * t), expf(-sigma.z * t));
}
+ccl_device float kernel_volume_channel_get(float3 value, int channel)
+{
+ return (channel == 0)? value.x: ((channel == 1)? value.y: value.z);
+}
+
ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, VolumeStack *stack)
{
- for(int i = 0; stack[i].shader != SHADER_NO_ID; i++) {
+ for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
int shader_flag = kernel_tex_fetch(__shader_flag, (stack[i].shader & SHADER_MASK)*2);
if(shader_flag & SD_HETEROGENEOUS_VOLUME)
@@ -114,14 +121,14 @@ ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, VolumeStack *st
* These functions are used to attenuate shadow rays to lights. Both absorption
* and scattering will block light, represented by the extinction coefficient. */
-/* homogenous volume: assume shader evaluation at the starts gives
+/* homogeneous volume: assume shader evaluation at the starts gives
* the extinction coefficient for the entire line segment */
ccl_device void kernel_volume_shadow_homogeneous(KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, float3 *throughput)
{
float3 sigma_t;
if(volume_shader_extinction_sample(kg, sd, state, ray->P, &sigma_t))
- *throughput *= volume_color_attenuation(sigma_t, ray->t);
+ *throughput *= volume_color_transmittance(sigma_t, ray->t);
}
/* heterogeneous volume: integrate stepping through the volume until we
@@ -138,34 +145,29 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
/* compute extinction at the start */
float t = 0.0f;
- float3 P = ray->P;
- float3 sigma_t;
-
- if(!volume_shader_extinction_sample(kg, sd, state, P, &sigma_t))
- sigma_t = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < max_steps; i++) {
/* advance to new position */
- float new_t = min(ray->t, t + random_jitter_offset + i * step);
- float3 new_P = ray->P + ray->D * new_t;
- float3 new_sigma_t;
+ float new_t = min(ray->t, (i+1) * step);
+ float dt = new_t - t;
+
+ /* use random position inside this segment to sample shader */
+ if(new_t == ray->t)
+ random_jitter_offset = lcg_step_float(&state->rng_congruential) * dt;
+
+ float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ float3 sigma_t;
/* compute attenuation over segment */
- if(volume_shader_extinction_sample(kg, sd, state, new_P, &new_sigma_t)) {
+ if(volume_shader_extinction_sample(kg, sd, state, new_P, &sigma_t)) {
/* todo: we could avoid computing expf() for each step by summing,
* because exp(a)*exp(b) = exp(a+b), but we still want a quick
* tp_eps check too */
- tp *= volume_color_attenuation(0.5f*(sigma_t + new_sigma_t), new_t - t);
+ tp *= volume_color_transmittance(sigma_t, new_t - t);
/* stop if nearly all light blocked */
if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps)
break;
-
- sigma_t = new_sigma_t;
- }
- else {
- /* skip empty space */
- sigma_t = make_float3(0.0f, 0.0f, 0.0f);
}
/* stop if at the end of the volume */
@@ -182,7 +184,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, PathState *state, Ray *ray, float3 *throughput)
{
ShaderData sd;
- shader_setup_from_volume(kg, &sd, ray, state->bounce);
+ shader_setup_from_volume(kg, &sd, ray, state->bounce, state->transparent_bounce);
if(volume_stack_is_heterogeneous(kg, state->volume_stack))
kernel_volume_shadow_heterogeneous(kg, state, ray, &sd, throughput);
@@ -190,9 +192,123 @@ ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg, PathState *stat
kernel_volume_shadow_homogeneous(kg, state, ray, &sd, throughput);
}
+/* Equi-angular sampling as in:
+ * "Importance Sampling Techniques for Path Tracing in Participating Media" */
+
+ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, float xi, float *pdf)
+{
+ float t = ray->t;
+
+ float delta = dot((light_P - ray->P) , ray->D);
+ float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ float theta_a = -atan2f(delta, D);
+ float theta_b = atan2f(t - delta, D);
+ float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
+
+ *pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
+
+ return min(t, delta + t_); /* min is only for float precision errors */
+}
+
+ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t)
+{
+ float delta = dot((light_P - ray->P) , ray->D);
+ float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
+
+ float t = ray->t;
+ float t_ = sample_t - delta;
+
+ float theta_a = -atan2f(delta, D);
+ float theta_b = atan2f(t - delta, D);
+
+ float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
+
+ return pdf;
+}
+
+ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float3 *light_P)
+{
+ /* light RNGs */
+ float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ /* light sample */
+ LightSample ls;
+ light_sample(kg, light_t, light_u, light_v, ray->time, ray->P, &ls);
+ if(ls.pdf == 0.0f)
+ return false;
+
+ *light_P = ls.P;
+ return true;
+}
+
+ccl_device float kernel_volume_decoupled_equiangular_pdf(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float sample_t)
+{
+ float3 light_P;
+
+ if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
+ return 0.0f;
+
+ return kernel_volume_equiangular_pdf(ray, light_P, sample_t);
+}
+
+/* Distance sampling */
+
+ccl_device float kernel_volume_distance_sample(float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
+{
+ /* xi is [0, 1[ so log(0) should never happen, division by zero is
+ * avoided because sample_sigma_t > 0 when SD_SCATTER is set */
+ float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
+ float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ float sample_transmittance = kernel_volume_channel_get(full_transmittance, channel);
+
+ float sample_t = min(max_t, -logf(1.0f - xi*(1.0f - sample_transmittance))/sample_sigma_t);
+
+ *transmittance = volume_color_transmittance(sigma_t, sample_t);
+ *pdf = (sigma_t * *transmittance)/(make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
+
+ /* todo: optimization: when taken together with hit/miss decision,
+ * the full_transmittance cancels out drops out and xi does not
+ * need to be remapped */
+
+ return sample_t;
+}
+
+ccl_device float3 kernel_volume_distance_pdf(float max_t, float3 sigma_t, float sample_t)
+{
+ float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ float3 transmittance = volume_color_transmittance(sigma_t, sample_t);
+
+ return (sigma_t * transmittance)/(make_float3(1.0f, 1.0f, 1.0f) - full_transmittance);
+}
+
+/* Emission */
+
+ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coeff, int closure_flag, float3 transmittance, float t)
+{
+ /* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
+ * this goes to E * t as sigma_t goes to zero
+ *
+ * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
+ float3 emission = coeff->emission;
+
+ if(closure_flag & SD_ABSORPTION) {
+ float3 sigma_t = coeff->sigma_a + coeff->sigma_s;
+
+ emission.x *= (sigma_t.x > 0.0f)? (1.0f - transmittance.x)/sigma_t.x: t;
+ emission.y *= (sigma_t.y > 0.0f)? (1.0f - transmittance.y)/sigma_t.y: t;
+ emission.z *= (sigma_t.z > 0.0f)? (1.0f - transmittance.z)/sigma_t.z: t;
+ }
+ else
+ emission *= t;
+
+ return emission;
+}
+
/* Volume Path */
-/* homogenous volume: assume shader evaluation at the starts gives
+/* homogeneous volume: assume shader evaluation at the start gives
* the volume shading coefficient for the entire line segment */
ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGlobals *kg,
PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput,
@@ -206,69 +322,73 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
int closure_flag = sd->flag;
float t = ray->t;
float3 new_tp;
- float3 transmittance;
/* randomly scatter, and if we do t is shortened */
if(closure_flag & SD_SCATTER) {
+ /* extinction coefficient */
float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
- /* set up variables for sampling */
+ /* pick random color channel, we use the Veach one-sample
+ * model with balance heuristic for the channels */
float rphase = path_state_rng_1D(kg, rng, state, PRNG_PHASE);
int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel;
- /* pick random color channel, we use the Veach one-sample
- * model with balance heuristic for the channels */
- float sample_sigma_t;
+ float xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
- if(channel == 0)
- sample_sigma_t = sigma_t.x;
- else if(channel == 1)
- sample_sigma_t = sigma_t.y;
- else
- sample_sigma_t = sigma_t.z;
+ /* decide if we will hit or miss */
+ float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
+ float sample_transmittance = expf(-sample_sigma_t * t);
- /* xi is [0, 1[ so log(0) should never happen, division by zero is
- * avoided because sample_sigma_t > 0 when SD_SCATTER is set */
- float xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
- float sample_t = min(t, -logf(1.0f - xi)/sample_sigma_t);
+ if(xi >= sample_transmittance) {
+ /* scattering */
+ float3 pdf;
+ float3 transmittance;
+ float sample_t;
- transmittance = volume_color_attenuation(sigma_t, sample_t);
+ /* rescale random number so we can reuse it */
+ xi = (xi - sample_transmittance)/(1.0f - sample_transmittance);
- if(sample_t < t) {
- float pdf = dot(sigma_t, transmittance);
- new_tp = *throughput * coeff.sigma_s * transmittance * (3.0f / pdf);
+ if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
+ /* distance sampling */
+ sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf);
+ }
+ else {
+ /* equiangular sampling */
+ float3 light_P;
+ float equi_pdf;
+ if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
+ return VOLUME_PATH_MISSED;
+
+ sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
+ transmittance = volume_color_transmittance(sigma_t, sample_t);
+ pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
+ }
+
+ /* modifiy pdf for hit/miss decision */
+ pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
+
+ new_tp = *throughput * coeff.sigma_s * transmittance / average(pdf);
t = sample_t;
}
else {
- float pdf = (transmittance.x + transmittance.y + transmittance.z);
- new_tp = *throughput * transmittance * (3.0f / pdf);
+ /* no scattering */
+ float3 transmittance = volume_color_transmittance(sigma_t, t);
+ float pdf = average(transmittance);
+ new_tp = *throughput * transmittance / pdf;
}
}
else if(closure_flag & SD_ABSORPTION) {
/* absorption only, no sampling needed */
- transmittance = volume_color_attenuation(coeff.sigma_a, t);
+ float3 transmittance = volume_color_transmittance(coeff.sigma_a, t);
new_tp = *throughput * transmittance;
}
- /* integrate emission attenuated by extinction
- * integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
- * this goes to E * t as sigma_t goes to zero
- *
- * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
+ /* integrate emission attenuated by extinction */
if(closure_flag & SD_EMISSION) {
- float3 emission = coeff.emission;
-
- if(closure_flag & SD_ABSORPTION) {
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
-
- emission.x *= (sigma_t.x > 0.0f)? (1.0f - transmittance.x)/sigma_t.x: t;
- emission.y *= (sigma_t.y > 0.0f)? (1.0f - transmittance.y)/sigma_t.y: t;
- emission.z *= (sigma_t.z > 0.0f)? (1.0f - transmittance.z)/sigma_t.z: t;
- }
- else
- emission *= t;
-
+ float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 transmittance = volume_color_transmittance(sigma_t, ray->t);
+ float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, ray->t);
path_radiance_accum_emission(L, *throughput, emission, state->bounce);
}
@@ -293,45 +413,38 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous(KernelGlobals *kg,
PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput, RNG *rng)
{
- VolumeShaderCoefficients coeff;
float3 tp = *throughput;
const float tp_eps = 1e-10f; /* todo: this is likely not the right value */
/* prepare for stepping */
int max_steps = kernel_data.integrator.volume_max_steps;
- float step = kernel_data.integrator.volume_step_size;
- float random_jitter_offset = lcg_step_float(&state->rng_congruential) * step;
+ float step_size = kernel_data.integrator.volume_step_size;
+ float random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
/* compute coefficients at the start */
float t = 0.0f;
- float3 P = ray->P;
-
- if(!volume_shader_sample(kg, sd, state, P, &coeff)) {
- coeff.sigma_a = make_float3(0.0f, 0.0f, 0.0f);
- coeff.sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- coeff.emission = make_float3(0.0f, 0.0f, 0.0f);
- }
-
- /* accumulate these values so we can use a single stratified number to sample */
float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
- float3 accum_sigma_t = make_float3(0.0f, 0.0f, 0.0f);
- float3 accum_sigma_s = make_float3(0.0f, 0.0f, 0.0f);
/* cache some constant variables */
- float nlogxi;
+ float xi;
int channel = -1;
bool has_scatter = false;
for(int i = 0; i < max_steps; i++) {
/* advance to new position */
- float new_t = min(ray->t, t + random_jitter_offset + i * step);
- float3 new_P = ray->P + ray->D * new_t;
- VolumeShaderCoefficients new_coeff;
+ float new_t = min(ray->t, (i+1) * step_size);
+ float dt = new_t - t;
+
+ /* use random position inside this segment to sample shader */
+ if(new_t == ray->t)
+ random_jitter_offset = lcg_step_float(&state->rng_congruential) * dt;
+
+ float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ VolumeShaderCoefficients coeff;
/* compute segment */
- if(volume_shader_sample(kg, sd, state, new_P, &new_coeff)) {
+ if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
int closure_flag = sd->flag;
- float dt = new_t - t;
float3 new_tp;
float3 transmittance;
bool scatter = false;
@@ -341,94 +454,58 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous(KernelGlo
has_scatter = true;
/* average sigma_t and sigma_s over segment */
- float3 last_sigma_t = coeff.sigma_a + coeff.sigma_s;
- float3 new_sigma_t = new_coeff.sigma_a + new_coeff.sigma_s;
- float3 sigma_t = 0.5f*(last_sigma_t + new_sigma_t);
- float3 sigma_s = 0.5f*(coeff.sigma_s + new_coeff.sigma_s);
+ float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ float3 sigma_s = coeff.sigma_s;
/* lazily set up variables for sampling */
if(channel == -1) {
- float xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
- nlogxi = -logf(1.0f - xi);
+ /* pick random color channel, we use the Veach one-sample
+ * model with balance heuristic for the channels */
+ xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D(kg, rng, state, PRNG_PHASE);
channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel;
}
- /* pick random color channel, we use the Veach one-sample
- * model with balance heuristic for the channels */
- float sample_sigma_t;
+ /* compute transmittance over full step */
+ transmittance = volume_color_transmittance(sigma_t, dt);
- if(channel == 0)
- sample_sigma_t = accum_sigma_t.x + dt*sigma_t.x;
- else if(channel == 1)
- sample_sigma_t = accum_sigma_t.y + dt*sigma_t.y;
- else
- sample_sigma_t = accum_sigma_t.z + dt*sigma_t.z;
+ /* decide if we will scatter or continue */
+ float sample_transmittance = kernel_volume_channel_get(transmittance, channel);
- if(nlogxi < sample_sigma_t) {
+ if(1.0f - xi >= sample_transmittance) {
/* compute sampling distance */
- sample_sigma_t /= new_t;
- new_t = nlogxi/sample_sigma_t;
- dt = new_t - t;
-
- transmittance = volume_color_attenuation(sigma_t, dt);
-
- accum_transmittance *= transmittance;
- accum_sigma_t = (accum_sigma_t + dt*sigma_t)/new_t;
- accum_sigma_s = (accum_sigma_s + dt*sigma_s)/new_t;
-
- /* todo: it's not clear to me that this is correct if we move
- * through a color volumed, needs verification */
- float pdf = dot(accum_sigma_t, accum_transmittance);
- new_tp = tp * accum_sigma_s * transmittance * (3.0f / pdf);
-
+ float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
+ float new_dt = -logf(1.0f - xi)/sample_sigma_t;
+ new_t = t + new_dt;
+
+ /* transmittance, throughput */
+ float3 new_transmittance = volume_color_transmittance(sigma_t, new_dt);
+ float pdf = average(sigma_t * new_transmittance);
+ new_tp = tp * sigma_s * new_transmittance / pdf;
scatter = true;
}
else {
- transmittance = volume_color_attenuation(sigma_t, dt);
-
- accum_transmittance *= transmittance;
- accum_sigma_t += dt*sigma_t;
- accum_sigma_s += dt*sigma_s;
+ /* throughput */
+ float pdf = average(transmittance);
+ new_tp = tp * transmittance / pdf;
- new_tp = tp * transmittance;
+ /* remap xi so we can reuse it and keep thing stratified */
+ xi = 1.0f - (1.0f - xi)/sample_transmittance;
}
}
else if(closure_flag & SD_ABSORPTION) {
/* absorption only, no sampling needed */
- float3 sigma_a = 0.5f*(coeff.sigma_a + new_coeff.sigma_a);
- transmittance = volume_color_attenuation(sigma_a, dt);
-
- accum_transmittance *= transmittance;
- accum_sigma_t += dt*sigma_a;
+ float3 sigma_a = coeff.sigma_a;
+ transmittance = volume_color_transmittance(sigma_a, dt);
new_tp = tp * transmittance;
-
- /* todo: we could avoid computing expf() for each step by summing,
- * because exp(a)*exp(b) = exp(a+b), but we still want a quick
- * tp_eps check too */
}
- /* integrate emission attenuated by absorption
- * integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
- * this goes to E * t as sigma_t goes to zero
- *
- * todo: we should use an epsilon to avoid precision issues near zero sigma_t */
+ /* integrate emission attenuated by absorption */
if(closure_flag & SD_EMISSION) {
- float3 emission = 0.5f*(coeff.emission + new_coeff.emission);
-
- if(closure_flag & SD_ABSORPTION) {
- float3 sigma_t = 0.5f*(coeff.sigma_a + coeff.sigma_s + new_coeff.sigma_a + new_coeff.sigma_s);
-
- emission.x *= (sigma_t.x > 0.0f)? (1.0f - transmittance.x)/sigma_t.x: dt;
- emission.y *= (sigma_t.y > 0.0f)? (1.0f - transmittance.y)/sigma_t.y: dt;
- emission.z *= (sigma_t.z > 0.0f)? (1.0f - transmittance.z)/sigma_t.z: dt;
- }
- else
- emission *= dt;
-
+ float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
path_radiance_accum_emission(L, tp, emission, state->bounce);
}
@@ -450,47 +527,323 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous(KernelGlo
return VOLUME_PATH_SCATTERED;
}
+ else {
+ /* accumulate transmittance */
+ accum_transmittance *= transmittance;
+ }
}
+ }
+
+ /* stop if at the end of the volume */
+ t = new_t;
+ if(t == ray->t)
+ break;
+ }
+
+ *throughput = tp;
- coeff = new_coeff;
+ return VOLUME_PATH_ATTENUATED;
+}
+
+/* Decoupled Volume Sampling
+ *
+ * VolumeSegment is list of coefficients and transmittance stored at all steps
+ * through a volume. This can then latter be used for decoupled sampling as in:
+ * "Importance Sampling Techniques for Path Tracing in Participating Media" */
+
+/* CPU only because of malloc/free */
+#ifdef __KERNEL_CPU__
+
+typedef struct VolumeStep {
+ float3 sigma_s; /* scatter coefficient */
+ float3 sigma_t; /* extinction coefficient */
+ float3 accum_transmittance; /* accumulated transmittance including this step */
+ float3 cdf_distance; /* cumulative density function for distance sampling */
+ float t; /* distance at end of this step */
+ float shade_t; /* jittered distance where shading was done in step */
+ int closure_flag; /* shader evaluation closure flags */
+} VolumeStep;
+
+typedef struct VolumeSegment {
+ VolumeStep *steps; /* recorded steps */
+ int numsteps; /* number of steps */
+ int closure_flag; /* accumulated closure flags from all steps */
+
+ float3 accum_emission; /* accumulated emission at end of segment */
+ float3 accum_transmittance; /* accumulated transmittance at end of segment */
+} VolumeSegment;
+
+/* record volume steps to the end of the volume.
+ *
+ * it would be nice if we could only record up to the point that we need to scatter,
+ * but the entire segment is needed to do always scattering, rather than probalistically
+ * hitting or missing the volume. if we don't know the transmittance at the end of the
+ * volume we can't generate stratitied distance samples up to that transmittance */
+ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state,
+ Ray *ray, ShaderData *sd, VolumeSegment *segment, bool heterogeneous)
+{
+ /* prepare for volume stepping */
+ int max_steps;
+ float step_size, random_jitter_offset;
+
+ if(heterogeneous) {
+ max_steps = kernel_data.integrator.volume_max_steps;
+ step_size = kernel_data.integrator.volume_step_size;
+ random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
+
+ /* compute exact steps in advance for malloc */
+ max_steps = max((int)ceilf(ray->t/step_size), 1);
+ }
+ else {
+ max_steps = 1;
+ step_size = ray->t;
+ random_jitter_offset = 0.0f;
+ }
+
+ /* init accumulation variables */
+ float3 accum_emission = make_float3(0.0f, 0.0f, 0.0f);
+ float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
+ float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
+ float t = 0.0f;
+
+ segment->closure_flag = 0;
+ segment->numsteps = 0;
+ segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
+
+ VolumeStep *step = segment->steps;
+
+ for(int i = 0; i < max_steps; i++, step++) {
+ /* advance to new position */
+ float new_t = min(ray->t, (i+1) * step_size);
+ float dt = new_t - t;
+
+ /* use random position inside this segment to sample shader */
+ if(heterogeneous && new_t == ray->t)
+ random_jitter_offset = lcg_step_float(&state->rng_congruential) * dt;
+
+ float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ VolumeShaderCoefficients coeff;
+
+ /* compute segment */
+ if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
+ int closure_flag = sd->flag;
+ float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+
+ /* compute accumulated transmittance */
+ float3 transmittance = volume_color_transmittance(sigma_t, dt);
+
+ /* compute emission attenuated by absorption */
+ if(closure_flag & SD_EMISSION) {
+ float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
+ accum_emission += accum_transmittance * emission;
+ }
+
+ accum_transmittance *= transmittance;
+
+ /* compute pdf for distance sampling */
+ float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
+ cdf_distance = cdf_distance + pdf_distance;
+
+ /* write step data */
+ step->sigma_t = sigma_t;
+ step->sigma_s = coeff.sigma_s;
+ step->closure_flag = closure_flag;
+
+ segment->closure_flag |= closure_flag;
}
else {
- /* skip empty space */
- coeff.sigma_a = make_float3(0.0f, 0.0f, 0.0f);
- coeff.sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- coeff.emission = make_float3(0.0f, 0.0f, 0.0f);
+ /* store empty step (todo: skip consecutive empty steps) */
+ step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
+ step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ step->closure_flag = 0;
}
+ step->accum_transmittance = accum_transmittance;
+ step->cdf_distance = cdf_distance;
+ step->t = new_t;
+ step->shade_t = t + random_jitter_offset;
+
+ segment->numsteps++;
+
/* stop if at the end of the volume */
t = new_t;
if(t == ray->t)
break;
}
- /* include pdf for volumes with scattering */
- if(has_scatter) {
- float pdf = (accum_transmittance.x + accum_transmittance.y + accum_transmittance.z);
- if(pdf > 0.0f)
- tp *= (3.0f/pdf);
+ /* store total emission and transmittance */
+ segment->accum_emission = accum_emission;
+ segment->accum_transmittance = accum_transmittance;
+
+ /* normalize cumulative density function for distance sampling */
+ VolumeStep *last_step = segment->steps + segment->numsteps - 1;
+
+ if(!is_zero(last_step->cdf_distance)) {
+ VolumeStep *step = &segment->steps[0];
+ int numsteps = segment->numsteps;
+ float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance);
+
+ for(int i = 0; i < numsteps; i++, step++)
+ step->cdf_distance *= inv_cdf_distance_sum;
+ }
+}
+
+ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *segment)
+{
+ free(segment->steps);
+}
+
+/* scattering for homogeneous and heterogeneous volumes, using decoupled ray
+ * marching. unlike the non-decoupled functions, these do not do probalistic
+ * scattering, they always scatter if there is any non-zero scattering
+ * coefficient.
+ *
+ * these also do not do emission or modify throughput. */
+ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
+ KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd,
+ float3 *throughput, RNG *rng, VolumeSegment *segment)
+{
+ int closure_flag = segment->closure_flag;
+
+ if(!(closure_flag & SD_SCATTER))
+ return VOLUME_PATH_MISSED;
+
+ /* pick random color channel, we use the Veach one-sample
+ * model with balance heuristic for the channels */
+ float rphase = path_state_rng_1D(kg, rng, state, PRNG_PHASE);
+ int channel = (int)(rphase*3.0f);
+ sd->randb_closure = rphase*3.0f - channel;
+
+ float xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
+
+ VolumeStep *step;
+ float3 transmittance;
+ float pdf, sample_t;
+
+ /* distance sampling */
+ if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
+ /* find step in cdf */
+ step = segment->steps;
+
+ float prev_t = 0.0f;
+ float3 step_pdf = make_float3(1.0f, 1.0f, 1.0f);
+
+ if(segment->numsteps > 1) {
+ float prev_cdf = 0.0f;
+ float step_cdf = 1.0f;
+ float3 prev_cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
+
+ for(int i = 0; ; i++, step++) {
+ /* todo: optimize using binary search */
+ step_cdf = kernel_volume_channel_get(step->cdf_distance, channel);
+
+ if(xi < step_cdf || i == segment->numsteps-1)
+ break;
+
+ prev_cdf = step_cdf;
+ prev_t = step->t;
+ prev_cdf_distance = step->cdf_distance;
+ }
+
+ /* remap xi so we can reuse it */
+ xi = (xi - prev_cdf)/(step_cdf - prev_cdf);
+
+ /* pdf for picking step */
+ step_pdf = step->cdf_distance - prev_cdf_distance;
+ }
+
+ /* determine range in which we will sample */
+ float step_t = step->t - prev_t;
+
+ /* sample distance and compute transmittance */
+ float3 distance_pdf;
+ sample_t = prev_t + kernel_volume_distance_sample(step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf);
+ pdf = average(distance_pdf * step_pdf);
}
+ /* equi-angular sampling */
+ else {
+ /* pick position on light */
+ float3 light_P;
+ if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
+ return VOLUME_PATH_MISSED;
- *throughput = tp;
+ /* sample distance */
+ sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &pdf);
- return VOLUME_PATH_ATTENUATED;
+ /* find step in which sampled distance is located */
+ step = segment->steps;
+
+ float prev_t = 0.0f;
+
+ if(segment->numsteps > 1) {
+ /* todo: optimize using binary search */
+ for(int i = 0; i < segment->numsteps-1; i++, step++) {
+ if(sample_t < step->t)
+ break;
+
+ prev_t = step->t;
+ }
+ }
+
+ /* compute transmittance */
+ transmittance = volume_color_transmittance(step->sigma_t, sample_t - prev_t);
+ }
+
+ /* compute transmittance up to this step */
+ if(step != segment->steps)
+ transmittance *= (step-1)->accum_transmittance;
+
+ /* modify throughput */
+ *throughput *= step->sigma_s * transmittance / pdf;
+
+ /* evaluate shader to create closures at shading point */
+ if(segment->numsteps > 1) {
+ sd->P = ray->P + step->shade_t*ray->D;
+
+ VolumeShaderCoefficients coeff;
+ volume_shader_sample(kg, sd, state, sd->P, &coeff);
+ }
+
+ /* move to new position */
+ sd->P = ray->P + sample_t*ray->D;
+
+ return VOLUME_PATH_SCATTERED;
}
+#endif
+
/* get the volume attenuation and emission over line segment defined by
* ray, with the assumption that there are no surfaces blocking light
* between the endpoints */
ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals *kg,
PathState *state, ShaderData *sd, Ray *ray, PathRadiance *L, float3 *throughput, RNG *rng)
{
- shader_setup_from_volume(kg, sd, ray, state->bounce);
+ /* workaround to fix correlation bug in T38710, can find better solution
+ * in random number generator later, for now this is done here to not impact
+ * performance of rendering without volumes */
+ RNG tmp_rng = cmj_hash(*rng, state->rng_offset);
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
- if(volume_stack_is_heterogeneous(kg, state->volume_stack))
- return kernel_volume_integrate_heterogeneous(kg, state, ray, sd, L, throughput, rng);
+#if 0
+ /* debugging code to compare decoupled ray marching */
+ VolumeSegment segment;
+
+ shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
+ kernel_volume_decoupled_record(kg, state, ray, sd, &segment, heterogeneous);
+
+ VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, throughput, &tmp_rng, &segment);
+
+ kernel_volume_decoupled_free(kg, &segment);
+
+ return result;
+#else
+ shader_setup_from_volume(kg, sd, ray, state->bounce, state->transparent_bounce);
+
+ if(heterogeneous)
+ return kernel_volume_integrate_heterogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
else
- return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, rng);
+ return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
+#endif
}
/* Volume Stack
@@ -501,13 +854,13 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
ccl_device void kernel_volume_stack_init(KernelGlobals *kg, VolumeStack *stack)
{
/* todo: this assumes camera is always in air, need to detect when it isn't */
- if(kernel_data.background.volume_shader == SHADER_NO_ID) {
- stack[0].shader = SHADER_NO_ID;
+ if(kernel_data.background.volume_shader == SHADER_NONE) {
+ stack[0].shader = SHADER_NONE;
}
else {
stack[0].shader = kernel_data.background.volume_shader;
- stack[0].object = ~0;
- stack[1].shader = SHADER_NO_ID;
+ stack[0].object = PRIM_NONE;
+ stack[1].shader = SHADER_NONE;
}
}
@@ -522,14 +875,14 @@ ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd
if(sd->flag & SD_BACKFACING) {
/* exit volume object: remove from stack */
- for(int i = 0; stack[i].shader != SHADER_NO_ID; i++) {
+ for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
if(stack[i].object == sd->object) {
/* shift back next stack entries */
do {
stack[i] = stack[i+1];
i++;
}
- while(stack[i].shader != SHADER_NO_ID);
+ while(stack[i].shader != SHADER_NONE);
return;
}
@@ -539,7 +892,7 @@ ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd
/* enter volume object: add to stack */
int i;
- for(i = 0; stack[i].shader != SHADER_NO_ID; i++) {
+ for(i = 0; stack[i].shader != SHADER_NONE; i++) {
/* already in the stack? then we have nothing to do */
if(stack[i].object == sd->object)
return;
@@ -552,7 +905,7 @@ ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd
/* add to the end of the stack */
stack[i].shader = sd->shader;
stack[i].object = sd->object;
- stack[i+1].shader = SHADER_NO_ID;
+ stack[i+1].shader = SHADER_NONE;
}
}
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 4fad66be6e1..54894ea19eb 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -30,18 +30,16 @@
#include "kernel_compat_cpu.h"
#include "kernel_globals.h"
-#include "kernel_montecarlo.h"
+#include "kernel_random.h"
#include "kernel_projection.h"
#include "kernel_differential.h"
-#include "kernel_object.h"
-#include "kernel_random.h"
-#include "kernel_bvh.h"
-#include "kernel_triangle.h"
-#include "kernel_curve.h"
-#include "kernel_primitive.h"
+#include "kernel_montecarlo.h"
+#include "kernel_camera.h"
+
+#include "geom/geom.h"
+
#include "kernel_projection.h"
#include "kernel_accumulate.h"
-#include "kernel_camera.h"
#include "kernel_shader.h"
#ifdef WITH_PTEX
@@ -52,11 +50,16 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */
-#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
+#define COPY_MATRIX44(m1, m2) { \
+ CHECK_TYPE(m1, OSL::Matrix44*); \
+ CHECK_TYPE(m2, Transform*); \
+ memcpy(m1, m2, sizeof(*m2)); \
+} (void)0
/* static ustrings */
ustring OSLRenderServices::u_distance("distance");
ustring OSLRenderServices::u_index("index");
+ustring OSLRenderServices::u_world("world");
ustring OSLRenderServices::u_camera("camera");
ustring OSLRenderServices::u_screen("screen");
ustring OSLRenderServices::u_raster("raster");
@@ -87,6 +90,7 @@ ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
#endif
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
+ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
ustring OSLRenderServices::u_trace("trace");
ustring OSLRenderServices::u_hit("hit");
ustring OSLRenderServices::u_hitdist("hitdist");
@@ -131,7 +135,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
KernelGlobals *kg = sd->osl_globals;
int object = sd->object;
- if (object != ~0) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
Transform tfm;
@@ -161,7 +165,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
KernelGlobals *kg = sd->osl_globals;
int object = sd->object;
- if (object != ~0) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
Transform itfm;
@@ -206,6 +210,10 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
COPY_MATRIX44(&result, &tfm);
return true;
}
+ else if (from == u_world) {
+ result.makeIdentity();
+ return true;
+ }
return false;
}
@@ -234,6 +242,10 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
COPY_MATRIX44(&result, &tfm);
return true;
}
+ else if (to == u_world) {
+ result.makeIdentity();
+ return true;
+ }
return false;
}
@@ -246,7 +258,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
const ShaderData *sd = (const ShaderData *)xform;
int object = sd->object;
- if (object != ~0) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_tfm;
#else
@@ -271,7 +283,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
const ShaderData *sd = (const ShaderData *)xform;
int object = sd->object;
- if (object != ~0) {
+ if (object != OBJECT_NONE) {
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
#else
@@ -525,7 +537,8 @@ static bool get_mesh_element_attribute(KernelGlobals *kg, const ShaderData *sd,
const TypeDesc& type, bool derivatives, void *val)
{
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
+ attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
+ {
float3 fval[3];
fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
@@ -596,44 +609,44 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
/* Particle Attributes */
else if (name == u_particle_index) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float f = particle_index(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_particle_age) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float f = particle_age(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_particle_lifetime) {
- uint particle_id = object_particle_id(kg, sd->object);
- float f= particle_lifetime(kg, particle_id);
+ int particle_id = object_particle_id(kg, sd->object);
+ float f = particle_lifetime(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_particle_location) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float3 f = particle_location(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
#if 0 /* unsupported */
else if (name == u_particle_rotation) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float4 f = particle_rotation(kg, particle_id);
return set_attribute_float4(f, type, derivatives, val);
}
#endif
else if (name == u_particle_size) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float f = particle_size(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_particle_velocity) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float3 f = particle_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
else if (name == u_particle_angular_velocity) {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
float3 f = particle_angular_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
@@ -644,12 +657,17 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
}
else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
#ifdef __HAIR__
- && sd->segment == ~0) {
+ && sd->type & PRIMITIVE_ALL_TRIANGLE)
#else
- ) {
+ )
#endif
+ {
float3 P[3];
- triangle_vertices(kg, sd->prim, P);
+
+ if(sd->type & PRIMITIVE_TRIANGLE)
+ triangle_vertices(kg, sd->prim, P);
+ else
+ motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
if(!(sd->flag & SD_TRANSFORM_APPLIED)) {
object_position_transform(kg, sd, &P[0]);
@@ -670,7 +688,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
#ifdef __HAIR__
/* Hair Attributes */
else if (name == u_is_curve) {
- float f = (sd->segment != ~0);
+ float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_curve_thickness) {
@@ -699,13 +717,18 @@ bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *
int f = sd->ray_depth;
return set_attribute_int(f, type, derivatives, val);
}
+ else if (name == u_path_transparent_depth) {
+ /* Ray Depth */
+ int f = sd->transparent_depth;
+ return set_attribute_int(f, type, derivatives, val);
+ }
else if (name == u_ndc) {
/* NDC coordinates with special exception for otho */
OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
float3 ndc[3];
- if((globals->raytype & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ if((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
if(derivatives) {
@@ -733,7 +756,9 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
{
ShaderData *sd = (ShaderData *)renderstate;
KernelGlobals *kg = sd->osl_globals;
- int object, prim, segment;
+ bool is_curve;
+ int object;
+ // int prim;
/* lookup of attribute on another object */
if (object_name != u_empty) {
@@ -743,24 +768,20 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
return false;
object = it->second;
- prim = ~0;
- segment = ~0;
+ // prim = PRIM_NONE;
+ is_curve = false;
}
else {
object = sd->object;
- prim = sd->prim;
-#ifdef __HAIR__
- segment = sd->segment;
-#else
- segment = ~0;
-#endif
+ // prim = sd->prim;
+ is_curve = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
- if (object == ~0)
+ if (object == OBJECT_NONE)
return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
- object = object*ATTR_PRIM_TYPES + (segment != ~0);
+ object = object*ATTR_PRIM_TYPES + (is_curve == true);
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
@@ -769,8 +790,8 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (attr.elem != ATTR_ELEMENT_OBJECT) {
/* triangle and vertex attributes */
- if (prim != ~0)
- return get_mesh_element_attribute(kg, sd, attr, type, derivatives, val);
+ if(get_mesh_element_attribute(kg, sd, attr, type, derivatives, val))
+ return true;
else
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
@@ -1001,12 +1022,13 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
tracedata->ray = ray;
tracedata->setup = false;
tracedata->init = true;
+ tracedata->sd.osl_globals = sd->osl_globals;
/* raytrace */
#ifdef __HAIR__
- return scene_intersect(sd->osl_globals, &ray, ~0, &tracedata->isect, NULL, 0.0f, 0.0f);
+ 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, ~0, &tracedata->isect);
+ return scene_intersect(sd->osl_globals, &ray, PATH_RAY_ALL_VISIBILITY, &tracedata->isect);
#endif
}
@@ -1018,9 +1040,9 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
if(source == u_trace && tracedata->init) {
if(name == u_hit) {
- return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
+ return set_attribute_int((tracedata->isect.prim != PRIM_NONE), type, derivatives, val);
}
- else if(tracedata->isect.prim != ~0) {
+ else if(tracedata->isect.prim != PRIM_NONE) {
if(name == u_hitdist) {
float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
return set_attribute_float(f, type, derivatives, val);
@@ -1033,8 +1055,9 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustri
/* lazy shader data setup */
ShaderData *original_sd = (ShaderData *)(sg->renderstate);
int bounce = original_sd->ray_depth + 1;
+ int transparent_bounce = original_sd->transparent_depth;
- shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce);
+ shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray, bounce, transparent_bounce);
tracedata->setup = true;
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 479b6da1afb..069722d81b6 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -110,12 +110,13 @@ public:
ustring dataname, TypeDesc datatype, void *data);
static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val);
+ TypeDesc type, bool derivatives, void *val);
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
- TypeDesc type, bool derivatives, void *val);
+ TypeDesc type, bool derivatives, void *val);
static ustring u_distance;
static ustring u_index;
+ static ustring u_world;
static ustring u_camera;
static ustring u_screen;
static ustring u_raster;
@@ -144,6 +145,7 @@ public:
static ustring u_curve_tangent_normal;
static ustring u_path_ray_length;
static ustring u_path_ray_depth;
+ static ustring u_path_transparent_depth;
static ustring u_trace;
static ustring u_hit;
static ustring u_hitdist;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 554f647df7c..843dcdd0985 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -18,7 +18,8 @@
#include "kernel_montecarlo.h"
#include "kernel_types.h"
#include "kernel_globals.h"
-#include "kernel_object.h"
+
+#include "geom/geom_object.h"
#include "closure/bsdf_diffuse.h"
#include "closure/bssrdf.h"
@@ -112,7 +113,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->dvdy = sd->dv.dy;
globals->dPdu = TO_VEC3(sd->dPdu);
globals->dPdv = TO_VEC3(sd->dPdv);
- globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object);
+ globals->surfacearea = (sd->object == OBJECT_NONE) ? 1.0f : object_surface_area(kg, sd->object);
globals->time = sd->time;
/* booleans */
@@ -408,8 +409,9 @@ static void flatten_volume_closure_tree(ShaderData *sd,
sc.data1 = volume->sc.data1;
/* add */
- if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF &&
- sd->num_closure < MAX_CLOSURE) {
+ if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) &&
+ (sd->num_closure < MAX_CLOSURE))
+ {
sd->closure[sd->num_closure++] = sc;
sd->flag |= volume->shaderdata_flag();
}
@@ -535,7 +537,7 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id,
/* for OSL, a hash map is used to lookup the attribute by name. */
int object = sd->object*ATTR_PRIM_TYPES;
#ifdef __HAIR__
- if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
+ if(sd->type & PRIMITIVE_ALL_CURVE) object += ATTR_PRIM_CURVE;
#endif
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
@@ -546,7 +548,7 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id,
const OSLGlobals::Attribute &osl_attr = it->second;
*elem = osl_attr.elem;
- if(sd->prim == ~0 && (AttributeElement)osl_attr.elem != ATTR_ELEMENT_MESH)
+ if(sd->prim == PRIM_NONE && (AttributeElement)osl_attr.elem != ATTR_ELEMENT_MESH)
return ATTR_STD_NOT_FOUND;
/* return result */
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 045abdb80af..5518d652bf9 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -77,6 +77,7 @@ set(SRC_OSL
node_wave_texture.osl
node_wireframe.osl
node_hair_bsdf.osl
+ node_uv_map.osl
)
set(SRC_OSL_HEADERS
diff --git a/intern/cycles/kernel/shaders/node_absorption_volume.osl b/intern/cycles/kernel/shaders/node_absorption_volume.osl
index 69c4c0ef7af..6bac83ba4f5 100644
--- a/intern/cycles/kernel/shaders/node_absorption_volume.osl
+++ b/intern/cycles/kernel/shaders/node_absorption_volume.osl
@@ -21,6 +21,6 @@ shader node_absorption_volume(
float Density = 1.0,
output closure color Volume = 0)
{
- Volume = ((color(1.0, 1.0, 1.0) - Color) * Density) * absorption();
+ Volume = ((color(1.0, 1.0, 1.0) - Color) * max(Density, 0.0)) * absorption();
}
diff --git a/intern/cycles/kernel/shaders/node_fresnel.osl b/intern/cycles/kernel/shaders/node_fresnel.osl
index 8c59d5bb512..7ef553c0f39 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.osl
+++ b/intern/cycles/kernel/shaders/node_fresnel.osl
@@ -23,7 +23,7 @@ shader node_fresnel(
output float Fac = 0.0)
{
float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f: f;
+ float eta = backfacing() ? 1.0 / f : f;
float cosi = dot(I, Normal);
Fac = fresnel_dielectric_cos(cosi, eta);
}
diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index 96934199621..b3d6133553b 100644
--- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -26,7 +26,7 @@ shader node_glass_bsdf(
output closure color BSDF = 0)
{
float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f: f;
+ float eta = backfacing() ? 1.0 / f : f;
float cosi = dot(I, Normal);
float Fr = fresnel_dielectric_cos(cosi, eta);
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index caa755636b9..7238a1e8862 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -17,9 +17,9 @@
#include "stdosl.h"
#include "node_color.h"
-color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha, int use_alpha, int is_float)
+color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha, int use_alpha, int is_float, string interpolation)
{
- color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "alpha", Alpha);
+ color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
if (use_alpha) {
rgb = color_unpremultiply(rgb, Alpha);
@@ -42,6 +42,7 @@ shader node_image_texture(
string filename = "",
string color_space = "sRGB",
string projection = "Flat",
+ string interpolation = "smartcubic",
float projection_blend = 0.0,
int is_float = 1,
int use_alpha = 1,
@@ -54,7 +55,7 @@ shader node_image_texture(
p = transform(mapping, p);
if (projection == "Flat") {
- Color = image_texture_lookup(filename, color_space, p[0], p[1], Alpha, use_alpha, is_float);
+ Color = image_texture_lookup(filename, color_space, p[0], p[1], Alpha, use_alpha, is_float, interpolation);
}
else if (projection == "Box") {
/* object space normal */
@@ -119,15 +120,15 @@ shader node_image_texture(
float tmp_alpha;
if (weight[0] > 0.0) {
- Color += weight[0] * image_texture_lookup(filename, color_space, p[1], p[2], tmp_alpha, use_alpha, is_float);
+ Color += weight[0] * image_texture_lookup(filename, color_space, p[1], p[2], tmp_alpha, use_alpha, is_float, interpolation);
Alpha += weight[0] * tmp_alpha;
}
if (weight[1] > 0.0) {
- Color += weight[1] * image_texture_lookup(filename, color_space, p[0], p[2], tmp_alpha, use_alpha, is_float);
+ Color += weight[1] * image_texture_lookup(filename, color_space, p[0], p[2], tmp_alpha, use_alpha, is_float, interpolation);
Alpha += weight[1] * tmp_alpha;
}
if (weight[2] > 0.0) {
- Color += weight[2] * image_texture_lookup(filename, color_space, p[1], p[0], tmp_alpha, use_alpha, is_float);
+ Color += weight[2] * image_texture_lookup(filename, color_space, p[1], p[0], tmp_alpha, use_alpha, is_float, interpolation);
Alpha += weight[2] * tmp_alpha;
}
}
diff --git a/intern/cycles/kernel/shaders/node_light_path.osl b/intern/cycles/kernel/shaders/node_light_path.osl
index 599c7f5a262..95fbcabf917 100644
--- a/intern/cycles/kernel/shaders/node_light_path.osl
+++ b/intern/cycles/kernel/shaders/node_light_path.osl
@@ -26,7 +26,8 @@ shader node_light_path(
output float IsTransmissionRay = 0.0,
output float IsVolumeScatterRay = 0.0,
output float RayLength = 0.0,
- output float RayDepth = 0.0)
+ output float RayDepth = 0.0,
+ output float TransparentDepth = 0.0)
{
IsCameraRay = raytype("camera");
IsShadowRay = raytype("shadow");
@@ -42,5 +43,9 @@ shader node_light_path(
int ray_depth;
getattribute("path:ray_depth", ray_depth);
RayDepth = (float)ray_depth;
+
+ int transparent_depth;
+ getattribute("path:transparent_depth", transparent_depth);
+ TransparentDepth = (float)transparent_depth;
}
diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index 066e5f8dbe1..abb6a359e75 100644
--- a/intern/cycles/kernel/shaders/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -93,6 +93,8 @@ shader node_math(
Value = Value1 > Value2;
else if (type == "Modulo")
Value = safe_modulo(Value1, Value2);
+ else if (type == "Absolute")
+ Value = fabs(Value1);
if (Clamp)
Value = clamp(Value, 0.0, 1.0);
diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index c2c397c6446..dd54fd814de 100644
--- a/intern/cycles/kernel/shaders/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -88,7 +88,7 @@ color node_mix_diff(float t, color col1, color col2)
color node_mix_dark(float t, color col1, color col2)
{
- return min(col1, col2 * t);
+ return min(col1, col2) * t + col1 * (1.0 - t);
}
color node_mix_light(float t, color col1, color col2)
diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
index f87b3a5dd86..4a32415b482 100644
--- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -25,7 +25,7 @@ shader node_refraction_bsdf(
output closure color BSDF = 0)
{
float f = max(IOR, 1e-5);
- float eta = backfacing() ? 1.0 / f: f;
+ float eta = backfacing() ? 1.0 / f : f;
if (distribution == "Sharp")
BSDF = Color * refraction(Normal, eta);
diff --git a/intern/cycles/kernel/shaders/node_scatter_volume.osl b/intern/cycles/kernel/shaders/node_scatter_volume.osl
index bf23abbf933..77c157bd92b 100644
--- a/intern/cycles/kernel/shaders/node_scatter_volume.osl
+++ b/intern/cycles/kernel/shaders/node_scatter_volume.osl
@@ -22,6 +22,6 @@ shader node_scatter_volume(
float Anisotropy = 0.0,
output closure color Volume = 0)
{
- Volume = (Color * Density) * henyey_greenstein(Anisotropy);
+ Volume = (Color * max(Density, 0.0)) * henyey_greenstein(Anisotropy);
}
diff --git a/intern/cycles/kernel/shaders/node_uv_map.osl b/intern/cycles/kernel/shaders/node_uv_map.osl
new file mode 100644
index 00000000000..01c984aff4c
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_uv_map.osl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011-2013 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 "stdosl.h"
+
+shader node_uv_map(
+ int from_dupli = 0,
+ string name = "",
+ string bump_offset = "center",
+ output point UV = point(0.0, 0.0, 0.0))
+{
+ if (from_dupli) {
+ getattribute("geom:dupli_uv", UV);
+ }
+ else {
+ if (name == "")
+ getattribute("geom:uv", UV);
+ else
+ getattribute(name, UV);
+ }
+
+ if (bump_offset == "dx") {
+ if (!from_dupli) {
+ UV += Dx(UV);
+ }
+ }
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ UV += Dy(UV);
+ }
+ }
+}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 96c7cefbcb2..dbf59c60cb0 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -182,10 +182,9 @@ CCL_NAMESPACE_BEGIN
/* Main Interpreter Loop */
-ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, float randb, int path_flag)
+ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, int path_flag)
{
float stack[SVM_STACK_SIZE];
- float closure_weight = 1.0f;
int offset = sd->shader & SHADER_MASK;
while(1) {
@@ -200,7 +199,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
break;
}
case NODE_CLOSURE_BSDF:
- svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag, &offset);
+ svm_node_closure_bsdf(kg, sd, stack, node, path_flag, &offset);
break;
case NODE_CLOSURE_EMISSION:
svm_node_closure_emission(sd, stack, node);
@@ -227,13 +226,15 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
svm_node_emission_weight(kg, sd, stack, node);
break;
case NODE_MIX_CLOSURE:
- svm_node_mix_closure(sd, stack, node, &offset, &randb);
+ svm_node_mix_closure(sd, stack, node);
break;
- case NODE_ADD_CLOSURE:
- svm_node_add_closure(sd, stack, node.y, node.z, &offset, &randb, &closure_weight);
+ case NODE_JUMP_IF_ZERO:
+ if(stack_load_float(stack, node.z) == 0.0f)
+ offset += node.y;
break;
- case NODE_JUMP:
- offset = node.y;
+ case NODE_JUMP_IF_ONE:
+ if(stack_load_float(stack, node.z) == 1.0f)
+ offset += node.y;
break;
#ifdef __IMAGE_TEXTURES__
case NODE_TEX_IMAGE:
@@ -437,9 +438,6 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
#endif
case NODE_END:
default:
-#ifndef __MULTI_CLOSURE__
- sd->closure.weight *= closure_weight;
-#endif
return;
}
}
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index 4c53bfd74fa..fd0ea7fef31 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -22,12 +22,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
uint4 node, NodeAttributeType *type,
NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset)
{
- if(sd->object != ~0 && sd->prim != ~0) {
+ if(sd->object != OBJECT_NONE) {
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
#ifdef __HAIR__
- attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+ attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
#endif
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 2813e38d8f7..a3770877544 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -51,7 +51,6 @@ ccl_device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type
ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight)
{
-#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
if(sd->num_closure < MAX_CLOSURE) {
@@ -65,14 +64,10 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, C
}
return NULL;
-#else
- return &sd->closure;
-#endif
}
ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight)
{
-#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight * mix_weight;
float sample_weight = fabsf(average(weight));
@@ -88,14 +83,10 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float
}
return NULL;
-#else
- return &sd->closure;
-#endif
}
ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd, float mix_weight)
{
-#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = (make_float3(1.0f, 1.0f, 1.0f) - sc->weight) * mix_weight;
float sample_weight = fabsf(average(weight));
@@ -111,16 +102,12 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd,
}
return NULL;
-#else
- return &sd->closure;
-#endif
}
-ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset)
+ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int *offset)
{
uint type, param1_offset, param2_offset;
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset;
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
@@ -132,13 +119,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
return;
float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
-#else
- decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
- float mix_weight = 1.0f;
-
- uint4 data_node = read_node(kg, offset);
- float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
-#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
@@ -255,7 +235,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float roughness = param1;
-#ifdef __MULTI_CLOSURE__
/* reflection */
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight;
@@ -279,15 +258,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->N = N;
svm_node_glass_setup(sd, sc, type, eta, roughness, true);
}
-#else
- ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
-
- if(sc) {
- sc->N = N;
- bool refract = (randb > fresnel);
- svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
- }
-#endif
break;
}
@@ -364,10 +334,16 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
- if(sd->flag & SD_BACKFACING && sd->segment != ~0) {
+ if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
if(sc) {
- sc->weight = make_float3(1.0f,1.0f,1.0f);
+ /* todo: giving a fixed weight here will cause issues when
+ * mixing multiple BSDFS. energey will not be conserved and
+ * the throughput can blow up after multiple bounces. we
+ * better figure out a way to skip backfaces from rays
+ * spawned by transmission from the front */
+ sc->weight = make_float3(1.0f, 1.0f, 1.0f);
sc->N = N;
sd->flag |= bsdf_transparent_setup(sc);
}
@@ -381,12 +357,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->data0 = param1;
sc->data1 = param2;
sc->offset = -stack_load_float(stack, data_node.z);
- if(sd->segment == ~0) {
+
+ if(!(sd->type & PRIMITIVE_ALL_CURVE)) {
sc->T = normalize(sd->dPdv);
sc->offset = 0.0f;
}
else
sc->T = sd->dPdu;
+
if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
sd->flag |= bsdf_hair_reflection_setup(sc);
}
@@ -484,21 +462,16 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
#ifdef __VOLUME__
uint type, param1_offset, param2_offset;
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset;
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
if(mix_weight == 0.0f)
return;
-#else
- decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
- float mix_weight = 1.0f;
-#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
- float density = param1;
+ float density = fmaxf(param1, 0.0f);
switch(type) {
case CLOSURE_VOLUME_ABSORPTION_ID: {
@@ -527,7 +500,6 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
{
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@@ -540,17 +512,12 @@ ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 no
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f);
-#else
- ShaderClosure *sc = &sd->closure;
- sc->type = CLOSURE_EMISSION_ID;
-#endif
sd->flag |= SD_EMISSION;
}
ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
{
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@@ -563,15 +530,10 @@ ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f);
-#else
- ShaderClosure *sc = &sd->closure;
- sc->type = CLOSURE_BACKGROUND_ID;
-#endif
}
ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
{
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@@ -584,17 +546,12 @@ ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 nod
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f);
-#else
- ShaderClosure *sc = &sd->closure;
- sc->type = CLOSURE_HOLDOUT_ID;
-#endif
sd->flag |= SD_HOLDOUT;
}
ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
{
-#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@@ -607,10 +564,6 @@ ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack,
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f);
-#else
- ShaderClosure *sc = &sd->closure;
- sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
-#endif
sd->flag |= SD_AO;
}
@@ -619,12 +572,8 @@ ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack,
ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
{
-#ifdef __MULTI_CLOSURE__
if(sd->num_closure < MAX_CLOSURE)
sd->closure[sd->num_closure].weight = weight;
-#else
- sd->closure.weight = weight;
-#endif
}
ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
@@ -637,7 +586,7 @@ ccl_device void svm_node_emission_set_weight_total(KernelGlobals *kg, ShaderData
{
float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
weight /= object_surface_area(kg, sd->object);
svm_node_closure_store_weight(sd, weight);
@@ -659,16 +608,14 @@ ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, floa
float strength = stack_load_float(stack, strength_offset);
float3 weight = stack_load_float3(stack, color_offset)*strength;
- if(total_power && sd->object != ~0)
+ if(total_power && sd->object != OBJECT_NONE)
weight /= object_surface_area(kg, sd->object);
svm_node_closure_store_weight(sd, weight);
}
-ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack,
- uint4 node, int *offset, float *randb)
+ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
{
-#ifdef __MULTI_CLOSURE__
/* fetch weight from blend input, previous mix closures,
* and write to stack to be used by closure nodes later */
uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
@@ -683,44 +630,6 @@ ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack,
stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
if(stack_valid(weight2_offset))
stack_store_float(stack, weight2_offset, in_weight*weight);
-#else
- /* pick a closure and make the random number uniform over 0..1 again.
- * closure 1 starts on the next node, for closure 2 the start is at an
- * offset from the current node, so we jump */
- uint weight_offset = node.y;
- uint node_jump = node.z;
- float weight = stack_load_float(stack, weight_offset);
- weight = clamp(weight, 0.0f, 1.0f);
-
- if(*randb < weight) {
- *offset += node_jump;
- *randb = *randb/weight;
- }
- else
- *randb = (*randb - weight)/(1.0f - weight);
-#endif
-}
-
-ccl_device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
- uint node_jump, int *offset, float *randb, float *closure_weight)
-{
-#ifdef __MULTI_CLOSURE__
- /* nothing to do, handled in compiler */
-#else
- /* pick one of the two closures with probability 0.5. sampling quality
- * is not going to be great, for that we'd need to evaluate the weights
- * of the two closures being added */
- float weight = 0.5f;
-
- if(*randb < weight) {
- *offset += node_jump;
- *randb = *randb/weight;
- }
- else
- *randb = (*randb - weight)/(1.0f - weight);
-
- *closure_weight *= 2.0f;
-#endif
}
/* (Bump) normal */
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index ad0cacb027a..fe681ec92af 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -98,44 +98,44 @@ ccl_device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float
{
switch(type) {
case NODE_INFO_PAR_INDEX: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_index(kg, particle_id));
break;
}
case NODE_INFO_PAR_AGE: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_age(kg, particle_id));
break;
}
case NODE_INFO_PAR_LIFETIME: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
break;
}
case NODE_INFO_PAR_LOCATION: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
break;
}
- #if 0 /* XXX float4 currently not supported in SVM stack */
+#if 0 /* XXX float4 currently not supported in SVM stack */
case NODE_INFO_PAR_ROTATION: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
break;
}
- #endif
+#endif
case NODE_INFO_PAR_SIZE: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_size(kg, particle_id));
break;
}
case NODE_INFO_PAR_VELOCITY: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
break;
}
case NODE_INFO_PAR_ANGULAR_VELOCITY: {
- uint particle_id = object_particle_id(kg, sd->object);
+ int particle_id = object_particle_id(kg, sd->object);
stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
break;
}
@@ -153,7 +153,7 @@ ccl_device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *sta
switch(type) {
case NODE_INFO_CURVE_IS_STRAND: {
- data = (sd->segment != ~0);
+ data = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
stack_store_float(stack, out_offset, data);
break;
}
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index bc76ea1e662..daf7c6652d2 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -60,31 +60,51 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
uint width = info.x;
uint height = info.y;
uint offset = info.z;
- uint periodic = info.w;
+ uint periodic = (info.w & 0x1);
+ uint interpolation = info.w >> 1;
+ float4 r;
int ix, iy, nix, niy;
- float tx = svm_image_texture_frac(x*width, &ix);
- float ty = svm_image_texture_frac(y*height, &iy);
+ if (interpolation == INTERPOLATION_CLOSEST) {
+ svm_image_texture_frac(x*width, &ix);
+ svm_image_texture_frac(y*height, &iy);
- if(periodic) {
- ix = svm_image_texture_wrap_periodic(ix, width);
- iy = svm_image_texture_wrap_periodic(iy, height);
+ if(periodic) {
+ ix = svm_image_texture_wrap_periodic(ix, width);
+ iy = svm_image_texture_wrap_periodic(iy, height);
+ }
+ else {
+ ix = svm_image_texture_wrap_clamp(ix, width);
+ iy = svm_image_texture_wrap_clamp(iy, height);
- nix = svm_image_texture_wrap_periodic(ix+1, width);
- niy = svm_image_texture_wrap_periodic(iy+1, height);
+ }
+ r = svm_image_texture_read(kg, offset + ix + iy*width);
}
- else {
- ix = svm_image_texture_wrap_clamp(ix, width);
- iy = svm_image_texture_wrap_clamp(iy, height);
+ else { /* We default to linear interpolation if it is not closest */
+ float tx = svm_image_texture_frac(x*width, &ix);
+ float ty = svm_image_texture_frac(y*height, &iy);
- nix = svm_image_texture_wrap_clamp(ix+1, width);
- niy = svm_image_texture_wrap_clamp(iy+1, height);
- }
+ if(periodic) {
+ ix = svm_image_texture_wrap_periodic(ix, width);
+ iy = svm_image_texture_wrap_periodic(iy, height);
- float4 r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + iy*width);
- r += (1.0f - ty)*tx*svm_image_texture_read(kg, offset + nix + iy*width);
- r += ty*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + niy*width);
- r += ty*tx*svm_image_texture_read(kg, offset + nix + niy*width);
+ nix = svm_image_texture_wrap_periodic(ix+1, width);
+ niy = svm_image_texture_wrap_periodic(iy+1, height);
+ }
+ else {
+ ix = svm_image_texture_wrap_clamp(ix, width);
+ iy = svm_image_texture_wrap_clamp(iy, height);
+
+ nix = svm_image_texture_wrap_clamp(ix+1, width);
+ niy = svm_image_texture_wrap_clamp(iy+1, height);
+ }
+
+
+ r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + iy*width);
+ r += (1.0f - ty)*tx*svm_image_texture_read(kg, offset + nix + iy*width);
+ r += ty*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + niy*width);
+ r += ty*tx*svm_image_texture_read(kg, offset + nix + niy*width);
+ }
if(use_alpha && r.w != 1.0f && r.w != 0.0f) {
float invw = 1.0f/r.w;
@@ -129,8 +149,8 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
* - group by size and use a 3d texture, performance impact
* - group into larger texture with some padding for correct lerp
*
- * also note that cuda has 128 textures limit, we use 100 now, since
- * we still need some for other storage */
+ * also note that cuda has a textures limit (128 for Fermi, 256 for Kepler),
+ * and we cannot use all since we still need some for other storage */
switch(id) {
case 0: r = kernel_tex_image_interp(__tex_image_float_000, x, y); break;
@@ -233,7 +253,62 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
case 97: r = kernel_tex_image_interp(__tex_image_097, x, y); break;
case 98: r = kernel_tex_image_interp(__tex_image_098, x, y); break;
case 99: r = kernel_tex_image_interp(__tex_image_099, x, y); break;
- default:
+
+#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 300)
+ case 100: r = kernel_tex_image_interp(__tex_image_100, x, y); break;
+ case 101: r = kernel_tex_image_interp(__tex_image_101, x, y); break;
+ case 102: r = kernel_tex_image_interp(__tex_image_102, x, y); break;
+ case 103: r = kernel_tex_image_interp(__tex_image_103, x, y); break;
+ case 104: r = kernel_tex_image_interp(__tex_image_104, x, y); break;
+ case 105: r = kernel_tex_image_interp(__tex_image_105, x, y); break;
+ case 106: r = kernel_tex_image_interp(__tex_image_106, x, y); break;
+ case 107: r = kernel_tex_image_interp(__tex_image_107, x, y); break;
+ case 108: r = kernel_tex_image_interp(__tex_image_108, x, y); break;
+ case 109: r = kernel_tex_image_interp(__tex_image_109, x, y); break;
+ case 110: r = kernel_tex_image_interp(__tex_image_110, x, y); break;
+ case 111: r = kernel_tex_image_interp(__tex_image_111, x, y); break;
+ case 112: r = kernel_tex_image_interp(__tex_image_112, x, y); break;
+ case 113: r = kernel_tex_image_interp(__tex_image_113, x, y); break;
+ case 114: r = kernel_tex_image_interp(__tex_image_114, x, y); break;
+ case 115: r = kernel_tex_image_interp(__tex_image_115, x, y); break;
+ case 116: r = kernel_tex_image_interp(__tex_image_116, x, y); break;
+ case 117: r = kernel_tex_image_interp(__tex_image_117, x, y); break;
+ case 118: r = kernel_tex_image_interp(__tex_image_118, x, y); break;
+ case 119: r = kernel_tex_image_interp(__tex_image_119, x, y); break;
+ case 120: r = kernel_tex_image_interp(__tex_image_120, x, y); break;
+ case 121: r = kernel_tex_image_interp(__tex_image_121, x, y); break;
+ case 122: r = kernel_tex_image_interp(__tex_image_122, x, y); break;
+ case 123: r = kernel_tex_image_interp(__tex_image_123, x, y); break;
+ case 124: r = kernel_tex_image_interp(__tex_image_124, x, y); break;
+ case 125: r = kernel_tex_image_interp(__tex_image_125, x, y); break;
+ case 126: r = kernel_tex_image_interp(__tex_image_126, x, y); break;
+ case 127: r = kernel_tex_image_interp(__tex_image_127, x, y); break;
+ case 128: r = kernel_tex_image_interp(__tex_image_128, x, y); break;
+ case 129: r = kernel_tex_image_interp(__tex_image_129, x, y); break;
+ case 130: r = kernel_tex_image_interp(__tex_image_130, x, y); break;
+ case 131: r = kernel_tex_image_interp(__tex_image_131, x, y); break;
+ case 132: r = kernel_tex_image_interp(__tex_image_132, x, y); break;
+ case 133: r = kernel_tex_image_interp(__tex_image_133, x, y); break;
+ case 134: r = kernel_tex_image_interp(__tex_image_134, x, y); break;
+ case 135: r = kernel_tex_image_interp(__tex_image_135, x, y); break;
+ case 136: r = kernel_tex_image_interp(__tex_image_136, x, y); break;
+ case 137: r = kernel_tex_image_interp(__tex_image_137, x, y); break;
+ case 138: r = kernel_tex_image_interp(__tex_image_138, x, y); break;
+ case 139: r = kernel_tex_image_interp(__tex_image_139, x, y); break;
+ case 140: r = kernel_tex_image_interp(__tex_image_140, x, y); break;
+ case 141: r = kernel_tex_image_interp(__tex_image_141, x, y); break;
+ case 142: r = kernel_tex_image_interp(__tex_image_142, x, y); break;
+ case 143: r = kernel_tex_image_interp(__tex_image_143, x, y); break;
+ case 144: r = kernel_tex_image_interp(__tex_image_144, x, y); break;
+ case 145: r = kernel_tex_image_interp(__tex_image_145, x, y); break;
+ case 146: r = kernel_tex_image_interp(__tex_image_146, x, y); break;
+ case 147: r = kernel_tex_image_interp(__tex_image_147, x, y); break;
+ case 148: r = kernel_tex_image_interp(__tex_image_148, x, y); break;
+ case 149: r = kernel_tex_image_interp(__tex_image_149, x, y); break;
+ case 150: r = kernel_tex_image_interp(__tex_image_150, x, y); break;
+#endif
+
+ default:
kernel_assert(0);
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
@@ -302,7 +377,7 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
float3 N = sd->N;
N = sd->N;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_normal_transform(kg, sd, &N);
/* project from direction vector to barycentric coordinates in triangles */
diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h
index 8968146c5e2..da544c63ae0 100644
--- a/intern/cycles/kernel/svm/svm_light_path.h
+++ b/intern/cycles/kernel/svm/svm_light_path.h
@@ -34,6 +34,7 @@ ccl_device void svm_node_light_path(ShaderData *sd, float *stack, uint type, uin
case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break;
case NODE_LP_ray_length: info = sd->ray_length; break;
case NODE_LP_ray_depth: info = (float)sd->ray_depth; break;
+ case NODE_LP_ray_transparent: info = sd->transparent_depth; break;
}
stack_store_float(stack, out_offset, info);
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index bb46d443a6b..1ce9386e40e 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -56,6 +56,8 @@ ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
Fac = Fac1 > Fac2;
else if(type == NODE_MATH_MODULO)
Fac = safe_modulo(Fac1, Fac2);
+ else if(type == NODE_MATH_ABSOLUTE)
+ Fac = fabsf(Fac1);
else if(type == NODE_MATH_CLAMP)
Fac = clamp(Fac1, 0.0f, 1.0f);
else
diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h
index 4e834b7c500..edc3903865e 100644
--- a/intern/cycles/kernel/svm/svm_mix.h
+++ b/intern/cycles/kernel/svm/svm_mix.h
@@ -89,7 +89,7 @@ ccl_device float3 svm_mix_diff(float t, float3 col1, float3 col2)
ccl_device float3 svm_mix_dark(float t, float3 col1, float3 col2)
{
- return min(col1, col2*t);
+ return min(col1, col2)*t + col1*(1.0f - t);
}
ccl_device float3 svm_mix_light(float t, float3 col1, float3 col2)
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 282ad191470..91dda8972f9 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -357,15 +357,13 @@ ccl_device float3 cellnoise_color(float3 p)
return make_float3(r, g, b);
}
#else
-ccl_device float3 cellnoise_color(const float3& p)
+ccl_device __m128 cellnoise_color(const __m128& p)
{
- __m128i v_yxz = quick_floor_sse(_mm_setr_ps(p.y, p.x, p.z, 0.0f));
- __m128i v_xyy = shuffle<1, 0, 0, 3>(v_yxz);
- __m128i v_zzx = shuffle<2, 2, 1, 3>(v_yxz);
- __m128 rgb = bits_to_01_sse(hash_sse(v_xyy, v_yxz, v_zzx));
-
- float3 result = *(float3*)&rgb;
- return result;
+ __m128i ip = quick_floor_sse(p);
+ __m128i ip_yxz = shuffle<1, 0, 2, 3>(ip);
+ __m128i ip_xyy = shuffle<0, 1, 1, 3>(ip);
+ __m128i ip_zzx = shuffle<2, 2, 0, 3>(ip);
+ return bits_to_01_sse(hash_sse(ip_xyy, ip_yxz, ip_zzx));
}
#endif
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
index 0f68ecbea03..111d5d47988 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
@@ -42,12 +42,12 @@ ccl_device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *
/* Convert to HSV */
color = rgb_to_hsv(color);
- if (stack_valid(hue_out))
- stack_store_float(stack, hue_out, color.x);
- if (stack_valid(saturation_out))
- stack_store_float(stack, saturation_out, color.y);
- if (stack_valid(value_out))
- stack_store_float(stack, value_out, color.z);
+ if (stack_valid(hue_out))
+ stack_store_float(stack, hue_out, color.x);
+ if (stack_valid(saturation_out))
+ stack_store_float(stack, saturation_out, color.y);
+ if (stack_valid(value_out))
+ stack_store_float(stack, value_out, color.z);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index 1e3552647bd..500b5146931 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -74,7 +74,7 @@ ccl_device float sky_radiance_internal(float *configuration, float theta, float
float expM = expf(configuration[4] * gamma);
float rayM = cgamma * cgamma;
float mieM = (1.0f + rayM) / powf((1.0f + configuration[8]*configuration[8] - 2.0f*configuration[8]*cgamma), 1.5f);
- float zenith = sqrt(ctheta);
+ float zenith = sqrtf(ctheta);
return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) *
(configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith);
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 4b1f30e55bb..a17e4a25efe 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -25,27 +25,27 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_position_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_NORMAL: {
data = sd->N;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_normal_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_CAMERA: {
Transform tfm = kernel_data.cam.worldtocamera;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = transform_point(&tfm, sd->P);
else
data = transform_point(&tfm, sd->P + camera_position(kg));
break;
}
case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
data = camera_world_to_ndc(kg, sd, sd->ray_P);
else
data = camera_world_to_ndc(kg, sd, sd->P);
@@ -53,7 +53,7 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
break;
}
case NODE_TEXCO_REFLECTION: {
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
else
data = sd->I;
@@ -70,17 +70,10 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P;
- if(sd->object != ~0) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
@@ -96,27 +89,27 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P + sd->dP.dx;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_position_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_NORMAL: {
data = sd->N;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_normal_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_CAMERA: {
Transform tfm = kernel_data.cam.worldtocamera;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = transform_point(&tfm, sd->P + sd->dP.dx);
else
data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg));
break;
}
case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx);
else
data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
@@ -124,7 +117,7 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
break;
}
case NODE_TEXCO_REFLECTION: {
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
else
data = sd->I;
@@ -141,17 +134,10 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P + sd->dP.dx;
- if(sd->object != ~0) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
@@ -170,27 +156,27 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P + sd->dP.dy;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_position_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_NORMAL: {
data = sd->N;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
object_inverse_normal_transform(kg, sd, &data);
break;
}
case NODE_TEXCO_CAMERA: {
Transform tfm = kernel_data.cam.worldtocamera;
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = transform_point(&tfm, sd->P + sd->dP.dy);
else
data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg));
break;
}
case NODE_TEXCO_WINDOW: {
- if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
+ if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy);
else
data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
@@ -198,7 +184,7 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
break;
}
case NODE_TEXCO_REFLECTION: {
- if(sd->object != ~0)
+ if(sd->object != OBJECT_NONE)
data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
else
data = sd->I;
@@ -215,17 +201,10 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P + sd->dP.dy;
- if(sd->object != ~0) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
@@ -248,7 +227,7 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st
if(space == NODE_NORMAL_MAP_TANGENT) {
/* tangent space */
- if(sd->object == ~0) {
+ if(sd->object == OBJECT_NONE) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
return;
}
diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h
index 8ced8390b0b..5fd9204cbf6 100644
--- a/intern/cycles/kernel/svm/svm_texture.h
+++ b/intern/cycles/kernel/svm/svm_texture.h
@@ -18,6 +18,7 @@ CCL_NAMESPACE_BEGIN
/* Voronoi Distances */
+#if 0
ccl_device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, float e)
{
#if 0
@@ -43,8 +44,7 @@ ccl_device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d,
}
/* Voronoi / Worley like */
-
-ccl_device_noinline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
+ccl_device_inline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
{
float da[4];
float3 pa[4];
@@ -119,7 +119,95 @@ ccl_device_noinline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
return result;
}
+#endif
+
+ccl_device float voronoi_F1_distance(float3 p)
+{
+ /* returns squared distance in da */
+ float da = 1e10f;
+
+#ifndef __KERNEL_SSE2__
+ int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z);
+
+ for (int xx = -1; xx <= 1; xx++) {
+ for (int yy = -1; yy <= 1; yy++) {
+ for (int zz = -1; zz <= 1; zz++) {
+ float3 ip = make_float3(ix + xx, iy + yy, iz + zz);
+ float3 vp = ip + cellnoise_color(ip);
+ float d = len_squared(p - vp);
+ da = min(d, da);
+ }
+ }
+ }
+#else
+ __m128 vec_p = load_m128(p);
+ __m128i xyzi = quick_floor_sse(vec_p);
+
+ for (int xx = -1; xx <= 1; xx++) {
+ for (int yy = -1; yy <= 1; yy++) {
+ for (int zz = -1; zz <= 1; zz++) {
+ __m128 ip = _mm_cvtepi32_ps(_mm_add_epi32(xyzi, _mm_setr_epi32(xx, yy, zz, 0)));
+ __m128 vp = _mm_add_ps(ip, cellnoise_color(ip));
+ float d = len_squared<1, 1, 1, 0>(_mm_sub_ps(vec_p, vp));
+ da = min(d, da);
+ }
+ }
+ }
+#endif
+
+ return da;
+}
+
+ccl_device float3 voronoi_F1_color(float3 p)
+{
+ /* returns color of the nearest point */
+ float da = 1e10f;
+
+#ifndef __KERNEL_SSE2__
+ float3 pa;
+ int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z);
+
+ for (int xx = -1; xx <= 1; xx++) {
+ for (int yy = -1; yy <= 1; yy++) {
+ for (int zz = -1; zz <= 1; zz++) {
+ float3 ip = make_float3(ix + xx, iy + yy, iz + zz);
+ float3 vp = ip + cellnoise_color(ip);
+ float d = len_squared(p - vp);
+
+ if(d < da) {
+ da = d;
+ pa = vp;
+ }
+ }
+ }
+ }
+
+ return cellnoise_color(pa);
+#else
+ __m128 pa, vec_p = load_m128(p);
+ __m128i xyzi = quick_floor_sse(vec_p);
+
+ for (int xx = -1; xx <= 1; xx++) {
+ for (int yy = -1; yy <= 1; yy++) {
+ for (int zz = -1; zz <= 1; zz++) {
+ __m128 ip = _mm_cvtepi32_ps(_mm_add_epi32(xyzi, _mm_setr_epi32(xx, yy, zz, 0)));
+ __m128 vp = _mm_add_ps(ip, cellnoise_color(ip));
+ float d = len_squared<1, 1, 1, 0>(_mm_sub_ps(vec_p, vp));
+
+ if(d < da) {
+ da = d;
+ pa = vp;
+ }
+ }
+ }
+ }
+
+ __m128 color = cellnoise_color(pa);
+ return (float3 &)color;
+#endif
+}
+#if 0
ccl_device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; }
ccl_device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; }
ccl_device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; }
@@ -139,6 +227,7 @@ ccl_device float voronoi_F3S(float3 p) { return 2.0f*voronoi_F3(p) - 1.0f; }
ccl_device float voronoi_F4S(float3 p) { return 2.0f*voronoi_F4(p) - 1.0f; }
ccl_device float voronoi_F1F2S(float3 p) { return 2.0f*voronoi_F1F2(p) - 1.0f; }
ccl_device float voronoi_CrS(float3 p) { return 2.0f*voronoi_Cr(p) - 1.0f; }
+#endif
/* Noise Bases */
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index ad5e1ea6d2e..80972ec82bc 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -36,7 +36,8 @@ typedef enum NodeType {
NODE_CLOSURE_SET_WEIGHT,
NODE_CLOSURE_WEIGHT,
NODE_MIX_CLOSURE,
- NODE_JUMP,
+ NODE_JUMP_IF_ZERO,
+ NODE_JUMP_IF_ONE,
NODE_TEX_IMAGE,
NODE_TEX_IMAGE_BOX,
NODE_TEX_SKY,
@@ -71,7 +72,6 @@ typedef enum NodeType {
NODE_TEX_COORD,
NODE_TEX_COORD_BUMP_DX,
NODE_TEX_COORD_BUMP_DY,
- NODE_ADD_CLOSURE,
NODE_EMISSION_SET_WEIGHT_TOTAL,
NODE_ATTR_BUMP_DX,
NODE_ATTR_BUMP_DY,
@@ -102,7 +102,8 @@ typedef enum NodeType {
NODE_CLOSURE_AMBIENT_OCCLUSION,
NODE_TANGENT,
NODE_NORMAL_MAP,
- NODE_HAIR_INFO
+ NODE_HAIR_INFO,
+ NODE_UVMAP
} NodeType;
typedef enum NodeAttributeType {
@@ -158,7 +159,8 @@ typedef enum NodeLightPath {
NODE_LP_volume_scatter,
NODE_LP_backfacing,
NODE_LP_ray_length,
- NODE_LP_ray_depth
+ NODE_LP_ray_depth,
+ NODE_LP_ray_transparent
} NodeLightPath;
typedef enum NodeLightFalloff {
@@ -219,6 +221,7 @@ typedef enum NodeMath {
NODE_MATH_LESS_THAN,
NODE_MATH_GREATER_THAN,
NODE_MATH_MODULO,
+ NODE_MATH_ABSOLUTE,
NODE_MATH_CLAMP /* used for the clamp UI option */
} NodeMath;
@@ -401,6 +404,8 @@ typedef enum ClosureType {
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
+#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type == CLOSURE_BSDF_WARD_ID)
+#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h
index 1e3fc2fa03b..61d33aeb8cf 100644
--- a/intern/cycles/kernel/svm/svm_vector_transform.h
+++ b/intern/cycles/kernel/svm/svm_vector_transform.h
@@ -33,7 +33,7 @@ ccl_device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, flo
NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito;
Transform tfm;
- bool is_object = (sd->object != ~0);
+ bool is_object = (sd->object != OBJECT_NONE);
bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR || type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
/* From world */
@@ -91,9 +91,9 @@ ccl_device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, flo
if(type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL)
in = normalize(in);
- /* Output */
+ /* Output */
if(stack_valid(vector_out)) {
- stack_store_float3(stack, vector_out, in);
+ stack_store_float3(stack, vector_out, in);
}
}
diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h
index 7f597dc8bff..083a2f30e06 100644
--- a/intern/cycles/kernel/svm/svm_voronoi.h
+++ b/intern/cycles/kernel/svm/svm_voronoi.h
@@ -20,23 +20,16 @@ CCL_NAMESPACE_BEGIN
ccl_device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float3 p)
{
- /* compute distance and point coordinate of 4 nearest neighbours */
- float4 dpa0 = voronoi_Fn(p, 1.0f, 0, -1);
-
- /* output */
- float fac;
- float3 color;
-
if(coloring == NODE_VORONOI_INTENSITY) {
- fac = fabsf(dpa0.w);
- color = make_float3(fac, fac, fac);
+ /* compute squared distance to the nearest neighbour */
+ float fac = voronoi_F1_distance(p);
+ return make_float4(fac, fac, fac, fac);
}
else {
- color = cellnoise_color(float4_to_float3(dpa0));
- fac = average(color);
+ /* compute color of the nearest neighbour */
+ float3 color = voronoi_F1_color(p);
+ return make_float4(color.x, color.y, color.z, average(color));
}
-
- return make_float4(color.x, color.y, color.z, fac);
}
ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h
index dca4003b89a..9e57c470c0f 100644
--- a/intern/cycles/kernel/svm/svm_wavelength.h
+++ b/intern/cycles/kernel/svm/svm_wavelength.h
@@ -43,33 +43,33 @@ ccl_device void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelengt
// cie_colour_match[(lambda - 380) / 5][1] = yBar
// cie_colour_match[(lambda - 380) / 5][2] = zBar
const float cie_colour_match[81][3] = {
- {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201},
- {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102},
- {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456},
- {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230},
- {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721},
- {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281},
- {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130},
- {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533},
- {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582},
- {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573},
- {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203},
- {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057},
- {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021},
- {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014},
- {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008},
- {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002},
- {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000},
- {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000},
- {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000},
- {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000},
- {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000},
- {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000},
- {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000},
- {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000},
- {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000},
- {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000},
- {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000}
+ {0.0014f,0.0000f,0.0065f}, {0.0022f,0.0001f,0.0105f}, {0.0042f,0.0001f,0.0201f},
+ {0.0076f,0.0002f,0.0362f}, {0.0143f,0.0004f,0.0679f}, {0.0232f,0.0006f,0.1102f},
+ {0.0435f,0.0012f,0.2074f}, {0.0776f,0.0022f,0.3713f}, {0.1344f,0.0040f,0.6456f},
+ {0.2148f,0.0073f,1.0391f}, {0.2839f,0.0116f,1.3856f}, {0.3285f,0.0168f,1.6230f},
+ {0.3483f,0.0230f,1.7471f}, {0.3481f,0.0298f,1.7826f}, {0.3362f,0.0380f,1.7721f},
+ {0.3187f,0.0480f,1.7441f}, {0.2908f,0.0600f,1.6692f}, {0.2511f,0.0739f,1.5281f},
+ {0.1954f,0.0910f,1.2876f}, {0.1421f,0.1126f,1.0419f}, {0.0956f,0.1390f,0.8130f},
+ {0.0580f,0.1693f,0.6162f}, {0.0320f,0.2080f,0.4652f}, {0.0147f,0.2586f,0.3533f},
+ {0.0049f,0.3230f,0.2720f}, {0.0024f,0.4073f,0.2123f}, {0.0093f,0.5030f,0.1582f},
+ {0.0291f,0.6082f,0.1117f}, {0.0633f,0.7100f,0.0782f}, {0.1096f,0.7932f,0.0573f},
+ {0.1655f,0.8620f,0.0422f}, {0.2257f,0.9149f,0.0298f}, {0.2904f,0.9540f,0.0203f},
+ {0.3597f,0.9803f,0.0134f}, {0.4334f,0.9950f,0.0087f}, {0.5121f,1.0000f,0.0057f},
+ {0.5945f,0.9950f,0.0039f}, {0.6784f,0.9786f,0.0027f}, {0.7621f,0.9520f,0.0021f},
+ {0.8425f,0.9154f,0.0018f}, {0.9163f,0.8700f,0.0017f}, {0.9786f,0.8163f,0.0014f},
+ {1.0263f,0.7570f,0.0011f}, {1.0567f,0.6949f,0.0010f}, {1.0622f,0.6310f,0.0008f},
+ {1.0456f,0.5668f,0.0006f}, {1.0026f,0.5030f,0.0003f}, {0.9384f,0.4412f,0.0002f},
+ {0.8544f,0.3810f,0.0002f}, {0.7514f,0.3210f,0.0001f}, {0.6424f,0.2650f,0.0000f},
+ {0.5419f,0.2170f,0.0000f}, {0.4479f,0.1750f,0.0000f}, {0.3608f,0.1382f,0.0000f},
+ {0.2835f,0.1070f,0.0000f}, {0.2187f,0.0816f,0.0000f}, {0.1649f,0.0610f,0.0000f},
+ {0.1212f,0.0446f,0.0000f}, {0.0874f,0.0320f,0.0000f}, {0.0636f,0.0232f,0.0000f},
+ {0.0468f,0.0170f,0.0000f}, {0.0329f,0.0119f,0.0000f}, {0.0227f,0.0082f,0.0000f},
+ {0.0158f,0.0057f,0.0000f}, {0.0114f,0.0041f,0.0000f}, {0.0081f,0.0029f,0.0000f},
+ {0.0058f,0.0021f,0.0000f}, {0.0041f,0.0015f,0.0000f}, {0.0029f,0.0010f,0.0000f},
+ {0.0020f,0.0007f,0.0000f}, {0.0014f,0.0005f,0.0000f}, {0.0010f,0.0004f,0.0000f},
+ {0.0007f,0.0002f,0.0000f}, {0.0005f,0.0002f,0.0000f}, {0.0003f,0.0001f,0.0000f},
+ {0.0002f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0001f,0.0000f,0.0000f},
+ {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f}
};
float lambda_nm = stack_load_float(stack, wavelength);
diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h
index e560e6303cc..660e6e2ca47 100644
--- a/intern/cycles/kernel/svm/svm_wireframe.h
+++ b/intern/cycles/kernel/svm/svm_wireframe.h
@@ -45,17 +45,21 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
/* Calculate wireframe */
#ifdef __HAIR__
- if (sd->prim != ~0 && sd->segment == ~0) {
+ if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
#else
- if (sd->prim != ~0) {
+ if (sd->prim != PRIM_NONE)
#endif
+ {
float3 Co[3];
float pixelwidth = 1.0f;
/* Triangles */
- float np = 3;
+ int np = 3;
- triangle_vertices(kg, sd->prim, Co);
+ if(sd->type & PRIMITIVE_TRIANGLE)
+ triangle_vertices(kg, sd->prim, Co);
+ else
+ motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co);
if(!(sd->flag & SD_TRANSFORM_APPLIED)) {
object_position_transform(kg, sd, &Co[0]);
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 7d00ed92164..449c1391980 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -16,6 +16,7 @@ set(INC_SYS
set(SRC
attribute.cpp
background.cpp
+ bake.cpp
blackbody.cpp
buffers.cpp
camera.cpp
@@ -43,6 +44,7 @@ set(SRC
set(SRC_HEADERS
attribute.h
+ bake.h
background.h
blackbody.h
buffers.h
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 61b9cf2f3bc..14805b6f11a 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -14,6 +14,7 @@
* limitations under the License
*/
+#include "image.h"
#include "mesh.h"
#include "attribute.h"
@@ -25,6 +26,17 @@ CCL_NAMESPACE_BEGIN
/* Attribute */
+Attribute::~Attribute()
+{
+ /* for voxel data, we need to remove the image from the image manager */
+ if(element == ATTR_ELEMENT_VOXEL) {
+ VoxelAttribute *voxel_data = data_voxel();
+
+ if(voxel_data)
+ voxel_data->manager->remove_image(voxel_data->slot);
+ }
+}
+
void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
name = name_;
@@ -38,9 +50,14 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix);
}
-void Attribute::reserve(int numverts, int numtris, int numcurves, int numkeys)
+void Attribute::reserve(int numverts, int numtris, int numsteps, int numcurves, int numkeys, bool resize)
{
- buffer.resize(buffer_size(numverts, numtris, numcurves, numkeys), 0);
+ if (resize) {
+ buffer.resize(buffer_size(numverts, numtris, numsteps, numcurves, numkeys), 0);
+ }
+ else {
+ buffer.reserve(buffer_size(numverts, numtris, numsteps, numcurves, numkeys));
+ }
}
void Attribute::add(const float& f)
@@ -70,9 +87,28 @@ void Attribute::add(const Transform& f)
buffer.push_back(data[i]);
}
+void Attribute::add(const VoxelAttribute& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+void Attribute::add(const char *data)
+{
+ size_t size = data_sizeof();
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
size_t Attribute::data_sizeof() const
{
- if(type == TypeDesc::TypeFloat)
+ if(element == ATTR_ELEMENT_VOXEL)
+ return sizeof(VoxelAttribute);
+ else if(type == TypeDesc::TypeFloat)
return sizeof(float);
else if(type == TypeDesc::TypeMatrix)
return sizeof(Transform);
@@ -80,18 +116,22 @@ size_t Attribute::data_sizeof() const
return sizeof(float3);
}
-size_t Attribute::element_size(int numverts, int numtris, int numcurves, int numkeys) const
+size_t Attribute::element_size(int numverts, int numtris, int numsteps, int numcurves, int numkeys) const
{
size_t size;
switch(element) {
case ATTR_ELEMENT_OBJECT:
case ATTR_ELEMENT_MESH:
+ case ATTR_ELEMENT_VOXEL:
size = 1;
break;
case ATTR_ELEMENT_VERTEX:
size = numverts;
break;
+ case ATTR_ELEMENT_VERTEX_MOTION:
+ size = numverts * (numsteps - 1);
+ break;
case ATTR_ELEMENT_FACE:
size = numtris;
break;
@@ -104,6 +144,9 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num
case ATTR_ELEMENT_CURVE_KEY:
size = numkeys;
break;
+ case ATTR_ELEMENT_CURVE_KEY_MOTION:
+ size = numkeys * (numsteps - 1);
+ break;
default:
size = 0;
break;
@@ -112,9 +155,9 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num
return size;
}
-size_t Attribute::buffer_size(int numverts, int numtris, int numcurves, int numkeys) const
+size_t Attribute::buffer_size(int numverts, int numtris, int numsteps, int numcurves, int numkeys) const
{
- return element_size(numverts, numtris, numcurves, numkeys)*data_sizeof();
+ return element_size(numverts, numtris, numsteps, numcurves, numkeys)*data_sizeof();
}
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
@@ -136,40 +179,65 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
const char *Attribute::standard_name(AttributeStandard std)
{
- if(std == ATTR_STD_VERTEX_NORMAL)
- return "N";
- else if(std == ATTR_STD_FACE_NORMAL)
- return "Ng";
- else if(std == ATTR_STD_UV)
- return "uv";
- else if(std == ATTR_STD_GENERATED)
- return "generated";
- else if(std == ATTR_STD_UV_TANGENT)
- return "tangent";
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- return "tangent_sign";
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- return "undeformed";
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- return "undisplaced";
- else if(std == ATTR_STD_MOTION_PRE)
- return "motion_pre";
- else if(std == ATTR_STD_MOTION_POST)
- return "motion_post";
- else if(std == ATTR_STD_PARTICLE)
- return "particle";
- else if(std == ATTR_STD_CURVE_INTERCEPT)
- return "curve_intercept";
- else if(std == ATTR_STD_PTEX_FACE_ID)
- return "ptex_face_id";
- else if(std == ATTR_STD_PTEX_UV)
- return "ptex_uv";
- else if(std == ATTR_STD_GENERATED_TRANSFORM)
- return "generated_transform";
+ switch(std) {
+ case ATTR_STD_VERTEX_NORMAL:
+ return "N";
+ case ATTR_STD_FACE_NORMAL:
+ return "Ng";
+ case ATTR_STD_UV:
+ return "uv";
+ case ATTR_STD_GENERATED:
+ return "generated";
+ case ATTR_STD_GENERATED_TRANSFORM:
+ return "generated_transform";
+ case ATTR_STD_UV_TANGENT:
+ return "tangent";
+ case ATTR_STD_UV_TANGENT_SIGN:
+ return "tangent_sign";
+ case ATTR_STD_POSITION_UNDEFORMED:
+ return "undeformed";
+ case ATTR_STD_POSITION_UNDISPLACED:
+ return "undisplaced";
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ return "motion_P";
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ return "motion_N";
+ case ATTR_STD_PARTICLE:
+ return "particle";
+ case ATTR_STD_CURVE_INTERCEPT:
+ return "curve_intercept";
+ case ATTR_STD_PTEX_FACE_ID:
+ return "ptex_face_id";
+ case ATTR_STD_PTEX_UV:
+ return "ptex_uv";
+ case ATTR_STD_VOLUME_DENSITY:
+ return "density";
+ case ATTR_STD_VOLUME_COLOR:
+ return "color";
+ case ATTR_STD_VOLUME_FLAME:
+ return "flame";
+ case ATTR_STD_VOLUME_HEAT:
+ return "heat";
+ case ATTR_STD_VOLUME_VELOCITY:
+ return "velocity";
+ case ATTR_STD_NOT_FOUND:
+ case ATTR_STD_NONE:
+ case ATTR_STD_NUM:
+ return "";
+ }
return "";
}
+AttributeStandard Attribute::name_standard(const char *name)
+{
+ for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
+ if(strcmp(name, Attribute::standard_name((AttributeStandard)std)) == 0)
+ return (AttributeStandard)std;
+
+ return ATTR_STD_NONE;
+}
+
/* Attribute Set */
AttributeSet::AttributeSet()
@@ -182,7 +250,7 @@ AttributeSet::~AttributeSet()
{
}
-Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element)
+Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element, bool resize)
{
Attribute *attr = find(name);
@@ -202,9 +270,9 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
/* this is weak .. */
if(triangle_mesh)
- attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), triangle_mesh->motion_steps, 0, 0, resize);
if(curve_mesh)
- attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
+ attr->reserve(0, 0, curve_mesh->motion_steps, curve_mesh->curves.size(), curve_mesh->curve_keys.size(), resize);
return attr;
}
@@ -261,10 +329,14 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_GENERATED:
case ATTR_STD_POSITION_UNDEFORMED:
case ATTR_STD_POSITION_UNDISPLACED:
- case ATTR_STD_MOTION_PRE:
- case ATTR_STD_MOTION_POST:
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
break;
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
+ break;
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
+ break;
case ATTR_STD_PTEX_FACE_ID:
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
break;
@@ -274,6 +346,17 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_GENERATED_TRANSFORM:
attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
break;
+ case ATTR_STD_VOLUME_DENSITY:
+ case ATTR_STD_VOLUME_FLAME:
+ case ATTR_STD_VOLUME_HEAT:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
+ break;
+ case ATTR_STD_VOLUME_COLOR:
+ attr = add(name, TypeDesc::TypeColor, ATTR_ELEMENT_VOXEL);
+ break;
+ case ATTR_STD_VOLUME_VELOCITY:
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
+ break;
default:
assert(0);
break;
@@ -285,9 +368,8 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_GENERATED:
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
break;
- case ATTR_STD_MOTION_PRE:
- case ATTR_STD_MOTION_POST:
- attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY_MOTION);
break;
case ATTR_STD_CURVE_INTERCEPT:
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
@@ -343,9 +425,9 @@ void AttributeSet::reserve()
{
foreach(Attribute& attr, attributes) {
if(triangle_mesh)
- attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), triangle_mesh->motion_steps, 0, 0, true);
if(curve_mesh)
- attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
+ attr.reserve(0, 0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size(), true);
}
}
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index 0b8905ae5a3..9fc32db8444 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -27,12 +27,20 @@
CCL_NAMESPACE_BEGIN
class Attribute;
-class AttributeSet;
class AttributeRequest;
class AttributeRequestSet;
+class AttributeSet;
+class ImageManager;
class Mesh;
struct Transform;
+/* Attributes for voxels are images */
+
+struct VoxelAttribute {
+ ImageManager *manager;
+ int slot;
+};
+
/* Attribute
*
* Arbitrary data layers on meshes.
@@ -48,29 +56,37 @@ public:
AttributeElement element;
Attribute() {}
+ ~Attribute();
void set(ustring name, TypeDesc type, AttributeElement element);
- void reserve(int numverts, int numfaces, int numcurves, int numkeys);
+ void reserve(int numverts, int numfaces, int numsteps, int numcurves, int numkeys, bool resize);
size_t data_sizeof() const;
- size_t element_size(int numverts, int numfaces, int numcurves, int numkeys) const;
- size_t buffer_size(int numverts, int numfaces, int numcurves, int numkeys) const;
+ size_t element_size(int numverts, int numfaces, int numsteps, int numcurves, int numkeys) const;
+ size_t buffer_size(int numverts, int numfaces, int numsteps, int numcurves, int numkeys) const;
char *data() { return (buffer.size())? &buffer[0]: NULL; };
float3 *data_float3() { return (float3*)data(); }
+ float4 *data_float4() { return (float4*)data(); }
float *data_float() { return (float*)data(); }
Transform *data_transform() { return (Transform*)data(); }
+ VoxelAttribute *data_voxel() { return ( VoxelAttribute*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
const float3 *data_float3() const { return (const float3*)data(); }
+ const float4 *data_float4() const { return (const float4*)data(); }
const float *data_float() const { return (const float*)data(); }
const Transform *data_transform() const { return (const Transform*)data(); }
+ const VoxelAttribute *data_voxel() const { return (const VoxelAttribute*)data(); }
void add(const float& f);
void add(const float3& f);
void add(const Transform& f);
+ void add(const VoxelAttribute& f);
+ void add(const char *data);
static bool same_storage(TypeDesc a, TypeDesc b);
static const char *standard_name(AttributeStandard std);
+ static AttributeStandard name_standard(const char *name);
};
/* Attribute Set
@@ -86,7 +102,7 @@ public:
AttributeSet();
~AttributeSet();
- Attribute *add(ustring name, TypeDesc type, AttributeElement element);
+ Attribute *add(ustring name, TypeDesc type, AttributeElement element, bool resize = true);
Attribute *find(ustring name) const;
void remove(ustring name);
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index c9c66dad3fe..a877c52fbed 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -35,7 +35,7 @@ Background::Background()
use = true;
- visibility = ~0;
+ visibility = PATH_RAY_ALL_VISIBILITY;
shader = 0;
transparent = false;
@@ -70,7 +70,7 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
if(scene->shaders[shader]->has_volume)
kbackground->volume_shader = kbackground->surface_shader;
else
- kbackground->volume_shader = SHADER_NO_ID;
+ kbackground->volume_shader = SHADER_NONE;
if(!(visibility & PATH_RAY_DIFFUSE))
kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
new file mode 100644
index 00000000000..aa317ab672f
--- /dev/null
+++ b/intern/cycles/render/bake.cpp
@@ -0,0 +1,206 @@
+/*
+ * 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 "bake.h"
+
+CCL_NAMESPACE_BEGIN
+
+BakeData::BakeData(const int object, const int tri_offset, const int num_pixels):
+m_object(object),
+m_tri_offset(tri_offset),
+m_num_pixels(num_pixels)
+{
+ m_primitive.resize(num_pixels);
+ m_u.resize(num_pixels);
+ m_v.resize(num_pixels);
+ m_dudx.resize(num_pixels);
+ m_dudy.resize(num_pixels);
+ m_dvdx.resize(num_pixels);
+ m_dvdy.resize(num_pixels);
+}
+
+BakeData::~BakeData()
+{
+ m_primitive.clear();
+ m_u.clear();
+ m_v.clear();
+ m_dudx.clear();
+ m_dudy.clear();
+ m_dvdx.clear();
+ m_dvdy.clear();
+}
+
+void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
+{
+ m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
+ m_u[i] = uv[0];
+ m_v[i] = uv[1];
+ m_dudx[i] = dudx;
+ m_dudy[i] = dudy;
+ m_dvdx[i] = dvdx;
+ m_dvdy[i] = dvdy;
+}
+
+int BakeData::object()
+{
+ return m_object;
+}
+
+int BakeData::size()
+{
+ return m_num_pixels;
+}
+
+bool BakeData::is_valid(int i)
+{
+ return m_primitive[i] != -1;
+}
+
+uint4 BakeData::data(int i)
+{
+ return make_uint4(
+ m_object,
+ m_primitive[i],
+ __float_as_int(m_u[i]),
+ __float_as_int(m_v[i])
+ );
+}
+
+uint4 BakeData::differentials(int i)
+{
+ return make_uint4(
+ __float_as_int(m_dudx[i]),
+ __float_as_int(m_dudy[i]),
+ __float_as_int(m_dvdx[i]),
+ __float_as_int(m_dvdy[i])
+ );
+}
+
+BakeManager::BakeManager()
+{
+ m_bake_data = NULL;
+ m_is_baking = false;
+ need_update = true;
+}
+
+BakeManager::~BakeManager()
+{
+ if(m_bake_data)
+ delete m_bake_data;
+}
+
+bool BakeManager::get_baking()
+{
+ return m_is_baking;
+}
+
+void BakeManager::set_baking(const bool value)
+{
+ m_is_baking = value;
+}
+
+BakeData *BakeManager::init(const int object, const int tri_offset, const int num_pixels)
+{
+ m_bake_data = new BakeData(object, tri_offset, num_pixels);
+ return m_bake_data;
+}
+
+bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[])
+{
+ size_t limit = bake_data->size();
+
+ /* setup input for device task */
+ device_vector<uint4> d_input;
+ uint4 *d_input_data = d_input.resize(limit * 2);
+ size_t d_input_size = 0;
+
+ for(size_t i = 0; i < limit; i++) {
+ d_input_data[d_input_size++] = bake_data->data(i);
+ d_input_data[d_input_size++] = bake_data->differentials(i);
+ }
+
+ if(d_input_size == 0)
+ return false;
+
+ /* run device task */
+ device_vector<float4> d_output;
+ d_output.resize(limit);
+
+ /* needs to be up to data for attribute access */
+ device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+
+ device->mem_alloc(d_input, MEM_READ_ONLY);
+ device->mem_copy_to(d_input);
+ device->mem_alloc(d_output, MEM_WRITE_ONLY);
+
+ DeviceTask task(DeviceTask::SHADER);
+ task.shader_input = d_input.device_pointer;
+ task.shader_output = d_output.device_pointer;
+ task.shader_eval_type = shader_type;
+ task.shader_x = 0;
+ task.shader_w = d_output.size();
+ task.get_cancel = function_bind(&Progress::get_cancel, &progress);
+
+ device->task_add(task);
+ device->task_wait();
+
+ if(progress.get_cancel()) {
+ device->mem_free(d_input);
+ device->mem_free(d_output);
+ m_is_baking = false;
+ return false;
+ }
+
+ device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
+ device->mem_free(d_input);
+ device->mem_free(d_output);
+
+ /* read result */
+ int k = 0;
+
+ float4 *offset = (float4*)d_output.data_pointer;
+
+ size_t depth = 4;
+ for(size_t i = 0; i < limit; i++) {
+ size_t index = i * depth;
+ float4 out = offset[k++];
+
+ if(bake_data->is_valid(i)) {
+ for(size_t j=0; j < 4; j++) {
+ result[index + j] = out[j];
+ }
+ }
+ }
+
+ m_is_baking = false;
+ return true;
+}
+
+void BakeManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ if(!need_update)
+ return;
+
+ if(progress.get_cancel()) return;
+
+ need_update = false;
+}
+
+void BakeManager::device_free(Device *device, DeviceScene *dscene)
+{
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
new file mode 100644
index 00000000000..ea403f7d39a
--- /dev/null
+++ b/intern/cycles/render/bake.h
@@ -0,0 +1,77 @@
+/*
+ * 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 __BAKE_H__
+#define __BAKE_H__
+
+#include "util_vector.h"
+#include "device.h"
+#include "scene.h"
+#include "session.h"
+
+CCL_NAMESPACE_BEGIN
+
+class BakeData {
+public:
+ BakeData(const int object, const int tri_offset, const int num_pixels);
+ ~BakeData();
+
+ void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy);
+ int object();
+ int size();
+ uint4 data(int i);
+ uint4 differentials(int i);
+ bool is_valid(int i);
+
+private:
+ int m_object;
+ int m_tri_offset;
+ int m_num_pixels;
+ vector<int>m_primitive;
+ vector<float>m_u;
+ vector<float>m_v;
+ vector<float>m_dudx;
+ vector<float>m_dudy;
+ vector<float>m_dvdx;
+ vector<float>m_dvdy;
+};
+
+class BakeManager {
+public:
+ BakeManager();
+ ~BakeManager();
+
+ bool get_baking();
+ void set_baking(const bool value);
+
+ BakeData *init(const int object, const int tri_offset, const int num_pixels);
+
+ bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]);
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_free(Device *device, DeviceScene *dscene);
+
+ bool need_update;
+
+private:
+ BakeData *m_bake_data;
+ bool m_is_baking;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __BAKE_H__ */
+
diff --git a/intern/cycles/render/blackbody.cpp b/intern/cycles/render/blackbody.cpp
index ab61886e262..89af714e8ec 100644
--- a/intern/cycles/render/blackbody.cpp
+++ b/intern/cycles/render/blackbody.cpp
@@ -59,33 +59,33 @@ vector<float> blackbody_table()
*/
const float cie_colour_match[81][3] = {
- {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201},
- {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102},
- {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456},
- {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230},
- {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721},
- {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281},
- {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130},
- {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533},
- {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582},
- {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573},
- {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203},
- {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057},
- {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021},
- {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014},
- {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008},
- {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002},
- {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000},
- {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000},
- {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000},
- {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000},
- {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000},
- {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000},
- {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000},
- {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000},
- {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000},
- {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000},
- {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000}
+ {0.0014f,0.0000f,0.0065f}, {0.0022f,0.0001f,0.0105f}, {0.0042f,0.0001f,0.0201f},
+ {0.0076f,0.0002f,0.0362f}, {0.0143f,0.0004f,0.0679f}, {0.0232f,0.0006f,0.1102f},
+ {0.0435f,0.0012f,0.2074f}, {0.0776f,0.0022f,0.3713f}, {0.1344f,0.0040f,0.6456f},
+ {0.2148f,0.0073f,1.0391f}, {0.2839f,0.0116f,1.3856f}, {0.3285f,0.0168f,1.6230f},
+ {0.3483f,0.0230f,1.7471f}, {0.3481f,0.0298f,1.7826f}, {0.3362f,0.0380f,1.7721f},
+ {0.3187f,0.0480f,1.7441f}, {0.2908f,0.0600f,1.6692f}, {0.2511f,0.0739f,1.5281f},
+ {0.1954f,0.0910f,1.2876f}, {0.1421f,0.1126f,1.0419f}, {0.0956f,0.1390f,0.8130f},
+ {0.0580f,0.1693f,0.6162f}, {0.0320f,0.2080f,0.4652f}, {0.0147f,0.2586f,0.3533f},
+ {0.0049f,0.3230f,0.2720f}, {0.0024f,0.4073f,0.2123f}, {0.0093f,0.5030f,0.1582f},
+ {0.0291f,0.6082f,0.1117f}, {0.0633f,0.7100f,0.0782f}, {0.1096f,0.7932f,0.0573f},
+ {0.1655f,0.8620f,0.0422f}, {0.2257f,0.9149f,0.0298f}, {0.2904f,0.9540f,0.0203f},
+ {0.3597f,0.9803f,0.0134f}, {0.4334f,0.9950f,0.0087f}, {0.5121f,1.0000f,0.0057f},
+ {0.5945f,0.9950f,0.0039f}, {0.6784f,0.9786f,0.0027f}, {0.7621f,0.9520f,0.0021f},
+ {0.8425f,0.9154f,0.0018f}, {0.9163f,0.8700f,0.0017f}, {0.9786f,0.8163f,0.0014f},
+ {1.0263f,0.7570f,0.0011f}, {1.0567f,0.6949f,0.0010f}, {1.0622f,0.6310f,0.0008f},
+ {1.0456f,0.5668f,0.0006f}, {1.0026f,0.5030f,0.0003f}, {0.9384f,0.4412f,0.0002f},
+ {0.8544f,0.3810f,0.0002f}, {0.7514f,0.3210f,0.0001f}, {0.6424f,0.2650f,0.0000f},
+ {0.5419f,0.2170f,0.0000f}, {0.4479f,0.1750f,0.0000f}, {0.3608f,0.1382f,0.0000f},
+ {0.2835f,0.1070f,0.0000f}, {0.2187f,0.0816f,0.0000f}, {0.1649f,0.0610f,0.0000f},
+ {0.1212f,0.0446f,0.0000f}, {0.0874f,0.0320f,0.0000f}, {0.0636f,0.0232f,0.0000f},
+ {0.0468f,0.0170f,0.0000f}, {0.0329f,0.0119f,0.0000f}, {0.0227f,0.0082f,0.0000f},
+ {0.0158f,0.0057f,0.0000f}, {0.0114f,0.0041f,0.0000f}, {0.0081f,0.0029f,0.0000f},
+ {0.0058f,0.0021f,0.0000f}, {0.0041f,0.0015f,0.0000f}, {0.0029f,0.0010f,0.0000f},
+ {0.0020f,0.0007f,0.0000f}, {0.0014f,0.0005f,0.0000f}, {0.0010f,0.0004f,0.0000f},
+ {0.0007f,0.0002f,0.0000f}, {0.0005f,0.0002f,0.0000f}, {0.0003f,0.0001f,0.0000f},
+ {0.0002f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0001f,0.0000f,0.0000f},
+ {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f}
};
const double c1 = 3.74183e-16; // 2*pi*h*c^2, W*m^2
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index da1b7484b77..fc65922fc87 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -358,14 +358,14 @@ void DisplayBuffer::draw_set(int width, int height)
draw_height = height;
}
-void DisplayBuffer::draw(Device *device)
+void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
{
if(draw_width != 0 && draw_height != 0) {
glPushMatrix();
glTranslatef(params.full_x, params.full_y, 0.0f);
device_memory& rgba = rgba_data();
- device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent);
+ device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent, draw_params);
glPopMatrix();
}
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 81eaf41077f..27ab20bbafd 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -31,6 +31,7 @@
CCL_NAMESPACE_BEGIN
class Device;
+struct DeviceDrawParams;
struct float4;
/* Buffer Parameters
@@ -114,7 +115,7 @@ public:
void write(Device *device, const string& filename);
void draw_set(int width, int height);
- void draw(Device *device);
+ void draw(Device *device, const DeviceDrawParams& draw_params);
bool draw_ready();
device_memory& rgba_data();
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index edf7f7fb09d..8659fe4f7a3 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -44,8 +44,8 @@ Camera::Camera()
fisheye_lens = 10.5f;
fov = M_PI_4_F;
- sensorwidth = 0.036;
- sensorheight = 0.024;
+ sensorwidth = 0.036f;
+ sensorheight = 0.024f;
nearclip = 1e-5f;
farclip = 1e5f;
@@ -78,6 +78,24 @@ Camera::~Camera()
{
}
+void Camera::compute_auto_viewplane()
+{
+ float aspect = (float)width/(float)height;
+
+ if(width >= height) {
+ viewplane.left = -aspect;
+ viewplane.right = aspect;
+ viewplane.bottom = -1.0f;
+ viewplane.top = 1.0f;
+ }
+ else {
+ viewplane.left = -1.0f;
+ viewplane.right = 1.0f;
+ viewplane.bottom = -1.0f/aspect;
+ viewplane.top = 1.0f/aspect;
+ }
+}
+
void Camera::update()
{
if(!need_update)
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 4e8f3d72111..c28670bc55f 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -102,6 +102,8 @@ public:
/* functions */
Camera();
~Camera();
+
+ void compute_auto_viewplane();
void update();
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
index 6e6b11ca92f..2c96ffa655e 100644
--- a/intern/cycles/render/curves.cpp
+++ b/intern/cycles/render/curves.cpp
@@ -110,7 +110,7 @@ void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scen
progress.set_status("Updating Hair settings", "Copying Hair settings to device");
- KernelCurves *kcurve= &dscene->data.curve;
+ KernelCurves *kcurve = &dscene->data.curve;
kcurve->curveflags = 0;
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 30ad86a8d4c..c1aefbcfbbc 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -155,6 +155,9 @@ void Pass::add(PassType type, vector<Pass>& passes)
pass.components = 4;
pass.exposure = false;
break;
+ case PASS_LIGHT:
+ /* ignores */
+ break;
}
passes.push_back(pass);
@@ -393,6 +396,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_shadow = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
+
+ case PASS_LIGHT:
+ kfilm->use_light_pass = 1;
+ break;
case PASS_NONE:
break;
}
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 9142eb5308c..0ff904d06e7 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -227,7 +227,7 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
-void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
+void ShaderGraph::finalize(bool do_bump, bool do_osl)
{
/* before compiling, the shader graph may undergo a number of modifications.
* currently we set default geometry shader inputs, and create automatic bump
@@ -242,17 +242,15 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
if(do_bump)
bump_from_displacement();
- if(do_multi_transform) {
- ShaderInput *surface_in = output()->input("Surface");
- ShaderInput *volume_in = output()->input("Volume");
+ ShaderInput *surface_in = output()->input("Surface");
+ ShaderInput *volume_in = output()->input("Volume");
- /* todo: make this work when surface and volume closures are tangled up */
+ /* todo: make this work when surface and volume closures are tangled up */
- if(surface_in->link)
- transform_multi_closure(surface_in->link->parent, NULL, false);
- if(volume_in->link)
- transform_multi_closure(volume_in->link->parent, NULL, true);
- }
+ if(surface_in->link)
+ transform_multi_closure(surface_in->link->parent, NULL, false);
+ if(volume_in->link)
+ transform_multi_closure(volume_in->link->parent, NULL, true);
finalized = true;
}
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index f31e2103229..89a066195d6 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -193,6 +193,7 @@ public:
virtual bool has_surface_bssrdf() { return false; }
virtual bool has_converter_blackbody() { return false; }
virtual bool has_bssrdf_bump() { return false; }
+ virtual bool has_spatial_varying() { return false; }
vector<ShaderInput*> inputs;
vector<ShaderOutput*> outputs;
@@ -246,7 +247,7 @@ public:
void disconnect(ShaderInput *to);
void remove_unneeded_nodes();
- void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
+ void finalize(bool do_bump = false, bool do_osl = false);
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 91aae6f3ec3..86755badc42 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -59,11 +59,16 @@ void ImageManager::set_osl_texture_system(void *texture_system)
osl_texture_system = texture_system;
}
-void ImageManager::set_extended_image_limits(void)
+void ImageManager::set_extended_image_limits(const DeviceInfo& info)
{
- tex_num_images = TEX_EXTENDED_NUM_IMAGES;
- tex_num_float_images = TEX_EXTENDED_NUM_FLOAT_IMAGES;
- tex_image_byte_start = TEX_EXTENDED_IMAGE_BYTE_START;
+ if(info.type == DEVICE_CPU) {
+ tex_num_images = TEX_EXTENDED_NUM_IMAGES_CPU;
+ tex_num_float_images = TEX_EXTENDED_NUM_FLOAT_IMAGES;
+ tex_image_byte_start = TEX_EXTENDED_IMAGE_BYTE_START;
+ }
+ else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) {
+ tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU;
+ }
}
bool ImageManager::set_animation_frame_update(int frame)
@@ -90,8 +95,8 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo
if(builtin_data) {
if(builtin_image_info_cb) {
- int width, height, channels;
- builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels);
+ int width, height, depth, channels;
+ builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels);
}
if(is_float)
@@ -145,7 +150,14 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo
return is_float;
}
-int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear)
+static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, InterpolationType interpolation)
+{
+ return image->filename == filename &&
+ image->builtin_data == builtin_data &&
+ image->interpolation == interpolation;
+}
+
+int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha)
{
Image *img;
size_t slot;
@@ -156,7 +168,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
if(is_float) {
/* find existing image */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && float_images[slot]->filename == filename) {
+ if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) {
float_images[slot]->users++;
return slot;
}
@@ -185,13 +197,15 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->builtin_data = builtin_data;
img->need_load = true;
img->animated = animated;
+ img->interpolation = interpolation;
img->users = 1;
+ img->use_alpha = use_alpha;
float_images[slot] = img;
}
else {
for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && images[slot]->filename == filename) {
+ if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) {
images[slot]->users++;
return slot+tex_image_byte_start;
}
@@ -220,7 +234,9 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->builtin_data = builtin_data;
img->need_load = true;
img->animated = animated;
+ img->interpolation = interpolation;
img->users = 1;
+ img->use_alpha = use_alpha;
images[slot] = img;
@@ -231,22 +247,43 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
return slot;
}
-void ImageManager::remove_image(const string& filename, void *builtin_data)
+void ImageManager::remove_image(int slot)
{
- size_t slot;
+ if(slot >= tex_image_byte_start) {
+ slot -= tex_image_byte_start;
- for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && images[slot]->filename == filename && images[slot]->builtin_data == builtin_data) {
- /* decrement user count */
- images[slot]->users--;
- assert(images[slot]->users >= 0);
+ assert(images[slot] != NULL);
+
+ /* decrement user count */
+ images[slot]->users--;
+ assert(images[slot]->users >= 0);
+
+ /* don't remove immediately, rather do it all together later on. one of
+ * the reasons for this is that on shader changes we add and remove nodes
+ * that use them, but we do not want to reload the image all the time. */
+ if(images[slot]->users == 0)
+ need_update = true;
+ }
+ else {
+ /* decrement user count */
+ float_images[slot]->users--;
+ assert(float_images[slot]->users >= 0);
+
+ /* don't remove immediately, rather do it all together later on. one of
+ * the reasons for this is that on shader changes we add and remove nodes
+ * that use them, but we do not want to reload the image all the time. */
+ if(float_images[slot]->users == 0)
+ need_update = true;
+ }
+}
- /* don't remove immediately, rather do it all together later on. one of
- * the reasons for this is that on shader changes we add and remove nodes
- * that use them, but we do not want to reload the image all the time. */
- if(images[slot]->users == 0)
- need_update = true;
+void ImageManager::remove_image(const string& filename, void *builtin_data, InterpolationType interpolation)
+{
+ size_t slot;
+ for(slot = 0; slot < images.size(); slot++) {
+ if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) {
+ remove_image(slot+tex_image_byte_start);
break;
}
}
@@ -254,17 +291,8 @@ void ImageManager::remove_image(const string& filename, void *builtin_data)
if(slot == images.size()) {
/* see if it's in a float texture slot */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->builtin_data == builtin_data) {
- /* decrement user count */
- float_images[slot]->users--;
- assert(float_images[slot]->users >= 0);
-
- /* don't remove immediately, rather do it all together later on. one of
- * the reasons for this is that on shader changes we add and remove nodes
- * that use them, but we do not want to reload the image all the time. */
- if(float_images[slot]->users == 0)
- need_update = true;
-
+ if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) {
+ remove_image(slot);
break;
}
}
@@ -277,7 +305,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
return false;
ImageInput *in = NULL;
- int width, height, components;
+ int width, height, depth, components;
if(!img->builtin_data) {
/* load image from file through OIIO */
@@ -286,15 +314,20 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
if(!in)
return false;
- ImageSpec spec;
+ ImageSpec spec = ImageSpec();
+ ImageSpec config = ImageSpec();
+
+ if(img->use_alpha == false)
+ config.attribute("oiio:UnassociatedAlpha", 1);
- if(!in->open(img->filename, spec)) {
+ if(!in->open(img->filename, spec, config)) {
delete in;
return false;
}
width = spec.width;
height = spec.height;
+ depth = spec.depth;
components = spec.nchannels;
}
else {
@@ -303,7 +336,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
return false;
bool is_float;
- builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components);
}
/* we only handle certain number of components */
@@ -317,15 +350,21 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
/* read RGBA pixels */
- uchar *pixels = (uchar*)tex_img.resize(width, height);
- int scanlinesize = width*components*sizeof(uchar);
+ uchar *pixels = (uchar*)tex_img.resize(width, height, depth);
if(in) {
- in->read_image(TypeDesc::UINT8,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(depth <= 1) {
+ int scanlinesize = width*components*sizeof(uchar);
+
+ in->read_image(TypeDesc::UINT8,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ else {
+ in->read_image(TypeDesc::UINT8, (uchar*)pixels);
+ }
in->close();
delete in;
@@ -335,7 +374,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
if(components == 2) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = pixels[i*2+1];
pixels[i*4+2] = pixels[i*2+0];
pixels[i*4+1] = pixels[i*2+0];
@@ -343,7 +382,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
}
else if(components == 3) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = 255;
pixels[i*4+2] = pixels[i*3+2];
pixels[i*4+1] = pixels[i*3+1];
@@ -351,7 +390,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
}
else if(components == 1) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = 255;
pixels[i*4+2] = pixels[i];
pixels[i*4+1] = pixels[i];
@@ -359,6 +398,12 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
}
+ if(img->use_alpha == false) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
+ pixels[i*4+3] = 255;
+ }
+ }
+
return true;
}
@@ -368,7 +413,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
return false;
ImageInput *in = NULL;
- int width, height, components;
+ int width, height, depth, components;
if(!img->builtin_data) {
/* load image from file through OIIO */
@@ -377,9 +422,13 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
if(!in)
return false;
- ImageSpec spec;
+ ImageSpec spec = ImageSpec();
+ ImageSpec config = ImageSpec();
+
+ if(img->use_alpha == false)
+ config.attribute("oiio:UnassociatedAlpha",1);
- if(!in->open(img->filename, spec)) {
+ if(!in->open(img->filename, spec, config)) {
delete in;
return false;
}
@@ -387,6 +436,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
/* we only handle certain number of components */
width = spec.width;
height = spec.height;
+ depth = spec.depth;
components = spec.nchannels;
}
else {
@@ -395,7 +445,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
return false;
bool is_float;
- builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components);
}
if(!(components >= 1 && components <= 4)) {
@@ -407,15 +457,21 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
}
/* read RGBA pixels */
- float *pixels = (float*)tex_img.resize(width, height);
- int scanlinesize = width*components*sizeof(float);
+ float *pixels = (float*)tex_img.resize(width, height, depth);
if(in) {
- in->read_image(TypeDesc::FLOAT,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(depth <= 1) {
+ int scanlinesize = width*components*sizeof(float);
+
+ in->read_image(TypeDesc::FLOAT,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ else {
+ in->read_image(TypeDesc::FLOAT, (uchar*)pixels);
+ }
in->close();
delete in;
@@ -425,7 +481,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
}
if(components == 2) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = pixels[i*2+1];
pixels[i*4+2] = pixels[i*2+0];
pixels[i*4+1] = pixels[i*2+0];
@@ -433,7 +489,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
}
}
else if(components == 3) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = 1.0f;
pixels[i*4+2] = pixels[i*3+2];
pixels[i*4+1] = pixels[i*3+1];
@@ -441,7 +497,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
}
}
else if(components == 1) {
- for(int i = width*height-1; i >= 0; i--) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
pixels[i*4+3] = 1.0f;
pixels[i*4+2] = pixels[i];
pixels[i*4+1] = pixels[i];
@@ -449,6 +505,12 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
}
}
+ if(img->use_alpha == false) {
+ for(int i = width*height*depth-1; i >= 0; i--) {
+ pixels[i*4+3] = 1.0f;
+ }
+ }
+
return true;
}
@@ -456,9 +518,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
{
if(progress->get_cancel())
return;
- if(osl_texture_system)
- return;
-
+
Image *img;
bool is_float;
@@ -471,6 +531,9 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
is_float = true;
}
+ if(osl_texture_system && !img->builtin_data)
+ return;
+
if(is_float) {
string filename = path_filename(float_images[slot]->filename);
progress->set_status("Updating Images", "Loading " + filename);
@@ -499,7 +562,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
if(!pack_images) {
thread_scoped_lock device_lock(device_mutex);
- device->tex_alloc(name.c_str(), tex_img, true, true);
+ device->tex_alloc(name.c_str(), tex_img, img->interpolation, true);
}
}
else {
@@ -530,7 +593,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
if(!pack_images) {
thread_scoped_lock device_lock(device_mutex);
- device->tex_alloc(name.c_str(), tex_img, true, true);
+ device->tex_alloc(name.c_str(), tex_img, img->interpolation, true);
}
}
@@ -552,7 +615,7 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int sl
}
if(img) {
- if(osl_texture_system) {
+ if(osl_texture_system && !img->builtin_data) {
#ifdef WITH_OSL
ustring filename(images[slot]->filename);
((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
@@ -602,7 +665,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
device_free_image(device, dscene, slot + tex_image_byte_start);
}
else if(images[slot]->need_load) {
- if(!osl_texture_system)
+ if(!osl_texture_system || images[slot]->builtin_data)
pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot + tex_image_byte_start, &progress));
}
}
@@ -615,7 +678,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
device_free_image(device, dscene, slot);
}
else if(float_images[slot]->need_load) {
- if(!osl_texture_system)
+ if(!osl_texture_system || float_images[slot]->builtin_data)
pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot, &progress));
}
}
@@ -653,16 +716,32 @@ void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progr
device_vector<uchar4>& tex_img = dscene->tex_image[slot];
- info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, 1);
+ /* todo: support 3D textures, only CPU for now */
+
+ /* The image options are packed
+ bit 0 -> periodic
+ bit 1 + 2 -> interpolation type */
+ uint8_t interpolation = (images[slot]->interpolation << 1) + 1;
+ info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation);
memcpy(pixels+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
offset += tex_img.size();
}
- if(dscene->tex_image_packed.size())
+ if(dscene->tex_image_packed.size()) {
+ if(dscene->tex_image_packed.device_pointer) {
+ thread_scoped_lock device_lock(device_mutex);
+ device->tex_free(dscene->tex_image_packed);
+ }
device->tex_alloc("__tex_image_packed", dscene->tex_image_packed);
- if(dscene->tex_image_packed_info.size())
+ }
+ if(dscene->tex_image_packed_info.size()) {
+ if(dscene->tex_image_packed_info.device_pointer) {
+ thread_scoped_lock device_lock(device_mutex);
+ device->tex_free(dscene->tex_image_packed_info);
+ }
device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info);
+ }
}
void ImageManager::device_free(Device *device, DeviceScene *dscene)
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 187c5fd0f02..561550fe0d2 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -17,6 +17,7 @@
#ifndef __IMAGE_H__
#define __IMAGE_H__
+#include "device.h"
#include "device_memory.h"
#include "util_string.h"
@@ -27,11 +28,16 @@
CCL_NAMESPACE_BEGIN
+/* generic */
#define TEX_NUM_IMAGES 95
#define TEX_IMAGE_BYTE_START TEX_NUM_FLOAT_IMAGES
+/* extended gpu */
+#define TEX_EXTENDED_NUM_IMAGES_GPU 145
+
+/* extended cpu */
#define TEX_EXTENDED_NUM_FLOAT_IMAGES 1024
-#define TEX_EXTENDED_NUM_IMAGES 1024
+#define TEX_EXTENDED_NUM_IMAGES_CPU 1024
#define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES
/* color to use when textures are not found */
@@ -49,8 +55,9 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear);
- void remove_image(const string& filename, void *builtin_data);
+ int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha);
+ void remove_image(int slot);
+ void remove_image(const string& filename, void *builtin_data, InterpolationType interpolation);
bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
@@ -58,30 +65,34 @@ public:
void set_osl_texture_system(void *texture_system);
void set_pack_images(bool pack_images_);
- void set_extended_image_limits(void);
+ void set_extended_image_limits(const DeviceInfo& info);
bool set_animation_frame_update(int frame);
bool need_update;
- boost::function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &channels)> builtin_image_info_cb;
+ boost::function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb;
boost::function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb;
boost::function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb;
-private:
- int tex_num_images;
- int tex_num_float_images;
- int tex_image_byte_start;
- thread_mutex device_mutex;
- int animation_frame;
struct Image {
string filename;
void *builtin_data;
+ bool use_alpha;
bool need_load;
bool animated;
+ InterpolationType interpolation;
+
int users;
};
+private:
+ int tex_num_images;
+ int tex_num_float_images;
+ int tex_image_byte_start;
+ thread_mutex device_mutex;
+ int animation_frame;
+
vector<Image*> images;
vector<Image*> float_images;
void *osl_texture_system;
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index f48e04f31e1..59a0de07e5a 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -34,15 +34,14 @@ Integrator::Integrator()
max_glossy_bounce = max_bounce;
max_transmission_bounce = max_bounce;
max_volume_bounce = max_bounce;
- probalistic_termination = true;
transparent_min_bounce = min_bounce;
transparent_max_bounce = max_bounce;
- transparent_probalistic = true;
transparent_shadows = false;
+ volume_homogeneous_sampling = 0;
volume_max_steps = 1024;
- volume_step_size = 0.1;
+ volume_step_size = 0.1f;
no_caustics = false;
filter_glossy = 0.0f;
@@ -82,10 +81,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
/* integrator parameters */
kintegrator->max_bounce = max_bounce + 1;
- if(probalistic_termination)
- kintegrator->min_bounce = min_bounce + 1;
- else
- kintegrator->min_bounce = kintegrator->max_bounce;
+ kintegrator->min_bounce = min_bounce + 1;
kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
@@ -97,13 +93,11 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->max_volume_bounce = 1;
kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
- if(transparent_probalistic)
- kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
- else
- kintegrator->transparent_min_bounce = kintegrator->transparent_max_bounce;
+ kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
kintegrator->transparent_shadows = transparent_shadows;
+ kintegrator->volume_homogeneous_sampling = volume_homogeneous_sampling;
kintegrator->volume_max_steps = volume_max_steps;
kintegrator->volume_step_size = volume_step_size;
@@ -120,7 +114,6 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->sample_clamp_indirect = (sample_clamp_indirect == 0.0f)? FLT_MAX: sample_clamp_indirect*3.0f;
kintegrator->branched = (method == BRANCHED_PATH);
- kintegrator->aa_samples = aa_samples;
kintegrator->diffuse_samples = diffuse_samples;
kintegrator->glossy_samples = glossy_samples;
kintegrator->transmission_samples = transmission_samples;
@@ -128,8 +121,11 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->mesh_light_samples = mesh_light_samples;
kintegrator->subsurface_samples = subsurface_samples;
kintegrator->volume_samples = volume_samples;
+ kintegrator->sample_all_lights_direct = sample_all_lights_direct;
+ kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
kintegrator->sampling_pattern = sampling_pattern;
+ kintegrator->aa_samples = aa_samples;
/* sobol directions table */
int max_samples = 1;
@@ -171,11 +167,10 @@ bool Integrator::modified(const Integrator& integrator)
max_glossy_bounce == integrator.max_glossy_bounce &&
max_transmission_bounce == integrator.max_transmission_bounce &&
max_volume_bounce == integrator.max_volume_bounce &&
- probalistic_termination == integrator.probalistic_termination &&
transparent_min_bounce == integrator.transparent_min_bounce &&
transparent_max_bounce == integrator.transparent_max_bounce &&
- transparent_probalistic == integrator.transparent_probalistic &&
transparent_shadows == integrator.transparent_shadows &&
+ volume_homogeneous_sampling == integrator.volume_homogeneous_sampling &&
volume_max_steps == integrator.volume_max_steps &&
volume_step_size == integrator.volume_step_size &&
no_caustics == integrator.no_caustics &&
@@ -194,7 +189,9 @@ bool Integrator::modified(const Integrator& integrator)
subsurface_samples == integrator.subsurface_samples &&
volume_samples == integrator.volume_samples &&
motion_blur == integrator.motion_blur &&
- sampling_pattern == integrator.sampling_pattern);
+ sampling_pattern == integrator.sampling_pattern &&
+ sample_all_lights_direct == integrator.sample_all_lights_direct &&
+ sample_all_lights_indirect == integrator.sample_all_lights_indirect);
}
void Integrator::tag_update(Scene *scene)
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 573b258af60..380c1a65722 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -34,13 +34,12 @@ public:
int max_glossy_bounce;
int max_transmission_bounce;
int max_volume_bounce;
- bool probalistic_termination;
int transparent_min_bounce;
int transparent_max_bounce;
- bool transparent_probalistic;
bool transparent_shadows;
+ int volume_homogeneous_sampling;
int volume_max_steps;
float volume_step_size;
@@ -62,6 +61,8 @@ public:
int mesh_light_samples;
int subsurface_samples;
int volume_samples;
+ bool sample_all_lights_direct;
+ bool sample_all_lights_indirect;
enum Method {
BRANCHED_PATH = 0,
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index bab4218aae9..7bdb1fbf8af 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -29,7 +29,7 @@
CCL_NAMESPACE_BEGIN
-static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
+static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels, Progress& progress)
{
/* create input */
int width = res;
@@ -66,6 +66,7 @@ static void shade_background_pixels(Device *device, DeviceScene *dscene, int res
main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
main_task.shader_x = 0;
main_task.shader_w = width*height;
+ main_task.get_cancel = function_bind(&Progress::get_cancel, &progress);
/* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */
list<DeviceTask> split_tasks;
@@ -149,7 +150,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
size_t num_lights = scene->lights.size();
size_t num_background_lights = 0;
size_t num_triangles = 0;
- size_t num_curve_segments = 0;
foreach(Object *object, scene->objects) {
Mesh *mesh = object->mesh;
@@ -159,6 +159,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT)))
continue;
+ /* skip motion blurred deforming meshes, not supported yet */
+ if(mesh->has_motion_blur())
+ continue;
+
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
@@ -177,20 +181,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->use_mis && shader->has_surface_emission)
num_triangles++;
}
-
- /* disabled for curves */
-#if 0
- foreach(Mesh::Curve& curve, mesh->curves) {
- Shader *shader = scene->shaders[curve.shader];
-
- if(shader->use_mis && shader->has_surface_emission)
- num_curve_segments += curve.num_segments();
-#endif
}
}
- size_t num_distribution = num_triangles + num_curve_segments;
- num_distribution += num_lights;
+ size_t num_distribution = num_triangles + num_lights;
/* emission area */
float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
@@ -210,6 +204,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
continue;
}
+ /* skip motion blurred deforming meshes, not supported yet */
+ if(mesh->has_motion_blur())
+ continue;
+
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
@@ -225,21 +223,21 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
bool transform_applied = mesh->transform_applied;
Transform tfm = object->tfm;
int object_id = j;
- int shader_id = SHADER_MASK;
+ int shader_flag = 0;
if(transform_applied)
object_id = ~object_id;
if(!(object->visibility & PATH_RAY_DIFFUSE)) {
- shader_id |= SHADER_EXCLUDE_DIFFUSE;
+ shader_flag |= SHADER_EXCLUDE_DIFFUSE;
use_light_visibility = true;
}
if(!(object->visibility & PATH_RAY_GLOSSY)) {
- shader_id |= SHADER_EXCLUDE_GLOSSY;
+ shader_flag |= SHADER_EXCLUDE_GLOSSY;
use_light_visibility = true;
}
if(!(object->visibility & PATH_RAY_TRANSMIT)) {
- shader_id |= SHADER_EXCLUDE_TRANSMIT;
+ shader_flag |= SHADER_EXCLUDE_TRANSMIT;
use_light_visibility = true;
}
@@ -249,7 +247,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->use_mis && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
- distribution[offset].z = __int_as_float(shader_id);
+ distribution[offset].z = __int_as_float(shader_flag);
distribution[offset].w = __int_as_float(object_id);
offset++;
@@ -267,40 +265,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
totarea += triangle_area(p1, p2, p3);
}
}
-
- /* sample as light disabled for strands */
-#if 0
- size_t i = 0;
-
- foreach(Mesh::Curve& curve, mesh->curves) {
- Shader *shader = scene->shaders[curve.shader];
- int first_key = curve.first_key;
-
- if(shader->use_mis && shader->has_surface_emission) {
- for(int j = 0; j < curve.num_segments(); j++) {
- distribution[offset].x = totarea;
- distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
- distribution[offset].z = __int_as_float(j) & SHADER_MASK;
- distribution[offset].w = __int_as_float(object_id);
- offset++;
-
- float3 p1 = mesh->curve_keys[first_key + j].loc;
- float r1 = mesh->curve_keys[first_key + j].radius;
- float3 p2 = mesh->curve_keys[first_key + j + 1].loc;
- float r2 = mesh->curve_keys[first_key + j + 1].radius;
-
- if(!transform_applied) {
- p1 = transform_point(&tfm, p1);
- p2 = transform_point(&tfm, p2);
- }
-
- totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
- }
- }
-
- i++;
- }
-#endif
}
if(progress.get_cancel()) return;
@@ -432,7 +396,7 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene,
assert(res > 0);
vector<float3> pixels;
- shade_background_pixels(device, dscene, res, pixels);
+ shade_background_pixels(device, dscene, res, pixels, progress);
if(progress.get_cancel())
return;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 93f24886dc9..9c5ddd55010 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -18,6 +18,7 @@
#include "bvh_build.h"
#include "camera.h"
+#include "curves.h"
#include "device.h"
#include "shader.h"
#include "light.h"
@@ -34,6 +35,39 @@
CCL_NAMESPACE_BEGIN
+/* Triangle */
+
+void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const
+{
+ bounds.grow(verts[v[0]]);
+ bounds.grow(verts[v[1]]);
+ bounds.grow(verts[v[2]]);
+}
+
+/* Curve */
+
+void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const
+{
+ float3 P[4];
+
+ P[0] = float4_to_float3(curve_keys[max(first_key + k - 1,first_key)]);
+ P[1] = float4_to_float3(curve_keys[first_key + k]);
+ P[2] = float4_to_float3(curve_keys[first_key + k + 1]);
+ P[3] = float4_to_float3(curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]);
+
+ float3 lower;
+ float3 upper;
+
+ curvebounds(&lower.x, &upper.x, P, 0);
+ curvebounds(&lower.y, &upper.y, P, 1);
+ curvebounds(&lower.z, &upper.z, P, 2);
+
+ float mr = max(curve_keys[first_key + k].w, curve_keys[first_key + k + 1].w);
+
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
+}
+
/* Mesh */
Mesh::Mesh()
@@ -46,6 +80,9 @@ Mesh::Mesh()
displacement_method = DISPLACE_BUMP;
bounds = BoundBox::empty;
+ motion_steps = 3;
+ use_motion_blur = false;
+
bvh = NULL;
tri_offset = 0;
@@ -97,6 +134,22 @@ void Mesh::clear()
transform_normal = transform_identity();
}
+int Mesh::split_vertex(int vertex)
+{
+ /* copy vertex location and vertex attributes */
+ verts.push_back(verts[vertex]);
+
+ foreach(Attribute& attr, attributes.attributes) {
+ if(attr.element == ATTR_ELEMENT_VERTEX) {
+ vector<char> tmp(attr.data_sizeof());
+ memcpy(&tmp[0], attr.data() + tmp.size()*vertex, tmp.size());
+ attr.add(&tmp[0]);
+ }
+ }
+
+ return verts.size() - 1;
+}
+
void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_)
{
Triangle tri;
@@ -123,9 +176,8 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
void Mesh::add_curve_key(float3 co, float radius)
{
- CurveKey key;
- key.co = co;
- key.radius = radius;
+ float4 key = float3_to_float4(co);
+ key.w = radius;
curve_keys.push_back(key);
}
@@ -151,7 +203,25 @@ void Mesh::compute_bounds()
bnds.grow(verts[i]);
for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow(curve_keys[i].co, curve_keys[i].radius);
+ bnds.grow(float4_to_float3(curve_keys[i]), curve_keys[i].w);
+
+ Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (use_motion_blur && attr) {
+ size_t steps_size = verts.size() * (motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow(vert_steps[i]);
+ }
+
+ Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if(use_motion_blur && curve_attr) {
+ size_t steps_size = curve_keys.size() * (motion_steps - 1);
+ float3 *key_steps = curve_attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow(key_steps[i]);
+ }
if(!bnds.valid()) {
bnds = BoundBox::empty;
@@ -161,7 +231,23 @@ void Mesh::compute_bounds()
bnds.grow_safe(verts[i]);
for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow_safe(curve_keys[i].co, curve_keys[i].radius);
+ bnds.grow_safe(float4_to_float3(curve_keys[i]), curve_keys[i].w);
+
+ if (use_motion_blur && attr) {
+ size_t steps_size = verts.size() * (motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow_safe(vert_steps[i]);
+ }
+
+ if (use_motion_blur && curve_attr) {
+ size_t steps_size = curve_keys.size() * (motion_steps - 1);
+ float3 *key_steps = curve_attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ bnds.grow_safe(key_steps[i]);
+ }
}
}
@@ -173,6 +259,21 @@ void Mesh::compute_bounds()
bounds = bnds;
}
+static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
+{
+ float3 v0 = verts[t.v[0]];
+ float3 v1 = verts[t.v[1]];
+ float3 v2 = verts[t.v[2]];
+
+ float3 norm = cross(v1 - v0, v2 - v0);
+ float normlen = len(norm);
+
+ if(normlen == 0.0f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ return norm / normlen;
+}
+
void Mesh::add_face_normals()
{
/* don't compute if already there */
@@ -192,17 +293,7 @@ void Mesh::add_face_normals()
Triangle *triangles_ptr = &triangles[0];
for(size_t i = 0; i < triangles_size; i++) {
- Triangle t = triangles_ptr[i];
- float3 v0 = verts_ptr[t.v[0]];
- float3 v1 = verts_ptr[t.v[1]];
- float3 v2 = verts_ptr[t.v[2]];
-
- float3 norm = cross(v1 - v0, v2 - v0);
- float normlen = len(norm);
- if(normlen == 0.0f)
- fN[i] = make_float3(0.0f, 0.0f, 0.0f);
- else
- fN[i] = norm / normlen;
+ fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
if(flip)
fN[i] = -fN[i];
@@ -220,36 +311,69 @@ void Mesh::add_face_normals()
void Mesh::add_vertex_normals()
{
- /* don't compute if already there */
- if(attributes.find(ATTR_STD_VERTEX_NORMAL))
- return;
-
- /* get attributes */
- Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
- Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
+ bool flip = transform_negative_scaled;
+ size_t verts_size = verts.size();
+ size_t triangles_size = triangles.size();
- float3 *fN = attr_fN->data_float3();
- float3 *vN = attr_vN->data_float3();
+ /* static vertex normals */
+ if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
+ /* get attributes */
+ Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
+ Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
- /* compute vertex normals */
- memset(vN, 0, verts.size()*sizeof(float3));
+ float3 *fN = attr_fN->data_float3();
+ float3 *vN = attr_vN->data_float3();
- size_t verts_size = verts.size();
- size_t triangles_size = triangles.size();
- bool flip = transform_negative_scaled;
+ /* compute vertex normals */
+ memset(vN, 0, verts.size()*sizeof(float3));
- if(triangles_size) {
- Triangle *triangles_ptr = &triangles[0];
+ if(triangles_size) {
+ Triangle *triangles_ptr = &triangles[0];
- for(size_t i = 0; i < triangles_size; i++)
- for(size_t j = 0; j < 3; j++)
- vN[triangles_ptr[i].v[j]] += fN[i];
+ for(size_t i = 0; i < triangles_size; i++)
+ for(size_t j = 0; j < 3; j++)
+ vN[triangles_ptr[i].v[j]] += fN[i];
+ }
+
+ for(size_t i = 0; i < verts_size; i++) {
+ vN[i] = normalize(vN[i]);
+ if(flip)
+ vN[i] = -vN[i];
+ }
}
- for(size_t i = 0; i < verts_size; i++) {
- vN[i] = normalize(vN[i]);
- if(flip)
- vN[i] = -vN[i];
+ /* motion vertex normals */
+ Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ if(has_motion_blur() && attr_mP && !attr_mN) {
+ /* create attribute */
+ attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
+
+ for(int step = 0; step < motion_steps - 1; step++) {
+ float3 *mP = attr_mP->data_float3() + step*verts.size();
+ float3 *mN = attr_mN->data_float3() + step*verts.size();
+
+ /* compute */
+ memset(mN, 0, verts.size()*sizeof(float3));
+
+ if(triangles_size) {
+ Triangle *triangles_ptr = &triangles[0];
+
+ for(size_t i = 0; i < triangles_size; i++) {
+ for(size_t j = 0; j < 3; j++) {
+ float3 fN = compute_face_normal(triangles_ptr[i], mP);
+ mN[triangles_ptr[i].v[j]] += fN;
+ }
+ }
+ }
+
+ for(size_t i = 0; i < verts_size; i++) {
+ mN[i] = normalize(mN[i]);
+ if(flip)
+ mN[i] = -mN[i];
+ }
+ }
}
}
@@ -335,18 +459,14 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
{
size_t curve_keys_size = curve_keys.size();
- CurveKey *keys_ptr = NULL;
+ float4 *keys_ptr = NULL;
/* pack curve keys */
if(curve_keys_size) {
keys_ptr = &curve_keys[0];
- for(size_t i = 0; i < curve_keys_size; i++) {
- float3 p = keys_ptr[i].co;
- float radius = keys_ptr[i].radius;
-
- curve_key_co[i] = make_float4(p.x, p.y, p.z, radius);
- }
+ for(size_t i = 0; i < curve_keys_size; i++)
+ curve_key_co[i] = keys_ptr[i];
}
/* pack curve segments */
@@ -430,6 +550,13 @@ void Mesh::tag_update(Scene *scene, bool rebuild)
scene->object_manager->need_update = true;
}
+bool Mesh::has_motion_blur() const
+{
+ return (use_motion_blur &&
+ (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
+ curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)));
+}
+
/* Mesh Manager */
MeshManager::MeshManager()
@@ -641,10 +768,16 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
size_t size = mattr->element_size(
mesh->verts.size(),
mesh->triangles.size(),
+ mesh->motion_steps,
mesh->curves.size(),
mesh->curve_keys.size());
- if(mattr->type == TypeDesc::TypeFloat) {
+ if(mattr->element == ATTR_ELEMENT_VOXEL) {
+ /* store slot in offset value */
+ VoxelAttribute *voxel_data = mattr->data_voxel();
+ offset = voxel_data->slot;
+ }
+ else if(mattr->type == TypeDesc::TypeFloat) {
float *data = mattr->data_float();
offset = attr_float.size();
@@ -663,19 +796,21 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
attr_float3[offset+k] = (&tfm->x)[k];
}
else {
- float3 *data = mattr->data_float3();
+ float4 *data = mattr->data_float4();
offset = attr_float3.size();
attr_float3.resize(attr_float3.size() + size);
for(size_t k = 0; k < size; k++)
- attr_float3[offset+k] = float3_to_float4(data[k]);
+ attr_float3[offset+k] = data[k];
}
/* mesh vertex/curve index is global, not per object, so we sneak
* a correction for that in here */
if(element == ATTR_ELEMENT_VERTEX)
offset -= mesh->vert_offset;
+ else if(element == ATTR_ELEMENT_VERTEX_MOTION)
+ offset -= mesh->vert_offset;
else if(element == ATTR_ELEMENT_FACE)
offset -= mesh->tri_offset;
else if(element == ATTR_ELEMENT_CORNER)
@@ -684,6 +819,8 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
offset -= mesh->curve_offset;
else if(element == ATTR_ELEMENT_CURVE_KEY)
offset -= mesh->curvekey_offset;
+ else if(element == ATTR_ELEMENT_CURVE_KEY_MOTION)
+ offset -= mesh->curvekey_offset;
}
else {
/* attribute not found */
@@ -750,8 +887,8 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
/* create attribute lookup maps */
if(scene->shader_manager->use_osl())
update_osl_attributes(device, scene, mesh_attributes);
- else
- update_svm_attributes(device, dscene, scene, mesh_attributes);
+
+ update_svm_attributes(device, dscene, scene, mesh_attributes);
if(progress.get_cancel()) return;
@@ -866,9 +1003,9 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
device->tex_alloc("__tri_woop", dscene->tri_woop);
}
- if(pack.prim_segment.size()) {
- dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size());
- device->tex_alloc("__prim_segment", dscene->prim_segment);
+ if(pack.prim_type.size()) {
+ dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size());
+ device->tex_alloc("__prim_type", dscene->prim_type);
}
if(pack.prim_visibility.size()) {
dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
@@ -956,7 +1093,6 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
foreach(Shader *shader, scene->shaders)
shader->need_update_attributes = false;
- float shuttertime = scene->camera->shuttertime;
#ifdef __OBJECT_MOTION__
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
bool motion_blur = need_motion == Scene::MOTION_BLUR;
@@ -965,7 +1101,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
#endif
foreach(Object *object, scene->objects)
- object->compute_bounds(motion_blur, shuttertime);
+ object->compute_bounds(motion_blur);
if(progress.get_cancel()) return;
@@ -979,7 +1115,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->bvh_nodes);
device->tex_free(dscene->object_node);
device->tex_free(dscene->tri_woop);
- device->tex_free(dscene->prim_segment);
+ device->tex_free(dscene->prim_type);
device->tex_free(dscene->prim_visibility);
device->tex_free(dscene->prim_index);
device->tex_free(dscene->prim_object);
@@ -996,7 +1132,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->bvh_nodes.clear();
dscene->object_node.clear();
dscene->tri_woop.clear();
- dscene->prim_segment.clear();
+ dscene->prim_type.clear();
dscene->prim_visibility.clear();
dscene->prim_index.clear();
dscene->prim_object.clear();
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 281a8f0645e..247e3dd555e 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -46,6 +46,8 @@ public:
/* Mesh Triangle */
struct Triangle {
int v[3];
+
+ void bounds_grow(const float3 *verts, BoundBox& bounds) const;
};
/* Mesh Curve */
@@ -55,11 +57,8 @@ public:
uint shader;
int num_segments() { return num_keys - 1; }
- };
- struct CurveKey {
- float3 co;
- float radius;
+ void bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const;
};
/* Displacement */
@@ -77,7 +76,7 @@ public:
vector<uint> shader;
vector<bool> smooth;
- vector<CurveKey> curve_keys;
+ vector<float4> curve_keys; /* co + radius */
vector<Curve> curves;
vector<uint> used_shaders;
@@ -90,6 +89,9 @@ public:
Transform transform_normal;
DisplacementMethod displacement_method;
+ uint motion_steps;
+ bool use_motion_blur;
+
/* Update Flags */
bool need_update;
bool need_update_rebuild;
@@ -112,6 +114,7 @@ public:
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
void add_curve_key(float3 loc, float radius);
void add_curve(int first_key, int num_keys, int shader);
+ int split_vertex(int vertex);
void compute_bounds();
void add_face_normals();
@@ -126,6 +129,8 @@ public:
bool need_attribute(Scene *scene, ustring name);
void tag_update(Scene *scene, bool rebuild);
+
+ bool has_motion_blur() const;
};
/* Mesh Manager */
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index 2fd8a978511..661fd9c66c1 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -44,7 +44,7 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me
progress.set_status("Updating Mesh", msg);
/* find object index. todo: is arbitrary */
- size_t object_index = ~0;
+ size_t object_index = OBJECT_NONE;
for(size_t i = 0; i < scene->objects.size(); i++) {
if(scene->objects[i]->mesh == mesh) {
@@ -119,17 +119,21 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me
task.shader_eval_type = SHADER_EVAL_DISPLACE;
task.shader_x = 0;
task.shader_w = d_output.size();
+ task.get_cancel = function_bind(&Progress::get_cancel, &progress);
device->task_add(task);
device->task_wait();
+ if(progress.get_cancel()) {
+ device->mem_free(d_input);
+ device->mem_free(d_output);
+ return false;
+ }
+
device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
device->mem_free(d_input);
device->mem_free(d_output);
- if(progress.get_cancel())
- return false;
-
/* read result */
done.clear();
done.resize(mesh->verts.size(), false);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index af6fca29ab0..a53e0b39435 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -189,10 +189,12 @@ ImageTextureNode::ImageTextureNode()
slot = -1;
is_float = -1;
is_linear = false;
+ use_alpha = true;
filename = "";
builtin_data = NULL;
color_space = ustring("Color");
projection = ustring("Flat");
+ interpolation = INTERPOLATION_LINEAR;
projection_blend = 0.0f;
animated = false;
@@ -204,7 +206,7 @@ ImageTextureNode::ImageTextureNode()
ImageTextureNode::~ImageTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename, builtin_data);
+ image_manager->remove_image(filename, builtin_data, interpolation);
}
ShaderNode *ImageTextureNode::clone() const
@@ -241,7 +243,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(is_float == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
+ slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear, interpolation, use_alpha);
is_float = (int)is_float_bool;
}
@@ -315,6 +317,22 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("projection_blend", projection_blend);
compiler.parameter("is_float", is_float);
compiler.parameter("use_alpha", !alpha_out->links.empty());
+
+ switch (interpolation) {
+ case INTERPOLATION_CLOSEST:
+ compiler.parameter("interpolation", "closest");
+ break;
+ case INTERPOLATION_CUBIC:
+ compiler.parameter("interpolation", "cubic");
+ break;
+ case INTERPOLATION_SMART:
+ compiler.parameter("interpolation", "smart");
+ break;
+ case INTERPOLATION_LINEAR:
+ default:
+ compiler.parameter("interpolation", "linear");
+ break;
+ }
compiler.add(this, "node_image_texture");
}
@@ -340,6 +358,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
slot = -1;
is_float = -1;
is_linear = false;
+ use_alpha = true;
filename = "";
builtin_data = NULL;
color_space = ustring("Color");
@@ -354,7 +373,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
EnvironmentTextureNode::~EnvironmentTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename, builtin_data);
+ image_manager->remove_image(filename, builtin_data, INTERPOLATION_LINEAR);
}
ShaderNode *EnvironmentTextureNode::clone() const
@@ -389,7 +408,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
+ slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear, INTERPOLATION_LINEAR, use_alpha);
is_float = (int)is_float_bool;
}
@@ -565,13 +584,13 @@ static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidi
/* Copy values from sky_state to SunSky */
for (int i = 0; i < 9; ++i) {
- sunsky->config_x[i] = sky_state->configs[0][i];
- sunsky->config_y[i] = sky_state->configs[1][i];
- sunsky->config_z[i] = sky_state->configs[2][i];
+ sunsky->config_x[i] = (float)sky_state->configs[0][i];
+ sunsky->config_y[i] = (float)sky_state->configs[1][i];
+ sunsky->config_z[i] = (float)sky_state->configs[2][i];
}
- sunsky->radiance_x = sky_state->radiances[0];
- sunsky->radiance_y = sky_state->radiances[1];
- sunsky->radiance_z = sky_state->radiances[2];
+ sunsky->radiance_x = (float)sky_state->radiances[0];
+ sunsky->radiance_y = (float)sky_state->radiances[1];
+ sunsky->radiance_z = (float)sky_state->radiances[2];
/* Free sky_state */
arhosekskymodelstate_free(sky_state);
@@ -612,6 +631,8 @@ void SkyTextureNode::compile(SVMCompiler& compiler)
sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
else if(type_enum[type] == NODE_SKY_NEW)
sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ else
+ assert(false);
if(vector_in->link)
compiler.stack_assign(vector_in);
@@ -649,6 +670,8 @@ void SkyTextureNode::compile(OSLCompiler& compiler)
sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
else if(type_enum[type] == NODE_SKY_NEW)
sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
+ else
+ assert(false);
compiler.parameter("sky_model", type);
compiler.parameter("theta", sunsky.theta);
@@ -2192,8 +2215,9 @@ void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attr
if(shader->has_volume) {
if(!from_dupli) {
- if(!output("Generated")->links.empty())
+ if(!output("Generated")->links.empty()) {
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
}
}
@@ -2310,6 +2334,78 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_texture_coordinate");
}
+UVMapNode::UVMapNode()
+: ShaderNode("uvmap")
+{
+ attribute = "";
+ from_dupli = false;
+
+ add_output("UV", SHADER_SOCKET_POINT);
+}
+
+void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
+{
+ if(shader->has_surface) {
+ if(!from_dupli) {
+ if(!output("UV")->links.empty()) {
+ if (attribute != "")
+ attributes->add(attribute);
+ else
+ attributes->add(ATTR_STD_UV);
+ }
+ }
+ }
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void UVMapNode::compile(SVMCompiler& compiler)
+{
+ ShaderOutput *out = output("UV");
+ NodeType texco_node = NODE_TEX_COORD;
+ NodeType attr_node = NODE_ATTR;
+ int attr;
+
+ if(bump == SHADER_BUMP_DX) {
+ texco_node = NODE_TEX_COORD_BUMP_DX;
+ attr_node = NODE_ATTR_BUMP_DX;
+ }
+ else if(bump == SHADER_BUMP_DY) {
+ texco_node = NODE_TEX_COORD_BUMP_DY;
+ attr_node = NODE_ATTR_BUMP_DY;
+ }
+
+ if(!out->links.empty()) {
+ if(from_dupli) {
+ compiler.stack_assign(out);
+ compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, out->stack_offset);
+ }
+ else {
+ if (attribute != "")
+ attr = compiler.attribute(attribute);
+ else
+ attr = compiler.attribute(ATTR_STD_UV);
+
+ compiler.stack_assign(out);
+ compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+ }
+ }
+}
+
+void UVMapNode::compile(OSLCompiler& compiler)
+{
+ if(bump == SHADER_BUMP_DX)
+ compiler.parameter("bump_offset", "dx");
+ else if(bump == SHADER_BUMP_DY)
+ compiler.parameter("bump_offset", "dy");
+ else
+ compiler.parameter("bump_offset", "center");
+
+ compiler.parameter("from_dupli", from_dupli);
+ compiler.parameter("name", attribute.c_str());
+ compiler.add(this, "node_uv_map");
+}
+
/* Light Path */
LightPathNode::LightPathNode()
@@ -2325,6 +2421,7 @@ LightPathNode::LightPathNode()
add_output("Is Volume Scatter Ray", SHADER_SOCKET_FLOAT);
add_output("Ray Length", SHADER_SOCKET_FLOAT);
add_output("Ray Depth", SHADER_SOCKET_FLOAT);
+ add_output("Transparent Depth", SHADER_SOCKET_FLOAT);
}
void LightPathNode::compile(SVMCompiler& compiler)
@@ -2392,6 +2489,11 @@ void LightPathNode::compile(SVMCompiler& compiler)
compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, out->stack_offset);
}
+ out = output("Transparent Depth");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, out->stack_offset);
+ }
}
void LightPathNode::compile(OSLCompiler& compiler)
@@ -2612,7 +2714,7 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
if(!intercept_out->links.empty())
attributes->add(ATTR_STD_CURVE_INTERCEPT);
}
-
+
ShaderNode::attributes(shader, attributes);
}
@@ -3126,15 +3228,22 @@ AttributeNode::AttributeNode()
void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- ShaderOutput *color_out = output("Color");
- ShaderOutput *vector_out = output("Vector");
- ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *vector_out = output("Vector");
+ ShaderOutput *fac_out = output("Fac");
- if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty())
+ if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) {
+ AttributeStandard std = Attribute::name_standard(attribute.c_str());
+
+ if(std != ATTR_STD_NONE)
+ attributes->add(std);
+ else
attributes->add(attribute);
}
-
+
+ if(shader->has_volume)
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+
ShaderNode::attributes(shader, attributes);
}
@@ -3144,6 +3253,13 @@ void AttributeNode::compile(SVMCompiler& compiler)
ShaderOutput *vector_out = output("Vector");
ShaderOutput *fac_out = output("Fac");
NodeType attr_node = NODE_ATTR;
+ AttributeStandard std = Attribute::name_standard(attribute.c_str());
+ int attr;
+
+ if(std != ATTR_STD_NONE)
+ attr = compiler.attribute(std);
+ else
+ attr = compiler.attribute(attribute);
if(bump == SHADER_BUMP_DX)
attr_node = NODE_ATTR_BUMP_DX;
@@ -3151,8 +3267,6 @@ void AttributeNode::compile(SVMCompiler& compiler)
attr_node = NODE_ATTR_BUMP_DY;
if(!color_out->links.empty() || !vector_out->links.empty()) {
- int attr = compiler.attribute(attribute);
-
if(!color_out->links.empty()) {
compiler.stack_assign(color_out);
compiler.add_node(attr_node, attr, color_out->stack_offset, NODE_ATTR_FLOAT3);
@@ -3164,8 +3278,6 @@ void AttributeNode::compile(SVMCompiler& compiler)
}
if(!fac_out->links.empty()) {
- int attr = compiler.attribute(attribute);
-
compiler.stack_assign(fac_out);
compiler.add_node(attr_node, attr, fac_out->stack_offset, NODE_ATTR_FLOAT);
}
@@ -3179,8 +3291,12 @@ void AttributeNode::compile(OSLCompiler& compiler)
compiler.parameter("bump_offset", "dy");
else
compiler.parameter("bump_offset", "center");
+
+ if(Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
+ compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
+ else
+ compiler.parameter("name", attribute.c_str());
- compiler.parameter("name", attribute.c_str());
compiler.add(this, "node_attribute");
}
@@ -3428,6 +3544,7 @@ static ShaderEnum math_type_init()
enm.insert("Less Than", NODE_MATH_LESS_THAN);
enm.insert("Greater Than", NODE_MATH_GREATER_THAN);
enm.insert("Modulo", NODE_MATH_MODULO);
+ enm.insert("Absolute", NODE_MATH_ABSOLUTE);
return enm;
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 86c4f490875..d94d8ce6033 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -72,10 +72,12 @@ public:
int slot;
int is_float;
bool is_linear;
+ bool use_alpha;
string filename;
void *builtin_data;
ustring color_space;
ustring projection;
+ InterpolationType interpolation;
float projection_blend;
bool animated;
@@ -94,6 +96,7 @@ public:
int slot;
int is_float;
bool is_linear;
+ bool use_alpha;
string filename;
void *builtin_data;
ustring color_space;
@@ -208,6 +211,7 @@ public:
BsdfNode(bool scattering = false);
SHADER_NODE_BASE_CLASS(BsdfNode);
+ bool has_spatial_varying() { return true; }
void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
ClosureType closure;
@@ -279,6 +283,7 @@ public:
SHADER_NODE_CLASS(SubsurfaceScatteringNode)
bool has_surface_bssrdf() { return true; }
bool has_bssrdf_bump();
+ bool has_spatial_varying() { return true; }
static ShaderEnum falloff_enum;
};
@@ -288,6 +293,7 @@ public:
SHADER_NODE_CLASS(EmissionNode)
bool has_surface_emission() { return true; }
+ bool has_spatial_varying() { return true; }
bool total_power;
};
@@ -305,6 +311,8 @@ public:
class AmbientOcclusionNode : public ShaderNode {
public:
SHADER_NODE_CLASS(AmbientOcclusionNode)
+
+ bool has_spatial_varying() { return true; }
};
class VolumeNode : public ShaderNode {
@@ -339,16 +347,28 @@ class GeometryNode : public ShaderNode {
public:
SHADER_NODE_CLASS(GeometryNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
};
class TextureCoordinateNode : public ShaderNode {
public:
SHADER_NODE_CLASS(TextureCoordinateNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
bool from_dupli;
};
+class UVMapNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(UVMapNode)
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
+
+ ustring attribute;
+ bool from_dupli;
+};
+
class LightPathNode : public ShaderNode {
public:
SHADER_NODE_CLASS(LightPathNode)
@@ -357,6 +377,7 @@ public:
class LightFalloffNode : public ShaderNode {
public:
SHADER_NODE_CLASS(LightFalloffNode)
+ bool has_spatial_varying() { return true; }
};
class ObjectInfoNode : public ShaderNode {
@@ -375,6 +396,7 @@ public:
SHADER_NODE_CLASS(HairInfoNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
};
class ValueNode : public ShaderNode {
@@ -460,6 +482,7 @@ class AttributeNode : public ShaderNode {
public:
SHADER_NODE_CLASS(AttributeNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
ustring attribute;
};
@@ -467,21 +490,25 @@ public:
class CameraNode : public ShaderNode {
public:
SHADER_NODE_CLASS(CameraNode)
+ bool has_spatial_varying() { return true; }
};
class FresnelNode : public ShaderNode {
public:
SHADER_NODE_CLASS(FresnelNode)
+ bool has_spatial_varying() { return true; }
};
class LayerWeightNode : public ShaderNode {
public:
SHADER_NODE_CLASS(LayerWeightNode)
+ bool has_spatial_varying() { return true; }
};
class WireframeNode : public ShaderNode {
public:
SHADER_NODE_CLASS(WireframeNode)
+ bool has_spatial_varying() { return true; }
bool use_pixel_size;
};
@@ -538,6 +565,8 @@ public:
class BumpNode : public ShaderNode {
public:
SHADER_NODE_CLASS(BumpNode)
+ bool has_spatial_varying() { return true; }
+
bool invert;
};
@@ -568,6 +597,10 @@ public:
class OSLScriptNode : public ShaderNode {
public:
SHADER_NODE_CLASS(OSLScriptNode)
+
+ /* ideally we could beter detect this, but we can't query this now */
+ bool has_spatial_varying() { return true; }
+
string filepath;
string bytecode_hash;
@@ -581,6 +614,7 @@ class NormalMapNode : public ShaderNode {
public:
SHADER_NODE_CLASS(NormalMapNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
ustring space;
static ShaderEnum space_enum;
@@ -592,6 +626,7 @@ class TangentNode : public ShaderNode {
public:
SHADER_NODE_CLASS(TangentNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
+ bool has_spatial_varying() { return true; }
ustring direction_type;
static ShaderEnum direction_type_enum;
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 3edb934ef2c..027bfd71931 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -19,6 +19,7 @@
#include "mesh.h"
#include "curves.h"
#include "object.h"
+#include "particles.h"
#include "scene.h"
#include "util_foreach.h"
@@ -38,7 +39,8 @@ Object::Object()
visibility = ~0;
random_id = 0;
pass_id = 0;
- particle_id = 0;
+ particle_system = NULL;
+ particle_index = 0;
bounds = BoundBox::empty;
motion.pre = transform_identity();
motion.mid = transform_identity();
@@ -53,7 +55,7 @@ Object::~Object()
{
}
-void Object::compute_bounds(bool motion_blur, float shuttertime)
+void Object::compute_bounds(bool motion_blur)
{
BoundBox mbounds = mesh->bounds;
@@ -66,10 +68,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime)
/* todo: this is really terrible. according to pbrt there is a better
* way to find this iteratively, but did not find implementation yet
* or try to implement myself */
- float start_t = 0.5f - shuttertime*0.25f;
- float end_t = 0.5f + shuttertime*0.25f;
-
- for(float t = start_t; t < end_t; t += (1.0f/128.0f)*shuttertime) {
+ for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
transform_motion_interpolate(&ttfm, &decomp, t);
@@ -80,29 +79,83 @@ void Object::compute_bounds(bool motion_blur, float shuttertime)
bounds = mbounds.transformed(&tfm);
}
-void Object::apply_transform()
+void Object::apply_transform(bool apply_to_motion)
{
if(!mesh || tfm == transform_identity())
return;
+
+ /* triangles */
+ if(mesh->verts.size()) {
+ /* store matrix to transform later. when accessing these as attributes we
+ * do not want the transform to be applied for consistency between static
+ * and dynamic BVH, so we do it on packing. */
+ mesh->transform_normal = transform_transpose(transform_inverse(tfm));
+
+ /* apply to mesh vertices */
+ for(size_t i = 0; i < mesh->verts.size(); i++)
+ mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
+
+ if(apply_to_motion) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (attr) {
+ size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps_size; i++)
+ vert_steps[i] = transform_point(&tfm, vert_steps[i]);
+ }
- float3 c0 = transform_get_column(&tfm, 0);
- float3 c1 = transform_get_column(&tfm, 1);
- float3 c2 = transform_get_column(&tfm, 2);
- float scalar = pow(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
+ Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
- for(size_t i = 0; i < mesh->verts.size(); i++)
- mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
+ if(attr_N) {
+ Transform ntfm = mesh->transform_normal;
+ size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1);
+ float3 *normal_steps = attr_N->data_float3();
- for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
- mesh->curve_keys[i].co = transform_point(&tfm, mesh->curve_keys[i].co);
- /* scale for strand radius - only correct for uniform transforms*/
- mesh->curve_keys[i].radius *= scalar;
+ for (size_t i = 0; i < steps_size; i++)
+ normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
+ }
+ }
}
- /* store matrix to transform later. when accessing these as attributes we
- * do not want the transform to be applied for consistency between static
- * and dynamic BVH, so we do it on packing. */
- mesh->transform_normal = transform_transpose(transform_inverse(tfm));
+ /* curves */
+ if(mesh->curve_keys.size()) {
+ /* compute uniform scale */
+ float3 c0 = transform_get_column(&tfm, 0);
+ float3 c1 = transform_get_column(&tfm, 1);
+ float3 c2 = transform_get_column(&tfm, 2);
+ float scalar = pow(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
+
+ /* apply transform to curve keys */
+ for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
+ float3 co = transform_point(&tfm, float4_to_float3(mesh->curve_keys[i]));
+ float radius = mesh->curve_keys[i].w * scalar;
+
+ /* scale for curve radius is only correct for uniform scale */
+ mesh->curve_keys[i] = float3_to_float4(co);
+ mesh->curve_keys[i].w = radius;
+ }
+
+ if(apply_to_motion) {
+ Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if (curve_attr) {
+ /* apply transform to motion curve keys */
+ size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
+ float4 *key_steps = curve_attr->data_float4();
+
+ for (size_t i = 0; i < steps_size; i++) {
+ float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
+ float radius = key_steps[i].w * scalar;
+
+ /* scale for curve radius is only correct for uniform scale */
+ key_steps[i] = float3_to_float4(co);
+ key_steps[i].w = radius;
+ }
+ }
+ }
+ }
/* we keep normals pointing in same direction on negative scale, notify
* mesh about this in it (re)calculates normals */
@@ -111,7 +164,7 @@ void Object::apply_transform()
if(bounds.valid()) {
mesh->compute_bounds();
- compute_bounds(false, 0.0f);
+ compute_bounds(false);
}
/* tfm is not reset to identity, all code that uses it needs to check the
@@ -137,6 +190,26 @@ void Object::tag_update(Scene *scene)
scene->object_manager->need_update = true;
}
+vector<float> Object::motion_times()
+{
+ /* compute times at which we sample motion for this object */
+ vector<float> times;
+
+ if(!mesh || mesh->motion_steps == 1)
+ return times;
+
+ int motion_steps = mesh->motion_steps;
+
+ for(int step = 0; step < motion_steps; step++) {
+ if(step != motion_steps / 2) {
+ float time = 2.0f * step / (motion_steps - 1) - 1.0f;
+ times.push_back(time);
+ }
+ }
+
+ return times;
+}
+
/* Object Manager */
ObjectManager::ObjectManager()
@@ -154,6 +227,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
float4 *objects_vector = NULL;
int i = 0;
map<Mesh*, float> surface_area_map;
+ map<ParticleSystem*, int> particle_offset;
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
bool have_motion = false;
bool have_curves = false;
@@ -162,6 +236,15 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
if(need_motion == Scene::MOTION_PASS)
objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
+ /* particle system device offsets
+ * 0 is dummy particle, index starts at 1
+ */
+ int numparticles = 1;
+ foreach(ParticleSystem *psys, scene->particle_systems) {
+ particle_offset[psys] = numparticles;
+ numparticles += psys->particles.size();
+ }
+
foreach(Object *ob, scene->objects) {
Mesh *mesh = ob->mesh;
uint flag = 0;
@@ -177,6 +260,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
float surface_area = 0.0f;
float pass_id = ob->pass_id;
float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
+ int particle_index = (ob->particle_system)? ob->particle_index + particle_offset[ob->particle_system]: 0;
if(transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -190,20 +274,6 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
- foreach(Mesh::Curve& curve, mesh->curves) {
- int first_key = curve.first_key;
-
- for(int i = 0; i < curve.num_segments(); i++) {
- float3 p1 = mesh->curve_keys[first_key + i].co;
- float r1 = mesh->curve_keys[first_key + i].radius;
- float3 p2 = mesh->curve_keys[first_key + i + 1].co;
- float r2 = mesh->curve_keys[first_key + i + 1].radius;
-
- /* currently ignores segment overlaps*/
- surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
- }
- }
-
surface_area_map[mesh] = surface_area;
}
else
@@ -219,31 +289,17 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
-
- foreach(Mesh::Curve& curve, mesh->curves) {
- int first_key = curve.first_key;
-
- for(int i = 0; i < curve.num_segments(); i++) {
- float3 p1 = mesh->curve_keys[first_key + i].co;
- float r1 = mesh->curve_keys[first_key + i].radius;
- float3 p2 = mesh->curve_keys[first_key + i + 1].co;
- float r2 = mesh->curve_keys[first_key + i + 1].radius;
-
- p1 = transform_point(&tfm, p1);
- p2 = transform_point(&tfm, p2);
-
- /* currently ignores segment overlaps*/
- surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
- }
- }
}
/* pack in texture */
int offset = i*OBJECT_SIZE;
+ /* OBJECT_TRANSFORM */
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
+ /* OBJECT_INVERSE_TRANSFORM */
memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
- objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
+ /* OBJECT_PROPERTIES */
+ objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(particle_index));
if(need_motion == Scene::MOTION_PASS) {
/* motion transformations, is world/object space depending if mesh
@@ -252,10 +308,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
Transform mtfm_pre = ob->motion.pre;
Transform mtfm_post = ob->motion.post;
- if(!(mesh->attributes.find(ATTR_STD_MOTION_PRE) || mesh->curve_attributes.find(ATTR_STD_MOTION_PRE)))
+ if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
mtfm_pre = mtfm_pre * itfm;
- if(!(mesh->attributes.find(ATTR_STD_MOTION_POST) || mesh->curve_attributes.find(ATTR_STD_MOTION_POST)))
mtfm_post = mtfm_post * itfm;
+ }
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
@@ -274,9 +330,17 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
}
#endif
- /* dupli object coords */
- objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
- objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+ if(mesh->use_motion_blur)
+ have_motion = true;
+
+ /* dupli object coords and motion info */
+ int totalsteps = mesh->motion_steps;
+ int numsteps = (totalsteps - 1)/2;
+ int numverts = mesh->verts.size();
+ int numkeys = mesh->curve_keys.size();
+
+ objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], __int_as_float(numkeys));
+ objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], __int_as_float(numsteps), __int_as_float(numverts));
/* object flag */
if(ob->use_holdout)
@@ -355,6 +419,7 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, u
#ifdef __OBJECT_MOTION__
Scene::MotionType need_motion = scene->need_motion();
bool motion_blur = need_motion == Scene::MOTION_BLUR;
+ bool apply_to_motion = need_motion != Scene::MOTION_PASS;
#else
bool motion_blur = false;
#endif
@@ -377,7 +442,7 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, u
if(mesh_users[object->mesh] == 1) {
if(!(motion_blur && object->use_motion)) {
if(!object->mesh->transform_applied) {
- object->apply_transform();
+ object->apply_transform(apply_to_motion);
object->mesh->transform_applied = true;
if(progress.get_cancel()) return;
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 5da85be3873..677526b715f 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -27,6 +27,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Mesh;
+class ParticleSystem;
class Progress;
class Scene;
struct Transform;
@@ -50,15 +51,18 @@ public:
float3 dupli_generated;
float2 dupli_uv;
- int particle_id;
-
+ ParticleSystem *particle_system;
+ int particle_index;
+
Object();
~Object();
void tag_update(Scene *scene);
- void compute_bounds(bool motion_blur, float shuttertime);
- void apply_transform();
+ void compute_bounds(bool motion_blur);
+ void apply_transform(bool apply_to_motion);
+
+ vector<float> motion_times();
};
/* Object Manager */
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index e2798f438e2..94866102f60 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -203,7 +203,6 @@ void OSLShaderManager::shading_system_init()
"glossy", /* PATH_RAY_GLOSSY */
"singular", /* PATH_RAY_SINGULAR */
"transparent", /* PATH_RAY_TRANSPARENT */
- "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */
"shadow", /* PATH_RAY_SHADOW_OPAQUE */
"shadow", /* PATH_RAY_SHADOW_TRANSPARENT */
@@ -212,6 +211,8 @@ void OSLShaderManager::shading_system_init()
"diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
"glossy_ancestor", /* PATH_RAY_GLOSSY_ANCESTOR */
"bssrdf_ancestor", /* PATH_RAY_BSSRDF_ANCESTOR */
+ "__unused__", /* PATH_RAY_SINGLE_PASS_DONE */
+ "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */
};
const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]);
@@ -512,16 +513,14 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
}
}
- /* create shader of the appropriate type. we pass "surface" to all shaders,
- * because "volume" and "displacement" don't work yet in OSL. the shaders
- * work fine, but presumably these values would be used for more strict
- * checking, so when that is fixed, we should update the code here too. */
+ /* create shader of the appropriate type. OSL only distinguishes between "surface"
+ * and "displacement" atm */
if(current_type == SHADER_TYPE_SURFACE)
ss->Shader("surface", name, id(node).c_str());
else if(current_type == SHADER_TYPE_VOLUME)
ss->Shader("surface", name, id(node).c_str());
else if(current_type == SHADER_TYPE_DISPLACEMENT)
- ss->Shader("surface", name, id(node).c_str());
+ ss->Shader("displacement", name, id(node).c_str());
else
assert(0);
@@ -544,7 +543,7 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
/* test if we shader contains specific closures */
OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name);
- if(info) {
+ if(info && current_type == SHADER_TYPE_SURFACE) {
if(info->has_surface_emission)
current_shader->has_surface_emission = true;
if(info->has_surface_transparent)
@@ -554,6 +553,10 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
current_shader->has_bssrdf_bump = true; /* can't detect yet */
}
}
+ else if(current_type == SHADER_TYPE_VOLUME) {
+ if(node->has_spatial_varying())
+ current_shader->has_heterogeneous_volume = true;
+ }
}
void OSLCompiler::parameter(const char *name, float f)
@@ -709,14 +712,20 @@ void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes)
node->compile(*this);
done.insert(node);
- if(node->has_surface_emission())
- current_shader->has_surface_emission = true;
- if(node->has_surface_transparent())
- current_shader->has_surface_transparent = true;
- if(node->has_surface_bssrdf()) {
- current_shader->has_surface_bssrdf = true;
- if(node->has_bssrdf_bump())
- current_shader->has_bssrdf_bump = true;
+ if(current_type == SHADER_TYPE_SURFACE) {
+ if(node->has_surface_emission())
+ current_shader->has_surface_emission = true;
+ if(node->has_surface_transparent())
+ current_shader->has_surface_transparent = true;
+ if(node->has_surface_bssrdf()) {
+ current_shader->has_surface_bssrdf = true;
+ if(node->has_bssrdf_bump())
+ current_shader->has_bssrdf_bump = true;
+ }
+ }
+ else if(current_type == SHADER_TYPE_VOLUME) {
+ if(node->has_spatial_varying())
+ current_shader->has_heterogeneous_volume = true;
}
}
else
@@ -798,6 +807,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_bssrdf_bump = false;
shader->has_volume = false;
shader->has_displacement = false;
+ shader->has_heterogeneous_volume = false;
/* generate surface shader */
if(shader->used && graph && output->input("Surface")->link) {
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 71f5a9dafed..4f5ad439520 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include "background.h"
+#include "bake.h"
#include "camera.h"
#include "curves.h"
#include "device.h"
@@ -54,6 +55,7 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
image_manager = new ImageManager();
particle_system_manager = new ParticleSystemManager();
curve_system_manager = new CurveSystemManager();
+ bake_manager = new BakeManager();
/* OSL only works on the CPU */
if(device_info_.type == DEVICE_CPU)
@@ -61,8 +63,8 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
else
shader_manager = ShaderManager::create(this, SceneParams::SVM);
- if (device_info_.type == DEVICE_CPU)
- image_manager->set_extended_image_limits();
+ /* Extended image limits for CPU and GPUs */
+ image_manager->set_extended_image_limits(device_info_);
}
Scene::~Scene()
@@ -103,6 +105,8 @@ void Scene::free_memory(bool final)
particle_system_manager->device_free(device, &dscene);
curve_system_manager->device_free(device, &dscene);
+ bake_manager->device_free(device, &dscene);
+
if(!params.persistent_data || final)
image_manager->device_free(device, &dscene);
@@ -122,6 +126,7 @@ void Scene::free_memory(bool final)
delete particle_system_manager;
delete curve_system_manager;
delete image_manager;
+ delete bake_manager;
}
}
@@ -137,6 +142,8 @@ void Scene::device_update(Device *device_, Progress& progress)
* - Camera may be used for adapative subdivison.
* - Displacement shader must have all shader data available.
* - Light manager needs lookup tables and final mesh data to compute emission CDF.
+ * - Film needs light manager to run for use_light_visibility
+ * - Lookup tables are done a second time to handle film tables
*/
image_manager->set_pack_images(device->info.pack_images);
@@ -171,11 +178,6 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
- progress.set_status("Updating Film");
- film->device_update(device, &dscene, this);
-
- if(progress.get_cancel()) return;
-
progress.set_status("Updating Lookup Tables");
lookup_tables->device_update(device, &dscene);
@@ -196,11 +198,26 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
+ progress.set_status("Updating Film");
+ film->device_update(device, &dscene, this);
+
+ if(progress.get_cancel()) return;
+
progress.set_status("Updating Integrator");
integrator->device_update(device, &dscene, this);
if(progress.get_cancel()) return;
+ progress.set_status("Updating Lookup Tables");
+ lookup_tables->device_update(device, &dscene);
+
+ if(progress.get_cancel()) return;
+
+ progress.set_status("Updating Baking");
+ bake_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel()) return;
+
progress.set_status("Updating Device", "Writing constant memory");
device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
}
@@ -219,8 +236,10 @@ bool Scene::need_global_attribute(AttributeStandard std)
{
if(std == ATTR_STD_UV)
return Pass::contains(film->passes, PASS_UV);
- if(std == ATTR_STD_MOTION_PRE || std == ATTR_STD_MOTION_POST)
- return need_motion() == MOTION_PASS;
+ else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
+ return need_motion() != MOTION_NONE;
+ else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
+ return need_motion() == MOTION_BLUR;
return false;
}
@@ -249,7 +268,8 @@ bool Scene::need_reset()
|| integrator->need_update
|| shader_manager->need_update
|| particle_system_manager->need_update
- || curve_system_manager->need_update);
+ || curve_system_manager->need_update
+ || bake_manager->need_update);
}
void Scene::reset()
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 2c223192536..0f0bb725823 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -51,6 +51,8 @@ class CurveSystemManager;
class Shader;
class ShaderManager;
class Progress;
+class BakeManager;
+class BakeData;
/* Scene Device Data */
@@ -60,7 +62,7 @@ public:
device_vector<float4> bvh_nodes;
device_vector<uint> object_node;
device_vector<float4> tri_woop;
- device_vector<uint> prim_segment;
+ device_vector<uint> prim_type;
device_vector<uint> prim_visibility;
device_vector<uint> prim_index;
device_vector<uint> prim_object;
@@ -103,8 +105,8 @@ public:
/* integrator */
device_vector<uint> sobol_directions;
- /* images */
- device_vector<uchar4> tex_image[TEX_EXTENDED_NUM_IMAGES];
+ /* cpu images */
+ device_vector<uchar4> tex_image[TEX_EXTENDED_NUM_IMAGES_CPU];
device_vector<float4> tex_float_image[TEX_EXTENDED_NUM_FLOAT_IMAGES];
/* opencl images */
@@ -174,6 +176,7 @@ public:
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
CurveSystemManager *curve_system_manager;
+ BakeManager *bake_manager;
/* default shaders */
int default_surface;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 0805a685467..28b44df6b36 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -23,6 +23,7 @@
#include "integrator.h"
#include "scene.h"
#include "session.h"
+#include "bake.h"
#include "util_foreach.h"
#include "util_function.h"
@@ -50,7 +51,7 @@ Session::Session(const SessionParams& params_)
device = Device::create(params.device, stats, params.background);
- if(params.background) {
+ if(params.background && params.output_path.empty()) {
buffers = NULL;
display = NULL;
}
@@ -81,6 +82,7 @@ Session::Session(const SessionParams& params_)
Session::~Session()
{
if(session_thread) {
+ /* wait for session thread to end */
progress.set_cancel("Exiting");
gpu_need_tonemap = false;
@@ -95,13 +97,19 @@ Session::~Session()
wait();
}
- if(display && !params.output_path.empty()) {
- tonemap();
+ if(!params.output_path.empty()) {
+ /* tonemap and write out image if requested */
+ delete display;
+
+ display = new DisplayBuffer(device, false);
+ display->reset(device, buffers->params);
+ tonemap(params.samples);
progress.set_status("Writing Image", params.output_path);
display->write(device, params.output_path);
}
+ /* clean up */
foreach(RenderBuffers *buffers, tile_buffers)
delete buffers;
@@ -151,7 +159,7 @@ void Session::reset_gpu(BufferParams& buffer_params, int samples)
pause_cond.notify_all();
}
-bool Session::draw_gpu(BufferParams& buffer_params)
+bool Session::draw_gpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
{
/* block for buffer access */
thread_scoped_lock display_lock(display_mutex);
@@ -165,12 +173,12 @@ bool Session::draw_gpu(BufferParams& buffer_params)
* only access GL buffers from the main thread */
if(gpu_need_tonemap) {
thread_scoped_lock buffers_lock(buffers_mutex);
- tonemap();
+ tonemap(tile_manager.state.sample);
gpu_need_tonemap = false;
gpu_need_tonemap_cond.notify_all();
}
- display->draw(device);
+ display->draw(device, draw_params);
if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
return false;
@@ -315,7 +323,7 @@ void Session::reset_cpu(BufferParams& buffer_params, int samples)
pause_cond.notify_all();
}
-bool Session::draw_cpu(BufferParams& buffer_params)
+bool Session::draw_cpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
{
thread_scoped_lock display_lock(display_mutex);
@@ -324,7 +332,7 @@ bool Session::draw_cpu(BufferParams& buffer_params)
/* then verify the buffers have the expected size, so we don't
* draw previous results in a resized window */
if(!buffer_params.modified(display->params)) {
- display->draw(device);
+ display->draw(device, draw_params);
if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
return false;
@@ -367,7 +375,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
/* in case of a permanent buffer, return it, otherwise we will allocate
* a new temporary buffer */
- if(!params.background) {
+ if(!(params.background && params.output_path.empty())) {
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
rtile.buffer = buffers->buffer.device_pointer;
@@ -567,8 +575,8 @@ void Session::run_cpu()
}
else if(need_tonemap) {
/* tonemap only if we do not reset, we don't we don't
- * want to show the result of an incomplete sample*/
- tonemap();
+ * want to show the result of an incomplete sample */
+ tonemap(tile_manager.state.sample);
}
if(!device->error_message().empty())
@@ -624,12 +632,12 @@ void Session::run()
progress.set_update();
}
-bool Session::draw(BufferParams& buffer_params)
+bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params)
{
if(device_use_gl)
- return draw_gpu(buffer_params);
+ return draw_gpu(buffer_params, draw_params);
else
- return draw_cpu(buffer_params);
+ return draw_cpu(buffer_params, draw_params);
}
void Session::reset_(BufferParams& buffer_params, int samples)
@@ -726,10 +734,14 @@ void Session::update_scene()
cam->tag_update();
}
- /* number of samples is needed by multi jittered sampling pattern */
+ /* number of samples is needed by multi jittered
+ * sampling pattern and by baking */
Integrator *integrator = scene->integrator;
+ BakeManager *bake_manager = scene->bake_manager;
- if(integrator->sampling_pattern == SAMPLING_PATTERN_CMJ) {
+ if(integrator->sampling_pattern == SAMPLING_PATTERN_CMJ ||
+ bake_manager->get_baking())
+ {
int aa_samples = tile_manager.num_samples;
if(aa_samples != integrator->aa_samples) {
@@ -834,7 +846,7 @@ void Session::path_trace()
device->task_add(task);
}
-void Session::tonemap()
+void Session::tonemap(int sample)
{
/* add tonemap task */
DeviceTask task(DeviceTask::FILM_CONVERT);
@@ -846,7 +858,7 @@ void Session::tonemap()
task.rgba_byte = display->rgba_byte.device_pointer;
task.rgba_half = display->rgba_half.device_pointer;
task.buffer = buffers->buffer.device_pointer;
- task.sample = tile_manager.state.sample;
+ task.sample = sample;
tile_manager.state.buffer.get_offset_stride(task.offset, task.stride);
if(task.w > 0 && task.h > 0) {
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 1227edf81b6..1e625158652 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -128,7 +128,7 @@ public:
~Session();
void start();
- bool draw(BufferParams& params);
+ bool draw(BufferParams& params, DeviceDrawParams& draw_params);
void wait();
bool ready_to_reset();
@@ -136,6 +136,7 @@ public:
void set_samples(int samples);
void set_pause(bool pause);
+ void update_scene();
void device_free();
protected:
struct DelayedReset {
@@ -147,19 +148,18 @@ protected:
void run();
- void update_scene();
void update_status_time(bool show_pause = false, bool show_done = false);
- void tonemap();
+ void tonemap(int sample);
void path_trace();
void reset_(BufferParams& params, int samples);
void run_cpu();
- bool draw_cpu(BufferParams& params);
+ bool draw_cpu(BufferParams& params, DeviceDrawParams& draw_params);
void reset_cpu(BufferParams& params, int samples);
void run_gpu();
- bool draw_gpu(BufferParams& params);
+ bool draw_gpu(BufferParams& params, DeviceDrawParams& draw_params);
void reset_gpu(BufferParams& params, int samples);
bool acquire_tile(Device *tile_device, RenderTile& tile);
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 20f0fd7ed1e..b25673b36c3 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -53,6 +53,7 @@ Shader::Shader()
has_volume = false;
has_displacement = false;
has_bssrdf_bump = false;
+ has_heterogeneous_volume = false;
used = false;
@@ -249,7 +250,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
* the case with camera inside volumes too */
flag |= SD_HAS_TRANSPARENT_SHADOW;
}
- if(shader->heterogeneous_volume)
+ if(shader->heterogeneous_volume && shader->has_heterogeneous_volume)
flag |= SD_HETEROGENEOUS_VOLUME;
if(shader->has_bssrdf_bump)
flag |= SD_HAS_BSSRDF_BUMP;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 5f87050fe19..874e8face7a 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -77,6 +77,7 @@ public:
bool has_surface_bssrdf;
bool has_converter_blackbody;
bool has_bssrdf_bump;
+ bool has_heterogeneous_volume;
/* requested mesh attributes */
AttributeRequestSet attributes;
diff --git a/intern/cycles/render/sky_model.cpp b/intern/cycles/render/sky_model.cpp
index 6f250c06bc1..adb07d9e288 100644
--- a/intern/cycles/render/sky_model.cpp
+++ b/intern/cycles/render/sky_model.cpp
@@ -310,7 +310,7 @@ double arhosekskymodel_radiance(
double wavelength
)
{
- int low_wl = (wavelength - 320.0 ) / 40.0;
+ int low_wl = (int)((wavelength - 320.0) / 40.0);
if ( low_wl < 0 || low_wl >= 11 )
return 0.0f;
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 538b1aae313..576c176759c 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -63,8 +63,6 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
}
- bool use_multi_closure = device->info.advanced_shading;
-
for(i = 0; i < scene->shaders.size(); i++) {
Shader *shader = scene->shaders[i];
@@ -75,8 +73,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
- SVMCompiler compiler(scene->shader_manager, scene->image_manager,
- use_multi_closure);
+ SVMCompiler compiler(scene->shader_manager, scene->image_manager);
compiler.background = ((int)i == scene->default_background);
compiler.compile(shader, svm_nodes, i);
}
@@ -104,7 +101,7 @@ void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s
/* Graph Compiler */
-SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_, bool use_multi_closure_)
+SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_)
{
shader_manager = shader_manager_;
image_manager = image_manager_;
@@ -114,7 +111,6 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_man
current_graph = NULL;
background = false;
mix_weight_offset = SVM_STACK_INVALID;
- use_multi_closure = use_multi_closure_;
compile_failed = false;
}
@@ -230,7 +226,8 @@ void SVMCompiler::stack_assign(ShaderInput *input)
else if(input->type == SHADER_SOCKET_VECTOR ||
input->type == SHADER_SOCKET_NORMAL ||
input->type == SHADER_SOCKET_POINT ||
- input->type == SHADER_SOCKET_COLOR) {
+ input->type == SHADER_SOCKET_COLOR)
+ {
add_node(NODE_VALUE_V, input->stack_offset);
add_node(NODE_VALUE_V, input->value);
@@ -379,6 +376,22 @@ void SVMCompiler::find_dependencies(set<ShaderNode*>& dependencies, const set<Sh
}
}
+void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done)
+{
+ node->compile(*this);
+ stack_clear_users(node, done);
+ stack_clear_temporary(node);
+
+ if(current_type == SHADER_TYPE_VOLUME) {
+ if(node->has_spatial_varying())
+ current_shader->has_heterogeneous_volume = true;
+ }
+
+ /* detect if we have a blackbody converter, to prepare lookup table */
+ if(node->has_converter_blackbody())
+ current_shader->has_converter_blackbody = true;
+}
+
void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done)
{
bool nodes_done;
@@ -396,13 +409,7 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
inputs_done = false;
if(inputs_done) {
- /* Detect if we have a blackbody converter, to prepare lookup table */
- if(node->has_converter_blackbody())
- current_shader->has_converter_blackbody = true;
-
- node->compile(*this);
- stack_clear_users(node, done);
- stack_clear_temporary(node);
+ generate_node(node, done);
done.insert(node);
}
else
@@ -412,83 +419,34 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
} while(!nodes_done);
}
-void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
+void SVMCompiler::generate_closure_node(ShaderNode *node, set<ShaderNode*>& done)
{
- if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
- ShaderInput *fin = node->input("Fac");
- ShaderInput *cl1in = node->input("Closure1");
- ShaderInput *cl2in = node->input("Closure2");
-
- /* execute dependencies for mix weight */
- if(fin) {
+ /* execute dependencies for closure */
+ foreach(ShaderInput *in, node->inputs) {
+ if(!node_skip_input(node, in) && in->link) {
set<ShaderNode*> dependencies;
- find_dependencies(dependencies, done, fin);
+ find_dependencies(dependencies, done, in);
generate_svm_nodes(dependencies, done);
-
- /* add mix node */
- stack_assign(fin);
- }
-
- int mix_offset = svm_nodes.size();
-
- if(fin)
- add_node(NODE_MIX_CLOSURE, fin->stack_offset, 0, 0);
- else
- add_node(NODE_ADD_CLOSURE, 0, 0, 0);
-
- /* generate code for closure 1
- * note we backup all compiler state and restore it afterwards, so one
- * closure choice doesn't influence the other*/
- if(cl1in->link) {
- StackBackup backup;
- stack_backup(backup, done);
-
- generate_closure(cl1in->link->parent, done);
- add_node(NODE_END, 0, 0, 0);
-
- stack_restore(backup, done);
}
- else
- add_node(NODE_END, 0, 0, 0);
-
- /* generate code for closure 2 */
- int cl2_offset = svm_nodes.size();
-
- if(cl2in->link) {
- StackBackup backup;
- stack_backup(backup, done);
-
- generate_closure(cl2in->link->parent, done);
- add_node(NODE_END, 0, 0, 0);
-
- stack_restore(backup, done);
- }
- else
- add_node(NODE_END, 0, 0, 0);
+ }
- /* set jump for mix node, -1 because offset is already
- * incremented when this jump is added to it */
- svm_nodes[mix_offset].z = cl2_offset - mix_offset - 1;
+ /* closure mix weight */
+ const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight";
+ ShaderInput *weight_in = node->input(weight_name);
- done.insert(node);
- stack_clear_users(node, done);
- stack_clear_temporary(node);
+ if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) {
+ stack_assign(weight_in);
+ mix_weight_offset = weight_in->stack_offset;
}
- else {
- /* execute dependencies for closure */
- foreach(ShaderInput *in, node->inputs) {
- if(!node_skip_input(node, in) && in->link) {
- set<ShaderNode*> dependencies;
- find_dependencies(dependencies, done, in);
- generate_svm_nodes(dependencies, done);
- }
- }
+ else
+ mix_weight_offset = SVM_STACK_INVALID;
- /* compile closure itself */
- node->compile(*this);
- stack_clear_users(node, done);
- stack_clear_temporary(node);
+ /* compile closure itself */
+ generate_node(node, done);
+ mix_weight_offset = SVM_STACK_INVALID;
+
+ if(current_type == SHADER_TYPE_SURFACE) {
if(node->has_surface_emission())
current_shader->has_surface_emission = true;
if(node->has_surface_transparent())
@@ -498,18 +456,24 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
if(node->has_bssrdf_bump())
current_shader->has_bssrdf_bump = true;
}
+ }
+}
- /* end node is added outside of this */
+void SVMCompiler::generated_shared_closure_nodes(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done, const set<ShaderNode*>& shared)
+{
+ if(shared.find(node) != shared.end()) {
+ generate_multi_closure(node, done, closure_done);
+ }
+ else {
+ foreach(ShaderInput *in, node->inputs) {
+ if(in->type == SHADER_SOCKET_CLOSURE && in->link)
+ generated_shared_closure_nodes(in->link->parent, done, closure_done, shared);
+ }
}
}
void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done)
{
- /* todo: the weak point here is that unlike the single closure sampling
- * we will evaluate all nodes even if they are used as input for closures
- * that are unused. it's not clear what would be the best way to skip such
- * nodes at runtime, especially if they are tangled up */
-
/* only generate once */
if(closure_done.find(node) != closure_done.end())
return;
@@ -520,50 +484,81 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
/* weighting is already taken care of in ShaderGraph::transform_multi_closure */
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
+ ShaderInput *facin = node->input("Fac");
- if(cl1in->link)
- generate_multi_closure(cl1in->link->parent, done, closure_done);
- if(cl2in->link)
- generate_multi_closure(cl2in->link->parent, done, closure_done);
- }
- else {
- /* execute dependencies for closure */
- foreach(ShaderInput *in, node->inputs) {
- if(!node_skip_input(node, in) && in->link) {
- set<ShaderNode*> dependencies;
- find_dependencies(dependencies, done, in);
- generate_svm_nodes(dependencies, done);
+ /* skip empty mix/add closure nodes */
+ if(!cl1in->link && !cl2in->link)
+ return;
+
+ if(facin && facin->link) {
+ /* mix closure: generate instructions to compute mix weight */
+ set<ShaderNode*> dependencies;
+ find_dependencies(dependencies, done, facin);
+ generate_svm_nodes(dependencies, done);
+
+ stack_assign(facin);
+
+ /* execute shared dependencies. this is needed to allow skipping
+ * of zero weight closures and their dependencies later, so we
+ * ensure that they only skip dependencies that are unique to them */
+ set<ShaderNode*> cl1deps, cl2deps, shareddeps;
+
+ find_dependencies(cl1deps, done, cl1in);
+ find_dependencies(cl2deps, done, cl2in);
+
+ set_intersection(cl1deps.begin(), cl1deps.end(),
+ cl2deps.begin(), cl2deps.end(),
+ std::inserter(shareddeps, shareddeps.begin()));
+
+ if(!shareddeps.empty()) {
+ if(cl1in->link)
+ generated_shared_closure_nodes(cl1in->link->parent, done, closure_done, shareddeps);
+ if(cl2in->link)
+ generated_shared_closure_nodes(cl2in->link->parent, done, closure_done, shareddeps);
+
+ generate_svm_nodes(shareddeps, done);
}
- }
- /* closure mix weight */
- const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight";
- ShaderInput *weight_in = node->input(weight_name);
+ /* generate instructions for input closure 1 */
+ if(cl1in->link) {
+ /* add instruction to skip closure and its dependencies if mix weight is zero */
+ svm_nodes.push_back(make_int4(NODE_JUMP_IF_ONE, 0, facin->stack_offset, 0));
+ int node_jump_skip_index = svm_nodes.size() - 1;
- if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) {
- stack_assign(weight_in);
- mix_weight_offset = weight_in->stack_offset;
- }
- else
- mix_weight_offset = SVM_STACK_INVALID;
+ generate_multi_closure(cl1in->link->parent, done, closure_done);
- /* compile closure itself */
- node->compile(*this);
- stack_clear_users(node, done);
- stack_clear_temporary(node);
+ /* fill in jump instruction location to be after closure */
+ svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
+ }
- mix_weight_offset = SVM_STACK_INVALID;
+ /* generate instructions for input closure 2 */
+ if(cl2in->link) {
+ /* add instruction to skip closure and its dependencies if mix weight is zero */
+ svm_nodes.push_back(make_int4(NODE_JUMP_IF_ZERO, 0, facin->stack_offset, 0));
+ int node_jump_skip_index = svm_nodes.size() - 1;
- if(node->has_surface_emission())
- current_shader->has_surface_emission = true;
- if(node->has_surface_transparent())
- current_shader->has_surface_transparent = true;
- if(node->has_surface_bssrdf()) {
- current_shader->has_surface_bssrdf = true;
- if(node->has_bssrdf_bump())
- current_shader->has_bssrdf_bump = true;
+ generate_multi_closure(cl2in->link->parent, done, closure_done);
+
+ /* fill in jump instruction location to be after closure */
+ svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
+ }
+
+ /* unassign */
+ facin->stack_offset = SVM_STACK_INVALID;
+ }
+ else {
+ /* execute closures and their dependencies, no runtime checks
+ * to skip closures here because was already optimized due to
+ * fixed weight or add closure that always needs both */
+ if(cl1in->link)
+ generate_multi_closure(cl1in->link->parent, done, closure_done);
+ if(cl2in->link)
+ generate_multi_closure(cl2in->link->parent, done, closure_done);
}
}
+ else {
+ generate_closure_node(node, done);
+ }
done.insert(node);
}
@@ -642,14 +637,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
}
if(generate) {
- set<ShaderNode*> done;
-
- if(use_multi_closure) {
- set<ShaderNode*> closure_done;
- generate_multi_closure(clin->link->parent, done, closure_done);
- }
- else
- generate_closure(clin->link->parent, done);
+ set<ShaderNode*> done, closure_done;
+ generate_multi_closure(clin->link->parent, done, closure_done);
}
}
@@ -676,9 +665,9 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->graph_bump = shader->graph->copy();
/* finalize */
- shader->graph->finalize(false, false, use_multi_closure);
+ shader->graph->finalize(false, false);
if(shader->graph_bump)
- shader->graph_bump->finalize(true, false, use_multi_closure);
+ shader->graph_bump->finalize(true, false);
current_shader = shader;
@@ -690,6 +679,7 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->has_converter_blackbody = false;
shader->has_volume = false;
shader->has_displacement = false;
+ shader->has_heterogeneous_volume = false;
/* generate surface shader */
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index 3d84a67e173..45aa4d26926 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -52,8 +52,7 @@ public:
class SVMCompiler {
public:
- SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager,
- bool use_multi_closure_);
+ SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager);
void compile(Shader *shader, vector<int4>& svm_nodes, int index);
void stack_assign(ShaderOutput *output);
@@ -123,9 +122,13 @@ protected:
bool node_skip_input(ShaderNode *node, ShaderInput *input);
/* single closure */
- void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
+ void find_dependencies(set<ShaderNode*>& dependencies,
+ const set<ShaderNode*>& done, ShaderInput *input);
+ void generate_node(ShaderNode *node, set<ShaderNode*>& done);
+ void generate_closure_node(ShaderNode *node, set<ShaderNode*>& done);
+ void generated_shared_closure_nodes(ShaderNode *node, set<ShaderNode*>& done,
+ set<ShaderNode*>& closure_done, const set<ShaderNode*>& shared);
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
- void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
/* multi closure */
void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done);
@@ -140,7 +143,6 @@ protected:
Stack active_stack;
int max_stack_use;
uint mix_weight_offset;
- bool use_multi_closure;
bool compile_failed;
};
diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp
index be0d4afbe2c..a8d502c432d 100644
--- a/intern/cycles/render/tables.cpp
+++ b/intern/cycles/render/tables.cpp
@@ -39,7 +39,10 @@ void LookupTables::device_update(Device *device, DeviceScene *dscene)
if(!need_update)
return;
- device->tex_alloc("__lookup_table", dscene->lookup_table);
+ device->tex_free(dscene->lookup_table);
+
+ if(lookup_tables.size() > 0)
+ device->tex_alloc("__lookup_table", dscene->lookup_table);
need_update = false;
}
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 417ecfffd49..6bbf4af3f85 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -94,7 +94,7 @@ void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2
*t1 = T(patch, *P, Pend);
}
else {
- int I = floor(t*0.5f);
+ int I = (int)floor((float)t*0.5f);
*P = interp(Pstart, Pend, (t == 0)? 0: I/(float)t); /* XXX is t faces or verts */
*t0 = I;
*t1 = t - I;
diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h
index 0cfa4049d3e..b72cc6bc873 100644
--- a/intern/cycles/util/util_color.h
+++ b/intern/cycles/util/util_color.h
@@ -61,22 +61,22 @@ ccl_device float3 rgb_to_hsv(float3 rgb)
h = 0.0f;
}
- if(s == 0.0f) {
- h = 0.0f;
- }
- else {
+ if(s != 0.0f) {
float3 cmax3 = make_float3(cmax, cmax, cmax);
c = (cmax3 - rgb)/cdelta;
- if(rgb.x == cmax) h = c.z - c.y;
- else if(rgb.y == cmax) h = 2.0f + c.x - c.z;
- else h = 4.0f + c.y - c.x;
+ if (rgb.x == cmax) h = c.z - c.y;
+ else if(rgb.y == cmax) h = 2.0f + c.x - c.z;
+ else h = 4.0f + c.y - c.x;
h /= 6.0f;
if(h < 0.0f)
h += 1.0f;
}
+ else {
+ h = 0.0f;
+ }
return make_float3(h, s, v);
}
@@ -90,13 +90,10 @@ ccl_device float3 hsv_to_rgb(float3 hsv)
s = hsv.y;
v = hsv.z;
- if(s == 0.0f) {
- rgb = make_float3(v, v, v);
- }
- else {
+ if(s != 0.0f) {
if(h == 1.0f)
h = 0.0f;
-
+
h *= 6.0f;
i = floorf(h);
f = h - i;
@@ -104,13 +101,16 @@ ccl_device float3 hsv_to_rgb(float3 hsv)
p = v*(1.0f-s);
q = v*(1.0f-(s*f));
t = v*(1.0f-(s*(1.0f-f)));
-
- if(i == 0.0f) rgb = make_float3(v, t, p);
+
+ if (i == 0.0f) rgb = make_float3(v, t, p);
else if(i == 1.0f) rgb = make_float3(q, v, p);
else if(i == 2.0f) rgb = make_float3(p, v, t);
else if(i == 3.0f) rgb = make_float3(p, q, v);
else if(i == 4.0f) rgb = make_float3(t, p, v);
- else rgb = make_float3(v, p, q);
+ else rgb = make_float3(v, p, q);
+ }
+ else {
+ rgb = make_float3(v, v, v);
}
return rgb;
@@ -132,8 +132,8 @@ ccl_device float3 xyY_to_xyz(float x, float y, float Y)
ccl_device float3 xyz_to_rgb(float x, float y, float z)
{
return make_float3(3.240479f * x + -1.537150f * y + -0.498535f * z,
- -0.969256f * x + 1.875991f * y + 0.041556f * z,
- 0.055648f * x + -0.204043f * y + 1.057311f * z);
+ -0.969256f * x + 1.875991f * y + 0.041556f * z,
+ 0.055648f * x + -0.204043f * y + 1.057311f * z);
}
#ifndef __KERNEL_OPENCL__
diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h
index deb2ff969d6..0c80303df9b 100644
--- a/intern/cycles/util/util_cuda.h
+++ b/intern/cycles/util/util_cuda.h
@@ -206,7 +206,8 @@ typedef enum CUjit_target_enum
CU_TARGET_COMPUTE_20,
CU_TARGET_COMPUTE_21,
CU_TARGET_COMPUTE_30,
- CU_TARGET_COMPUTE_35
+ CU_TARGET_COMPUTE_35,
+ CU_TARGET_COMPUTE_50
} CUjit_target;
typedef enum CUjit_fallback_enum
diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index 21192024f7f..da6fae79bb9 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -19,13 +19,17 @@
#include "util_types.h"
+#ifdef __KERNEL_SSE2__
+#include "util_simd.h"
+#endif
+
CCL_NAMESPACE_BEGIN
/* Half Floats */
#ifdef __KERNEL_OPENCL__
-#define float4_store_half(h, f, scale) vstore_half4(*(f) * (scale), 0, h);
+#define float4_store_half(h, f, scale) vstore_half4(f * (scale), 0, h);
#else
@@ -34,24 +38,24 @@ struct half4 { half x, y, z, w; };
#ifdef __KERNEL_CUDA__
-ccl_device_inline void float4_store_half(half *h, const float4 *f, float scale)
+ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
{
- h[0] = __float2half_rn(f->x * scale);
- h[1] = __float2half_rn(f->y * scale);
- h[2] = __float2half_rn(f->z * scale);
- h[3] = __float2half_rn(f->w * scale);
+ h[0] = __float2half_rn(f.x * scale);
+ h[1] = __float2half_rn(f.y * scale);
+ h[2] = __float2half_rn(f.z * scale);
+ h[3] = __float2half_rn(f.w * scale);
}
#else
-ccl_device_inline void float4_store_half(half *h, const float4 *f, float scale)
+ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
{
#ifndef __KERNEL_SSE2__
for(int i = 0; i < 4; i++) {
/* optimized float to half for pixels:
* assumes no negative, no nan, no inf, and sets denormal to 0 */
union { uint i; float f; } in;
- float fscale = (*f)[i] * scale;
+ float fscale = f[i] * scale;
in.f = (fscale > 0.0f)? ((fscale < 65500.0f)? fscale: 65500.0f): 0.0f;
int x = in.i;
@@ -70,7 +74,7 @@ ccl_device_inline void float4_store_half(half *h, const float4 *f, float scale)
const __m128i mm_7FFFFFFF = _mm_set1_epi32(0x7FFFFFFF);
const __m128i mm_C8000000 = _mm_set1_epi32(0xC8000000);
- __m128 mm_fscale = _mm_mul_ps(*(__m128*)f, mm_scale);
+ __m128 mm_fscale = _mm_mul_ps(load_m128(f), mm_scale);
__m128i x = _mm_castps_si128(_mm_min_ps(_mm_max_ps(mm_fscale, _mm_set_ps1(0.0f)), _mm_set_ps1(65500.0f)));
__m128i absolute = _mm_and_si128(x, mm_7FFFFFFF);
__m128i Z = _mm_add_epi32(absolute, mm_C8000000);
diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h
index ded25c92b90..edd2448efa4 100644
--- a/intern/cycles/util/util_hash.h
+++ b/intern/cycles/util/util_hash.h
@@ -23,7 +23,7 @@ CCL_NAMESPACE_BEGIN
static inline uint hash_int_2d(uint kx, uint ky)
{
- #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
uint a, b, c;
@@ -41,7 +41,7 @@ static inline uint hash_int_2d(uint kx, uint ky)
return c;
- #undef rot
+#undef rot
}
static inline uint hash_int(uint k)
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 2e73639d2bb..ded75762cd2 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -163,11 +163,7 @@ ccl_device_inline float clamp(float a, float mn, float mx)
ccl_device_inline int float_to_int(float f)
{
-#if defined(__KERNEL_SSE2__) && !defined(_MSC_VER)
- return _mm_cvtt_ss2si(_mm_load_ss(&f));
-#else
return (int)f;
-#endif
}
ccl_device_inline int floor_to_int(float f)
@@ -469,6 +465,15 @@ ccl_device_inline float dot(const float3 a, const float3 b)
#endif
}
+ccl_device_inline float dot(const float4 a, const float4 b)
+{
+#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
+#else
+ return (a.x*b.x + a.y*b.y) + (a.z*b.z + a.w*b.w);
+#endif
+}
+
ccl_device_inline float3 cross(const float3 a, const float3 b)
{
float3 r = make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
@@ -493,6 +498,11 @@ ccl_device_inline float len_squared(const float3 a)
#ifndef __KERNEL_OPENCL__
+ccl_device_inline float len_squared(const float4 a)
+{
+ return dot(a, a);
+}
+
ccl_device_inline float3 normalize(const float3 a)
{
#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
@@ -812,11 +822,6 @@ ccl_device_inline float average(const float4& a)
return reduce_add(a) * 0.25f;
}
-ccl_device_inline float dot(const float4& a, const float4& b)
-{
- return reduce_add(a * b);
-}
-
ccl_device_inline float len(const float4 a)
{
return sqrtf(dot(a, a));
@@ -1113,6 +1118,17 @@ ccl_device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
/* Color division */
+ccl_device_inline float3 safe_invert_color(float3 a)
+{
+ float x, y, z;
+
+ x = (a.x != 0.0f)? 1.0f/a.x: 0.0f;
+ y = (a.y != 0.0f)? 1.0f/a.y: 0.0f;
+ z = (a.z != 0.0f)? 1.0f/a.z: 0.0f;
+
+ return make_float3(x, y, z);
+}
+
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
{
float x, y, z;
@@ -1221,7 +1237,7 @@ ccl_device float compatible_powf(float x, float y)
ccl_device float safe_powf(float a, float b)
{
- if(a < 0.0f && b != float_to_int(b))
+ if(UNLIKELY(a < 0.0f && b != float_to_int(b)))
return 0.0f;
return compatible_powf(a, b);
@@ -1229,7 +1245,7 @@ ccl_device float safe_powf(float a, float b)
ccl_device float safe_logf(float a, float b)
{
- if(a < 0.0f || b < 0.0f)
+ if(UNLIKELY(a < 0.0f || b < 0.0f))
return 0.0f;
return logf(a)/logf(b);
@@ -1289,7 +1305,7 @@ ccl_device bool ray_aligned_disk_intersect(
float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
float div = dot(ray_D, disk_N);
- if(div == 0.0f)
+ if(UNLIKELY(div == 0.0f))
return false;
/* compute t to intersection point */
@@ -1319,7 +1335,7 @@ ccl_device bool ray_triangle_intersect(
float3 s1 = cross(ray_D, e2);
const float divisor = dot(s1, e1);
- if(divisor == 0.0f)
+ if(UNLIKELY(divisor == 0.0f))
return false;
const float invdivisor = 1.0f/divisor;
@@ -1351,6 +1367,50 @@ ccl_device bool ray_triangle_intersect(
return true;
}
+ccl_device bool ray_triangle_intersect_uv(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 v0, float3 v1, float3 v2,
+ float *isect_u, float *isect_v, float *isect_t)
+{
+ /* Calculate intersection */
+ float3 e1 = v1 - v0;
+ float3 e2 = v2 - v0;
+ float3 s1 = cross(ray_D, e2);
+
+ const float divisor = dot(s1, e1);
+ if(UNLIKELY(divisor == 0.0f))
+ return false;
+
+ const float invdivisor = 1.0f/divisor;
+
+ /* compute first barycentric coordinate */
+ const float3 d = ray_P - v0;
+ const float u = dot(d, s1)*invdivisor;
+ if(u < 0.0f)
+ return false;
+
+ /* Compute second barycentric coordinate */
+ const float3 s2 = cross(d, e1);
+ const float v = dot(ray_D, s2)*invdivisor;
+ if(v < 0.0f)
+ return false;
+
+ const float b0 = 1.0f - u - v;
+ if(b0 < 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ const float t = dot(e2, s2)*invdivisor;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ *isect_u = u;
+ *isect_v = v;
+ *isect_t = t;
+
+ return true;
+}
+
ccl_device bool ray_quad_intersect(
float3 ray_P, float3 ray_D, float ray_t,
float3 quad_P, float3 quad_u, float3 quad_v,
diff --git a/intern/cycles/util/util_md5.cpp b/intern/cycles/util/util_md5.cpp
index c53fbd90c67..add0d18c742 100644
--- a/intern/cycles/util/util_md5.cpp
+++ b/intern/cycles/util/util_md5.cpp
@@ -367,7 +367,7 @@ string MD5Hash::get_hex()
finish(digest);
for(int i = 0; i < 16; i++)
- sprintf(buf + i*2, "%02X", digest[i]);
+ sprintf(buf + i*2, "%02X", (unsigned int)digest[i]);
buf[sizeof(buf)-1] = '\0';
return string(buf);
diff --git a/intern/cycles/util/util_opencl.h b/intern/cycles/util/util_opencl.h
index 5f3f1667bcc..141c5e38273 100644
--- a/intern/cycles/util/util_opencl.h
+++ b/intern/cycles/util/util_opencl.h
@@ -304,7 +304,9 @@ typedef struct _cl_kernel * cl_kernel;
typedef struct _cl_event * cl_event;
typedef struct _cl_sampler * cl_sampler;
-typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */
+/* WARNING! Unlike cl_ types in cl_platform.h,
+ * cl_bool is not guaranteed to be the same size as the bool in kernels. */
+typedef cl_uint cl_bool;
typedef cl_ulong cl_bitfield;
typedef cl_bitfield cl_device_type;
typedef cl_uint cl_platform_info;
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index 4fd5df4316d..85d19b6a325 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -111,6 +111,11 @@ string path_escape(const string& path)
return result;
}
+bool path_is_relative(const string& path)
+{
+ return to_boost(path).is_relative();
+}
+
bool path_exists(const string& path)
{
return boost::filesystem::exists(to_boost(path));
diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h
index e9041e63dae..fd9ea11740d 100644
--- a/intern/cycles/util/util_path.h
+++ b/intern/cycles/util/util_path.h
@@ -41,6 +41,7 @@ string path_filename(const string& path);
string path_dirname(const string& path);
string path_join(const string& dir, const string& file);
string path_escape(const string& path);
+bool path_is_relative(const string& path);
/* file info */
bool path_exists(const string& path);
diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h
index fd5ba1de37b..f0f37fa57aa 100644
--- a/intern/cycles/util/util_simd.h
+++ b/intern/cycles/util/util_simd.h
@@ -71,7 +71,7 @@ ccl_device_inline const __m128 shuffle_swap(const __m128& a, shuffle_swap_t shuf
#ifdef __KERNEL_SSE41__
ccl_device_inline void gen_idirsplat_swap(const __m128 &pn, const shuffle_swap_t &shuf_identity, const shuffle_swap_t &shuf_swap,
- const float3& idir, __m128 idirsplat[3], shuffle_swap_t shufflexyz[3])
+ const float3& idir, __m128 idirsplat[3], shuffle_swap_t shufflexyz[3])
{
const __m128 idirsplat_raw[] = { _mm_set_ps1(idir.x), _mm_set_ps1(idir.y), _mm_set_ps1(idir.z) };
idirsplat[0] = _mm_xor_ps(idirsplat_raw[0], pn);
@@ -87,7 +87,7 @@ ccl_device_inline void gen_idirsplat_swap(const __m128 &pn, const shuffle_swap_t
}
#else
ccl_device_inline void gen_idirsplat_swap(const __m128 &pn, const shuffle_swap_t &shuf_identity, const shuffle_swap_t &shuf_swap,
- const float3& idir, __m128 idirsplat[3], shuffle_swap_t shufflexyz[3])
+ const float3& idir, __m128 idirsplat[3], shuffle_swap_t shufflexyz[3])
{
idirsplat[0] = _mm_xor_ps(_mm_set_ps1(idir.x), pn);
idirsplat[1] = _mm_xor_ps(_mm_set_ps1(idir.y), pn);
@@ -154,6 +154,12 @@ ccl_device_inline const __m128 fms(const __m128& a, const __m128& b, const __m12
return _mm_sub_ps(_mm_mul_ps(a, b), c);
}
+/* calculate -a*b+c (replacement for fused negated-multiply-subtract on SSE CPUs) */
+ccl_device_inline const __m128 fnma(const __m128& a, const __m128& b, const __m128& c)
+{
+ return _mm_sub_ps(c, _mm_mul_ps(a, b));
+}
+
template<size_t N> ccl_device_inline const __m128 broadcast(const __m128& a)
{
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(a), _MM_SHUFFLE(N, N, N, N)));
@@ -180,6 +186,88 @@ ccl_device_inline const __m128 set_sign_bit(const __m128 &a)
return _mm_xor_ps(a, _mm_castsi128_ps(_mm_setr_epi32(S1 << 31, S2 << 31, S3 << 31, S4 << 31)));
}
+#ifdef __KERNEL_WITH_SSE_ALIGN__
+ccl_device_inline const __m128 load_m128(const float4 &vec)
+{
+ return _mm_load_ps(&vec.x);
+}
+
+ccl_device_inline const __m128 load_m128(const float3 &vec)
+{
+ return _mm_load_ps(&vec.x);
+}
+
+#else
+
+ccl_device_inline const __m128 load_m128(const float4 &vec)
+{
+ return _mm_loadu_ps(&vec.x);
+}
+
+ccl_device_inline const __m128 load_m128(const float3 &vec)
+{
+ return _mm_loadu_ps(&vec.x);
+}
+#endif /* __KERNEL_WITH_SSE_ALIGN__ */
+
+ccl_device_inline const __m128 dot3_splat(const __m128& a, const __m128& b)
+{
+#ifdef __KERNEL_SSE41__
+ return _mm_dp_ps(a, b, 0x7f);
+#else
+ __m128 t = _mm_mul_ps(a, b);
+ return _mm_set1_ps(((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2]);
+#endif
+}
+
+/* squared length taking only specified axes into account */
+template<size_t X, size_t Y, size_t Z, size_t W>
+ccl_device_inline float len_squared(const __m128& a)
+{
+#ifndef __KERNEL_SSE41__
+ float4& t = (float4 &)a;
+ return (X ? t.x * t.x : 0.0f) + (Y ? t.y * t.y : 0.0f) + (Z ? t.z * t.z : 0.0f) + (W ? t.w * t.w : 0.0f);
+#else
+ return _mm_cvtss_f32(_mm_dp_ps(a, a, (X << 4) | (Y << 5) | (Z << 6) | (W << 7) | 0xf));
+#endif
+}
+
+ccl_device_inline float dot3(const __m128& a, const __m128& b)
+{
+#ifdef __KERNEL_SSE41__
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7f));
+#else
+ __m128 t = _mm_mul_ps(a, b);
+ return ((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2];
+#endif
+}
+
+ccl_device_inline const __m128 len3_squared_splat(const __m128& a)
+{
+ return dot3_splat(a, a);
+}
+
+ccl_device_inline float len3_squared(const __m128& a)
+{
+ return dot3(a, a);
+}
+
+ccl_device_inline float len3(const __m128& a)
+{
+ return _mm_cvtss_f32(_mm_sqrt_ss(dot3_splat(a, a)));
+}
+
+/* calculate shuffled cross product, useful when order of components does not matter */
+ccl_device_inline const __m128 cross_zxy(const __m128& a, const __m128& b)
+{
+ return fms(a, shuffle<1, 2, 0, 3>(b), _mm_mul_ps(b, shuffle<1, 2, 0, 3>(a)));
+}
+
+ccl_device_inline const __m128 cross(const __m128& a, const __m128& b)
+{
+ return shuffle<1, 2, 0, 3>(cross_zxy(a, b));
+}
+
#endif /* __KERNEL_SSE2__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 3d7781f6146..0764f7d9345 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -161,8 +161,25 @@ static CPUCapabilities& system_cpu_capabilities()
caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
caps.sse42 = (result[2] & ((int)1 << 20)) != 0;
- caps.avx = (result[2] & ((int)1 << 28)) != 0;
caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
+ caps.avx = false;
+ bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;
+ bool cpu_avx_support = (result[2] & ((int)1 << 28)) != 0;
+
+ if( os_uses_xsave_xrestore && cpu_avx_support) {
+ // Check if the OS will save the YMM registers
+ uint32_t xcr_feature_mask;
+#if defined(__GNUC__)
+ int edx; /* not used */
+ /* actual opcode for xgetbv */
+ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (xcr_feature_mask) , "=d" (edx) : "c" (0) );
+#elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ xcr_feature_mask = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK); /* min VS2010 SP1 compiler is required */
+#else
+ xcr_feature_mask = 0;
+#endif
+ caps.avx = (xcr_feature_mask & 0x6) == 0x6;
+ }
}
#if 0
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 12c2270a8d4..14613558501 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -75,7 +75,7 @@ static bool transform_matrix4_gj_inverse(float R[][4], float M[][4])
}
}
- if(pivotsize == 0)
+ if(UNLIKELY(pivotsize == 0.0f))
return false;
if(pivot != i) {
@@ -106,7 +106,7 @@ static bool transform_matrix4_gj_inverse(float R[][4], float M[][4])
for(int i = 3; i >= 0; --i) {
float f;
- if((f = M[i][i]) == 0)
+ if(UNLIKELY((f = M[i][i]) == 0.0f))
return false;
for(int j = 0; j < 4; j++) {
@@ -135,15 +135,16 @@ Transform transform_inverse(const Transform& tfm)
memcpy(R, &tfmR, sizeof(R));
memcpy(M, &tfm, sizeof(M));
- if(!transform_matrix4_gj_inverse(R, M)) {
+ if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
/* matrix is degenerate (e.g. 0 scale on some axis), ideally we should
* never be in this situation, but try to invert it anyway with tweak */
M[0][0] += 1e-8f;
M[1][1] += 1e-8f;
M[2][2] += 1e-8f;
- if(!transform_matrix4_gj_inverse(R, M))
+ if(UNLIKELY(!transform_matrix4_gj_inverse(R, M))) {
return transform_identity();
+ }
}
memcpy(&tfmR, R, sizeof(R));
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index 4c7ce12d1de..5b3dbe42f69 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -108,9 +108,9 @@ ccl_device_inline Transform transform_transpose(const Transform a)
}
ccl_device_inline Transform make_transform(float a, float b, float c, float d,
- float e, float f, float g, float h,
- float i, float j, float k, float l,
- float m, float n, float o, float p)
+ float e, float f, float g, float h,
+ float i, float j, float k, float l,
+ float m, float n, float o, float p)
{
Transform t;
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index c770931c69b..bfaab3dba3b 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -37,6 +37,7 @@
#define ccl_device_noinline static
#define ccl_global
#define ccl_constant
+#define __KERNEL_WITH_SSE_ALIGN__
#if defined(_WIN32) && !defined(FREE_WINDOWS)
@@ -45,6 +46,7 @@
#ifdef __KERNEL_64_BIT__
#define ccl_try_align(...) __declspec(align(__VA_ARGS__))
#else
+#undef __KERNEL_WITH_SSE_ALIGN__
#define ccl_try_align(...) /* not support for function arguments (error C2719) */
#endif
#define ccl_may_alias
@@ -63,8 +65,6 @@
#endif
-#else
-#define ccl_align(...)
#endif
/* Standard Integer Types */
@@ -159,8 +159,8 @@ struct int2 {
__forceinline int& operator[](int i) { return *(&x + i); }
};
-#ifdef __KERNEL_SSE__
struct ccl_try_align(16) int3 {
+#ifdef __KERNEL_SSE__
union {
__m128i m128;
struct { int x, y, z, w; };
@@ -171,7 +171,6 @@ struct ccl_try_align(16) int3 {
__forceinline operator const __m128i&(void) const { return m128; }
__forceinline operator __m128i&(void) { return m128; }
#else
-struct ccl_try_align(16) int3 {
int x, y, z, w;
#endif
@@ -179,8 +178,8 @@ struct ccl_try_align(16) int3 {
__forceinline int& operator[](int i) { return *(&x + i); }
};
-#ifdef __KERNEL_SSE__
struct ccl_try_align(16) int4 {
+#ifdef __KERNEL_SSE__
union {
__m128i m128;
struct { int x, y, z, w; };
@@ -191,7 +190,6 @@ struct ccl_try_align(16) int4 {
__forceinline operator const __m128i&(void) const { return m128; }
__forceinline operator __m128i&(void) { return m128; }
#else
-struct ccl_try_align(16) int4 {
int x, y, z, w;
#endif
@@ -227,8 +225,8 @@ struct float2 {
__forceinline float& operator[](int i) { return *(&x + i); }
};
-#ifdef __KERNEL_SSE__
struct ccl_try_align(16) float3 {
+#ifdef __KERNEL_SSE__
union {
__m128 m128;
struct { float x, y, z, w; };
@@ -239,7 +237,6 @@ struct ccl_try_align(16) float3 {
__forceinline operator const __m128&(void) const { return m128; }
__forceinline operator __m128&(void) { return m128; }
#else
-struct ccl_try_align(16) float3 {
float x, y, z, w;
#endif
@@ -247,8 +244,8 @@ struct ccl_try_align(16) float3 {
__forceinline float& operator[](int i) { return *(&x + i); }
};
-#ifdef __KERNEL_SSE__
struct ccl_try_align(16) float4 {
+#ifdef __KERNEL_SSE__
union {
__m128 m128;
struct { float x, y, z, w; };
@@ -259,7 +256,6 @@ struct ccl_try_align(16) float4 {
__forceinline operator const __m128&(void) const { return m128; }
__forceinline operator __m128&(void) { return m128; }
#else
-struct ccl_try_align(16) float4 {
float x, y, z, w;
#endif
@@ -450,6 +446,53 @@ ccl_device_inline int4 make_int4(const float3& f)
#endif
+/* Interpolation types for textures
+ * cuda also use texture space to store other objects */
+enum InterpolationType {
+ INTERPOLATION_NONE = -1,
+ INTERPOLATION_LINEAR = 0,
+ INTERPOLATION_CLOSEST = 1,
+ INTERPOLATION_CUBIC = 2,
+ INTERPOLATION_SMART = 3,
+};
+
+
+/* macros */
+
+/* hints for branch prediction, only use in code that runs a _lot_ */
+#if defined(__GNUC__) && defined(__KERNEL_CPU__)
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+#endif
+
+/* 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
+#else
+# define CHECK_TYPE(var, type)
+# define CHECK_TYPE_PAIR(var_a, var_b)
+#endif
+
+/* can be used in simple macros */
+#define CHECK_TYPE_INLINE(val, type) \
+ ((void)(((type)0) != (val)))
+
+
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index 361a7bc95f2..6bf9c9ed8c0 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -80,8 +80,8 @@ void view_display_info(const char *info)
void view_display_help()
{
- const int w = V.width / 1.15;
- const int h = V.height / 1.15;
+ const int w = (int)((float)V.width / 1.15f);
+ const int h = (int)((float)V.height / 1.15f);
const int x1 = (V.width - w) / 2;
const int x2 = x1 + w;
@@ -100,14 +100,16 @@ void view_display_help()
view_display_text(x1+20, y2-20, "Cycles Renderer");
view_display_text(x1+20, y2-40, "(C) 2011-2014 Blender Foundation");
view_display_text(x1+20, y2-80, "Controls:");
- view_display_text(x1+20, y2-100, "h: Show/Hide this help message");
- view_display_text(x1+20, y2-120, "r: Restart the render");
- view_display_text(x1+20, y2-140, "q: Quit the program");
- view_display_text(x1+20, y2-160, "esc: Cancel the render");
+ view_display_text(x1+20, y2-100, "h: Info/Help");
+ view_display_text(x1+20, y2-120, "r: Reset");
+ view_display_text(x1+20, y2-140, "p: Pause");
+ view_display_text(x1+20, y2-160, "esc: Cancel");
+ view_display_text(x1+20, y2-180, "q: Quit program");
- view_display_text(x1+20, y2-190, "Interactive Mode (i-key):");
- view_display_text(x1+20, y2-210, "LMB: Move camera");
- view_display_text(x1+20, y2-230, "RMB: Rotate camera");
+ view_display_text(x1+20, y2-210, "i: Interactive mode");
+ view_display_text(x1+20, y2-230, "Left mouse: Move camera");
+ view_display_text(x1+20, y2-250, "Right mouse: Rotate camera");
+ view_display_text(x1+20, y2-270, "W/A/S/D: Move camera");
glColor3f(1.0f, 1.0f, 1.0f);
}
@@ -246,9 +248,7 @@ void view_main_loop(const char *title, int width, int height,
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow(title);
-#ifndef __APPLE__
glewInit();
-#endif
view_reshape(width, height);
diff --git a/intern/elbeem/intern/mvmcoords.cpp b/intern/elbeem/intern/mvmcoords.cpp
index 281a9656fcf..838fc54491d 100644
--- a/intern/elbeem/intern/mvmcoords.cpp
+++ b/intern/elbeem/intern/mvmcoords.cpp
@@ -18,7 +18,7 @@
#include <algorithm>
#if defined(_MSC_VER) && _MSC_VER > 1600
-// sdt::greater
+// std::greater
#include <functional>
#endif
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index ff2cc405f4c..ac4da5b6133 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -103,6 +103,7 @@ FFMPEG_INLINE
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
{
/* no planar formats in FFmpeg < 0.9 */
+ (void) sample_fmt;
return 0;
}
@@ -172,6 +173,7 @@ FFMPEG_INLINE
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
const AVOption *rv = NULL;
+ (void) search_flags;
av_set_string3(obj, name, val, 1, &rv);
return rv != NULL;
}
@@ -180,6 +182,7 @@ FFMPEG_INLINE
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
{
const AVOption *rv = NULL;
+ (void) search_flags;
rv = av_set_int(obj, name, val);
return rv != NULL;
}
@@ -188,6 +191,7 @@ FFMPEG_INLINE
int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
{
const AVOption *rv = NULL;
+ (void) search_flags;
rv = av_set_double(obj, name, val);
return rv != NULL;
}
@@ -210,15 +214,12 @@ enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
}
#endif
-#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2)))
-# define avformat_close_input(x) av_close_input_file(*(x))
-#endif
-
#if ((LIBAVCODEC_VERSION_MAJOR < 53) || (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
FFMPEG_INLINE
int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
{
/* TODO: no options are taking into account */
+ (void) options;
return avcodec_open(avctx, codec);
}
#endif
@@ -228,6 +229,7 @@ FFMPEG_INLINE
AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
{
/* TODO: no codec is taking into account */
+ (void) c;
return av_new_stream(s, 0);
}
@@ -235,6 +237,7 @@ FFMPEG_INLINE
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
/* TODO: no options are taking into account */
+ (void) options;
return av_find_stream_info(ic);
}
#endif
@@ -435,4 +438,12 @@ AVRational av_get_r_frame_rate_compat(const AVStream *stream)
#endif
}
+#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 32, 0)
+# define AV_OPT_SEARCH_FAKE_OBJ 0
+#endif
+
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
+# define FFMPEG_HAVE_DEPRECATED_FLAGS2
+#endif
+
#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index f8c707b668c..c99680641c3 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -295,14 +295,14 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
return m_deviceType != NDOF_UnknownDevice;
}
-void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
+void GHOST_NDOFManager::updateTranslation(const short t[3], GHOST_TUns64 time)
{
memcpy(m_translation, t, sizeof(m_translation));
m_motionTime = time;
m_motionEventPending = true;
}
-void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
+void GHOST_NDOFManager::updateRotation(const short r[3], GHOST_TUns64 time)
{
memcpy(m_rotation, r, sizeof(m_rotation));
m_motionTime = time;
@@ -506,7 +506,5 @@ bool GHOST_NDOFManager::sendMotionEvent()
m_system.pushEvent(event);
- m_prevMotionTime = m_motionTime;
-
return true;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index 50f784d89c4..98aebfa4f30 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -128,8 +128,8 @@ public:
// rotations are + when CCW, - when CW
// each platform is responsible for getting axis data into this form
// these values should not be scaled (just shuffled or flipped)
- void updateTranslation(short t[3], GHOST_TUns64 time);
- void updateRotation(short r[3], GHOST_TUns64 time);
+ void updateTranslation(const short t[3], GHOST_TUns64 time);
+ void updateRotation(const short r[3], GHOST_TUns64 time);
// the latest raw button data from the device
// use HID button encoding (not NDOF_ButtonT)
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
index 4fc4f8016e5..1a029257f09 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -79,8 +79,8 @@ static void NDOF_DeviceEvent(io_connect_t connection, natural_t messageType, voi
case kConnexionCmdHandleAxis:
{
// convert to blender view coordinates
- short t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]};
- short r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])};
+ const short t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]};
+ const short r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])};
ndof_manager->updateTranslation(t, now);
ndof_manager->updateRotation(r, now);
@@ -162,7 +162,7 @@ GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
if (GHOST_NDOFManager3Dconnexion_available())
{
GHOST_NDOFManager3Dconnexion_UnregisterConnexionClient(m_clientID);
- GHOST_NDOFManager3Dconnexion_UnregisterConnexionClient(m_clientID);
+ GHOST_NDOFManager3Dconnexion_UnregisterConnexionClient(m_clientID);
GHOST_NDOFManager3Dconnexion_CleanupConnexionHandlers();
ghost_system = NULL;
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
index 947d8d74461..77e09e7ef49 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
@@ -77,23 +77,46 @@ bool GHOST_NDOFManagerX11::available()
return m_available;
}
+/*
+ * Workaround for a problem where we don't enter the 'GHOST_kFinished' state,
+ * this causes any proceeding event to have a very high 'dt' (time delta),
+ * many seconds for eg, causing the view to jump.
+ *
+ * this workaround expect's continuous events, if we miss a motion event,
+ * immediately send a dummy event with no motion to ensure the finished state is reached.
+ */
+#define USE_FINISH_GLITCH_WORKAROUND
+
+
+#ifdef USE_FINISH_GLITCH_WORKAROUND
+static bool motion_test_prev = false;
+#endif
+
bool GHOST_NDOFManagerX11::processEvents()
{
bool anyProcessed = false;
if (m_available) {
spnav_event e;
+
+#ifdef USE_FINISH_GLITCH_WORKAROUND
+ bool motion_test = false;
+#endif
+
while (spnav_poll_event(&e)) {
switch (e.type) {
case SPNAV_EVENT_MOTION:
{
/* convert to blender view coords */
GHOST_TUns64 now = m_system.getMilliSeconds();
- short t[3] = {(short)e.motion.x, (short)e.motion.y, (short)-e.motion.z};
- short r[3] = {(short)-e.motion.rx, (short)-e.motion.ry, (short)e.motion.rz};
+ const short t[3] = {(short)e.motion.x, (short)e.motion.y, (short)-e.motion.z};
+ const short r[3] = {(short)-e.motion.rx, (short)-e.motion.ry, (short)e.motion.rz};
updateTranslation(t, now);
updateRotation(r, now);
+#ifdef USE_FINISH_GLITCH_WORKAROUND
+ motion_test = true;
+#endif
break;
}
case SPNAV_EVENT_BUTTON:
@@ -103,6 +126,20 @@ bool GHOST_NDOFManagerX11::processEvents()
}
anyProcessed = true;
}
+
+#ifdef USE_FINISH_GLITCH_WORKAROUND
+ if (motion_test_prev == true && motion_test == false) {
+ GHOST_TUns64 now = m_system.getMilliSeconds();
+ const short v[3] = {0, 0, 0};
+
+ updateTranslation(v, now);
+ updateRotation(v, now);
+
+ anyProcessed = true;
+ }
+ motion_test_prev = motion_test;
+#endif
+
}
return anyProcessed;
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 8280474437b..070dd86c0fb 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -843,14 +843,14 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw)
{
case 1: // translation
{
- short *axis = (short *)(data + 1);
+ const short *axis = (short *)(data + 1);
// massage into blender view coords (same goes for rotation)
- short t[3] = {axis[0], -axis[2], axis[1]};
+ const short t[3] = {axis[0], -axis[2], axis[1]};
m_ndofManager->updateTranslation(t, now);
if (raw.data.hid.dwSizeHid == 13)
{ // this report also includes rotation
- short r[3] = {-axis[3], axis[5], -axis[4]};
+ const short r[3] = {-axis[3], axis[5], -axis[4]};
m_ndofManager->updateRotation(r, now);
// I've never gotten one of these, has anyone else?
@@ -860,8 +860,8 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw)
}
case 2: // rotation
{
- short *axis = (short *)(data + 1);
- short r[3] = {-axis[0], axis[2], -axis[1]};
+ const short *axis = (short *)(data + 1);
+ const short r[3] = {-axis[0], axis[2], -axis[1]};
m_ndofManager->updateRotation(r, now);
break;
}
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 9900f7e153f..8f1f9867724 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -755,7 +755,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
case KeyRelease:
{
XKeyEvent *xke = &(xe->xkey);
- KeySym key_sym = XLookupKeysym(xke, 0);
+ KeySym key_sym;
char ascii;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* utf8_array[] is initial buffer used for Xutf8LookupString().
@@ -771,7 +771,29 @@ GHOST_SystemX11::processEvent(XEvent *xe)
char *utf8_buf = NULL;
#endif
- GHOST_TKey gkey = convertXKey(key_sym);
+ GHOST_TKey gkey;
+
+ /* In keyboards like latin ones,
+ * numbers needs a 'Shift' to be accessed but key_sym
+ * is unmodified (or anyone swapping the keys with xmodmap).
+ *
+ * Here we look at the 'Shifted' version of the key.
+ * If it is a number, then we take it instead of the normal key.
+ *
+ * The modified key is sent in the 'ascii's variable anyway.
+ */
+ if ((xke->keycode >= 10 && xke->keycode < 20) &&
+ ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9))
+ {
+ /* pass (keep shift'ed key_sym) */
+ }
+ else {
+ /* regular case */
+ key_sym = XLookupKeysym(xke, 0);
+ }
+
+ gkey = convertXKey(key_sym);
+
GHOST_TEventType type = (xke->type == KeyPress) ?
GHOST_kEventKeyDown : GHOST_kEventKeyUp;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 4e3fcd4da3f..56e225e94a2 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -186,7 +186,8 @@ GHOST_WindowX11(
m_valid_setup(false),
m_invalid_window(false),
m_empty_cursor(None),
- m_custom_cursor(None)
+ m_custom_cursor(None),
+ m_visible_cursor(None)
{
/* Set up the minimum atrributes that we require and see if
@@ -1454,7 +1455,10 @@ setWindowCursorVisibility(
Cursor xcursor;
if (visible) {
- xcursor = getStandardCursor(getCursorShape() );
+ if (m_visible_cursor)
+ xcursor = m_visible_cursor;
+ else
+ xcursor = getStandardCursor(getCursorShape() );
}
else {
xcursor = getEmptyCursor();
@@ -1517,6 +1521,8 @@ setWindowCursorShape(
GHOST_TStandardCursor shape)
{
Cursor xcursor = getStandardCursor(shape);
+
+ m_visible_cursor = xcursor;
XDefineCursor(m_display, m_window, xcursor);
XFlush(m_display);
@@ -1566,6 +1572,8 @@ setWindowCustomCursorShape(
m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
XDefineCursor(m_display, m_window, m_custom_cursor);
XFlush(m_display);
+
+ m_visible_cursor = m_custom_cursor;
XFreePixmap(m_display, bitmap_pix);
XFreePixmap(m_display, mask_pix);
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index ff7b7409627..93ee9edda0e 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -391,6 +391,9 @@ private:
/** XCursor structure of the custom cursor */
Cursor m_custom_cursor;
+
+ /** XCursor to show when cursor is visible */
+ Cursor m_visible_cursor;
/** Cache of XC_* ID's to XCursor structures */
std::map<unsigned int, Cursor> m_standard_cursors;
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 8fb46ffc385..9a192c17180 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -74,7 +74,7 @@ void multitestapp_exit(MultiTestApp *app);
/**/
-void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, float *col, int width)
+void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float col[3], int width)
{
int ltidx = (side / 2) % 4;
int dkidx = (ltidx + 1 + (side & 1)) % 4;
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 2ac01a6c7e4..e85fba7a6d0 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -15,11 +15,6 @@
* 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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
* Contributor(s): Brecht Van Lommel
* Campbell Barton
*
@@ -43,7 +38,7 @@ size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
void (*MEM_freeN)(void *vmemh) = MEM_lockfree_freeN;
void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
-void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;;
+void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
@@ -71,7 +66,7 @@ void MEM_use_guarded_allocator(void)
MEM_freeN = MEM_guarded_freeN;
MEM_dupallocN = MEM_guarded_dupallocN;
MEM_reallocN_id = MEM_guarded_reallocN_id;
- MEM_recallocN_id = MEM_guarded_recallocN_id;;
+ MEM_recallocN_id = MEM_guarded_recallocN_id;
MEM_callocN = MEM_guarded_callocN;
MEM_mallocN = MEM_guarded_mallocN;
MEM_mapallocN = MEM_guarded_mapallocN;
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 352d18df732..172c79d50cd 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -497,9 +497,9 @@ void *MEM_guarded_mallocN(size_t len, const char *str)
memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
- if (memh) {
+ if (LIKELY(memh)) {
make_memhead_header(memh, len, str);
- if (malloc_debug_memset && len)
+ if (UNLIKELY(malloc_debug_memset && len))
memset(memh + 1, 255, len);
#ifdef DEBUG_MEMCOUNTER
@@ -544,7 +544,7 @@ void *MEM_guarded_mapallocN(size_t len, const char *str)
/* on 64 bit, simply use calloc instead, as mmap does not support
* allocating > 4 GB on Windows. the only reason mapalloc exists
* is to get around address space limitations in 32 bit OSes. */
- if(sizeof(void*) >= 8)
+ if (sizeof(void *) >= 8)
return MEM_guarded_callocN(len, str);
len = SIZET_ALIGN_4(len);
@@ -735,7 +735,7 @@ static void MEM_guarded_printmemlist_internal(int pydict)
membl->_count);
#else
print_error("%s len: " SIZET_FORMAT " %p\n",
- membl->name, SIZET_ARG(membl->len), membl + 1);
+ membl->name, SIZET_ARG(membl->len), (void *)(membl + 1));
#endif
#ifdef DEBUG_BACKTRACE
print_memhead_backtrace(membl);
@@ -951,7 +951,7 @@ static void rem_memblock(MemHead *memh)
#endif
}
else {
- if (malloc_debug_memset && memh->len)
+ if (UNLIKELY(malloc_debug_memset && memh->len))
memset(memh + 1, 255, memh->len);
free(memh);
}
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index db45b59b884..b0fd52d2766 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -77,6 +77,14 @@
#define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
+#ifdef __GNUC__
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+#endif
+
/* Prototypes for counted allocator functions */
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_lockfree_freeN(void *vmemh);
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 2c7c087966a..6fc01807af3 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -15,11 +15,6 @@
* 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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
* Contributor(s): Brecht Van Lommel
* Campbell Barton
* Sergey Sharybin
@@ -126,7 +121,7 @@ void MEM_lockfree_freeN(void *vmemh)
#endif
}
else {
- if (malloc_debug_memset && len) {
+ if (UNLIKELY(malloc_debug_memset && len)) {
memset(memh + 1, 255, len);
}
free(memh);
@@ -219,7 +214,7 @@ void *MEM_lockfree_callocN(size_t len, const char *str)
memh = (MemHead *)calloc(1, len + sizeof(MemHead));
- if (memh) {
+ if (LIKELY(memh)) {
memh->len = len;
atomic_add_u(&totblock, 1);
atomic_add_z(&mem_in_use, len);
@@ -242,8 +237,8 @@ void *MEM_lockfree_mallocN(size_t len, const char *str)
memh = (MemHead *)malloc(len + sizeof(MemHead));
- if (memh) {
- if (malloc_debug_memset && len) {
+ if (LIKELY(memh)) {
+ if (UNLIKELY(malloc_debug_memset && len)) {
memset(memh + 1, 255, len);
}
@@ -268,7 +263,7 @@ void *MEM_lockfree_mapallocN(size_t len, const char *str)
/* on 64 bit, simply use calloc instead, as mmap does not support
* allocating > 4 GB on Windows. the only reason mapalloc exists
* is to get around address space limitations in 32 bit OSes. */
- if(sizeof(void*) >= 8)
+ if (sizeof(void *) >= 8)
return MEM_lockfree_callocN(len, str);
len = SIZET_ALIGN_4(len);
diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript
index 1b7709bb986..bd20368f001 100644
--- a/intern/itasc/SConscript
+++ b/intern/itasc/SConscript
@@ -35,7 +35,4 @@ incs = '. ../../extern/Eigen3'
defs = []
-if env['OURPLATFORM']=='darwin' and env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4': # workaround for friend declaration specifies a default argument expression, not allowed anymore
- env.BlenderLib ('bf_intern_itasc', sources, Split(incs), defs, libtype=['intern','player'], priority=[20,100], cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
-else:
- env.BlenderLib ('bf_intern_itasc', sources, Split(incs), defs, libtype=['intern','player'], priority=[20,100])
+env.BlenderLib ('bf_intern_itasc', sources, Split(incs), defs, libtype=['intern','player'], priority=[20,100])
diff --git a/intern/itasc/kdl/frameacc.hpp b/intern/itasc/kdl/frameacc.hpp
index 40dd5bfa712..bccd229804d 100644
--- a/intern/itasc/kdl/frameacc.hpp
+++ b/intern/itasc/kdl/frameacc.hpp
@@ -78,9 +78,9 @@ public:
IMETHOD friend VectorAcc operator / (const VectorAcc& r2,const doubleAcc& r1);
- IMETHOD friend bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Vector& r1,const VectorAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const VectorAcc& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorAcc& r2,double eps);
+ IMETHOD friend bool Equal(const VectorAcc& r1,const Vector& r2,double eps);
IMETHOD friend VectorAcc operator - (const VectorAcc& r);
IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const VectorAcc& rhs);
IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const Vector& rhs);
@@ -132,9 +132,9 @@ public:
IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const RotationAcc& r2);
IMETHOD friend RotationAcc operator* (const Rotation& r1,const RotationAcc& r2);
IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const Rotation& r2);
- IMETHOD friend bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Rotation& r1,const RotationAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const RotationAcc& r1,const Rotation& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationAcc& r2,double eps);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const Rotation& r2,double eps);
IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
IMETHOD TwistAcc Inverse(const Twist& arg) const;
IMETHOD TwistAcc operator * (const TwistAcc& arg) const;
@@ -170,9 +170,9 @@ public:
IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const FrameAcc& f2);
IMETHOD friend FrameAcc operator * (const Frame& f1,const FrameAcc& f2);
IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const Frame& f2);
- IMETHOD friend bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Frame& r1,const FrameAcc& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const FrameAcc& r1,const Frame& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameAcc& r2,double eps);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const Frame& r2,double eps);
IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
IMETHOD TwistAcc Inverse(const Twist& arg) const;
@@ -226,9 +226,9 @@ public:
// the new point.
// Complexity : 6M+6A
- IMETHOD friend bool Equal(const TwistAcc& a,const TwistAcc& b,double eps=epsilon);
- IMETHOD friend bool Equal(const Twist& a,const TwistAcc& b,double eps=epsilon);
- IMETHOD friend bool Equal(const TwistAcc& a,const Twist& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistAcc& a,const TwistAcc& b,double eps);
+ IMETHOD friend bool Equal(const Twist& a,const TwistAcc& b,double eps);
+ IMETHOD friend bool Equal(const TwistAcc& a,const Twist& b,double eps);
IMETHOD Twist GetTwist() const;
@@ -240,9 +240,18 @@ public:
};
-
-
-
+IMETHOD bool Equal(const VectorAcc&, const VectorAcc&, double = epsilon);
+IMETHOD bool Equal(const Vector&, const VectorAcc&, double = epsilon);
+IMETHOD bool Equal(const VectorAcc&, const Vector&, double = epsilon);
+IMETHOD bool Equal(const RotationAcc&, const RotationAcc&, double = epsilon);
+IMETHOD bool Equal(const Rotation&, const RotationAcc&, double = epsilon);
+IMETHOD bool Equal(const RotationAcc&, const Rotation&, double = epsilon);
+IMETHOD bool Equal(const FrameAcc&, const FrameAcc&, double = epsilon);
+IMETHOD bool Equal(const Frame&, const FrameAcc&, double = epsilon);
+IMETHOD bool Equal(const FrameAcc&, const Frame&, double = epsilon);
+IMETHOD bool Equal(const TwistAcc&, const TwistAcc&, double = epsilon);
+IMETHOD bool Equal(const Twist&, const TwistAcc&, double = epsilon);
+IMETHOD bool Equal(const TwistAcc&, const Twist&, double = epsilon);
#ifdef KDL_INLINE
diff --git a/intern/itasc/kdl/frames.hpp b/intern/itasc/kdl/frames.hpp
index 28a59898e20..87eedea29f7 100644
--- a/intern/itasc/kdl/frames.hpp
+++ b/intern/itasc/kdl/frames.hpp
@@ -248,10 +248,10 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Vector& a,const Vector& b,double eps=epsilon);
+ inline friend bool Equal(const Vector& a,const Vector& b,double eps);
//! return a normalized vector
- inline friend Vector Normalize(const Vector& a, double eps=epsilon);
+ inline friend Vector Normalize(const Vector& a, double eps);
//! The literal equality operator==(), also identical.
inline friend bool operator==(const Vector& a,const Vector& b);
@@ -261,7 +261,7 @@ public:
friend class Rotation;
friend class Frame;
};
-
+ inline Vector Normalize(const Vector&, double eps=epsilon);
/**
\brief represents rotations in 3 dimensional space.
@@ -502,7 +502,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- friend bool Equal(const Rotation& a,const Rotation& b,double eps=epsilon);
+
//! The literal equality operator==(), also identical.
friend bool operator==(const Rotation& a,const Rotation& b);
@@ -663,7 +663,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Frame& a,const Frame& b,double eps=epsilon);
+ inline friend bool Equal(const Frame& a,const Frame& b,double eps);
//! The literal equality operator==(), also identical.
inline friend bool operator==(const Frame& a,const Frame& b);
@@ -735,7 +735,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Twist& a,const Twist& b,double eps=epsilon);
+ inline friend bool Equal(const Twist& a,const Twist& b,double eps);
//! The literal equality operator==(), also identical.
inline friend bool operator==(const Twist& a,const Twist& b);
@@ -898,7 +898,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Wrench& a,const Wrench& b,double eps=epsilon);
+ inline friend bool Equal(const Wrench& a,const Wrench& b,double eps);
//! The literal equality operator==(), also identical.
inline friend bool operator==(const Wrench& a,const Wrench& b);
@@ -979,7 +979,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Vector2& a,const Vector2& b,double eps=epsilon);
+ inline friend bool Equal(const Vector2& a,const Vector2& b,double eps);
friend class Rotation2;
};
@@ -1026,7 +1026,7 @@ public:
//! do not use operator == because the definition of Equal(.,.) is slightly
//! different. It compares whether the 2 arguments are equal in an eps-interval
- inline friend bool Equal(const Rotation2& a,const Rotation2& b,double eps=epsilon);
+ inline friend bool Equal(const Rotation2& a,const Rotation2& b,double eps);
};
//! A 2D frame class, for further documentation see the Frames class
@@ -1067,9 +1067,18 @@ public:
tmp.SetIdentity();
return tmp;
}
- inline friend bool Equal(const Frame2& a,const Frame2& b,double eps=epsilon);
+ inline friend bool Equal(const Frame2& a,const Frame2& b,double eps);
};
+inline bool Equal(const Vector&, const Vector&, double = epsilon);
+ bool Equal(const Rotation&, const Rotation&, double = epsilon);
+inline bool Equal(const Frame&, const Frame&, double = epsilon);
+inline bool Equal(const Twist&, const Twist&, double = epsilon);
+inline bool Equal(const Wrench&, const Wrench&, double = epsilon);
+inline bool Equal(const Vector2&, const Vector2&, double = epsilon);
+inline bool Equal(const Rotation2&, const Rotation2&, double = epsilon);
+inline bool Equal(const Frame2&, const Frame2&, double = epsilon);
+
IMETHOD Vector diff(const Vector& a,const Vector& b,double dt=1);
IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt=1);
IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt=1);
diff --git a/intern/itasc/kdl/framevel.hpp b/intern/itasc/kdl/framevel.hpp
index e95c5ef7907..17e1f2adfa0 100644
--- a/intern/itasc/kdl/framevel.hpp
+++ b/intern/itasc/kdl/framevel.hpp
@@ -110,9 +110,9 @@ public:
IMETHOD friend void SetToZero(VectorVel& v);
- IMETHOD friend bool Equal(const VectorVel& r1,const VectorVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Vector& r1,const VectorVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const VectorVel& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorVel& r1,const VectorVel& r2,double eps);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorVel& r2,double eps);
+ IMETHOD friend bool Equal(const VectorVel& r1,const Vector& r2,double eps);
IMETHOD friend VectorVel operator - (const VectorVel& r);
IMETHOD friend doubleVel dot(const VectorVel& lhs,const VectorVel& rhs);
IMETHOD friend doubleVel dot(const VectorVel& lhs,const Vector& rhs);
@@ -166,9 +166,9 @@ public:
IMETHOD friend RotationVel operator* (const RotationVel& r1,const RotationVel& r2);
IMETHOD friend RotationVel operator* (const Rotation& r1,const RotationVel& r2);
IMETHOD friend RotationVel operator* (const RotationVel& r1,const Rotation& r2);
- IMETHOD friend bool Equal(const RotationVel& r1,const RotationVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Rotation& r1,const RotationVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const RotationVel& r1,const Rotation& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationVel& r1,const RotationVel& r2,double eps);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationVel& r2,double eps);
+ IMETHOD friend bool Equal(const RotationVel& r1,const Rotation& r2,double eps);
IMETHOD TwistVel Inverse(const TwistVel& arg) const;
IMETHOD TwistVel Inverse(const Twist& arg) const;
@@ -220,9 +220,9 @@ public:
IMETHOD friend FrameVel operator * (const FrameVel& f1,const FrameVel& f2);
IMETHOD friend FrameVel operator * (const Frame& f1,const FrameVel& f2);
IMETHOD friend FrameVel operator * (const FrameVel& f1,const Frame& f2);
- IMETHOD friend bool Equal(const FrameVel& r1,const FrameVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const Frame& r1,const FrameVel& r2,double eps=epsilon);
- IMETHOD friend bool Equal(const FrameVel& r1,const Frame& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameVel& r1,const FrameVel& r2,double eps);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameVel& r2,double eps);
+ IMETHOD friend bool Equal(const FrameVel& r1,const Frame& r2,double eps);
IMETHOD TwistVel Inverse(const TwistVel& arg) const;
IMETHOD TwistVel Inverse(const Twist& arg) const;
@@ -292,9 +292,9 @@ public:
// = Equality operators
// do not use operator == because the definition of Equal(.,.) is slightly
// different. It compares whether the 2 arguments are equal in an eps-interval
- IMETHOD friend bool Equal(const TwistVel& a,const TwistVel& b,double eps=epsilon);
- IMETHOD friend bool Equal(const Twist& a,const TwistVel& b,double eps=epsilon);
- IMETHOD friend bool Equal(const TwistVel& a,const Twist& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistVel& a,const TwistVel& b,double eps);
+ IMETHOD friend bool Equal(const Twist& a,const TwistVel& b,double eps);
+ IMETHOD friend bool Equal(const TwistVel& a,const Twist& b,double eps);
// = Conversion to other entities
IMETHOD Twist GetTwist() const;
@@ -305,6 +305,19 @@ public:
};
+IMETHOD bool Equal(const VectorVel&, const VectorVel&, double = epsilon);
+IMETHOD bool Equal(const Vector&, const VectorVel&, double = epsilon);
+IMETHOD bool Equal(const VectorVel&, const Vector&, double = epsilon);
+IMETHOD bool Equal(const RotationVel&, const RotationVel&, double = epsilon);
+IMETHOD bool Equal(const Rotation&, const RotationVel&, double = epsilon);
+IMETHOD bool Equal(const RotationVel&, const Rotation&, double = epsilon);
+IMETHOD bool Equal(const FrameVel&, const FrameVel&, double = epsilon);
+IMETHOD bool Equal(const Frame&, const FrameVel&, double = epsilon);
+IMETHOD bool Equal(const FrameVel&, const Frame&, double = epsilon);
+IMETHOD bool Equal(const TwistVel&, const TwistVel&, double = epsilon);
+IMETHOD bool Equal(const Twist&, const TwistVel&, double = epsilon);
+IMETHOD bool Equal(const TwistVel&, const Twist&, double = epsilon);
+
IMETHOD VectorVel diff(const VectorVel& a,const VectorVel& b,double dt=1.0) {
return VectorVel(diff(a.p,b.p,dt),diff(a.v,b.v,dt));
}
diff --git a/intern/itasc/kdl/jacobian.hpp b/intern/itasc/kdl/jacobian.hpp
index e9057451c9f..9708ebd37be 100644
--- a/intern/itasc/kdl/jacobian.hpp
+++ b/intern/itasc/kdl/jacobian.hpp
@@ -45,7 +45,7 @@ namespace KDL
bool operator ==(const Jacobian& arg);
bool operator !=(const Jacobian& arg);
- friend bool Equal(const Jacobian& a,const Jacobian& b,double eps=epsilon);
+ friend bool Equal(const Jacobian& a,const Jacobian& b,double eps);
~Jacobian();
@@ -63,6 +63,7 @@ namespace KDL
};
+ bool Equal(const Jacobian&, const Jacobian&, double = epsilon);
}
#endif
diff --git a/intern/itasc/kdl/jntarray.hpp b/intern/itasc/kdl/jntarray.hpp
index ece6b0bdb6b..886171b11db 100644
--- a/intern/itasc/kdl/jntarray.hpp
+++ b/intern/itasc/kdl/jntarray.hpp
@@ -209,12 +209,12 @@ class MyTask : public RTT::TaskContext
* @return true if each element of src1 is within eps of the same
* element in src2, or if both src1 and src2 have no data (ie 0==rows())
*/
- friend bool Equal(const JntArray& src1,const JntArray& src2,double eps=epsilon);
+ friend bool Equal(const JntArray& src1,const JntArray& src2,double eps);
friend bool operator==(const JntArray& src1,const JntArray& src2);
//friend bool operator!=(const JntArray& src1,const JntArray& src2);
};
-
+ bool Equal(const JntArray&,const JntArray&, double = epsilon);
bool operator==(const JntArray& src1,const JntArray& src2);
//bool operator!=(const JntArray& src1,const JntArray& src2);
diff --git a/intern/itasc/kdl/jntarrayacc.hpp b/intern/itasc/kdl/jntarrayacc.hpp
index 275aa58f21e..fd1c26430e8 100644
--- a/intern/itasc/kdl/jntarrayacc.hpp
+++ b/intern/itasc/kdl/jntarrayacc.hpp
@@ -58,9 +58,10 @@ namespace KDL
friend void Divide(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest);
friend void Divide(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest);
friend void SetToZero(JntArrayAcc& array);
- friend bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps=epsilon);
-
+ friend bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps);
};
+
+ bool Equal(const JntArrayAcc&, const JntArrayAcc&, double = epsilon);
}
#endif
diff --git a/intern/itasc/kdl/jntarrayvel.hpp b/intern/itasc/kdl/jntarrayvel.hpp
index faa82076ebb..480f84f1708 100644
--- a/intern/itasc/kdl/jntarrayvel.hpp
+++ b/intern/itasc/kdl/jntarrayvel.hpp
@@ -51,9 +51,10 @@ namespace KDL
friend void Divide(const JntArrayVel& src,const double& factor,JntArrayVel& dest);
friend void Divide(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest);
friend void SetToZero(JntArrayVel& array);
- friend bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps=epsilon);
-
+ friend bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps);
};
+
+ bool Equal(const JntArrayVel&, const JntArrayVel&, double = epsilon);
}
#endif
diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt
index 3599aa68545..217fe9a8c71 100644
--- a/intern/locale/CMakeLists.txt
+++ b/intern/locale/CMakeLists.txt
@@ -36,6 +36,14 @@ set(SRC
boost_locale_wrapper.h
)
+if(WITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
+endif()
+
+if(WITH_GHOST_SDL)
+ add_definitions(-DWITH_GHOST_SDL)
+endif()
+
if(WITH_INTERNATIONAL)
list(APPEND INC_SYS
${BOOST_INCLUDE_DIR}
@@ -51,5 +59,10 @@ blender_add_lib(bf_intern_locale "${SRC}" "${INC}" "${INC_SYS}")
set(MSFFMT_SRC
msgfmt.cc
)
-
add_executable(msgfmt ${MSFFMT_SRC})
+
+if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND (NOT (CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)))
+ # needed for clang 3.4+
+ target_link_libraries(msgfmt ${PLATFORM_LINKLIBS})
+endif()
+
diff --git a/intern/locale/SConscript b/intern/locale/SConscript
index 4136ac8237d..24828c120ec 100644
--- a/intern/locale/SConscript
+++ b/intern/locale/SConscript
@@ -66,10 +66,6 @@ if env['WITH_BF_INTERNATIONAL']:
locale = env.Clone()
- msgfmt_executable = targetpath
- if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw', 'win64-mingw'):
- msgfmt_executable += ".exe"
-
# dependencies
dependencies = [msgfmt_target]
@@ -82,7 +78,7 @@ if env['WITH_BF_INTERNATIONAL']:
po_file = os.path.join(po_dir, f)
mo_file = os.path.join(build_dir, os.path.splitext(f)[0] + ".mo")
- command = "\"%s\" \"%s\" \"%s\"" % (msgfmt_executable, po_file, mo_file)
+ command = "\"%s\" \"%s\" \"%s\"" % (targetpath, po_file, mo_file)
locale.Command(mo_file, po_file, command)
locale.Depends(mo_file, dependencies)
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index 945d0bbc5da..25843d60578 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -64,7 +64,7 @@ void bl_locale_set(const char *locale)
_locale = gen(locale);
}
else {
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(WITH_HEADLESS) && !defined(WITH_GHOST_SDL)
extern char GHOST_user_locale[128]; // pulled from Ghost_SystemCocoa
std::string locale_osx = GHOST_user_locale + std::string(".UTF-8");
_locale = gen(locale_osx.c_str());
@@ -113,7 +113,11 @@ const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
return r;
return msgid;
}
- catch(std::exception const &) {
+ catch(std::bad_cast const &e) { /* if std::has_facet<char_message_facet>(l) == false, LC_ALL = "C" case */
+// std::cout << "bl_locale_pgettext(" << msgid << "): " << e.what() << " \n";
+ return msgid;
+ }
+ catch(std::exception const &e) {
// std::cout << "bl_locale_pgettext(" << msgctxt << ", " << msgid << "): " << e.what() << " \n";
return msgid;
}
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index ab7b851911a..6d39e328e82 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -726,8 +726,8 @@ rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
static void RB_trimesh_data_delete(rbMeshData *mesh)
{
delete mesh->index_array;
- delete mesh->vertices;
- delete mesh->triangles;
+ delete[] mesh->vertices;
+ delete[] mesh->triangles;
delete mesh;
}
diff --git a/intern/utfconv/utfconv.c b/intern/utfconv/utfconv.c
index 7f7a612528d..e5f8756917f 100644
--- a/intern/utfconv/utfconv.c
+++ b/intern/utfconv/utfconv.c
@@ -170,7 +170,7 @@ int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16)
{
char u;
char type = 0;
- wchar_t u32 = 0;
+ unsigned int u32 = 0;
wchar_t *out16end = out16 + size16;
int err = 0;
if (!size16 || !in8 || !out16) return UTF_ERROR_NULL_IN;
diff --git a/release/bin/blender-softwaregl b/release/bin/blender-softwaregl
index 8628dca2202..8628dca2202 100755..100644
--- a/release/bin/blender-softwaregl
+++ b/release/bin/blender-softwaregl
diff --git a/release/bin/blender-thumbnailer.py b/release/bin/blender-thumbnailer.py
index 22e811c538e..779c6156e70 100755..100644
--- a/release/bin/blender-thumbnailer.py
+++ b/release/bin/blender-thumbnailer.py
@@ -21,10 +21,16 @@
# <pep8 compliant>
"""
-Thumbnailer runs with python 2.6 and 3.x.
-To run automatically with nautilus:
- gconftool --type boolean --set /desktop/gnome/thumbnailers/application@x-blender/enable true
- gconftool --type string --set /desktop/gnome/thumbnailers/application@x-blender/command "blender-thumbnailer.py %u %o"
+Thumbnailer runs with python 2.7 and 3.x.
+To run automatically with a file manager such as Nautilus, save this file
+in a directory that is listed in PATH environment variable, and create
+blender.thumbnailer file in ${HOME}/.local/share/thumbnailers/ directory
+with the following contents:
+
+[Thumbnailer Entry]
+TryExec=blender-thumbnailer.py
+Exec=blender-thumbnailer.py %u %o
+MimeType=application/x-blender;
"""
import struct
@@ -34,21 +40,48 @@ def open_wrapper_get():
""" wrap OS spesific read functionality here, fallback to 'open()'
"""
- def open_gio(path, mode):
- g_file = gio.File(path).read()
- g_file.orig_seek = g_file.seek
+ class GFileWrapper:
+ __slots__ = ("mode", "g_file")
- def new_seek(offset, whence=0):
- return g_file.orig_seek(offset, [1, 0, 2][whence])
+ def __init__(self, url, mode='r'):
+ self.mode = mode # used in gzip module
+ self.g_file = Gio.File.parse_name(url).read(None)
- g_file.seek = new_seek
- return g_file
+ def read(self, size):
+ return self.g_file.read_bytes(size, None).get_data()
+
+ def seek(self, offset, whence=0):
+ self.g_file.seek(offset, [1, 0, 2][whence], None)
+ return self.g_file.tell()
+
+ def tell(self):
+ return self.g_file.tell()
+
+ def close(self):
+ self.g_file.close(None)
+
+ def open_local_url(url, mode='r'):
+ o = urlparse(url)
+ if o.scheme == '':
+ path = o.path
+ elif o.scheme == 'file':
+ path = unquote(o.path)
+ else:
+ raise(IOError('URL scheme "%s" needs gi.repository.Gio module' % o.scheme))
+ return open(path, mode)
try:
- import gio
- return open_gio
+ from gi.repository import Gio
+ return GFileWrapper
except ImportError:
- return open
+ try:
+ # Python 3
+ from urllib.parse import urlparse, unquote
+ except ImportError:
+ # Python 2
+ from urlparse import urlparse
+ from urllib import unquote
+ return open_local_url
def blend_extract_thumb(path):
diff --git a/release/darwin/codesigning_rules_blender.plist b/release/darwin/codesigning_rules_blender.plist
index b3baba80bbb..aa5580dd322 100644
--- a/release/darwin/codesigning_rules_blender.plist
+++ b/release/darwin/codesigning_rules_blender.plist
@@ -5,7 +5,7 @@
<key>rules</key>
<dict>
<!-- Exclude datafiles, python and scripts -->
- <key>^MacOS/2.69</key>
+ <key>^MacOS/2.70</key>
<false/>
<key>^Resources/</key>
<true/>
diff --git a/release/darwin/codesigning_rules_player.plist b/release/darwin/codesigning_rules_player.plist
index 2a85041f307..ff154df7b49 100644
--- a/release/darwin/codesigning_rules_player.plist
+++ b/release/darwin/codesigning_rules_player.plist
@@ -5,7 +5,7 @@
<key>rules</key>
<dict>
<!-- Exclude datafiles, python and scripts -->
- <key>^MacOS/2.69</key>
+ <key>^MacOS/2.70</key>
<false/>
<!-- Exclude Resources for placing game.blend and own icons -->
<key>^Resources/</key>
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index 8d6b9eef29d..7557b81c804 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -14,7 +14,7 @@
height="640"
id="svg2"
sodipodi:version="0.32"
- inkscape:version="0.48.4 r9939"
+ inkscape:version="0.48.4 r"
version="1.0"
sodipodi:docname="blender_icons.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
@@ -27207,6 +27207,1031 @@
offset="1"
style="stop-color:#f9fbff;stop-opacity:1" />
</linearGradient>
+ <linearGradient
+ gradientTransform="translate(-341.96134,-472.09253)"
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-4"
+ id="linearGradient16343"
+ x1="349.53067"
+ y1="480.05426"
+ x2="365.46213"
+ y2="461.89044"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="64.567902"
+ fx="20.892099"
+ r="5.257"
+ cy="64.567902"
+ cx="20.892099"
+ id="radialGradient16142-4">
+ <stop
+ id="stop16144-7"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16146-4"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-4"
+ id="linearGradient16082"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,550.17094,516.99093)"
+ x1="349.53067"
+ y1="480.05426"
+ x2="365.46213"
+ y2="461.89044" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43009"
+ id="linearGradient16932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.7118707,-0.00216237,-0.00556412,-1.3288889,198.24155,47.428048)"
+ x1="5.6458621"
+ y1="11.418204"
+ x2="7.3551626"
+ y2="13.092201" />
+ <linearGradient
+ id="linearGradient43009">
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:1;"
+ offset="0"
+ id="stop43011" />
+ <stop
+ id="stop16834"
+ offset="0.30847755"
+ style="stop-color:#e9e9e9;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="1"
+ id="stop43013" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2"
+ id="linearGradient16935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0850614,-0.0361511,0.02414524,-1.0240584,193.00521,36.425288)"
+ x1="4.155818"
+ y1="5.3683834"
+ x2="6.5799594"
+ y2="7.7035389" />
+ <linearGradient
+ id="linearGradient20756-2">
+ <stop
+ style="stop-color:#00327d;stop-opacity:1;"
+ offset="0"
+ id="stop20758-7" />
+ <stop
+ style="stop-color:#65a1fb;stop-opacity:1;"
+ offset="1"
+ id="stop20760-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16850"
+ id="linearGradient16939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0895881,0,0,-1.1205216,202.0323,36.300118)"
+ x1="5.1938357"
+ y1="8.7375145"
+ x2="7.5092869"
+ y2="11.3536" />
+ <linearGradient
+ id="linearGradient16850">
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="0"
+ id="stop16852" />
+ <stop
+ id="stop16854"
+ offset="0.38177863"
+ style="stop-color:#e9e9e9;stop-opacity:1;" />
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="1"
+ id="stop16856" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16824"
+ id="linearGradient16942"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9106402"
+ y1="8.3244486"
+ x2="8.5571098"
+ y2="12.702949"
+ gradientTransform="matrix(-1.1749798,0,0,-1.2083376,202.58771,37.243938)" />
+ <radialGradient
+ id="radialGradient16824"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#b7b7b7;stop-opacity:1;"
+ id="stop16826" />
+ <stop
+ id="stop16828"
+ style="stop-color:#646464;stop-opacity:1;"
+ offset="0.50338405" />
+ <stop
+ offset="1"
+ style="stop-color:#b7b7b7;stop-opacity:1;"
+ id="stop16830" />
+ </radialGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43009-7"
+ id="linearGradient16932-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.7118707,-0.00216237,-0.00556412,-1.3288889,207.1884,56.557374)"
+ x1="5.6458621"
+ y1="11.418204"
+ x2="7.3551626"
+ y2="13.092201" />
+ <linearGradient
+ id="linearGradient43009-7">
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:1;"
+ offset="0"
+ id="stop43011-4" />
+ <stop
+ id="stop16834-0"
+ offset="0.30847755"
+ style="stop-color:#e9e9e9;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="1"
+ id="stop43013-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-8"
+ id="linearGradient16935-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0850614,-0.0361511,0.02414524,-1.0240584,201.95206,45.554604)"
+ x1="4.155818"
+ y1="5.3683834"
+ x2="6.5799594"
+ y2="7.7035389" />
+ <linearGradient
+ id="linearGradient20756-2-8">
+ <stop
+ style="stop-color:#00327d;stop-opacity:1;"
+ offset="0"
+ id="stop20758-7-8" />
+ <stop
+ style="stop-color:#65a1fb;stop-opacity:1;"
+ offset="1"
+ id="stop20760-7-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16850-5"
+ id="linearGradient16939-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0895881,0,0,-1.1205216,210.97915,45.429444)"
+ x1="5.1938357"
+ y1="8.7375145"
+ x2="7.5092869"
+ y2="11.3536" />
+ <linearGradient
+ id="linearGradient16850-5">
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="0"
+ id="stop16852-5" />
+ <stop
+ id="stop16854-1"
+ offset="0.38177863"
+ style="stop-color:#e9e9e9;stop-opacity:1;" />
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:0;"
+ offset="1"
+ id="stop16856-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16824-1"
+ id="linearGradient16942-1"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9106402"
+ y1="8.3244486"
+ x2="8.5571098"
+ y2="12.702949"
+ gradientTransform="matrix(-1.1749798,0,0,-1.2083376,211.53456,46.373264)" />
+ <radialGradient
+ id="radialGradient16824-1"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#b7b7b7;stop-opacity:1;"
+ id="stop16826-5" />
+ <stop
+ id="stop16828-2"
+ style="stop-color:#646464;stop-opacity:1;"
+ offset="0.50338405" />
+ <stop
+ offset="1"
+ style="stop-color:#b7b7b7;stop-opacity:1;"
+ id="stop16830-7" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient18748-9"
+ inkscape:collect="always">
+ <stop
+ id="stop18750-7"
+ offset="0"
+ style="stop-color:#5894d4;stop-opacity:1" />
+ <stop
+ id="stop18752-0"
+ offset="1"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4980">
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0"
+ id="stop4982" />
+ <stop
+ style="stop-color:#afd1f5;stop-opacity:1"
+ offset="1"
+ id="stop4984" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8225-5-1-0-9-5">
+ <stop
+ style="stop-color:#84d458;stop-opacity:1"
+ offset="0"
+ id="stop8227-8-1-1-0-9" />
+ <stop
+ style="stop-color:#c8f5af;stop-opacity:1"
+ offset="1"
+ id="stop8229-7-3-1-4-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6369-5">
+ <stop
+ style="stop-color:#0d1e00;stop-opacity:1"
+ offset="0"
+ id="stop6371-3" />
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="1"
+ id="stop6373-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16719">
+ <stop
+ id="stop16721"
+ offset="0"
+ style="stop-color:#84d458;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.30000001"
+ id="stop5079" />
+ <stop
+ id="stop16723"
+ offset="1"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6369-3-9">
+ <stop
+ style="stop-color:#0e1e00;stop-opacity:1"
+ offset="0"
+ id="stop6371-2-4" />
+ <stop
+ style="stop-color:#001d1e;stop-opacity:1"
+ offset="1"
+ id="stop6373-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7701-5"
+ inkscape:collect="always">
+ <stop
+ id="stop7703-5"
+ offset="0"
+ style="stop-color:#84d458;stop-opacity:1" />
+ <stop
+ style="stop-color:#3dc0c7;stop-opacity:1"
+ offset="0.40000027"
+ id="stop5081" />
+ <stop
+ id="stop7705-2"
+ offset="1"
+ style="stop-color:#aff1f5;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5153"
+ inkscape:collect="always">
+ <stop
+ id="stop5155"
+ offset="0"
+ style="stop-color:#84d458;stop-opacity:1" />
+ <stop
+ id="stop5157"
+ offset="1"
+ style="stop-color:#c8f5af;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6522-6">
+ <stop
+ style="stop-color:#0e1e00;stop-opacity:1"
+ offset="0"
+ id="stop6524-8" />
+ <stop
+ style="stop-color:#1b1f09;stop-opacity:1"
+ offset="1"
+ id="stop6526-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16332-1">
+ <stop
+ style="stop-color:#84d458;stop-opacity:1"
+ offset="0"
+ id="stop16334-5" />
+ <stop
+ id="stop5161"
+ offset="0.37500033"
+ style="stop-color:#b5d034;stop-opacity:1" />
+ <stop
+ style="stop-color:#e9f5af;stop-opacity:1"
+ offset="1"
+ id="stop16336-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6541-9">
+ <stop
+ style="stop-color:#132701;stop-opacity:1"
+ offset="0"
+ id="stop6543-9" />
+ <stop
+ style="stop-color:#282100;stop-opacity:1"
+ offset="1"
+ id="stop6545-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15955-8"
+ inkscape:collect="always">
+ <stop
+ id="stop15957-7"
+ offset="0"
+ style="stop-color:#90d868;stop-opacity:1" />
+ <stop
+ style="stop-color:#dacf2a;stop-opacity:1"
+ offset="0.37500033"
+ id="stop5163" />
+ <stop
+ id="stop15959-4"
+ offset="1"
+ style="stop-color:#f5f1af;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6582-2">
+ <stop
+ style="stop-color:#282100;stop-opacity:1"
+ offset="0"
+ id="stop6584-4" />
+ <stop
+ style="stop-color:#201308;stop-opacity:1"
+ offset="1"
+ id="stop6586-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16021-1">
+ <stop
+ style="stop-color:#dacf2a;stop-opacity:1"
+ offset="0"
+ id="stop16023-4" />
+ <stop
+ id="stop5391"
+ offset="0.37792677"
+ style="stop-color:#ff9a2d;stop-opacity:1" />
+ <stop
+ style="stop-color:#f3c59d;stop-opacity:1"
+ offset="1"
+ id="stop16025-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6590-1">
+ <stop
+ style="stop-color:#290b11;stop-opacity:1"
+ offset="0"
+ id="stop6592-1" />
+ <stop
+ style="stop-color:#271301;stop-opacity:1"
+ offset="1"
+ id="stop6594-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16066-6"
+ inkscape:collect="always">
+ <stop
+ id="stop16068-8"
+ offset="0"
+ style="stop-color:#f13b60;stop-opacity:1" />
+ <stop
+ style="stop-color:#ff9a2d;stop-opacity:1"
+ offset="0.49796259"
+ id="stop4718" />
+ <stop
+ id="stop16070-9"
+ offset="1"
+ style="stop-color:#f3c59d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6668-2">
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="0"
+ id="stop6670-8" />
+ <stop
+ style="stop-color:#200820;stop-opacity:1"
+ offset="1"
+ id="stop6672-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12160"
+ inkscape:collect="always">
+ <stop
+ id="stop12162"
+ offset="0"
+ style="stop-color:#5894d4;stop-opacity:1" />
+ <stop
+ style="stop-color:#ef79ef;stop-opacity:1"
+ offset="0.72727275"
+ id="stop12164" />
+ <stop
+ id="stop12166"
+ offset="1"
+ style="stop-color:#f7bcf7;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5660"
+ inkscape:collect="always">
+ <stop
+ id="stop5662"
+ offset="0"
+ style="stop-color:#001128;stop-opacity:1" />
+ <stop
+ id="stop5664"
+ offset="1"
+ style="stop-color:#200820;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient11820">
+ <stop
+ style="stop-color:#afd1f5;stop-opacity:1"
+ offset="0"
+ id="stop11822" />
+ <stop
+ id="stop11824"
+ offset="0.44444144"
+ style="stop-color:#5894d4;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.55555254"
+ id="stop11826" />
+ <stop
+ style="stop-color:#ef79ef;stop-opacity:1"
+ offset="1"
+ id="stop11828" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6668-0-4">
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="0"
+ id="stop6670-5-2" />
+ <stop
+ style="stop-color:#200820;stop-opacity:1"
+ offset="1"
+ id="stop6672-0-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10750"
+ inkscape:collect="always">
+ <stop
+ id="stop10752"
+ offset="0"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.43061388"
+ id="stop10754" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.77194387"
+ id="stop10756" />
+ <stop
+ id="stop10758"
+ offset="1"
+ style="stop-color:#ef79ef;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17527-8-91-7">
+ <stop
+ style="stop-color:#0a0a0a;stop-opacity:1"
+ offset="0"
+ id="stop17529-0-2-6" />
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="1"
+ id="stop17531-0-6-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28135-1-17"
+ inkscape:collect="always">
+ <stop
+ id="stop28137-7-06"
+ offset="0"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.42811331"
+ id="stop5393" />
+ <stop
+ id="stop28139-7-9"
+ offset="1"
+ style="stop-color:#505050;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17533-0-8-9">
+ <stop
+ style="stop-color:#0a0a0a;stop-opacity:1"
+ offset="0"
+ id="stop17535-3-7-0" />
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="1"
+ id="stop17537-75-3-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28135-1-1"
+ inkscape:collect="always">
+ <stop
+ id="stop28137-7-0"
+ offset="0"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.42811331"
+ id="stop5393-00" />
+ <stop
+ id="stop28139-7-43"
+ offset="1"
+ style="stop-color:#505050;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17539-85-9-6">
+ <stop
+ style="stop-color:#000f3c;stop-opacity:1"
+ offset="0"
+ id="stop17541-1-5-6" />
+ <stop
+ id="stop17543-9-2-7"
+ offset="0.41666666"
+ style="stop-color:#0a0a0a;stop-opacity:1" />
+ <stop
+ id="stop17545-9-7-9"
+ offset="0.58333331"
+ style="stop-color:#0a0a0a;stop-opacity:1" />
+ <stop
+ style="stop-color:#001128;stop-opacity:1"
+ offset="1"
+ id="stop17547-04-5-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28147-1-4">
+ <stop
+ id="stop28149-4-1"
+ offset="0"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.18750006"
+ id="stop5469" />
+ <stop
+ style="stop-color:#505050;stop-opacity:1"
+ offset="0.40000001"
+ id="stop28151-7-6" />
+ <stop
+ id="stop28153-8-4"
+ offset="0.60000002"
+ style="stop-color:#505050;stop-opacity:1" />
+ <stop
+ style="stop-color:#5894d4;stop-opacity:1"
+ offset="0.81250006"
+ id="stop5471" />
+ <stop
+ id="stop28155-2-6"
+ offset="1"
+ style="stop-color:#afd1f5;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6668-2"
+ id="linearGradient17013"
+ gradientUnits="userSpaceOnUse"
+ x1="156.7054"
+ y1="957.10889"
+ x2="162.14577"
+ y2="957.10889" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12160"
+ id="linearGradient17015"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="155"
+ y1="976.36127"
+ x2="166"
+ y2="976.36127" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4980"
+ id="linearGradient17017"
+ gradientUnits="userSpaceOnUse"
+ x1="55"
+ y1="959.36218"
+ x2="55"
+ y2="951.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18748-9"
+ id="linearGradient17019"
+ gradientUnits="userSpaceOnUse"
+ x1="35"
+ y1="959.36218"
+ x2="35"
+ y2="951.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6369-5"
+ id="linearGradient17021"
+ gradientUnits="userSpaceOnUse"
+ x1="53"
+ y1="961.36218"
+ x2="59"
+ y2="955.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16719"
+ id="linearGradient17023"
+ gradientUnits="userSpaceOnUse"
+ x1="51"
+ y1="960.36218"
+ x2="60"
+ y2="951.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6369-3-9"
+ id="linearGradient17025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,21)"
+ x1="51"
+ y1="939.36218"
+ x2="61"
+ y2="929.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7701-5"
+ id="linearGradient17027"
+ gradientUnits="userSpaceOnUse"
+ x1="51"
+ y1="960.36218"
+ x2="60"
+ y2="951.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5153"
+ id="linearGradient17029"
+ gradientUnits="userSpaceOnUse"
+ x1="51"
+ y1="960.36218"
+ x2="61"
+ y2="951.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6541-9"
+ id="linearGradient17031"
+ gradientUnits="userSpaceOnUse"
+ x1="54.8125"
+ y1="961.73718"
+ x2="61"
+ y2="956.23718" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15955-8"
+ id="linearGradient17033"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="53"
+ y1="981.36218"
+ x2="61"
+ y2="972.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6582-2"
+ id="linearGradient17035"
+ gradientUnits="userSpaceOnUse"
+ x1="54"
+ y1="961.98718"
+ x2="60.9375"
+ y2="955.67468" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16021-1"
+ id="linearGradient17038"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="53"
+ y1="981.36218"
+ x2="61"
+ y2="971.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6590-1"
+ id="linearGradient17040"
+ gradientUnits="userSpaceOnUse"
+ x1="53.6875"
+ y1="961.48718"
+ x2="60.5625"
+ y2="956.04968" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16066-6"
+ id="linearGradient17042"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="54"
+ y1="981.36218"
+ x2="61"
+ y2="971.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5660"
+ id="linearGradient17044"
+ gradientUnits="userSpaceOnUse"
+ x1="162.875"
+ y1="955.48627"
+ x2="162.875"
+ y2="959.74042" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11820"
+ id="linearGradient17046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="165"
+ y1="971.36127"
+ x2="165"
+ y2="980.36127" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6668-0-4"
+ id="linearGradient17048"
+ gradientUnits="userSpaceOnUse"
+ x1="164.43785"
+ y1="955.23627"
+ x2="158.9816"
+ y2="955.23627" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10750"
+ id="linearGradient17050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="166.07713"
+ y1="970.98602"
+ x2="160.87317"
+ y2="980.77435" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6522-6"
+ id="linearGradient17052"
+ gradientUnits="userSpaceOnUse"
+ x1="54.268661"
+ y1="962.13489"
+ x2="61.251339"
+ y2="955.94769" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16332-1"
+ id="linearGradient17054"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="52"
+ y1="981.36218"
+ x2="61"
+ y2="972.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17527-8-91-7"
+ id="linearGradient17056"
+ gradientUnits="userSpaceOnUse"
+ x1="58.125019"
+ y1="951.23718"
+ x2="52.566891"
+ y2="951.23718" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28135-1-17"
+ id="linearGradient17058"
+ gradientUnits="userSpaceOnUse"
+ x1="51"
+ y1="960.36218"
+ x2="57"
+ y2="955.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17533-0-8-9"
+ id="linearGradient17060"
+ gradientUnits="userSpaceOnUse"
+ x1="58.125019"
+ y1="951.23718"
+ x2="52.566891"
+ y2="951.23718" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28135-1-1"
+ id="linearGradient17062"
+ gradientUnits="userSpaceOnUse"
+ x1="51"
+ y1="960.36218"
+ x2="57"
+ y2="955.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17539-85-9-6"
+ id="linearGradient17064"
+ gradientUnits="userSpaceOnUse"
+ x1="49"
+ y1="955.3623"
+ x2="61"
+ y2="955.3623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28147-1-4"
+ id="linearGradient17066"
+ gradientUnits="userSpaceOnUse"
+ x1="50"
+ y1="955.3623"
+ x2="60"
+ y2="955.3623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8225-5-1-0-9-5"
+ id="linearGradient17068"
+ gradientUnits="userSpaceOnUse"
+ x1="72"
+ y1="960.36072"
+ x2="80"
+ y2="950.36072" />
+ <linearGradient
+ id="linearGradient319-65-4-8-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-14-9-5-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-49-3-6-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8-7"
+ id="linearGradient17904-1-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-105.84265,-101.96449)"
+ x1="386.88852"
+ y1="409.84152"
+ x2="389.14081"
+ y2="412.45016" />
+ <linearGradient
+ id="linearGradient16340">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16342" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16344" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8-7"
+ id="linearGradient17893-5-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97.05081,-101.92897)"
+ x1="387"
+ y1="409.86362"
+ x2="388.86676"
+ y2="411.88974" />
+ <linearGradient
+ id="linearGradient16347">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16349" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16351" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-53"
+ id="linearGradient44954-5"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)" />
+ <linearGradient
+ id="linearGradient44939-8-53">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-53"
+ id="linearGradient16705"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,430.6795,387.09358)"
+ x1="280.20203"
+ y1="101.27402"
+ x2="283.77844"
+ y2="97.589958" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-53-7"
+ id="linearGradient16705-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,430.6795,387.09358)"
+ x1="280.20203"
+ y1="101.27402"
+ x2="283.77844"
+ y2="97.589958" />
+ <linearGradient
+ id="linearGradient44939-8-53-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-7-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-2" />
+ </linearGradient>
+ <linearGradient
+ y2="97.589958"
+ x2="283.77844"
+ y1="101.27402"
+ x1="280.20203"
+ gradientTransform="matrix(0,-1,-1,0,430.6795,387.09358)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16728"
+ xlink:href="#linearGradient44939-8-53-7"
+ inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
@@ -27218,16 +28243,16 @@
objecttolerance="10000"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.2444625"
- inkscape:cx="124.98646"
- inkscape:cy="335.47029"
+ inkscape:zoom="9.9557"
+ inkscape:cx="101.55361"
+ inkscape:cy="425.39887"
inkscape:document-units="px"
- inkscape:current-layer="g27669-35-7-7"
- showgrid="false"
- inkscape:window-width="1871"
- inkscape:window-height="1056"
- inkscape:window-x="49"
- inkscape:window-y="24"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="845"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showguides="true"
@@ -86542,6 +87567,56 @@
id="path27671-4-9-2"
d="m 243.50439,261.92816 -6.46154,-3.3e-4 0,12.12435 6.46154,3.3e-4 m 0,-2.71024 -3.93168,0 0,-6.73444 3.99798,0"
style="fill:url(#linearGradient17037);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path16893"
+ style="fill:none;stroke:#000000;stroke-width:0.87399995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 201.5467,38.012434 2.79722,-2.25264 c 0.45164,-0.43278 2.06766,-1.48999 2.83488,-3.34099 0.70812,-2.10437 1.91584,-2.91305 1.91584,-2.91305 l -0.6563,-0.74552 c 0,0 -0.95526,1.09547 -3.13241,1.53112 -1.93333,0.52639 -3.65608,2.44913 -3.65608,2.44913 l -2.68203,2.62741"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ d="m 201.61323,37.888554 2.72231,-2.19232 c 0.43955,-0.42119 2.0123,-1.45009 2.75897,-3.25153 0.68915,-2.048 1.86454,-2.83504 1.86454,-2.83504 l -0.63873,-0.72555 c 0,0 -0.92968,1.06614 -3.04853,1.49013 -1.88155,0.51228 -3.33445,2.20812 -3.57503,2.32453 l -2.52591,2.50648"
+ style="fill:url(#linearGradient16942-1);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ id="path16897" />
+ <path
+ id="path16907"
+ style="fill:url(#linearGradient16939-4);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ d="m 201.77885,37.561354 2.52447,-2.03299 c 0.4076,-0.39058 1.86605,-1.34471 2.55845,-3.01522 0.63908,-1.89917 1.72904,-2.62901 1.72904,-2.62901 l -0.59231,-0.67282 c 0,0 -0.86211,0.98866 -2.82697,1.38183 -1.74481,0.47506 -3.31522,2.1556 -3.31522,2.1556 l -2.66283,2.30087"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ id="path42945"
+ d="m 193.75914,44.994944 8.85401,-6.78865 m 0,0 c -0.48204,-0.79328 -2.52273,-3.35178 -3.70101,-3.87765 m 0,0 -5.60266,5.62151"
+ style="fill:none;stroke:#000000;stroke-width:1.05365074px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path42949"
+ d="m 193.33975,45.205134 9.22534,-7.0573 c -0.35109,-1.06864 -2.63524,-3.37319 -3.7137,-3.72187 l -5.84295,5.72212 c 0,0 0.0685,1.274 0.33131,5.05705 z"
+ style="fill:url(#linearGradient16935-4);fill-opacity:1;stroke:none;display:inline;enable-background:new" />
+ <path
+ style="fill:url(#linearGradient16932-1);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ d="m 193.24081,42.225684 c -3.9e-4,-3.18201 3.54751,-10.33668 9.15362,-4.50809 -0.22597,0.4981 -8.93557,6.84627 -8.93557,6.84627 -0.11742,-0.85263 -0.1517,-1.2913 -0.21806,-2.33818 z"
+ id="path43017"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path42981"
+ d="m 205.05836,32.290704 c -1.615,1.38333 -1.89187,1.62391 -1.89187,1.62391"
+ style="fill:none;stroke:#000000;stroke-width:0.73395383;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:transform-center-y="0.24985078"
+ inkscape:transform-center-x="0.0087216242" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.48930255;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 208.61393,29.286984 c -1.57524,1.41883 -3.88653,3.26666 -3.88653,3.26666"
+ id="path16832"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
</g>
<path
inkscape:connector-curvature="0"
@@ -86593,6 +87668,881 @@
</g>
</g>
</g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g6603"
+ transform="translate(168.02769,-748.47766)">
+ <g
+ id="g16520">
+ <g
+ id="g16552">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path53378"
+ d="m 166.5,949.86212 c -0.0525,5e-5 -0.448,0 -0.5,0 -1.9864,0 -2.6748,6.27454 -3.5,10.99914 -1,-5.50278 -4.01655,-5.48468 -5,10e-6 -0.95862,-2.50093 -2.5,-2.50094 -3.5,-10e-6 -0.0346,2e-4 -0.4699,0.002 -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17013);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cscccc" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17015);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 166.5,949.86212 -0.5,0 c -1.98887,0 -2.6748,6.30855 -3.5,11.03315 -0.98438,-5.50278 -3.99875,-5.52473 -5,-0.034 -0.95299,-2.47883 -2.5,-2.50002 -3.5,9.1e-4 -0.0346,2e-4 -0.4699,0.002 -0.5,0"
+ id="path53380"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16035-7-6"
+ width="16"
+ height="16"
+ x="152"
+ y="947.36127" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g6624"
+ transform="translate(84.027695,-748.47996)">
+ <g
+ id="g6562">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:#001128;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -1,0 -11,10.99986 -1,0"
+ id="path3948"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path3946"
+ d="m 61.5,949.86218 -1,0 -11,10.99986 -1,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17017);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18813-7"
+ width="16"
+ height="16"
+ x="47"
+ y="947.36218" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g6558"
+ transform="translate(84.027695,-748.47989)">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:#001128;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 40.5,949.8622 -6,0 0,11 -7,0"
+ id="path6545"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path6532"
+ d="m 40.5,949.8622 -6,0 0,11 -6.97,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17019);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18813-9"
+ width="16"
+ height="16"
+ x="26"
+ y="947.36218" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(126.02769,-748.47996)"
+ id="g4551">
+ <g
+ id="g4553">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path4555"
+ d="m 61.5,949.86218 -0.5,0 c -4.95,6.5 -7.066811,10.99986 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17021);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17023);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -4.95,6.5 -7.053239,10.99986 -12,10.99986 l -0.5,0"
+ id="path4557"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect4559"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g7689"
+ transform="translate(147.02769,-748.47996)">
+ <g
+ id="g7691">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17025);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -2.95,5.5 -7.066811,10.99986 -12,10.99986 l -0.5,0"
+ id="path7693"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path7695"
+ d="m 61.5,949.86218 -0.5,0 c -3,5.5 -7.053239,10.99986 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17027);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect7697"
+ width="16"
+ height="16"
+ x="47"
+ y="947.36218" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#001d1e;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 50,949.3622 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path15794" />
+ <path
+ id="path41073-2-6"
+ d="m 50,949.3622 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#58ced4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(168.02769,-748.47989)"
+ id="g7707">
+ <g
+ id="g7709">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path7711"
+ d="m 61.5,949.86218 -0.5,0 c -2.95,8.5 -7.066811,10.99986 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:#0e1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17029);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -2.95,8.5 -7.053239,10.99986 -12,10.99986 l -0.5,0"
+ id="path7713"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect7715"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#0e1e00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 50,949.3622 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path15813" />
+ <path
+ id="path41075-5-1"
+ d="m 50,949.3622 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="color:#000000;fill:#84d458;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g15886"
+ transform="translate(210.02769,-748.47996)">
+ <g
+ id="g15888">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17031);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,6.5 -4.149996,10.99986 -12,10.99986 l -0.5,0"
+ id="path15890"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path15892"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,6.5 -3.959647,10.99986 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17033);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15894"
+ width="16"
+ height="16"
+ x="47"
+ y="947.36218" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#282100;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 50,950.3622 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path15939" />
+ <path
+ id="path41079-6-0"
+ d="m 50,950.3622 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#dacf2a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(231.02769,-748.47989)"
+ id="g15961">
+ <g
+ id="g15963">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path15965"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,9.5 -1.956865,10.99986 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17035);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17038);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,8.5 -1.088169,10.99986 -12,10.99986 l -0.5,0"
+ id="path15967"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect15969"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16027-0"
+ transform="translate(252.02766,-748.47989)">
+ <g
+ id="g16029">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17040);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61,949.86218 -0.5,0 c 0.05,1.5 0.45,9.5 -11.5,10.99986 l -0.5,0"
+ id="path16031"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path16033"
+ d="m 61,949.86218 -0.5,0 c 0.05,1.5 0.45,9.5 -11.5,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17042);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16035"
+ width="16"
+ height="16"
+ x="47"
+ y="947.36218" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(189.02769,-748.48231)"
+ id="g16464">
+ <path
+ sodipodi:nodetypes="ccsssssc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17044);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 166.5,949.86126 c -0.0525,5e-5 -0.498,8.6e-4 -0.55,8.6e-4 0,0 -0.47718,10.99969 -2.50296,10.99969 -1.91589,0 -0.93193,-6.00055 -2.94704,-6.00055 -1.53921,0 -1.50766,3 -3,3 -1.03656,0 -0.99963,-2 -2,-2 -0.66974,0 -0.90046,1.00059 -1.5,1.00059 -0.0346,0 -0.4699,10e-4 -0.5,-8.7e-4"
+ id="path5578"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path16468"
+ d="m 166.5,949.86126 c -0.0525,5e-5 -0.498,8.6e-4 -0.55,8.6e-4 0,0 -0.47718,10.99969 -2.50296,10.99969 -1.91589,0 -0.93193,-6.00055 -2.94704,-6.00055 -1.53921,0 -1.50766,3 -3,3 -1.03656,0 -0.99963,-2 -2,-2 -0.66974,0 -0.90046,1.00059 -1.5,1.00059 -0.0346,0 -0.4699,10e-4 -0.5,-8.7e-4"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17046);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccsssssc" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16035-7"
+ width="16"
+ height="16"
+ x="152"
+ y="947.36127" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16576"
+ transform="translate(210.02769,-748.47898)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path16586"
+ d="m 166.5,949.86212 -0.55,0 c -1.95,6.49912 -3.14103,10.49912 -5.95,10.49912 -2.23607,0 -4.02976,-3.49912 -6,-3.49912 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17048);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccscc" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17050);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 166.5,949.86212 -0.55,0 c -1.95,6.49912 -3.14103,10.49912 -5.95,10.49912 -2.23607,0 -4.02976,-3.49912 -6,-3.49912 l -0.5,0"
+ id="path16580"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="947.36127"
+ x="152"
+ height="16"
+ width="16"
+ id="rect16582"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(189.02769,-748.47989)"
+ id="g4468">
+ <g
+ id="g4470">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path4472"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,4.5 -3.05,10.5 -12,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17052);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17054);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -0.95,5.5 -4.05,10.5 -12,10.99986 l -0.5,0"
+ id="path4474"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect4477"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path16306"
+ d="m 50,950.3622 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:none;stroke:#1b1f09;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#b5d034;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 50,950.3622 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ id="path41067-3-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(336.02769,-748.47858)"
+ id="g20295-7-9"
+ style="display:inline;enable-background:new">
+ <g
+ id="g20297-2-1">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path20299-51-2"
+ d="m 61.5,949.86218 -0.55,0 c -4.95,6.5 -5.985561,10.99986 -11.95,10.99986 l -0.5,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17056);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17058);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.55,0 c -4.95,6.5 -6.003239,10.99986 -11.95,10.99986 l -0.5,0"
+ id="path20301-63-8"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect20303-3-3"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g20305-4-1"
+ transform="matrix(-1,0,0,-1,467.02769,1162.2412)"
+ style="display:inline;enable-background:new">
+ <g
+ id="g20307-1-7">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17060);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -4.95,6.5 -5.985561,10.99986 -11.95,10.99986 l -0.55,0"
+ id="path20309-1-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path20311-8-0"
+ d="m 61.5,949.86218 -0.5,0 c -4.95,6.5 -5.971989,10.99986 -11.95,10.99986 l -0.55,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17062);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20313-92-1"
+ width="16"
+ height="16"
+ x="47"
+ y="947.36218" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,488.02769,1162.2445)"
+ id="g20315-6-2"
+ style="display:inline;enable-background:new">
+ <g
+ id="g20317-6-4">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path20319-7-7"
+ d="m 61.5,949.86218 -0.5,0 c -6.013721,0 -5.986773,10.99986 -11.95,10.99986 l -0.55,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17064);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17066);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 61.5,949.86218 -0.5,0 c -6.013721,0 -5.986773,10.99986 -11.95,10.99986 l -0.55,0"
+ id="path20321-90-9"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="947.36218"
+ x="47"
+ height="16"
+ width="16"
+ id="rect20323-5-1"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(84.027695,-748.48019)"
+ id="g20443-5-0">
+ <path
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#201308;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 78.565213,960.8622 -8.130425,0"
+ id="path22805-8-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path22809-2-4"
+ d="m 79.49996,960.8622 -9,0"
+ style="color:#000000;fill:none;stroke:#c86800;stroke-width:1.20000005;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(-0.83333333,0,0,0.83333,9.5,430.86427)"
+ d="m -81,636 c 0,1.65685 -1.343146,3 -3,3 -1.656854,0 -3,-1.34315 -3,-3 0,-1.65685 1.343146,-3 3,-3 1.656854,0 3,1.34315 3,3 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="636"
+ sodipodi:cx="-84"
+ id="path22807-1-8"
+ style="color:#000000;fill:#462300;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22811-6-3"
+ d="m 80,959.36217 c 0.554,0 1,0.446 1,1 l 0,1 c 0,0.554 -0.446,1 -1,1 l -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-1 c 0,-0.554 0.446,-1 1,-1 l 1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z"
+ style="color:#000000;fill:#ff9a2d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path20449-0-3"
+ d="m 72.434783,949.8622 8.130434,0"
+ style="color:#000000;fill:none;stroke:#201308;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:none;stroke:#c86800;stroke-width:1.20000005;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 72.5,949.8622 9,0"
+ id="path20451-8-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#462300;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path22736-5-7"
+ sodipodi:cx="-84"
+ sodipodi:cy="636"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m -81,636 c 0,1.65685 -1.343146,3 -3,3 -1.656854,0 -3,-1.34315 -3,-3 0,-1.65685 1.343146,-3 3,-3 1.656854,0 3,1.34315 3,3 z"
+ transform="matrix(0.83333333,0,0,0.83333,142.49996,419.86427)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path20453-7-1"
+ d="m 82.5,949.86218 c -0.12884,0 -0.37404,-4.1e-4 -0.5,0 -5.995321,0.0193 -5.998907,10.99986 -12,10.99986 -0.155311,0 -0.33371,0 -0.5,0"
+ style="color:#000000;fill:none;stroke:#0e1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cssc" />
+ <path
+ sodipodi:nodetypes="cssc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient17068);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 82.5,949.86218 c -0.12884,0 -0.37404,-4.1e-4 -0.5,0 -6.02657,0.0194 -5.998907,10.99986 -12,10.99986 -0.155311,0 -0.33371,0 -0.5,0"
+ id="path20457-48-5"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="947.36218"
+ x="68"
+ height="16"
+ width="16"
+ id="rect20459-9-9"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#ff9a2d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 71.99996,948.36217 c -0.554,0 -1,0.446 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 0,-1 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 z m 0,1 1,0 0,1 -1,0 0,-1 z"
+ id="rect22555-0-9"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22295-8"
+ d="m 71.49996,949.86216 0,-0.5014 c 0,-0.2493 0.196575,-0.4986 0.50004,-0.4986 l 0.49996,0"
+ style="fill:none;stroke:#f3c59d;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#f3c59d;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 78.49996,960.86216 0,-0.5014 c 0,-0.2493 0.196575,-0.4986 0.50004,-0.4986 l 0.49996,0"
+ id="path5059" />
+ </g>
+ <g
+ transform="translate(-63.051518,-85.06394)"
+ style="display:inline;enable-background:new"
+ id="g17942-1-7">
+ <rect
+ y="304"
+ x="278"
+ height="16"
+ width="16"
+ id="rect22048-0-1-2-2"
+ style="opacity:0.01000001;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17930-6-4">
+ <rect
+ y="305.5"
+ x="281.5"
+ height="6.0211244"
+ width="9.0000076"
+ id="rect22050-0-1-6-2"
+ style="opacity:0.6;fill:#ffd6aa;fill-opacity:1;fill-rule:evenodd;stroke:#2b1600;stroke-width:0.40000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path22157-2-9-1-2"
+ d="m 278.90735,308.28551 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#552c00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e98316;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 279.15735,308.53551 2.5,2.5 2.5,-2.5 -2.5,-2.5 -2.5,2.5 z"
+ id="path22159-1-9-5-8"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22161-4-8-9-9"
+ d="m 279.80239,308.53551 1.85496,-1.83839 1.85496,1.83839 -1.85496,1.86049 z"
+ style="fill:none;stroke:url(#linearGradient17904-1-8);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 287.69919,308.32103 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ id="path22208-0-8-1-5"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22212-5-4-4-6"
+ d="m 287.94919,308.57103 2.5,2.5 2.5,-2.5 -2.5,-2.5 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient17893-5-2);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 288.58981,308.57103 1.85938,-1.83594 1.85547,1.83594 -1.85547,1.875 z"
+ id="path22214-3-8-8-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(62.055528,67.113811)"
+ id="g36761-1-3"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 223,243 0,10 1,0 0,-1 1,0 1,0 0,2 1,0 0,1 1,0 0,-1 1,0 0,-2 -1,0 0,-2 1,0 1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36763-5-3"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36765-2-8"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ transform="translate(5,-6.0000002e-7)">
+ <rect
+ y="243"
+ x="218"
+ height="10"
+ width="1"
+ id="rect36767-7-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="244"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36769-6-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="245"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36771-1-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="246"
+ x="221"
+ height="1"
+ width="1"
+ id="rect36773-4-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="247"
+ x="222"
+ height="1"
+ width="1"
+ id="rect36775-2-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="248"
+ x="223"
+ height="1"
+ width="1"
+ id="rect36777-3-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="249"
+ x="224"
+ height="1"
+ width="1.0000017"
+ id="rect36779-2-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36781-2-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="251"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36783-1-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="221"
+ height="2"
+ width="1"
+ id="rect36785-6-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="250"
+ x="222.25"
+ height="2"
+ width="0.75"
+ id="rect36787-8-0"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="223"
+ height="1.9999931"
+ width="1"
+ id="rect36789-5-9"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="254"
+ x="222"
+ height="1.0000006"
+ width="1.5"
+ id="rect36791-7-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36793-6-2"
+ width="1.5"
+ height="1"
+ x="223.5"
+ y="250" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g44081-2"
+ transform="translate(-231.54762,126.06411)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44079-0"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-22.005631)"
+ id="g43931-0">
+ <g
+ id="g43459-4">
+ <g
+ transform="translate(0,21)"
+ id="g43446-0">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43450-7"
+ d="m 324.45461,83.386633 4.25,4.244369 4.25,-4.244369"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,655.70461,184.631)"
+ id="g43442-3">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 331.25,80.25 327,76.005631 322.75,80.25"
+ id="path42666-0"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient16705);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333.4295,103.09358 -4.5,4.5 -0.5,0 -3.87222,-3.79689"
+ id="path44952-5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-0.12714727,-29.00633)"
+ id="g43931-0-3">
+ <g
+ id="g43459-4-9">
+ <g
+ transform="translate(0,21)"
+ id="g43446-0-2">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43450-7-3"
+ d="m 324.45461,83.386633 4.25,4.244369 4.25,-4.244369"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,655.70461,184.631)"
+ id="g43442-3-7">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 331.25,80.25 327,76.005631 322.75,80.25"
+ id="path42666-0-5"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient16728);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333.4295,103.09358 -4.5,4.5 -0.5,0 -3.87222,-3.79689"
+ id="path44952-5-9"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_action_tweak.dat b/release/datafiles/blender_icons16/icon16_action_tweak.dat
new file mode 100644
index 00000000000..d2d1ec853d1
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_action_tweak.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_back.dat b/release/datafiles/blender_icons16/icon16_ipo_back.dat
new file mode 100644
index 00000000000..2c32cc176d7
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_back.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_bezier.dat b/release/datafiles/blender_icons16/icon16_ipo_bezier.dat
new file mode 100644
index 00000000000..527507cf009
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_bezier.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_bounce.dat b/release/datafiles/blender_icons16/icon16_ipo_bounce.dat
new file mode 100644
index 00000000000..bede5e12e57
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_bounce.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_circ.dat b/release/datafiles/blender_icons16/icon16_ipo_circ.dat
new file mode 100644
index 00000000000..c7b392003ed
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_circ.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_constant.dat b/release/datafiles/blender_icons16/icon16_ipo_constant.dat
new file mode 100644
index 00000000000..cb8882850ab
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_constant.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_cubic.dat b/release/datafiles/blender_icons16/icon16_ipo_cubic.dat
new file mode 100644
index 00000000000..6a84b66f725
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_cubic.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_ease_in.dat b/release/datafiles/blender_icons16/icon16_ipo_ease_in.dat
new file mode 100644
index 00000000000..e5c1c1dc051
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_ease_in.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_ease_in_out.dat b/release/datafiles/blender_icons16/icon16_ipo_ease_in_out.dat
new file mode 100644
index 00000000000..cf8ad3264f8
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_ease_in_out.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_ease_out.dat b/release/datafiles/blender_icons16/icon16_ipo_ease_out.dat
new file mode 100644
index 00000000000..bf68ab3169f
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_ease_out.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_elastic.dat b/release/datafiles/blender_icons16/icon16_ipo_elastic.dat
new file mode 100644
index 00000000000..5db0f974912
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_elastic.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_expo.dat b/release/datafiles/blender_icons16/icon16_ipo_expo.dat
new file mode 100644
index 00000000000..0456875782f
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_expo.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_linear.dat b/release/datafiles/blender_icons16/icon16_ipo_linear.dat
new file mode 100644
index 00000000000..84deef4dfe1
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_linear.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_quad.dat b/release/datafiles/blender_icons16/icon16_ipo_quad.dat
new file mode 100644
index 00000000000..f8dc28cf3fb
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_quad.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_quart.dat b/release/datafiles/blender_icons16/icon16_ipo_quart.dat
new file mode 100644
index 00000000000..9279f9551d3
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_quart.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_quint.dat b/release/datafiles/blender_icons16/icon16_ipo_quint.dat
new file mode 100644
index 00000000000..d76c781ac73
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_quint.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_sine.dat b/release/datafiles/blender_icons16/icon16_ipo_sine.dat
new file mode 100644
index 00000000000..4b1d22c360e
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_ipo_sine.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_line_data.dat b/release/datafiles/blender_icons16/icon16_line_data.dat
new file mode 100644
index 00000000000..22eec8a714e
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_line_data.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_nla_pushdown.dat b/release/datafiles/blender_icons16/icon16_nla_pushdown.dat
new file mode 100644
index 00000000000..37e5cacb333
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_nla_pushdown.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_action_tweak.dat b/release/datafiles/blender_icons32/icon32_action_tweak.dat
new file mode 100644
index 00000000000..140e5a3f8be
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_action_tweak.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_back.dat b/release/datafiles/blender_icons32/icon32_ipo_back.dat
new file mode 100644
index 00000000000..23897582e44
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_back.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_bezier.dat b/release/datafiles/blender_icons32/icon32_ipo_bezier.dat
new file mode 100644
index 00000000000..c05766e3a96
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_bezier.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_bounce.dat b/release/datafiles/blender_icons32/icon32_ipo_bounce.dat
new file mode 100644
index 00000000000..540ef0d1406
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_bounce.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_circ.dat b/release/datafiles/blender_icons32/icon32_ipo_circ.dat
new file mode 100644
index 00000000000..698e52f1d05
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_circ.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_constant.dat b/release/datafiles/blender_icons32/icon32_ipo_constant.dat
new file mode 100644
index 00000000000..275c124f6cf
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_constant.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_cubic.dat b/release/datafiles/blender_icons32/icon32_ipo_cubic.dat
new file mode 100644
index 00000000000..9df1bf06528
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_cubic.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_ease_in.dat b/release/datafiles/blender_icons32/icon32_ipo_ease_in.dat
new file mode 100644
index 00000000000..d84bea40aff
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_ease_in.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_ease_in_out.dat b/release/datafiles/blender_icons32/icon32_ipo_ease_in_out.dat
new file mode 100644
index 00000000000..a3ce296db39
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_ease_in_out.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_ease_out.dat b/release/datafiles/blender_icons32/icon32_ipo_ease_out.dat
new file mode 100644
index 00000000000..70e96b29eea
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_ease_out.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_elastic.dat b/release/datafiles/blender_icons32/icon32_ipo_elastic.dat
new file mode 100644
index 00000000000..dd65bfccf79
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_elastic.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_expo.dat b/release/datafiles/blender_icons32/icon32_ipo_expo.dat
new file mode 100644
index 00000000000..4fa63d6838f
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_expo.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_linear.dat b/release/datafiles/blender_icons32/icon32_ipo_linear.dat
new file mode 100644
index 00000000000..c0764a712af
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_linear.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_quad.dat b/release/datafiles/blender_icons32/icon32_ipo_quad.dat
new file mode 100644
index 00000000000..0693c648238
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_quad.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_quart.dat b/release/datafiles/blender_icons32/icon32_ipo_quart.dat
new file mode 100644
index 00000000000..a14a3046107
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_quart.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_quint.dat b/release/datafiles/blender_icons32/icon32_ipo_quint.dat
new file mode 100644
index 00000000000..daf7dda359b
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_quint.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_ipo_sine.dat b/release/datafiles/blender_icons32/icon32_ipo_sine.dat
new file mode 100644
index 00000000000..304c09ea036
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_ipo_sine.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_line_data.dat b/release/datafiles/blender_icons32/icon32_line_data.dat
new file mode 100644
index 00000000000..6f0f0315da2
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_line_data.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_nla_pushdown.dat b/release/datafiles/blender_icons32/icon32_nla_pushdown.dat
new file mode 100644
index 00000000000..83216ac5367
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_nla_pushdown.dat
Binary files differ
diff --git a/release/datafiles/blender_icons_update.py b/release/datafiles/blender_icons_update.py
index ec753c567fa..ec753c567fa 100755..100644
--- a/release/datafiles/blender_icons_update.py
+++ b/release/datafiles/blender_icons_update.py
diff --git a/release/datafiles/brushicons/clone.png b/release/datafiles/brushicons/clone.png
index b10faadef85..ce5e418bb79 100644
--- a/release/datafiles/brushicons/clone.png
+++ b/release/datafiles/brushicons/clone.png
Binary files differ
diff --git a/release/datafiles/brushicons/smear.png b/release/datafiles/brushicons/smear.png
index 5d42b3b24ee..756689d6b01 100644
--- a/release/datafiles/brushicons/smear.png
+++ b/release/datafiles/brushicons/smear.png
Binary files differ
diff --git a/release/datafiles/brushicons/soften.png b/release/datafiles/brushicons/soften.png
index 07367a4c189..84957a12b93 100644
--- a/release/datafiles/brushicons/soften.png
+++ b/release/datafiles/brushicons/soften.png
Binary files differ
diff --git a/release/datafiles/brushicons/texdraw.png b/release/datafiles/brushicons/texdraw.png
index 94faa584c19..86d9f269fe6 100644
--- a/release/datafiles/brushicons/texdraw.png
+++ b/release/datafiles/brushicons/texdraw.png
Binary files differ
diff --git a/release/datafiles/ctodata.py b/release/datafiles/ctodata.py
index a81a10102dc..a81a10102dc 100755..100644
--- a/release/datafiles/ctodata.py
+++ b/release/datafiles/ctodata.py
diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py
index f1fce08d7dd..f1fce08d7dd 100755..100644
--- a/release/datafiles/datatoc.py
+++ b/release/datafiles/datatoc.py
diff --git a/release/datafiles/prvicons_update.py b/release/datafiles/prvicons_update.py
index ecc466aab72..ecc466aab72 100755..100644
--- a/release/datafiles/prvicons_update.py
+++ b/release/datafiles/prvicons_update.py
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index ad0028ee0b4..b496bb77245 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
new file mode 100644
index 00000000000..654d07b093f
--- /dev/null
+++ b/release/datafiles/splash_2x.png
Binary files differ
diff --git a/release/datafiles/splash_template.xcf b/release/datafiles/splash_template.xcf
index 6d7e7d42c9f..b3141471c51 100644
--- a/release/datafiles/splash_template.xcf
+++ b/release/datafiles/splash_template.xcf
Binary files differ
diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
index c4e22192a89..ae0a8a04294 100644
--- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py
+++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
@@ -39,8 +39,10 @@ from freestyle.types import (
from freestyle.predicates import (
ExternalContourUP1D,
)
-from freestyle.utils import ContextFunctions as CF
-
+from freestyle.utils import (
+ ContextFunctions as CF,
+ stroke_normal,
+ )
import bpy
diff --git a/release/scripts/freestyle/modules/freestyle/predicates.py b/release/scripts/freestyle/modules/freestyle/predicates.py
index 08017953c35..ce6f0a35ffe 100644
--- a/release/scripts/freestyle/modules/freestyle/predicates.py
+++ b/release/scripts/freestyle/modules/freestyle/predicates.py
@@ -155,7 +155,6 @@ class pyParameterUP0D(UnaryPredicate0D):
## Unary predicates for 1D elements (curves)
############################################
-
class AndUP1D(UnaryPredicate1D):
def __init__(self, pred1, pred2):
UnaryPredicate1D.__init__(self)
@@ -515,11 +514,42 @@ class pyClosedCurveUP1D(UnaryPredicate1D):
## Binary predicates for 1D elements (curves)
#############################################
+class AndBP1D(BinaryPredicate1D):
+ def __init__(self, pred1, pred2):
+ BinaryPredicate1D.__init__(self)
+ self.__pred1 = pred1
+ self.__pred2 = pred2
+
+ def __call__(self, inter1, inter2):
+ return self.__pred1(inter1, inter2) and self.__pred2(inter1, inter2)
+
+
+class OrBP1D(BinaryPredicate1D):
+ def __init__(self, pred1, pred2):
+ BinaryPredicate1D.__init__(self)
+ self.__pred1 = pred1
+ self.__pred2 = pred2
+
+ def __call__(self, inter1, inter2):
+ return self.__pred1(inter1, inter2) or self.__pred2(inter1, inter2)
+
+
+class NotBP1D(BinaryPredicate1D):
+ def __init__(self, pred):
+ BinaryPredicate1D.__init__(self)
+ self.__pred = pred
+
+ def __call__(self, inter1, inter2):
+ return not self.__pred(inter1, inter2)
+
class pyZBP1D(BinaryPredicate1D):
+ def __init__(self, iType=IntegrationType.MEAN):
+ BinaryPredicate1D.__init__(self)
+ self._GetZ = GetZF1D(iType)
+
def __call__(self, i1, i2):
- func = GetZF1D()
- return (func(i1) > func(i2))
+ return (self._GetZ(i1) > self._GetZ(i2))
class pyZDiscontinuityBP1D(BinaryPredicate1D):
diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py
index a6ff61653be..ca14df7ac97 100644
--- a/release/scripts/freestyle/modules/freestyle/shaders.py
+++ b/release/scripts/freestyle/modules/freestyle/shaders.py
@@ -30,6 +30,7 @@ to be a collection of examples for shader definition in Python
from _freestyle import (
BackboneStretcherShader,
BezierCurveShader,
+ BlenderTextureShader,
CalligraphicShader,
ColorNoiseShader,
ColorVariationPatternShader,
@@ -44,6 +45,7 @@ from _freestyle import (
SmoothingShader,
SpatialNoiseShader,
StrokeTextureShader,
+ StrokeTextureStepShader,
TextureAssignerShader,
ThicknessNoiseShader,
ThicknessVariationPatternShader,
diff --git a/release/scripts/freestyle/modules/freestyle/utils.py b/release/scripts/freestyle/modules/freestyle/utils.py
index 6d2c9da8146..24ff86d5ef6 100644
--- a/release/scripts/freestyle/modules/freestyle/utils.py
+++ b/release/scripts/freestyle/modules/freestyle/utils.py
@@ -26,3 +26,44 @@ from _freestyle import (
getCurrentScene,
integrate,
)
+
+# constructs for definition of helper functions in Python
+from freestyle.types import (
+ StrokeVertexIterator,
+ )
+import mathutils
+
+
+def stroke_normal(it):
+ """
+ Compute the 2D normal at the stroke vertex pointed by the iterator
+ 'it'. It is noted that Normal2DF0D computes normals based on
+ underlying FEdges instead, which is inappropriate for strokes when
+ they have already been modified by stroke geometry modifiers.
+ """
+ # first stroke segment
+ it_next = StrokeVertexIterator(it)
+ it_next.increment()
+ if it.is_begin:
+ e = it_next.object.point_2d - it.object.point_2d
+ n = mathutils.Vector((e[1], -e[0]))
+ n.normalize()
+ return n
+ # last stroke segment
+ it_prev = StrokeVertexIterator(it)
+ it_prev.decrement()
+ if it_next.is_end:
+ e = it.object.point_2d - it_prev.object.point_2d
+ n = mathutils.Vector((e[1], -e[0]))
+ n.normalize()
+ return n
+ # two subsequent stroke segments
+ e1 = it_next.object.point_2d - it.object.point_2d
+ e2 = it.object.point_2d - it_prev.object.point_2d
+ n1 = mathutils.Vector((e1[1], -e1[0]))
+ n2 = mathutils.Vector((e2[1], -e2[0]))
+ n1.normalize()
+ n2.normalize()
+ n = n1 + n2
+ n.normalize()
+ return n
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py
index f3dd66b78cc..3304229e5ff 100644
--- a/release/scripts/freestyle/modules/parameter_editor.py
+++ b/release/scripts/freestyle/modules/parameter_editor.py
@@ -23,6 +23,7 @@
from freestyle.types import (
BinaryPredicate1D,
+ IntegrationType,
Interface0DIterator,
Nature,
Noise,
@@ -51,6 +52,8 @@ from freestyle.predicates import (
ExternalContourUP1D,
FalseBP1D,
FalseUP1D,
+ Length2DBP1D,
+ NotBP1D,
NotUP1D,
OrUP1D,
QuantitativeInvisibilityUP1D,
@@ -58,16 +61,19 @@ from freestyle.predicates import (
TrueUP1D,
WithinImageBoundaryUP1D,
pyNatureUP1D,
+ pyZBP1D,
)
from freestyle.shaders import (
BackboneStretcherShader,
BezierCurveShader,
+ BlenderTextureShader,
ConstantColorShader,
GuidingLinesShader,
PolygonalizationShader,
SamplingShader,
SpatialNoiseShader,
StrokeShader,
+ StrokeTextureStepShader,
TipRemoverShader,
pyBluePrintCirclesShader,
pyBluePrintEllipsesShader,
@@ -76,6 +82,7 @@ from freestyle.shaders import (
from freestyle.utils import (
ContextFunctions,
getCurrentScene,
+ stroke_normal,
)
from _freestyle import (
blendRamp,
@@ -582,13 +589,15 @@ class SinusDisplacementShader(StrokeShader):
self._wavelength = wavelength
self._amplitude = amplitude
self._phase = phase / wavelength * 2 * math.pi
- self._getNormal = Normal2DF0D()
def shade(self, stroke):
+ # separately iterate over stroke vertices to compute normals
+ buf = []
for it, distance in iter_distance_along_stroke(stroke):
- v = it.object
- n = self._getNormal(Interface0DIterator(it))
- n = n * self._amplitude * math.cos(distance / self._wavelength * 2 * math.pi + self._phase)
+ buf.append((it.object, distance, stroke_normal(it)))
+ # iterate over the vertices again to displace them
+ for v, distance, normal in buf:
+ n = normal * self._amplitude * math.cos(distance / self._wavelength * 2 * math.pi + self._phase)
v.point = v.point + n
stroke.update_length()
@@ -639,18 +648,19 @@ class Offset2DShader(StrokeShader):
self.__start = start
self.__end = end
self.__xy = mathutils.Vector((x, y))
- self.__getNormal = Normal2DF0D()
def shade(self, stroke):
+ # first iterate over stroke vertices to compute normals
+ buf = []
it = stroke.stroke_vertices_begin()
while not it.is_end:
- v = it.object
- u = v.u
- a = self.__start + u * (self.__end - self.__start)
- n = self.__getNormal(Interface0DIterator(it))
+ buf.append((it.object, stroke_normal(it)))
+ it.increment()
+ # again iterate over the vertices to add displacement
+ for v, n in buf:
+ a = self.__start + v.u * (self.__end - self.__start)
n = n * a
v.point = v.point + n + self.__xy
- it.increment()
stroke.update_length()
@@ -945,7 +955,8 @@ class DashedLineShader(StrokeShader):
if index == len(self._pattern):
index = 0
visible = not visible
- it.object.attribute.visible = visible
+ if not visible:
+ it.object.attribute.visible = visible
it.increment()
@@ -1159,6 +1170,14 @@ class StrokeCleaner(StrokeShader):
stroke.update_length()
+integration_types = {
+ 'MEAN': IntegrationType.MEAN,
+ 'MIN': IntegrationType.MIN,
+ 'MAX': IntegrationType.MAX,
+ 'FIRST': IntegrationType.FIRST,
+ 'LAST': IntegrationType.LAST}
+
+
# main function for parameter processing
def process(layer_name, lineset_name):
@@ -1287,6 +1306,16 @@ def process(layer_name, lineset_name):
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)
+ if linestyle.sort_key == 'DISTANCE_FROM_CAMERA':
+ bpred = pyZBP1D(integration)
+ elif linestyle.sort_key == '2D_LENGTH':
+ bpred = Length2DBP1D()
+ if linestyle.sort_order == 'REVERSE':
+ bpred = NotBP1D(bpred)
+ Operators.sort(bpred)
# prepare a list of stroke shaders
shaders_list = []
###
@@ -1341,6 +1370,14 @@ def process(layer_name, lineset_name):
elif m.type == '2D_TRANSFORM':
shaders_list.append(Transform2DShader(
m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y))
+ if linestyle.use_texture:
+ has_tex = False
+ for slot in linestyle.texture_slots:
+ if slot is not None:
+ shaders_list.append(BlenderTextureShader(slot))
+ has_tex = True
+ if has_tex:
+ shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing))
color = linestyle.color
if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object):
thickness_position = linestyle.thickness_position
diff --git a/release/scripts/freestyle/styles/anisotropic_diffusion.py b/release/scripts/freestyle/styles/anisotropic_diffusion.py
index f241f72fefe..b17e5c2a38c 100644
--- a/release/scripts/freestyle/styles/anisotropic_diffusion.py
+++ b/release/scripts/freestyle/styles/anisotropic_diffusion.py
@@ -26,7 +26,6 @@ from freestyle.predicates import (
AndUP1D,
ExternalContourUP1D,
NotUP1D,
- Operators,
QuantitativeInvisibilityUP1D,
TrueBP1D,
TrueUP1D,
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index e76bcc02751..88356b676d2 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -229,9 +229,9 @@ def check(module_name):
def _addon_ensure(module_name):
addons = _user_preferences.addons
- addon = _user_preferences.addons.get(module_name)
+ addon = addons.get(module_name)
if not addon:
- addon = _user_preferences.addons.new()
+ addon = addons.new()
addon.module = module_name
diff --git a/release/scripts/modules/animsys_refactor.py b/release/scripts/modules/animsys_refactor.py
index 8899bbf1ad7..aaa06c32312 100644
--- a/release/scripts/modules/animsys_refactor.py
+++ b/release/scripts/modules/animsys_refactor.py
@@ -25,6 +25,10 @@ rna values in fcurves and drivers.
Currently unused, but might become useful later again.
"""
+import sys
+import bpy
+
+
IS_TESTING = False
@@ -34,9 +38,21 @@ def drepr(string):
return '"%s"' % repr(string)[1:-1].replace("\"", "\\\"").replace("\\'", "'")
+def classes_recursive(base_type, clss=None):
+ if clss is None:
+ clss = [base_type]
+ else:
+ clss.append(base_type)
+
+ for base_type_iter in base_type.__bases__:
+ if base_type_iter is not object:
+ classes_recursive(base_type_iter, clss)
+
+ return clss
+
+
class DataPathBuilder(object):
- """ Dummy class used to parse fcurve and driver data paths.
- """
+ """Dummy class used to parse fcurve and driver data paths."""
__slots__ = ("data_path", )
def __init__(self, attrs):
@@ -55,38 +71,54 @@ class DataPathBuilder(object):
raise Exception("unsupported accessor %r of type %r (internal error)" % (key, type(key)))
return DataPathBuilder(self.data_path + (str_value, ))
- def resolve(self, real_base, rna_update_from_map=None):
- """ Return (attribute, value) pairs.
- """
+ def resolve(self, real_base, rna_update_from_map, fcurve, log):
+ """Return (attribute, value) pairs."""
pairs = []
base = real_base
for item in self.data_path:
if base is not Ellipsis:
- try:
- # this only works when running with an old blender
- # where the old path will resolve
- base = eval("base" + item)
- except:
- base_new = Ellipsis
- # guess the new name
- if item.startswith("."):
- for item_new in rna_update_from_map.get(item[1:], ()):
- try:
- print("base." + item_new)
- base_new = eval("base." + item_new)
+ base_new = Ellipsis
+ # find the new name
+ if item.startswith("."):
+ for class_name, item_new, options in rna_update_from_map.get(item[1:], []) + [(None, item[1:], None)]:
+ if callable(item_new):
+ # No type check here, callback is assumed to know what it's doing.
+ base_new, item_new = item_new(base, class_name, item[1:], fcurve, options)
+ if base_new is not Ellipsis:
break # found, don't keep looking
- except:
- pass
-
- if base_new is Ellipsis:
- print("Failed to resolve data path:", self.data_path)
- base = base_new
-
- pairs.append((item, base))
+ else:
+ # Type check!
+ type_ok = True
+ if class_name is not None:
+ type_ok = False
+ for base_type in classes_recursive(type(base)):
+ if base_type.__name__ == class_name:
+ type_ok = True
+ break
+ if type_ok:
+ try:
+ #print("base." + item_new)
+ base_new = eval("base." + item_new)
+ break # found, don't keep looking
+ except:
+ pass
+ item_new = "." + item_new
+ else:
+ item_new = item
+ try:
+ base_new = eval("base" + item_new)
+ except:
+ pass
+
+ if base_new is Ellipsis:
+ print("Failed to resolve data path:", self.data_path, file=log)
+ base = base_new
+ else:
+ item_new = item
+
+ pairs.append((item_new, base))
return pairs
-import bpy
-
def id_iter():
type_iter = type(bpy.data.objects)
@@ -110,20 +142,7 @@ def anim_data_actions(anim_data):
return [act for act in actions if act]
-def classes_recursive(base_type, clss=None):
- if clss is None:
- clss = [base_type]
- else:
- clss.append(base_type)
-
- for base_type_iter in base_type.__bases__:
- if base_type_iter is not object:
- classes_recursive(base_type_iter, clss)
-
- return clss
-
-
-def find_path_new(id_data, data_path, rna_update_dict, rna_update_from_map):
+def find_path_new(id_data, data_path, rna_update_from_map, fcurve, log):
# note!, id_data can be ID type or a node tree
# ignore ID props for now
if data_path.startswith("["):
@@ -131,46 +150,28 @@ def find_path_new(id_data, data_path, rna_update_dict, rna_update_from_map):
# recursive path fixing, likely will be one in most cases.
data_path_builder = eval("DataPathBuilder(tuple())." + data_path)
- data_resolve = data_path_builder.resolve(id_data, rna_update_from_map)
+ data_resolve = data_path_builder.resolve(id_data, rna_update_from_map, fcurve, log)
path_new = [pair[0] for pair in data_resolve]
- # print(data_resolve)
- data_base = id_data
-
- for i, (attr, data) in enumerate(data_resolve):
- if data is Ellipsis:
- break
-
- if attr.startswith("."):
- # try all classes
- for data_base_type in classes_recursive(type(data_base)):
- attr_new = rna_update_dict.get(data_base_type.__name__, {}).get(attr[1:])
- if attr_new:
- path_new[i] = "." + attr_new
+ return "".join(path_new)[1:] # skip the first "."
- # set this as the base for further properties
- data_base = data
- data_path_new = "".join(path_new)[1:] # skip the first "."
- return data_path_new
-
-
-def update_data_paths(rna_update):
- """ rna_update triple [(class_name, from, to), ...]
+def update_data_paths(rna_update, log=sys.stdout):
+ """
+ rna_update triple [(class_name, from, to or to_callback, callback options), ...]
+ to_callback is a function with this signature: update_cb(base, class_name, old_path, fcurve, options)
+ where base is current object, class_name is the expected type name of base (callback has to handle
+ this), old_path it the org name of base's property, fcurve is the affected fcurve (!),
+ and options is an opaque data.
+ class_name, fcurve and options may be None!
"""
-
- # make a faster lookup dict
- rna_update_dict = {}
- for ren_class, ren_from, ren_to in rna_update:
- rna_update_dict.setdefault(ren_class, {})[ren_from] = ren_to
rna_update_from_map = {}
- for ren_class, ren_from, ren_to in rna_update:
- rna_update_from_map.setdefault(ren_from, []).append(ren_to)
+ for ren_class, ren_from, ren_to, options in rna_update:
+ rna_update_from_map.setdefault(ren_from, []).append((ren_class, ren_to, options))
for id_data in id_iter():
-
# check node-trees too
anim_data_ls = [(id_data, getattr(id_data, "animation_data", None))]
node_tree = getattr(id_data, "node_tree", None)
@@ -183,13 +184,13 @@ def update_data_paths(rna_update):
for fcurve in anim_data.drivers:
data_path = fcurve.data_path
- data_path_new = find_path_new(anim_data_base, data_path, rna_update_dict, rna_update_from_map)
+ data_path_new = find_path_new(anim_data_base, data_path, rna_update_from_map, fcurve, log)
# print(data_path_new)
if data_path_new != data_path:
if not IS_TESTING:
fcurve.data_path = data_path_new
fcurve.driver.is_valid = True # reset to allow this to work again
- print("driver-fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new))
+ print("driver-fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new), file=log)
for var in fcurve.driver.variables:
if var.type == 'SINGLE_PROP':
@@ -198,32 +199,33 @@ def update_data_paths(rna_update):
data_path = tar.data_path
if id_data_other and data_path:
- data_path_new = find_path_new(id_data_other, data_path, rna_update_dict, rna_update_from_map)
+ data_path_new = find_path_new(id_data_other, data_path, rna_update_from_map, None, log)
# print(data_path_new)
if data_path_new != data_path:
if not IS_TESTING:
tar.data_path = data_path_new
- print("driver (%s): %s -> %s" % (id_data_other.name, data_path, data_path_new))
+ print("driver (%s): %s -> %s" % (id_data_other.name, data_path, data_path_new),
+ file=log)
for action in anim_data_actions(anim_data):
for fcu in action.fcurves:
data_path = fcu.data_path
- data_path_new = find_path_new(anim_data_base, data_path, rna_update_dict, rna_update_from_map)
+ data_path_new = find_path_new(anim_data_base, data_path, rna_update_from_map, fcu, log)
# print(data_path_new)
if data_path_new != data_path:
if not IS_TESTING:
fcu.data_path = data_path_new
- print("fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new))
+ print("fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new), file=log)
if __name__ == "__main__":
# Example, should be called externally
- # (class, from, to)
+ # (class, from, to or to_callback, callback_options)
replace_ls = [
- ("AnimVizMotionPaths", "frame_after", "frame_after"),
- ("AnimVizMotionPaths", "frame_before", "frame_before"),
- ("AnimVizOnionSkinning", "frame_after", "frame_after"),
+ ("AnimVizMotionPaths", "frame_after", "frame_after", None),
+ ("AnimVizMotionPaths", "frame_before", "frame_before", None),
+ ("AnimVizOnionSkinning", "frame_after", "frame_after", None),
]
update_data_paths(replace_ls)
diff --git a/release/scripts/modules/bl_i18n_utils/merge_po.py b/release/scripts/modules/bl_i18n_utils/merge_po.py
index d7dade22ffd..d7dade22ffd 100755..100644
--- a/release/scripts/modules/bl_i18n_utils/merge_po.py
+++ b/release/scripts/modules/bl_i18n_utils/merge_po.py
diff --git a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
index 24255d9be61..24255d9be61 100755..100644
--- a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
diff --git a/release/scripts/modules/bl_i18n_utils/utils_rtl.py b/release/scripts/modules/bl_i18n_utils/utils_rtl.py
index 261d1544ac6..261d1544ac6 100755..100644
--- a/release/scripts/modules/bl_i18n_utils/utils_rtl.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_rtl.py
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index ec8c4fc81d0..6eb0f02d2ea 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -39,6 +39,7 @@ class SpellChecker():
"decrement",
"derivate",
"doesn", # doesn't
+ "equi", # equi-angular, etc.
"fader",
"globbing",
"hasn", # hasn't
@@ -299,6 +300,7 @@ class SpellChecker():
"numpad",
"octree",
"opengl",
+ "openmp",
"polyline", "polylines",
"pulldown", "pulldowns",
"quantized",
@@ -321,6 +323,7 @@ class SpellChecker():
"bezier", "beziers",
"bicubic",
"bilinear",
+ "binormal",
"blackpoint", "whitepoint",
"blinn",
"bokeh",
@@ -362,6 +365,7 @@ class SpellChecker():
"specular", "specularity",
"spillmap",
"sobel",
+ "texel",
"tonemap",
"toon",
"timecode",
@@ -387,6 +391,7 @@ class SpellChecker():
"dupliobject", "dupliob",
"dupligroup",
"duplivert",
+ "dyntopo",
"editbone",
"editmode",
"fcurve", "fcurves",
@@ -412,6 +417,7 @@ class SpellChecker():
"poselib",
"pushpull",
"pyconstraint", "pyconstraints",
+ "qe", # keys...
"shapekey", "shapekeys",
"shrinkfatten",
"shrinkwrap",
@@ -427,6 +433,7 @@ class SpellChecker():
"vcol", "vcols",
"vgroup", "vgroups",
"vinterlace",
+ "wasd", "wasdqe", # keys...
"wetmap", "wetmaps",
"wpaint",
"uvwarp",
@@ -489,7 +496,7 @@ class SpellChecker():
"hdc",
"hdr",
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
- "hsv", "hsva",
+ "hsv", "hsva", "hsl",
"id",
"ior",
"itu",
diff --git a/release/scripts/modules/blend_render_info.py b/release/scripts/modules/blend_render_info.py
index a62eaeea143..a62eaeea143 100755..100644
--- a/release/scripts/modules/blend_render_info.py
+++ b/release/scripts/modules/blend_render_info.py
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 52bf1c04e65..f5455ce5018 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -74,10 +74,10 @@ class BPyOpsSubMod(object):
eg. bpy.ops.object
"""
- __slots__ = ("module",)
+ __slots__ = ("_module",)
def __init__(self, module):
- self.module = module
+ self._module = module
def __getattr__(self, func):
"""
@@ -85,13 +85,13 @@ class BPyOpsSubMod(object):
"""
if func.startswith('__'):
raise AttributeError(func)
- return BPyOpsSubModOp(self.module, func)
+ return BPyOpsSubModOp(self._module, func)
def __dir__(self):
functions = set()
- module_upper = self.module.upper()
+ module_upper = self._module.upper()
for id_name in op_dir():
id_split = id_name.split('_OT_', 1)
@@ -101,7 +101,7 @@ class BPyOpsSubMod(object):
return list(functions)
def __repr__(self):
- return "<module like class 'bpy.ops.%s'>" % self.module
+ return "<module like class 'bpy.ops.%s'>" % self._module
class BPyOpsSubModOp(object):
@@ -111,7 +111,7 @@ class BPyOpsSubModOp(object):
eg. bpy.ops.object.somefunc
"""
- __slots__ = ("module", "func")
+ __slots__ = ("_module", "_func")
def _get_doc(self):
return op_as_string(self.idname())
@@ -156,8 +156,8 @@ class BPyOpsSubModOp(object):
__doc__ = property(_get_doc)
def __init__(self, module, func):
- self.module = module
- self.func = func
+ self._module = module
+ self._func = func
def poll(self, *args):
C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
@@ -165,11 +165,11 @@ class BPyOpsSubModOp(object):
def idname(self):
# submod.foo -> SUBMOD_OT_foo
- return self.module.upper() + "_OT_" + self.func
+ return self._module.upper() + "_OT_" + self._func
def idname_py(self):
# submod.foo -> SUBMOD_OT_foo
- return self.module + "." + self.func
+ return self._module + "." + self._func
def __call__(self, *args, **kw):
import bpy
@@ -201,10 +201,15 @@ class BPyOpsSubModOp(object):
return op_get_instance(self.idname())
def __repr__(self): # useful display, repr(op)
- import bpy
+ # import bpy
idname = self.idname()
as_string = op_as_string(idname)
- op_class = getattr(bpy.types, idname)
+ # XXX You never quite know what you get from bpy.types,
+ # with operators... Operator and OperatorProperties
+ # are shadowing each other, and not in the same way for
+ # native ops and py ones! See T39158.
+ # op_class = getattr(bpy.types, idname)
+ op_class = op_get_rna(idname)
descr = op_class.bl_rna.description
# XXX, workaround for not registering
# every __doc__ to save time on load.
@@ -217,6 +222,6 @@ class BPyOpsSubModOp(object):
def __str__(self): # used for print(...)
return ("<function bpy.ops.%s.%s at 0x%x'>" %
- (self.module, self.func, id(self)))
+ (self._module, self._func, id(self)))
ops_fake_module = BPyOps()
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 608cd920865..ce1efa43b3e 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -25,6 +25,7 @@ not associated with blenders internal data.
__all__ = (
"blend_paths",
+ "escape_identifier",
"keyconfig_set",
"load_scripts",
"modules_from_path",
@@ -48,7 +49,13 @@ __all__ = (
"user_resource",
)
-from _bpy import register_class, unregister_class, blend_paths, resource_path
+from _bpy import (
+ escape_identifier,
+ register_class,
+ unregister_class,
+ blend_paths,
+ resource_path,
+ )
from _bpy import script_paths as _bpy_script_paths
from _bpy import user_resource as _user_resource
@@ -494,10 +501,10 @@ def keyconfig_set(filepath, report=None):
keyconfigs_old = keyconfigs[:]
try:
- keyfile = open(filepath)
- exec(compile(keyfile.read(), filepath, "exec"), {"__file__": filepath})
- keyfile.close()
error_msg = ""
+ with open(filepath, 'r', encoding='utf-8') as keyfile:
+ exec(compile(keyfile.read(), filepath, "exec"),
+ {"__file__": filepath})
except:
import traceback
error_msg = traceback.format_exc()
diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py
index 99f41b0699c..c50b320dceb 100644
--- a/release/scripts/modules/bpy_extras/keyconfig_utils.py
+++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py
@@ -175,7 +175,7 @@ def _export_properties(prefix, properties, kmi_id, lines=None):
elif properties.is_property_set(pname):
value = string_value(value)
if value != "":
- lines.append("set_kmi_prop(%s, '%s', %s, '%s')\n" % (prefix, pname, value, kmi_id))
+ lines.append("kmi_props_setattr(%s, '%s', %s)\n" % (prefix, pname, value))
return lines
@@ -221,11 +221,14 @@ def keyconfig_export(wm, kc, filepath):
f.write("import bpy\n")
f.write("import os\n\n")
- f.write("def set_kmi_prop(kmiprops, prop, value, kmiid):\n"
- " if hasattr(kmiprops, prop):\n"
- " setattr(kmiprops, prop, value)\n"
- " else:\n"
- " print(\"Warning: property '%s' not found in keymap item '%s'\" % (prop, kmiid))\n\n")
+ f.write("def kmi_props_setattr(kmi_props, attr, value):\n"
+ " try:\n"
+ " setattr(kmi_props, attr, value)\n"
+ " except AttributeError:\n"
+ " print(\"Warning: property '%s' not found in keymap item '%s'\" %\n"
+ " (attr, kmi_props.__class__.__name__))\n"
+ " except Exception as e:\n"
+ " print(\"Warning: %r\" % e)\n\n")
f.write("wm = bpy.context.window_manager\n")
f.write("kc = wm.keyconfigs.new(os.path.splitext(os.path.basename(__file__))[0])\n\n") # keymap must be created by caller
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index 7a075e93e1a..ad555a417d7 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -73,16 +73,11 @@ def region_2d_to_origin_3d(region, rv3d, coord):
:return: The origin of the viewpoint in 3d space.
:rtype: :class:`mathutils.Vector`
"""
- from mathutils import Vector
-
viewinv = rv3d.view_matrix.inverted()
if rv3d.is_perspective:
- from mathutils.geometry import intersect_line_plane
-
origin_start = viewinv.translation.copy()
else:
- from mathutils.geometry import intersect_point_line
persmat = rv3d.perspective_matrix.copy()
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 031d079e5dc..d2683471915 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -180,14 +180,14 @@ class _GenericBone:
@property
def y_axis(self):
- """ Vector pointing down the x-axis of the bone.
+ """ Vector pointing down the y-axis of the bone.
"""
from mathutils import Vector
return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0))
@property
def z_axis(self):
- """ Vector pointing down the x-axis of the bone.
+ """ Vector pointing down the z-axis of the bone.
"""
from mathutils import Vector
return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
@@ -279,7 +279,7 @@ class _GenericBone:
child = children_basename[0]
chain.append(child)
else:
- if len(children_basename):
+ if children_basename:
print("multiple basenames found, "
"this is probably not what you want!",
self.name, children_basename)
diff --git a/release/scripts/modules/nodeitems_utils.py b/release/scripts/modules/nodeitems_utils.py
index 7418452b039..f017c76ae6f 100644
--- a/release/scripts/modules/nodeitems_utils.py
+++ b/release/scripts/modules/nodeitems_utils.py
@@ -18,7 +18,6 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
class NodeCategory():
@@ -92,7 +91,6 @@ def register_node_categories(identifier, cat_list):
def draw_node_item(self, context):
layout = self.layout
col = layout.column()
- default_context = bpy.app.translations.contexts.default
for item in self.category.items(context):
item.draw(item, col, context)
diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py
index 831ba1ba597..12d99a00d44 100644
--- a/release/scripts/modules/rna_keymap_ui.py
+++ b/release/scripts/modules/rna_keymap_ui.py
@@ -255,6 +255,9 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
# KeyMapItem like dict, use for comparing against
# attr: {states, ...}
kmi_test_dict = {}
+ # Special handling of 'type' using a list if sets,
+ # keymap items must match against all.
+ kmi_test_type = []
# initialize? - so if a if a kmi has a MOD assigned it wont show up.
#~ for kv in key_mod.values():
@@ -265,16 +268,16 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
if kk in filter_text_split:
filter_text_split.remove(kk)
kmi_test_dict[kv] = {True}
+
# whats left should be the event type
- if len(filter_text_split) > 1:
- return False
- elif filter_text_split:
- kmi_type = filter_text_split[0].upper()
+ def kmi_type_set_from_string(kmi_type):
+ kmi_type = kmi_type.upper()
kmi_type_set = set()
if kmi_type in _EVENT_TYPES:
kmi_type_set.add(kmi_type)
- else:
+
+ if not kmi_type_set or len(kmi_type) > 1:
# replacement table
for event_type_map in (_EVENT_TYPE_MAP, _EVENT_TYPE_MAP_EXTRA):
kmi_type_test = event_type_map.get(kmi_type)
@@ -287,17 +290,37 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
for k, v in event_type_map.items():
if (kmi_type in k) or (kmi_type in v):
kmi_type_set.add(v)
+ return kmi_type_set
+
+ for i, kmi_type in enumerate(filter_text_split):
+ kmi_type_set = kmi_type_set_from_string(kmi_type)
- if not kmi_type_set:
- return False
+ if not kmi_type_set:
+ return False
- kmi_test_dict["type"] = kmi_type_set
+ kmi_test_type.append(kmi_type_set)
+ # tiny optimization, sort sets so the smallest is first
+ # improve chances of failing early
+ kmi_test_type.sort(key=lambda kmi_type_set: len(kmi_type_set))
# main filter func, runs many times
def filter_func(kmi):
for kk, ki in kmi_test_dict.items():
- if getattr(kmi, kk) not in ki:
+ val = getattr(kmi, kk)
+ if val not in ki:
return False
+
+ # special handling of 'type'
+ for ki in kmi_test_type:
+ val = kmi.type
+ if val == 'NONE' or val not in ki:
+ # exception for 'type'
+ # also inspect 'key_modifier' as a fallback
+ val = kmi.key_modifier
+ if not (val == 'NONE' or val not in ki):
+ continue
+ return False
+
return True
for km, kc in display_keymaps:
@@ -351,7 +374,7 @@ def draw_keymaps(context, layout):
row = subcol.row(align=True)
- #~ row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config:")
+ #~ row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config")
text = bpy.path.display_name(wm.keyconfigs.active.name)
if not text:
text = "Blender (default)"
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index dd0cd632413..5180bdb59ce 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -92,6 +92,8 @@ def draw(layout, context, context_member, property_type, use_edit=True):
if not rna_item:
return
+ from bpy.utils import escape_identifier
+
if rna_item.id_data.library is not None:
use_edit = False
@@ -138,18 +140,23 @@ def draw(layout, context, context_member, property_type, use_edit=True):
row.label(text=key, translate=False)
# explicit exception for arrays
+ is_rna = (key in rna_properties)
+
if to_dict or to_list:
row.label(text=val_draw, translate=False)
else:
- if key in rna_properties:
+ if is_rna:
row.prop(rna_item, key, text="")
else:
- row.prop(rna_item, '["%s"]' % key, text="")
+ row.prop(rna_item, '["%s"]' % escape_identifier(key), text="")
if use_edit:
row = split.row(align=True)
- props = row.operator("wm.properties_edit", text="Edit")
- assign_props(props, val_draw, key)
+ if not is_rna:
+ props = row.operator("wm.properties_edit", text="Edit")
+ assign_props(props, val_draw, key)
+ else:
+ row.label(text="API Defined")
props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
assign_props(props, val_draw, key)
diff --git a/release/scripts/presets/camera/1__colon__2.3_inch.py b/release/scripts/presets/camera/1__colon__2.3_inch.py
new file mode 100644
index 00000000000..829a060ab35
--- /dev/null
+++ b/release/scripts/presets/camera/1__colon__2.3_inch.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 6.16
+bpy.context.object.data.sensor_height = 4.62
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/1__colon__2.5_inch.py b/release/scripts/presets/camera/1__colon__2.5_inch.py
new file mode 100644
index 00000000000..3ddd240ab50
--- /dev/null
+++ b/release/scripts/presets/camera/1__colon__2.5_inch.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 5.76
+bpy.context.object.data.sensor_height = 4.29
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/2__colon__3_inch.py b/release/scripts/presets/camera/2__colon__3_inch.py
new file mode 100644
index 00000000000..edf3bbba2c9
--- /dev/null
+++ b/release/scripts/presets/camera/2__colon__3_inch.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 9.6
+bpy.context.object.data.sensor_height = 5.4
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/4__colon__3_inch.py b/release/scripts/presets/camera/4__colon__3_inch.py
new file mode 100644
index 00000000000..6e38782c4d8
--- /dev/null
+++ b/release/scripts/presets/camera/4__colon__3_inch.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 17.31
+bpy.context.object.data.sensor_height = 12.98
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Arri_Alexa.py b/release/scripts/presets/camera/Arri_Alexa.py
new file mode 100644
index 00000000000..2bdcf12240b
--- /dev/null
+++ b/release/scripts/presets/camera/Arri_Alexa.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.760
+bpy.context.object.data.sensor_height = 13.365
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py b/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py
new file mode 100644
index 00000000000..402a5b30cbb
--- /dev/null
+++ b/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 15.81
+bpy.context.object.data.sensor_height = 8.88
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_1D.py b/release/scripts/presets/camera/Canon_1D.py
deleted file mode 100644
index 0bb0e910377..00000000000
--- a/release/scripts/presets/camera/Canon_1D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 27.9
-bpy.context.object.data.sensor_height = 18.6
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_1DS.py b/release/scripts/presets/camera/Canon_1DS.py
deleted file mode 100644
index 158a6235f32..00000000000
--- a/release/scripts/presets/camera/Canon_1DS.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 36.0
-bpy.context.object.data.sensor_height = 24.0
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_500D.py b/release/scripts/presets/camera/Canon_500D.py
deleted file mode 100644
index 829e03cc5cf..00000000000
--- a/release/scripts/presets/camera/Canon_500D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_550D.py b/release/scripts/presets/camera/Canon_550D.py
deleted file mode 100644
index 829e03cc5cf..00000000000
--- a/release/scripts/presets/camera/Canon_550D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_5D.py b/release/scripts/presets/camera/Canon_5D.py
deleted file mode 100644
index 158a6235f32..00000000000
--- a/release/scripts/presets/camera/Canon_5D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 36.0
-bpy.context.object.data.sensor_height = 24.0
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_600D.py b/release/scripts/presets/camera/Canon_600D.py
deleted file mode 100644
index 829e03cc5cf..00000000000
--- a/release/scripts/presets/camera/Canon_600D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_60D.py b/release/scripts/presets/camera/Canon_60D.py
deleted file mode 100644
index 829e03cc5cf..00000000000
--- a/release/scripts/presets/camera/Canon_60D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_7D.py b/release/scripts/presets/camera/Canon_7D.py
deleted file mode 100644
index 829e03cc5cf..00000000000
--- a/release/scripts/presets/camera/Canon_7D.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/APS-C_DSLR.py b/release/scripts/presets/camera/Canon_APS-C.py
index 829e03cc5cf..829e03cc5cf 100644
--- a/release/scripts/presets/camera/APS-C_DSLR.py
+++ b/release/scripts/presets/camera/Canon_APS-C.py
diff --git a/release/scripts/presets/camera/Canon_APS-H.py b/release/scripts/presets/camera/Canon_APS-H.py
new file mode 100644
index 00000000000..d5cc02f4e4a
--- /dev/null
+++ b/release/scripts/presets/camera/Canon_APS-H.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 27.90
+bpy.context.object.data.sensor_height = 18.60
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_C300.py b/release/scripts/presets/camera/Canon_C300.py
new file mode 100644
index 00000000000..70c760c73b5
--- /dev/null
+++ b/release/scripts/presets/camera/Canon_C300.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 24.4
+bpy.context.object.data.sensor_height = 13.5
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/full_frame_35mm_film.py b/release/scripts/presets/camera/Full_Frame_35mm_Camera.py
index d3e141ba4d9..d3e141ba4d9 100644
--- a/release/scripts/presets/camera/full_frame_35mm_film.py
+++ b/release/scripts/presets/camera/Full_Frame_35mm_Camera.py
diff --git a/release/scripts/presets/camera/GoPro_Hero3_Black.py b/release/scripts/presets/camera/GoPro_Hero3_Black.py
new file mode 100644
index 00000000000..9cea698d8ab
--- /dev/null
+++ b/release/scripts/presets/camera/GoPro_Hero3_Black.py
@@ -0,0 +1,6 @@
+import bpy
+bpy.context.object.data.sensor_width = 6.16
+bpy.context.object.data.sensor_height = 4.62
+bpy.context.object.data.lens = 2.77
+
+bpy.context.object.data.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/GoPro_Hero3_Silver.py b/release/scripts/presets/camera/GoPro_Hero3_Silver.py
new file mode 100644
index 00000000000..1eee0750c2d
--- /dev/null
+++ b/release/scripts/presets/camera/GoPro_Hero3_Silver.py
@@ -0,0 +1,6 @@
+import bpy
+bpy.context.object.data.sensor_width = 5.371
+bpy.context.object.data.sensor_height = 4.035
+bpy.context.object.data.lens = 2.77
+
+bpy.context.object.data.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/GoPro_Hero3_White.py b/release/scripts/presets/camera/GoPro_Hero3_White.py
new file mode 100644
index 00000000000..3d1f368aab0
--- /dev/null
+++ b/release/scripts/presets/camera/GoPro_Hero3_White.py
@@ -0,0 +1,6 @@
+import bpy
+bpy.context.object.data.sensor_width = 5.76
+bpy.context.object.data.sensor_height = 4.29
+bpy.context.object.data.lens = 2.77
+
+bpy.context.object.data.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/Nexus_5.py b/release/scripts/presets/camera/Nexus_5.py
new file mode 100644
index 00000000000..aa781782acb
--- /dev/null
+++ b/release/scripts/presets/camera/Nexus_5.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.5
+bpy.context.object.data.sensor_height = 3.37
+bpy.context.object.data.lens = 3.91
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D3S.py b/release/scripts/presets/camera/Nikon_D3S.py
deleted file mode 100644
index e6dc62dc100..00000000000
--- a/release/scripts/presets/camera/Nikon_D3S.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 36.0
-bpy.context.object.data.sensor_height = 23.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D5000.py b/release/scripts/presets/camera/Nikon_D5000.py
deleted file mode 100644
index a0505bf9b9c..00000000000
--- a/release/scripts/presets/camera/Nikon_D5000.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 23.6
-bpy.context.object.data.sensor_height = 15.8
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D5100.py b/release/scripts/presets/camera/Nikon_D5100.py
deleted file mode 100644
index 1d819cce65b..00000000000
--- a/release/scripts/presets/camera/Nikon_D5100.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 23.6
-bpy.context.object.data.sensor_height = 15.6
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D7000.py b/release/scripts/presets/camera/Nikon_D7000.py
deleted file mode 100644
index 1d819cce65b..00000000000
--- a/release/scripts/presets/camera/Nikon_D7000.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 23.6
-bpy.context.object.data.sensor_height = 15.6
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D90.py b/release/scripts/presets/camera/Nikon_D90.py
deleted file mode 100644
index a0505bf9b9c..00000000000
--- a/release/scripts/presets/camera/Nikon_D90.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 23.6
-bpy.context.object.data.sensor_height = 15.8
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D300S.py b/release/scripts/presets/camera/Nikon_DX.py
index a0505bf9b9c..a0505bf9b9c 100644
--- a/release/scripts/presets/camera/Nikon_D300S.py
+++ b/release/scripts/presets/camera/Nikon_DX.py
diff --git a/release/scripts/presets/camera/Panasonic_AG-HVX200.py b/release/scripts/presets/camera/Panasonic_AG-HVX200.py
new file mode 100644
index 00000000000..ee82cbe9bf0
--- /dev/null
+++ b/release/scripts/presets/camera/Panasonic_AG-HVX200.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.68
+bpy.context.object.data.sensor_height = 2.633
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Panasonic_LX2.py b/release/scripts/presets/camera/Panasonic_LX2.py
new file mode 100644
index 00000000000..8e0f844e507
--- /dev/null
+++ b/release/scripts/presets/camera/Panasonic_LX2.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 8.5
+bpy.context.object.data.sensor_height = 4.78
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Samsung_Galaxy_S3.py b/release/scripts/presets/camera/Samsung_Galaxy_S3.py
new file mode 100644
index 00000000000..35670042e48
--- /dev/null
+++ b/release/scripts/presets/camera/Samsung_Galaxy_S3.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.8
+bpy.context.object.data.sensor_height = 3.6
+bpy.context.object.data.lens = 3.70
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Samsung_Galaxy_S4.py b/release/scripts/presets/camera/Samsung_Galaxy_S4.py
new file mode 100644
index 00000000000..ae16d4172f9
--- /dev/null
+++ b/release/scripts/presets/camera/Samsung_Galaxy_S4.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.8
+bpy.context.object.data.sensor_height = 3.6
+bpy.context.object.data.lens = 4.20
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Sony_EX1.py b/release/scripts/presets/camera/Sony_EX1.py
new file mode 100644
index 00000000000..00708175b40
--- /dev/null
+++ b/release/scripts/presets/camera/Sony_EX1.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 6.97
+bpy.context.object.data.sensor_height = 3.92
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Sony_F65.py b/release/scripts/presets/camera/Sony_F65.py
new file mode 100644
index 00000000000..e187828058b
--- /dev/null
+++ b/release/scripts/presets/camera/Sony_F65.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 24.33
+bpy.context.object.data.sensor_height = 12.83
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/super_16_film.py b/release/scripts/presets/camera/Super_16_Film.py
index 1e42953bf05..1e42953bf05 100644
--- a/release/scripts/presets/camera/super_16_film.py
+++ b/release/scripts/presets/camera/Super_16_Film.py
diff --git a/release/scripts/presets/camera/super_35_film.py b/release/scripts/presets/camera/Super_35_Film.py
index 65ccb0f216c..65ccb0f216c 100644
--- a/release/scripts/presets/camera/super_35_film.py
+++ b/release/scripts/presets/camera/Super_35_Film.py
diff --git a/release/scripts/presets/camera/iPhone_4.py b/release/scripts/presets/camera/iPhone_4.py
new file mode 100644
index 00000000000..b87dda18097
--- /dev/null
+++ b/release/scripts/presets/camera/iPhone_4.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.54
+bpy.context.object.data.sensor_height = 3.42
+bpy.context.object.data.lens = 3.85
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/iPhone_4S.py b/release/scripts/presets/camera/iPhone_4S.py
new file mode 100644
index 00000000000..ea747f339d4
--- /dev/null
+++ b/release/scripts/presets/camera/iPhone_4S.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.54
+bpy.context.object.data.sensor_height = 3.42
+bpy.context.object.data.lens = 4.28
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/iPhone_5.py b/release/scripts/presets/camera/iPhone_5.py
new file mode 100644
index 00000000000..2764788a405
--- /dev/null
+++ b/release/scripts/presets/camera/iPhone_5.py
@@ -0,0 +1,5 @@
+import bpy
+bpy.context.object.data.sensor_width = 4.54
+bpy.context.object.data.sensor_height = 3.42
+bpy.context.object.data.lens = 4.10
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/micro_four_thirds.py b/release/scripts/presets/camera/micro_four_thirds.py
deleted file mode 100644
index 36fb0aac391..00000000000
--- a/release/scripts/presets/camera/micro_four_thirds.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bpy
-bpy.context.object.data.sensor_width = 17.3
-bpy.context.object.data.sensor_height = 13.0
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/cloth/rubber.py b/release/scripts/presets/cloth/rubber.py
index c2d7625d333..cb354168daa 100644
--- a/release/scripts/presets/cloth/rubber.py
+++ b/release/scripts/presets/cloth/rubber.py
@@ -1,7 +1,7 @@
import bpy
-bpy.context.active_object.modifiers['Cloth'].settings.quality = 7
-bpy.context.active_object.modifiers['Cloth'].settings.mass = 3
-bpy.context.active_object.modifiers['Cloth'].settings.structural_stiffness = 15
-bpy.context.active_object.modifiers['Cloth'].settings.bending_stiffness = 25
-bpy.context.active_object.modifiers['Cloth'].settings.spring_damping = 25
-bpy.context.active_object.modifiers['Cloth'].settings.air_damping = 1
+bpy.context.cloth.settings.quality = 7
+bpy.context.cloth.settings.mass = 3
+bpy.context.cloth.settings.structural_stiffness = 15
+bpy.context.cloth.settings.bending_stiffness = 25
+bpy.context.cloth.settings.spring_damping = 25
+bpy.context.cloth.settings.air_damping = 1
diff --git a/release/scripts/presets/keyconfig/3dsmax.py b/release/scripts/presets/keyconfig/3dsmax.py
index 5993183a7e1..808ba7cee81 100644
--- a/release/scripts/presets/keyconfig/3dsmax.py
+++ b/release/scripts/presets/keyconfig/3dsmax.py
@@ -64,18 +64,18 @@ kmi.properties.value = 'TEXT_EDITOR'
kmi = km.keymap_items.new('wm.context_set_enum', 'F12', 'PRESS', shift=True)
kmi.properties.data_path = 'area.type'
kmi.properties.value = 'DOPESHEET_EDITOR'
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS')
-kmi.properties.decrease = False
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS')
-kmi.properties.decrease = True
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
-kmi.properties.decrease = False
-kmi.properties.fast = True
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
-kmi.properties.decrease = True
-kmi.properties.fast = True
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_PLUS', 'PRESS')
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.1
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_MINUS', 'PRESS')
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.0 / 1.1
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.5
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.0 / 1.5
kmi = km.keymap_items.new('info.reports_display_update', 'TIMER_REPORT', 'ANY', any=True)
# Map Screen
@@ -270,7 +270,7 @@ kmi.properties.name = 'VIEW3D_MT_bone_options_enable'
kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', alt=True)
kmi.properties.name = 'VIEW3D_MT_bone_options_disable'
kmi = km.keymap_items.new('armature.layers_show_all', 'ACCENT_GRAVE', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('pose.armature_layers', 'M', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.armature_layers', 'M', 'PRESS', shift=True)
kmi = km.keymap_items.new('pose.bone_layers', 'M', 'PRESS')
kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', ctrl=True, alt=True)
kmi.properties.mode = 'BONE_SIZE'
@@ -2149,7 +2149,7 @@ kmi.properties.quad_method = 'BEAUTY'
kmi.properties.ngon_method = 'BEAUTY'
kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', shift=True, ctrl=True)
kmi.properties.quad_method = 'FIXED'
-kmi.properties.ngon_method = 'SCANFILL'
+kmi.properties.ngon_method = 'CLIP'
kmi = km.keymap_items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
kmi = km.keymap_items.new('mesh.rip_move', 'V', 'PRESS')
kmi = km.keymap_items.new('mesh.rip_move_fill', 'V', 'PRESS', alt=True)
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index 4831a6291ba..3a5a6c7570a 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -64,18 +64,18 @@ kmi.properties.value = 'TEXT_EDITOR'
kmi = km.keymap_items.new('wm.context_set_enum', 'F12', 'PRESS', shift=True)
kmi.properties.data_path = 'area.type'
kmi.properties.value = 'DOPESHEET_EDITOR'
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS')
-kmi.properties.decrease = False
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS')
-kmi.properties.decrease = True
-kmi.properties.fast = False
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
-kmi.properties.decrease = False
-kmi.properties.fast = True
-kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
-kmi.properties.decrease = True
-kmi.properties.fast = True
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_PLUS', 'PRESS')
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.1
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_MINUS', 'PRESS')
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.0 / 1.1
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.5
+kmi = km.keymap_items.new('wm.context_scale_float', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
+kmi.properties.data_path = 'user_preferences.inputs.ndof_sensitivity'
+kmi.properties.value = 1.0 / 1.5
kmi = km.keymap_items.new('info.reports_display_update', 'TIMER', 'ANY', any=True)
# Map Screen
@@ -326,7 +326,7 @@ kmi.properties.name = 'VIEW3D_MT_pose_group'
kmi = km.keymap_items.new('wm.call_menu', 'RIGHTMOUSE', 'PRESS')
kmi.properties.name = 'VIEW3D_MT_bone_options_toggle'
kmi = km.keymap_items.new('armature.layers_show_all', 'ACCENT_GRAVE', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('pose.armature_layers', 'M', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.armature_layers', 'M', 'PRESS', shift=True)
kmi = km.keymap_items.new('pose.bone_layers', 'M', 'PRESS')
kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', ctrl=True, alt=True)
kmi = km.keymap_items.new('anim.keyframe_insert_menu', 'S', 'PRESS')
@@ -1173,7 +1173,7 @@ kmi = km.keymap_items.new('uv.pin', 'P', 'PRESS')
kmi.properties.clear = False
kmi = km.keymap_items.new('uv.pin', 'P', 'PRESS', alt=True)
kmi.properties.clear = True
-kmi = km.keymap_items.new('uv.unwrap', 'E', 'PRESS')
+kmi = km.keymap_items.new('uv.unwrap', 'U', 'PRESS')
kmi = km.keymap_items.new('uv.hide', 'H', 'PRESS', ctrl=True)
kmi.properties.unselected = False
kmi = km.keymap_items.new('uv.hide', 'H', 'PRESS', alt=True)
diff --git a/release/scripts/presets/tracking_camera/Canon_1D.py b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py
index 89590d3cc19..218e51a53a6 100644
--- a/release/scripts/presets/tracking_camera/Canon_1D.py
+++ b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py
@@ -1,10 +1,10 @@
import bpy
camera = bpy.context.edit_movieclip.tracking.camera
-camera.sensor_width = 27.9
+camera.sensor_width = 6.16
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_1DS.py b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py
index 7d9b6c8b390..0f16dc9b503 100644
--- a/release/scripts/presets/tracking_camera/Canon_1DS.py
+++ b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py
@@ -1,10 +1,10 @@
import bpy
camera = bpy.context.edit_movieclip.tracking.camera
-camera.sensor_width = 36.0
+camera.sensor_width = 5.76
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_500D.py b/release/scripts/presets/tracking_camera/2__colon__3_inch.py
index 3dd66c5b609..079d0c6308f 100644
--- a/release/scripts/presets/tracking_camera/Canon_500D.py
+++ b/release/scripts/presets/tracking_camera/2__colon__3_inch.py
@@ -1,10 +1,10 @@
import bpy
camera = bpy.context.edit_movieclip.tracking.camera
-camera.sensor_width = 22.3
+camera.sensor_width = 9.6
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_550D.py b/release/scripts/presets/tracking_camera/4__colon__3_inch.py
index 3dd66c5b609..0d3313ab755 100644
--- a/release/scripts/presets/tracking_camera/Canon_550D.py
+++ b/release/scripts/presets/tracking_camera/4__colon__3_inch.py
@@ -1,10 +1,10 @@
import bpy
camera = bpy.context.edit_movieclip.tracking.camera
-camera.sensor_width = 22.3
+camera.sensor_width = 17.31
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Arri_Alexa.py b/release/scripts/presets/tracking_camera/Arri_Alexa.py
new file mode 100644
index 00000000000..7144f9a03aa
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Arri_Alexa.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.76
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Blackmagic_Cinema_Camera.py b/release/scripts/presets/tracking_camera/Blackmagic_Cinema_Camera.py
new file mode 100644
index 00000000000..f84d0a19d22
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Blackmagic_Cinema_Camera.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 15.81
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_1100D.py b/release/scripts/presets/tracking_camera/Canon_1100D.py
index 7ea78412f40..dc09e3d0896 100644
--- a/release/scripts/presets/tracking_camera/Canon_1100D.py
+++ b/release/scripts/presets/tracking_camera/Canon_1100D.py
@@ -3,8 +3,8 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 22.2
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_5D.py b/release/scripts/presets/tracking_camera/Canon_5D.py
deleted file mode 100644
index 7d9b6c8b390..00000000000
--- a/release/scripts/presets/tracking_camera/Canon_5D.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 36.0
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_60D.py b/release/scripts/presets/tracking_camera/Canon_60D.py
deleted file mode 100644
index 3dd66c5b609..00000000000
--- a/release/scripts/presets/tracking_camera/Canon_60D.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 22.3
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_7D.py b/release/scripts/presets/tracking_camera/Canon_7D.py
deleted file mode 100644
index 3dd66c5b609..00000000000
--- a/release/scripts/presets/tracking_camera/Canon_7D.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 22.3
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_600D.py b/release/scripts/presets/tracking_camera/Canon_APS-C.py
index 3dd66c5b609..c55716a06a8 100644
--- a/release/scripts/presets/tracking_camera/Canon_600D.py
+++ b/release/scripts/presets/tracking_camera/Canon_APS-C.py
@@ -3,8 +3,8 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 22.3
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_APS-H.py b/release/scripts/presets/tracking_camera/Canon_APS-H.py
new file mode 100644
index 00000000000..0b757edef20
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_APS-H.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 27.90
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Canon_C300.py b/release/scripts/presets/tracking_camera/Canon_C300.py
new file mode 100644
index 00000000000..24fbbc78ff7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_C300.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 24.4
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py
new file mode 100644
index 00000000000..478e53584fb
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 36
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py
new file mode 100644
index 00000000000..47e026e9d00
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 6.16
+camera.units = 'MILLIMETERS'
+camera.focal_length = 2.77
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py
new file mode 100644
index 00000000000..10ca885769a
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 5.371
+camera.units = 'MILLIMETERS'
+camera.focal_length = 2.77
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py
new file mode 100644
index 00000000000..c9bda2258c8
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 5.76
+camera.units = 'MILLIMETERS'
+camera.focal_length = 2.77
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Nexus_5.py b/release/scripts/presets/tracking_camera/Nexus_5.py
new file mode 100644
index 00000000000..68ec347d3e1
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nexus_5.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.5
+camera.units = 'MILLIMETERS'
+camera.focal_length = 3.91
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Nikon_D3100.py b/release/scripts/presets/tracking_camera/Nikon_D3100.py
index a112dd22dd2..44646f8b112 100644
--- a/release/scripts/presets/tracking_camera/Nikon_D3100.py
+++ b/release/scripts/presets/tracking_camera/Nikon_D3100.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 23.1
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D35.py b/release/scripts/presets/tracking_camera/Nikon_D35.py
deleted file mode 100644
index 7d9b6c8b390..00000000000
--- a/release/scripts/presets/tracking_camera/Nikon_D35.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 36.0
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D5000.py b/release/scripts/presets/tracking_camera/Nikon_D5000.py
deleted file mode 100644
index 8db89189cd7..00000000000
--- a/release/scripts/presets/tracking_camera/Nikon_D5000.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 23.6
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D5100.py b/release/scripts/presets/tracking_camera/Nikon_D5100.py
deleted file mode 100644
index 8db89189cd7..00000000000
--- a/release/scripts/presets/tracking_camera/Nikon_D5100.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 23.6
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D7000.py b/release/scripts/presets/tracking_camera/Nikon_D7000.py
deleted file mode 100644
index 8db89189cd7..00000000000
--- a/release/scripts/presets/tracking_camera/Nikon_D7000.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 23.6
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D90.py b/release/scripts/presets/tracking_camera/Nikon_D90.py
deleted file mode 100644
index 8db89189cd7..00000000000
--- a/release/scripts/presets/tracking_camera/Nikon_D90.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import bpy
-camera = bpy.context.edit_movieclip.tracking.camera
-
-camera.sensor_width = 23.6
-camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
-camera.pixel_aspect = 1
-camera.k1 = 0.0
-camera.k2 = 0.0
-camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D300S.py b/release/scripts/presets/tracking_camera/Nikon_DX.py
index 8db89189cd7..8d9e3505e3f 100644
--- a/release/scripts/presets/tracking_camera/Nikon_D300S.py
+++ b/release/scripts/presets/tracking_camera/Nikon_DX.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 23.6
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Panasonic_AG-HVX200.py b/release/scripts/presets/tracking_camera/Panasonic_AG-HVX200.py
new file mode 100644
index 00000000000..49cc71fa5da
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Panasonic_AG-HVX200.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.68
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1.5
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Panasonic_LX2.py b/release/scripts/presets/tracking_camera/Panasonic_LX2.py
new file mode 100644
index 00000000000..f9ffcb8ec03
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Panasonic_LX2.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 8.5
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_Epic.py b/release/scripts/presets/tracking_camera/Red_Epic.py
index 913b507d296..c0790e6baed 100644
--- a/release/scripts/presets/tracking_camera/Red_Epic.py
+++ b/release/scripts/presets/tracking_camera/Red_Epic.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 30.0
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_2K.py b/release/scripts/presets/tracking_camera/Red_One_2K.py
index 0a52b377959..fa9585b5e08 100644
--- a/release/scripts/presets/tracking_camera/Red_One_2K.py
+++ b/release/scripts/presets/tracking_camera/Red_One_2K.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 11.1
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_3K.py b/release/scripts/presets/tracking_camera/Red_One_3K.py
index 88c232bb944..5a1b7472109 100644
--- a/release/scripts/presets/tracking_camera/Red_One_3K.py
+++ b/release/scripts/presets/tracking_camera/Red_One_3K.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 16.65
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_4K.py b/release/scripts/presets/tracking_camera/Red_One_4K.py
index 7ea78412f40..96d6d456337 100644
--- a/release/scripts/presets/tracking_camera/Red_One_4K.py
+++ b/release/scripts/presets/tracking_camera/Red_One_4K.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 22.2
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py
new file mode 100644
index 00000000000..6dbdaefbd2f
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.8
+camera.units = 'MILLIMETERS'
+camera.focal_length = 3.70
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py
new file mode 100644
index 00000000000..051cdf64402
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.8
+camera.units = 'MILLIMETERS'
+camera.focal_length = 4.2
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Sony_A55.py b/release/scripts/presets/tracking_camera/Sony_A55.py
index 5805bfa41db..26920d06f94 100644
--- a/release/scripts/presets/tracking_camera/Sony_A55.py
+++ b/release/scripts/presets/tracking_camera/Sony_A55.py
@@ -3,7 +3,6 @@ camera = bpy.context.edit_movieclip.tracking.camera
camera.sensor_width = 23.4
camera.units = 'MILLIMETERS'
-camera.focal_length = 24.0
camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Sony_EX1.py b/release/scripts/presets/tracking_camera/Sony_EX1.py
new file mode 100644
index 00000000000..2b99c91d221
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Sony_EX1.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 6.97
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Sony_F65.py b/release/scripts/presets/tracking_camera/Sony_F65.py
new file mode 100644
index 00000000000..7da93fd5d47
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Sony_F65.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 24.33
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Super_16.py b/release/scripts/presets/tracking_camera/Super_16.py
new file mode 100644
index 00000000000..f1a8bb37328
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Super_16.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 12.52
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/Super_35.py b/release/scripts/presets/tracking_camera/Super_35.py
new file mode 100644
index 00000000000..f533d3e4bcf
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Super_35.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 24.89
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/iPhone_4.py b/release/scripts/presets/tracking_camera/iPhone_4.py
new file mode 100644
index 00000000000..b0ac49706b3
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/iPhone_4.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.54
+camera.units = 'MILLIMETERS'
+camera.focal_length = 3.85
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/iPhone_4S.py b/release/scripts/presets/tracking_camera/iPhone_4S.py
new file mode 100644
index 00000000000..2569f9b412b
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/iPhone_4S.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.54
+camera.units = 'MILLIMETERS'
+camera.focal_length = 4.28
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_camera/iPhone_5.py b/release/scripts/presets/tracking_camera/iPhone_5.py
new file mode 100644
index 00000000000..f7944e3fa63
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/iPhone_5.py
@@ -0,0 +1,11 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 4.54
+camera.units = 'MILLIMETERS'
+camera.focal_length = 4.10
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
+
diff --git a/release/scripts/presets/tracking_settings/blurry_footage.py b/release/scripts/presets/tracking_settings/blurry_footage.py
index de6f085f53d..253a8f395ba 100644
--- a/release/scripts/presets/tracking_settings/blurry_footage.py
+++ b/release/scripts/presets/tracking_settings/blurry_footage.py
@@ -15,3 +15,4 @@ settings.use_default_red_channel = True
settings.use_default_green_channel = True
settings.use_default_blue_channel = True
settings.default_correlation_min = 0.6
+settings.default_weight = 1.0
diff --git a/release/scripts/presets/tracking_settings/default.py b/release/scripts/presets/tracking_settings/default.py
index 3c61ea7cd7f..3d2481ce7ad 100644
--- a/release/scripts/presets/tracking_settings/default.py
+++ b/release/scripts/presets/tracking_settings/default.py
@@ -2,8 +2,8 @@ import bpy
settings = bpy.context.edit_movieclip.tracking.settings
-settings.default_pattern_size = 15
-settings.default_search_size = 51
+settings.default_pattern_size = 21
+settings.default_search_size = 71
settings.default_motion_model = 'Loc'
settings.use_default_brute = True
settings.use_default_normalization = False
@@ -15,3 +15,4 @@ settings.use_default_red_channel = True
settings.use_default_green_channel = True
settings.use_default_blue_channel = True
settings.default_correlation_min = 0.75
+settings.default_weight = 1.0
diff --git a/release/scripts/presets/tracking_settings/fast_motion.py b/release/scripts/presets/tracking_settings/fast_motion.py
index 6051f235b0c..4294b7327d1 100644
--- a/release/scripts/presets/tracking_settings/fast_motion.py
+++ b/release/scripts/presets/tracking_settings/fast_motion.py
@@ -15,3 +15,4 @@ settings.use_default_red_channel = True
settings.use_default_green_channel = True
settings.use_default_blue_channel = True
settings.default_correlation_min = 0.6
+settings.default_weight = 1.0
diff --git a/release/scripts/presets/tracking_settings/planar.py b/release/scripts/presets/tracking_settings/planar.py
index 49a64046002..a099b3a800d 100644
--- a/release/scripts/presets/tracking_settings/planar.py
+++ b/release/scripts/presets/tracking_settings/planar.py
@@ -15,3 +15,4 @@ settings.use_default_red_channel = True
settings.use_default_green_channel = True
settings.use_default_blue_channel = True
settings.default_correlation_min = 0.75
+settings.default_weight = 1.0
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 39b0df1dd65..449a4cef1ef 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -22,7 +22,6 @@ from bpy.types import Operator
from bpy.props import (FloatProperty,
IntProperty,
- BoolProperty,
)
from bpy.app.translations import pgettext_data as data_
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 41f39b90464..e8890bfd936 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -23,6 +23,7 @@ if "bpy" in locals():
if "anim_utils" in locals():
imp.reload(anim_utils)
+
import bpy
from bpy.types import Operator
from bpy.props import (IntProperty,
@@ -281,3 +282,85 @@ class ClearUselessActions(Operator):
self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions"
% removed)
return {'FINISHED'}
+
+
+class UpdateAnimatedTransformConstraint(Operator):
+ """Update fcurves/drivers affecting Transform constraints (use it with files from 2.70 and earlier)"""
+ bl_idname = "anim.update_animated_transform_constraints"
+ bl_label = "Update Animated Transform Constraints"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ use_convert_to_radians = BoolProperty(
+ name="Convert To Radians",
+ description="Convert fcurves/drivers affecting rotations to radians (Warning: use this only once!)",
+ default=True,
+ )
+
+ def execute(self, context):
+ import animsys_refactor
+ from math import radians
+ import io
+
+ from_paths = {"from_max_x", "from_max_y", "from_max_z", "from_min_x", "from_min_y", "from_min_z"}
+ to_paths = {"to_max_x", "to_max_y", "to_max_z", "to_min_x", "to_min_y", "to_min_z"}
+ paths = from_paths | to_paths
+
+ def update_cb(base, class_name, old_path, fcurve, options):
+ print(options)
+ def handle_deg2rad(fcurve):
+ if fcurve is not None:
+ if hasattr(fcurve, "keyframes"):
+ for k in fcurve.keyframes:
+ k.co.y = radians(k.co.y)
+ for mod in fcurve.modifiers:
+ if mod.type == 'GENERATOR':
+ if mod.mode == 'POLYNOMIAL':
+ mod.coefficients[:] = [radians(c) for c in mod.coefficients]
+ else: # if mod.type == 'POLYNOMIAL_FACTORISED':
+ mod.coefficients[:2] = [radians(c) for c in mod.coefficients[:2]]
+ elif mod.type == 'FNGENERATOR':
+ mod.amplitude = radians(mod.amplitude)
+ fcurve.update()
+
+ data = ...
+ try:
+ data = eval("base." + old_path)
+ except:
+ pass
+ ret = (data, old_path)
+ if isinstance(base, bpy.types.TransformConstraint) and data is not ...:
+ new_path = None
+ map_info = base.map_from if old_path in from_paths else base.map_to
+ if map_info == 'ROTATION':
+ new_path = old_path + "_rot"
+ if options is not None and options["use_convert_to_radians"]:
+ handle_deg2rad(fcurve)
+ elif map_info == 'SCALE':
+ new_path = old_path + "_scale"
+
+ if new_path is not None:
+ data = ...
+ try:
+ data = eval("base." + new_path)
+ except:
+ pass
+ ret = (data, new_path)
+ #print(ret)
+
+ return ret
+
+ options = {"use_convert_to_radians": self.use_convert_to_radians}
+ replace_ls = [("TransformConstraint", p, update_cb, options) for p in paths]
+ log = io.StringIO()
+
+ animsys_refactor.update_data_paths(replace_ls, log)
+
+ context.scene.frame_set(context.scene.frame_current)
+
+ log = log.getvalue()
+ if log:
+ print(log)
+ text = bpy.data.texts.new("UpdateAnimatedTransformConstraint Report")
+ text.from_string(log)
+ self.report({'INFO'}, "Complete report available on '{}' text datablock".format(text.name))
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index e90879c448f..7e142cebb4f 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -121,6 +121,7 @@ def CLIP_default_settings_from_track(clip, track, framenr):
settings.use_default_red_channel = track.use_red_channel
settings.use_default_green_channel = track.use_green_channel
settings.use_default_blue_channel = track.use_blue_channel
+ settings.default_weight = track.weight
class CLIP_OT_track_to_empty(Operator):
@@ -188,6 +189,15 @@ class CLIP_OT_bundles_to_mesh(Operator):
new_verts = []
+ scene = context.scene
+ camera = scene.camera
+ matrix = Matrix.Identity(4)
+ if camera:
+ reconstruction = tracking_object.reconstruction
+ framenr = scene.frame_current - clip.frame_start + 1
+ reconstructed_matrix = reconstruction.cameras.matrix_from_frame(framenr)
+ matrix = camera.matrix_world * reconstructed_matrix.inverted()
+
mesh = bpy.data.meshes.new(name="Tracks")
for track in tracking_object.tracks:
if track.has_bundle:
@@ -199,6 +209,8 @@ class CLIP_OT_bundles_to_mesh(Operator):
ob = bpy.data.objects.new(name="Tracks", object_data=mesh)
+ ob.matrix_world = matrix
+
context.scene.objects.link(ob)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py
index 73232232e23..453be519abf 100644
--- a/release/scripts/startup/bl_operators/freestyle.py
+++ b/release/scripts/startup/bl_operators/freestyle.py
@@ -105,7 +105,7 @@ class SCENE_OT_freestyle_add_edge_marks_to_keying_set(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
for i, edge in enumerate(mesh.edges):
if not edge.hide and edge.select:
- path = 'edges[%d].use_freestyle_edge_mark' % i
+ path = 'edges[%d].use_freestyle_mark' % i
ks.paths.add(mesh, path, index=0)
bpy.ops.object.mode_set(mode=ob_mode, toggle=False)
return {'FINISHED'}
@@ -136,7 +136,7 @@ class SCENE_OT_freestyle_add_face_marks_to_keying_set(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
for i, polygon in enumerate(mesh.polygons):
if not polygon.hide and polygon.select:
- path = 'polygons[%d].use_freestyle_face_mark' % i
+ path = 'polygons[%d].use_freestyle_mark' % i
ks.paths.add(mesh, path, index=0)
bpy.ops.object.mode_set(mode=ob_mode, toggle=False)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 0d3d45d98fe..1653459bd71 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -90,8 +90,9 @@ class EditExternally(Operator):
def invoke(self, context, event):
import os
+ sd = context.space_data
try:
- image = context.space_data.image
+ image = sd.image
except AttributeError:
self.report({'ERROR'}, "Context incorrect, image not found")
return {'CANCELLED'}
@@ -100,7 +101,12 @@ class EditExternally(Operator):
self.report({'ERROR'}, "Image is packed, unpack before editing")
return {'CANCELLED'}
- filepath = bpy.path.abspath(image.filepath, library=image.library)
+ if sd.type == 'IMAGE_EDITOR':
+ filepath = image.filepath_from_user(sd.image_user)
+ else:
+ filepath = image.filepath
+
+ filepath = bpy.path.abspath(filepath, library=image.library)
self.filepath = os.path.normpath(filepath)
self.execute(context)
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index cead7d66097..f86c31cd9cc 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -87,7 +87,6 @@ class MeshMirrorUV(Operator):
polys = mesh.polygons
loops = mesh.loops
- verts = mesh.vertices
uv_loops = mesh.uv_layers.active.data
nbr_polys = len(polys)
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 13189b2e9d3..9bdd9289700 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -61,7 +61,6 @@ class NodeAddOperator():
@staticmethod
def store_mouse_cursor(context, event):
space = context.space_data
- v2d = context.region.view2d
tree = space.edit_tree
# convert mouse position to the View2D for later node placement
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index ae13ba8b559..5661e25bc0f 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -248,13 +248,17 @@ class SubdivisionSet(Operator):
for mod in obj.modifiers:
if mod.type == 'MULTIRES':
if not relative:
- if level <= mod.total_levels:
- if obj.mode == 'SCULPT':
- if mod.sculpt_levels != level:
- mod.sculpt_levels = level
- elif obj.mode == 'OBJECT':
- if mod.levels != level:
- mod.levels = level
+ if level > mod.total_levels:
+ sub = level - mod.total_levels
+ for i in range (0, sub):
+ bpy.ops.object.multires_subdivide(modifier="Multires")
+
+ if obj.mode == 'SCULPT':
+ if mod.sculpt_levels != level:
+ mod.sculpt_levels = level
+ elif obj.mode == 'OBJECT':
+ if mod.levels != level:
+ mod.levels = level
return
else:
if obj.mode == 'SCULPT':
@@ -276,8 +280,14 @@ class SubdivisionSet(Operator):
# add a new modifier
try:
- mod = obj.modifiers.new("Subsurf", 'SUBSURF')
- mod.levels = level
+ if obj.mode == 'SCULPT':
+ mod = obj.modifiers.new("Multires", 'MULTIRES')
+ if level > 0:
+ for i in range(0, level):
+ bpy.ops.object.multires_subdivide(modifier="Multires")
+ else:
+ mod = obj.modifiers.new("Subsurf", 'SUBSURF')
+ mod.levels = level
except:
self.report({'WARNING'},
"Modifiers cannot be added to object: " + obj.name)
@@ -687,7 +697,6 @@ class TransformsToDeltasAnim(Operator):
DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
# try to apply on each selected object
- success = False
for obj in context.selected_editable_objects:
adt = obj.animation_data
if (adt is None) or (adt.action is None):
@@ -792,7 +801,6 @@ class LodByName(Operator):
return (context.active_object is not None)
def execute(self, context):
- scene = context.scene
ob = context.active_object
prefix = ""
@@ -843,7 +851,6 @@ class LodClearAll(Operator):
return (context.active_object is not None)
def execute(self, context):
- scene = context.scene
ob = context.active_object
if ob.lod_levels:
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 765135d6f3d..556d34bb0ac 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -436,7 +436,7 @@ class QuickFluid(Operator):
def execute(self, context):
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
- if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
+ if (obj.type == 'MESH' and 0.0 not in obj.dimensions)]
min_co = Vector((100000.0, 100000.0, 100000.0))
max_co = -min_co
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index ae6ec3946f1..8b0ed7d9942 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -256,14 +256,26 @@ class AddPresetCamera(AddPresetBase, Operator):
"cam = bpy.context.object.data"
]
- preset_values = [
- "cam.sensor_width",
- "cam.sensor_height",
- "cam.sensor_fit"
- ]
-
preset_subdir = "camera"
+ use_focal_length = BoolProperty(
+ name="Include Focal Length",
+ description="Include focal length into the preset",
+ options={'SKIP_SAVE'},
+ )
+
+ @property
+ def preset_values(self):
+ preset_values = [
+ "cam.sensor_width",
+ "cam.sensor_height",
+ "cam.sensor_fit"
+ ]
+ if self.use_focal_length:
+ preset_values.append("cam.lens")
+ preset_values.append("cam.lens_unit")
+ return preset_values
+
class AddPresetSSS(AddPresetBase, Operator):
"""Add or remove a Subsurface Scattering Preset"""
@@ -398,18 +410,29 @@ class AddPresetTrackingCamera(AddPresetBase, Operator):
"camera = bpy.context.edit_movieclip.tracking.camera"
]
- preset_values = [
- "camera.sensor_width",
- "camera.units",
- "camera.focal_length",
- "camera.pixel_aspect",
- "camera.k1",
- "camera.k2",
- "camera.k3"
- ]
-
preset_subdir = "tracking_camera"
+ use_focal_length = BoolProperty(
+ name="Include Focal Length",
+ description="Include focal length into the preset",
+ options={'SKIP_SAVE'},
+ default=True
+ )
+
+ @property
+ def preset_values(self):
+ preset_values = [
+ "camera.sensor_width",
+ "camera.pixel_aspect",
+ "camera.k1",
+ "camera.k2",
+ "camera.k3"
+ ]
+ if self.use_focal_length:
+ preset_values.append("camera.units")
+ preset_values.append("camera.focal_length")
+ return preset_values
+
class AddPresetTrackingTrackColor(AddPresetBase, Operator):
"""Add or remove a Clip Track Color Preset"""
@@ -453,6 +476,7 @@ class AddPresetTrackingSettings(AddPresetBase, Operator):
"settings.use_default_red_channel",
"settings.use_default_green_channel",
"settings.use_default_blue_channel"
+ "settings.default_weight"
]
preset_subdir = "tracking_settings"
diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py
index f9461c85341..9a3aae53ceb 100644
--- a/release/scripts/startup/bl_operators/rigidbody.py
+++ b/release/scripts/startup/bl_operators/rigidbody.py
@@ -143,6 +143,9 @@ class BakeToKeyframes(Operator):
scene.frame_set(f)
for j, obj in enumerate(objects):
mat = bake[i][j]
+ # convert world space transform to parent space, so parented objects don't get offset after baking
+ if (obj.parent):
+ mat = obj.matrix_parent_inverse.inverted() * obj.parent.matrix_world.inverted() * mat
obj.location = mat.to_translation()
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 74fb9e98c82..bf8b10ac4af 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -23,7 +23,7 @@ import bpy
from bpy.types import Operator
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
-SMALL_NUM = 0.000001 # see bug [#31598] why we dont have smaller values
+SMALL_NUM = 0.00000001 # see bug [#31598] why we dont have smaller values
global USER_FILL_HOLES
global USER_FILL_HOLES_QUALITY
@@ -232,17 +232,29 @@ def islandIntersectUvIsland(source, target, SourceOffset):
return 0 # NO INTERSECTION
+def rotate_uvs(uv_points, angle):
+
+ if angle != 0.0:
+ mat = Matrix.Rotation(angle, 2)
+ for uv in uv_points:
+ uv[:] = mat * uv
+
+
def optiRotateUvIsland(faces):
uv_points = [uv for f in faces for uv in f.uv]
angle = geometry.box_fit_2d(uv_points)
if angle != 0.0:
- mat = Matrix.Rotation(angle, 2)
- i = 0 # count the serialized uv/vectors
- for f in faces:
- for j, k in enumerate(range(i, len(f.v) + i)):
- f.uv[j][:] = mat * uv_points[k]
- i += len(f.v)
+ rotate_uvs(uv_points, angle)
+
+ # orient them vertically (could be an option)
+ minx, miny, maxx, maxy = boundsIsland(faces)
+ w, h = maxx - minx, maxy - miny
+ # use epsilon so we dont randomly rotate (almost) perfect squares.
+ if h + 0.00001 < w:
+ from math import pi
+ angle = pi / 2.0
+ rotate_uvs(uv_points, angle)
# Takes an island list and tries to find concave, hollow areas to pack smaller islands into.
@@ -594,10 +606,10 @@ def packIslands(islandList):
# recalc width and height
w, h = maxx-minx, maxy-miny
- if w < 0.00001 or h < 0.00001:
- del islandList[islandIdx]
- islandIdx -=1
- continue
+ if w < SMALL_NUM:
+ w = SMALL_NUM
+ if h < SMALL_NUM:
+ h = SMALL_NUM
"""Save the offset to be applied later,
we could apply to the UVs now and allign them to the bottom left hand area
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index 345d8d4d3a1..68c9bc143be 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -99,7 +99,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
active_col_layer = None
- if len(me.vertex_colors):
+ if me.vertex_colors:
for lay in me.vertex_colors:
if lay.active:
active_col_layer = lay.data
@@ -183,7 +183,6 @@ class VertexPaintDirt(Operator):
def execute(self, context):
import time
- from math import radians
obj = context.object
mesh = obj.data
diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py
index da6628617e7..85cc9210c2d 100644
--- a/release/scripts/startup/bl_operators/view3d.py
+++ b/release/scripts/startup/bl_operators/view3d.py
@@ -19,7 +19,6 @@
# <pep8-80 compliant>
import bpy
-import mathutils
from bpy.types import Operator
from bpy.props import BoolProperty
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 332e4de124e..86ae8fdc4e6 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -19,7 +19,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Operator
+from bpy.types import Operator
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
@@ -757,6 +757,7 @@ class WM_OT_url_open(Operator):
"Open a website in the web-browser"
bl_idname = "wm.url_open"
bl_label = ""
+ bl_options = {'INTERNAL'}
url = StringProperty(
name="URL",
@@ -773,6 +774,7 @@ class WM_OT_path_open(Operator):
"Open a path in a file browser"
bl_idname = "wm.path_open"
bl_label = ""
+ bl_options = {'INTERNAL'}
filepath = StringProperty(
subtype='FILE_PATH',
@@ -1081,12 +1083,12 @@ class WM_OT_properties_edit(Operator):
prop_type_old = type(item[prop_old])
rna_idprop_ui_prop_clear(item, prop_old)
- exec_str = "del item['%s']" % prop_old
+ exec_str = "del item[%r]" % prop_old
# print(exec_str)
exec(exec_str)
# Reassign
- exec_str = "item['%s'] = %s" % (prop, repr(value_eval))
+ exec_str = "item[%r] = %s" % (prop, repr(value_eval))
# print(exec_str)
exec(exec_str)
self._last_prop[:] = [prop]
@@ -1103,8 +1105,9 @@ class WM_OT_properties_edit(Operator):
# If we have changed the type of the property, update its potential anim curves!
if prop_type_old != prop_type:
- data_path = '["%s"]' % prop
+ data_path = '["%s"]' % bpy.utils.escape_identifier(prop)
done = set()
+
def _update(fcurves):
for fcu in fcurves:
if fcu not in done and fcu.data_path == data_path:
@@ -1113,9 +1116,9 @@ class WM_OT_properties_edit(Operator):
def _update_strips(strips):
for st in strips:
- if st.type in {'CLIP'} and st.action:
+ if st.type == 'CLIP' and st.action:
_update(st.action.fcurves)
- elif st.type in {'META'}:
+ elif st.type == 'META':
_update_strips(st.strips)
adt = getattr(item, "animation_data", None)
@@ -2018,6 +2021,7 @@ class WM_OT_addon_expand(Operator):
"Display more information on this addon"
bl_idname = "wm.addon_expand"
bl_label = ""
+ bl_options = {'INTERNAL'}
module = StringProperty(
name="Module",
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index b1b1d0a4d73..6b72ef12dcc 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -43,6 +43,7 @@ _modules = [
"properties_material",
"properties_object",
"properties_paint_common",
+ "properties_grease_pencil_common",
"properties_particle",
"properties_physics_cloth",
"properties_physics_common",
@@ -194,7 +195,6 @@ class UI_UL_list(bpy.types.UIList):
return a list mapping org_idx -> new_idx,
or an empty list if no sorting has been done.
"""
- neworder = [None] * len(items)
_sort = [(idx, getattr(it, propname, "")) for idx, it in enumerate(items)]
return cls.sort_items_helper(_sort, lambda e: e[1].lower())
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index 4ad178bc064..50107604b3b 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -653,21 +653,22 @@ class ConstraintButtonsPanel():
col.row().prop(con, "map_from", expand=True)
split = layout.split()
+ ext = "" if con.map_from == 'LOCATION' else "_rot" if con.map_from == 'ROTATION' else "_scale"
sub = split.column(align=True)
sub.label(text="X:")
- sub.prop(con, "from_min_x", text="Min")
- sub.prop(con, "from_max_x", text="Max")
+ sub.prop(con, "from_min_x" + ext, text="Min")
+ sub.prop(con, "from_max_x" + ext, text="Max")
sub = split.column(align=True)
sub.label(text="Y:")
- sub.prop(con, "from_min_y", text="Min")
- sub.prop(con, "from_max_y", text="Max")
+ sub.prop(con, "from_min_y" + ext, text="Min")
+ sub.prop(con, "from_max_y" + ext, text="Max")
sub = split.column(align=True)
sub.label(text="Z:")
- sub.prop(con, "from_min_z", text="Min")
- sub.prop(con, "from_max_z", text="Max")
+ sub.prop(con, "from_min_z" + ext, text="Min")
+ sub.prop(con, "from_max_z" + ext, text="Max")
col = layout.column()
row = col.row()
@@ -694,27 +695,28 @@ class ConstraintButtonsPanel():
col.row().prop(con, "map_to", expand=True)
split = layout.split()
+ ext = "" if con.map_to == 'LOCATION' else "_rot" if con.map_to == 'ROTATION' else "_scale"
col = split.column()
col.label(text="X:")
sub = col.column(align=True)
- sub.prop(con, "to_min_x", text="Min")
- sub.prop(con, "to_max_x", text="Max")
+ sub.prop(con, "to_min_x" + ext, text="Min")
+ sub.prop(con, "to_max_x" + ext, text="Max")
col = split.column()
col.label(text="Y:")
sub = col.column(align=True)
- sub.prop(con, "to_min_y", text="Min")
- sub.prop(con, "to_max_y", text="Max")
+ sub.prop(con, "to_min_y" + ext, text="Min")
+ sub.prop(con, "to_max_y" + ext, text="Max")
col = split.column()
col.label(text="Z:")
sub = col.column(align=True)
- sub.prop(con, "to_min_z", text="Min")
- sub.prop(con, "to_max_z", text="Max")
+ sub.prop(con, "to_min_z" + ext, text="Min")
+ sub.prop(con, "to_max_z" + ext, text="Max")
self.space_template(layout, con)
@@ -856,10 +858,12 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel):
obj = context.object
- if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
+ if obj.type == 'ARMATURE' and obj.mode in {'POSE'}:
box = layout.box()
- box.alert = True
- box.label(icon='INFO', text="See Bone Constraints tab to Add Constraints to active bone")
+ box.alert = True # XXX: this should apply to the box background
+ box.label(icon='INFO', text="Constraints for active bone do not live here")
+ box.operator("wm.properties_context_change", icon='CONSTRAINT_BONE',
+ text="Go to Bone Constraints tab...").context = 'BONE_CONSTRAINT'
else:
layout.operator_menu_enum("object.constraint_add", "type", text="Add Object Constraint")
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index f27087a48b0..c6823f17153 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -201,10 +201,6 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
col.operator("poselib.action_sanitize", icon='HELP', text="") # XXX: put in menu?
- # properties for active marker
- if pose_marker_active is not None:
- layout.prop(pose_marker_active, "name")
-
# TODO: this panel will soon be deprecated too
class DATA_PT_ghost(ArmatureButtonsPanel, Panel):
@@ -296,7 +292,7 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
return (context.object) and (context.armature)
def draw(self, context):
- layout = self.layout
+ # layout = self.layout
ob = context.object
avs = ob.pose.animation_visualization
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 38f04639edd..0600c87244b 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -102,7 +102,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
row.prop(cam, "lens")
- elif cam.lens_unit == 'DEGREES':
+ elif cam.lens_unit == 'FOV':
row.prop(cam, "angle")
row.prop(cam, "lens_unit", text="")
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 8a3e31d8308..acfc4d1e263 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -183,13 +183,22 @@ class DATA_PT_geometry_curve(CurveButtonsPanelCurve, Panel):
col.prop(curve, "bevel_object", text="")
col = layout.column(align=True)
- col.prop(curve, "bevel_factor_start")
- col.prop(curve, "bevel_factor_end")
-
row = col.row()
- row.active = (curve.bevel_object is not None)
- row.prop(curve, "use_fill_caps")
+ row.label(text="Bevel Factor:")
+
+ col = layout.column()
+ col.active = (curve.bevel_depth > 0 or curve.bevel_object is not None)
+ row = col.row(align=True)
+ row.prop(curve, "bevel_factor_mapping_start", text="")
+ row.prop(curve, "bevel_factor_start", text="Start")
+ row = col.row(align=True)
+ row.prop(curve, "bevel_factor_mapping_end", text="")
+ row.prop(curve, "bevel_factor_end", text="End")
+
+ row = layout.row()
+ row.active = curve.bevel_object is not None
row.prop(curve, "use_map_taper")
+ row.prop(curve, "use_fill_caps")
class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index edf3354db4f..622c9ba2445 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -76,7 +76,7 @@ class MESH_UL_shape_keys(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.ShapeKey)
obj = active_data
- key = data
+ # key = data
key_block = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
split = layout.split(0.66, False)
@@ -323,7 +323,6 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
layout = self.layout
me = context.mesh
- lay = me.uv_textures.active
row = layout.row()
col = row.column()
@@ -343,7 +342,6 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
layout = self.layout
me = context.mesh
- lay = me.vertex_colors.active
row = layout.row()
col = row.column()
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 093b7f2cf40..60187ff1cd5 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -237,10 +237,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "use_transform")
def CLOTH(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def COLLISION(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def CURVE(self, layout, ob, md):
split = layout.split()
@@ -283,29 +283,28 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def DISPLACE(self, layout, ob, md):
has_texture = (md.texture is not None)
- split = layout.split()
-
- col = split.column()
+ col = layout.column(align=True)
col.label(text="Texture:")
col.template_ID(md, "texture", new="texture.new")
- col.label(text="Vertex Group:")
- col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
- col = split.column()
+ split = layout.split()
+
+ col = split.column(align=True)
col.label(text="Direction:")
col.prop(md, "direction", text="")
- colsub = col.column()
- colsub.active = has_texture
- colsub.label(text="Texture Coordinates:")
- colsub.prop(md, "texture_coords", text="")
+ col.label(text="Vertex Group:")
+ col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+ col = split.column(align=True)
+ col.active = has_texture
+ col.label(text="Texture Coordinates:")
+ col.prop(md, "texture_coords", text="")
if md.texture_coords == 'OBJECT':
- row = layout.row()
- row.active = has_texture
- row.prop(md, "texture_coords_object", text="Object")
+ col.label(text="Object:")
+ col.prop(md, "texture_coords_object", text="")
elif md.texture_coords == 'UV' and ob.type == 'MESH':
- row = layout.row()
- row.active = has_texture
- row.prop_search(md, "uv_layer", ob.data, "uv_textures")
+ col.label(text="UV Map:")
+ col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
layout.separator()
@@ -314,7 +313,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
row.prop(md, "strength")
def DYNAMIC_PAINT(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def EDGE_SPLIT(self, layout, ob, md):
split = layout.split()
@@ -349,7 +348,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.operator("object.explode_refresh", text="Refresh")
def FLUID_SIMULATION(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def HOOK(self, layout, ob, md):
split = layout.split()
@@ -766,7 +765,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "limits", slider=True)
def SMOKE(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def SMOOTH(self, layout, ob, md):
split = layout.split(percentage=0.25)
@@ -784,7 +783,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
def SOFT_BODY(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def SOLIDIFY(self, layout, ob, md):
split = layout.split()
@@ -845,7 +844,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "show_only_control_edges")
def SURFACE(self, layout, ob, md):
- layout.label(text="Settings can be found inside the Physics context")
+ layout.label(text="Settings are inside the Physics tab")
def UV_PROJECT(self, layout, ob, md):
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index 87a08104c5d..31a638d3c7e 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -60,8 +60,8 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
layout.prop(rd, "line_thickness")
row = layout.row()
- row.label(text="Line style settings are found in the Render Layers context")
- row.operator("wm.properties_context_change", text="", icon='BUTS').context = 'RENDER_LAYER'
+ row.label(text="Line style settings are in the Render Layers tab")
+ row.operator("wm.properties_context_change", text="", icon='RENDERLAYERS').context = 'RENDER_LAYER'
# Render layer properties
@@ -534,20 +534,18 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
row.prop(linestyle, "panel", expand=True)
if linestyle.panel == 'STROKES':
## Chaining
- layout.label(text="Chaining:")
+ layout.prop(linestyle, "use_chaining", text="Chaining:")
split = layout.split(align=True)
+ split.active = linestyle.use_chaining
# First column
col = split.column()
- col.prop(linestyle, "use_chaining", text="Enable Chaining")
- sub = col.row()
- sub.active = linestyle.use_chaining
- sub.prop(linestyle, "use_same_object")
- # Second column
- col = split.column()
col.active = linestyle.use_chaining
col.prop(linestyle, "chaining", text="")
if linestyle.chaining == 'SKETCHY':
col.prop(linestyle, "rounds")
+ # Second column
+ col = split.column()
+ col.prop(linestyle, "use_same_object")
## Splitting
layout.label(text="Splitting:")
@@ -603,23 +601,33 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
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
+ row = col.row(align=True)
+ row.prop(linestyle, "sort_key", 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)
+
## Caps
layout.label(text="Caps:")
row = layout.row(align=True)
row.prop(linestyle, "caps", expand=True)
## Dashed lines
- layout.label(text="Dashed Line:")
+ layout.prop(linestyle, "use_dashed_line", text="Dashed Line:")
row = layout.row(align=True)
- row.prop(linestyle, "use_dashed_line", text="")
- sub = row.row(align=True)
- sub.active = linestyle.use_dashed_line
- sub.prop(linestyle, "dash1", text="D1")
- sub.prop(linestyle, "gap1", text="G1")
- sub.prop(linestyle, "dash2", text="D2")
- sub.prop(linestyle, "gap2", text="G2")
- sub.prop(linestyle, "dash3", text="D3")
- sub.prop(linestyle, "gap3", text="G3")
+ row.active = linestyle.use_dashed_line
+ row.prop(linestyle, "dash1", text="D1")
+ row.prop(linestyle, "gap1", text="G1")
+ row.prop(linestyle, "dash2", text="D2")
+ row.prop(linestyle, "gap2", text="G2")
+ row.prop(linestyle, "dash3", text="D3")
+ row.prop(linestyle, "gap3", text="G3")
elif linestyle.panel == 'COLOR':
col = layout.column()
@@ -646,9 +654,11 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
row = col.row()
row.label(text="Base Thickness:")
row.prop(linestyle, "thickness")
- row = col.row()
+ subcol = col.column()
+ subcol.active = linestyle.chaining == 'PLAIN' and linestyle.use_same_object
+ row = subcol.row()
row.prop(linestyle, "thickness_position", expand=True)
- row = col.row()
+ row = subcol.row()
row.prop(linestyle, "thickness_ratio")
row.active = (linestyle.thickness_position == 'RELATIVE')
col = layout.column()
@@ -664,6 +674,19 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
for modifier in linestyle.geometry_modifiers:
self.draw_geometry_modifier(context, modifier)
+ elif linestyle.panel == 'TEXTURE':
+ layout.separator()
+
+ row = layout.row()
+ row.prop(linestyle, "use_texture")
+ row.prop(linestyle, "texture_spacing", text="Spacing Along Stroke")
+
+ row = layout.row()
+ op = row.operator("wm.properties_context_change",
+ text="Go to Linestyle Textures Properties",
+ icon='TEXTURE')
+ op.context = 'TEXTURE'
+
elif linestyle.panel == 'MISC':
pass
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
new file mode 100644
index 00000000000..5dd1f94747c
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -0,0 +1,50 @@
+# ##### 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 #####
+
+# <pep8 compliant>
+
+
+class GreasePencilPanel():
+ # subclass must set
+ # bl_space_type = 'IMAGE_EDITOR'
+ # bl_region_type = 'TOOLS'
+ bl_label = "Grease Pencil"
+
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+
+ col = layout.column(align=True)
+
+ row = col.row(align=True)
+ row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
+ row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
+
+ row = col.row(align=True)
+ row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
+ row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
+
+ row = col.row(align=True)
+ row.prop(context.tool_settings, "use_grease_pencil_sessions")
+
+ if context.space_data.type == 'VIEW_3D':
+ col.separator()
+
+ col.label(text="Measure:")
+ col.operator("view3d.ruler")
+
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index b98332fab19..9a2857cc7b8 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -108,8 +108,8 @@ class MASK_PT_layers:
layout.prop(active_layer, "falloff")
row = layout.row(align=True)
- layout.prop(active_layer, "use_fill_overlap")
- layout.prop(active_layer, "use_fill_holes")
+ row.prop(active_layer, "use_fill_overlap", text="Overlap")
+ row.prop(active_layer, "use_fill_holes", text="Holes")
class MASK_PT_spline():
@@ -173,9 +173,6 @@ class MASK_PT_point():
parent = point.parent
col = layout.column()
- col.prop(point, "handle_type")
-
- col = layout.column()
# Currently only parenting yo movie clip is allowed, so do not
# ver-oplicate things for now and use single template_ID
#col.template_any_ID(parent, "id", "id_type", text="")
@@ -286,8 +283,8 @@ class MASK_PT_tools():
col = layout.column(align=True)
col.label(text="Animation:")
row = col.row(align=True)
- row.operator("mask.shape_key_clear", text="Insert Key")
- row.operator("mask.shape_key_insert", text="Clear Key")
+ row.operator("mask.shape_key_insert", text="Insert Key")
+ row.operator("mask.shape_key_clear", text="Clear Key")
col.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
col.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
@@ -308,8 +305,8 @@ class MASK_PT_add():
layout = self.layout
col = layout.column(align=True)
- col.operator("mask.primitive_circle_add", icon="MESH_CIRCLE")
- col.operator("mask.primitive_square_add", icon="MESH_PLANE")
+ col.operator("mask.primitive_circle_add", icon='MESH_CIRCLE')
+ col.operator("mask.primitive_square_add", icon='MESH_PLANE')
class MASK_MT_mask(Menu):
@@ -331,6 +328,10 @@ class MASK_MT_mask(Menu):
layout.operator("mask.parent_set")
layout.separator()
+ layout.operator("mask.copy_splines")
+ layout.operator("mask.paste_splines")
+
+ layout.separator()
layout.menu("MASK_MT_visibility")
layout.menu("MASK_MT_transform")
layout.menu("MASK_MT_animation")
@@ -376,7 +377,6 @@ class MASK_MT_select(Menu):
def draw(self, context):
layout = self.layout
- sc = context.space_data
layout.operator("mask.select_border")
layout.operator("mask.select_circle")
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 9e56c269b2b..e3fcb0ef53e 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -73,7 +73,7 @@ class MATERIAL_MT_specials(Menu):
class MATERIAL_UL_matslots(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.MaterialSlot)
- ob = data
+ # ob = data
slot = item
ma = slot.material
if self.layout_type in {'DEFAULT', 'COMPACT'}:
@@ -216,15 +216,18 @@ class MATERIAL_PT_pipeline(MaterialButtonsPanel, Panel):
sub.active = mat_type
sub.prop(mat, "use_sky")
sub.prop(mat, "invert_z")
+ col.prop(mat, "pass_index")
col = split.column()
col.active = mat_type
+ col.prop(mat, "use_cast_shadows", text="Cast")
col.prop(mat, "use_cast_shadows_only", text="Cast Only")
- col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
col.prop(mat, "use_cast_buffer_shadows")
+ sub = col.column()
+ sub.active = mat.use_cast_buffer_shadows
+ sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
col.prop(mat, "use_cast_approximate")
- col.prop(mat, "pass_index")
class MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel):
@@ -814,24 +817,30 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel):
col = split.column()
col.prop(mat, "use_shadows", text="Receive")
col.prop(mat, "use_transparent_shadows", text="Receive Transparent")
- if simple_material(base_mat):
- col.prop(mat, "use_cast_shadows_only", text="Cast Only")
- col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
col.prop(mat, "use_only_shadow", text="Shadows Only")
sub = col.column()
sub.active = mat.use_only_shadow
sub.prop(mat, "shadow_only_type", text="")
- col = split.column()
+ if not simple_material(base_mat):
+ col = split.column()
+
+ col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias")
+ sub = col.column()
+ sub.active = (not mat.use_ray_shadow_bias)
+ sub.prop(mat, "shadow_ray_bias", text="Ray Bias")
+
if simple_material(base_mat):
+ col = split.column()
+
+ col.prop(mat, "use_cast_shadows", text="Cast")
+ col.prop(mat, "use_cast_shadows_only", text="Cast Only")
col.prop(mat, "use_cast_buffer_shadows")
sub = col.column()
sub.active = mat.use_cast_buffer_shadows
+ if simple_material(base_mat):
+ sub.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
sub.prop(mat, "shadow_buffer_bias", text="Buffer Bias")
- col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias")
- sub = col.column()
- sub.active = (not mat.use_ray_shadow_bias)
- sub.prop(mat, "shadow_ray_bias", text="Ray Bias")
if simple_material(base_mat):
col.prop(mat, "use_cast_approximate")
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 8d7f5cfdad1..3ff9ab9e12f 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -207,16 +207,18 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
obj_type = obj.type
is_geometry = (obj_type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'})
is_empty_image = (obj_type == 'EMPTY' and obj.empty_draw_type == 'IMAGE')
+ is_dupli = (obj.dupli_type != 'NONE')
split = layout.split()
col = split.column()
col.prop(obj, "show_name", text="Name")
col.prop(obj, "show_axis", text="Axis")
- if is_geometry:
- # Makes no sense for cameras, armatures, etc.!
+ # Makes no sense for cameras, armatures, etc.!
+ # but these settings do apply to dupli instances
+ if is_geometry or is_dupli:
col.prop(obj, "show_wire", text="Wire")
- if obj_type == 'MESH':
+ if obj_type == 'MESH' or is_dupli:
col.prop(obj, "show_all_edges")
col = split.column()
@@ -322,7 +324,7 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
return (context.object)
def draw(self, context):
- layout = self.layout
+ # layout = self.layout
ob = context.object
avs = ob.animation_visualization
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index c0ce8c9fcdd..6a6d8dcff4a 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -236,12 +236,12 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
# vertex format outputs
if surface.surface_format == 'VERTEX':
if surface_type == 'PAINT':
- # toggle active preview
+ # toggle active preview
layout.prop(surface, "preview_id")
# paint-map output
row = layout.row()
- row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer:")
+ row.prop_search(surface, "output_name_a", ob.data, "vertex_colors", text="Paintmap layer")
if surface.output_exists(object=ob, index=0):
ic = 'ZOOMOUT'
else:
@@ -251,7 +251,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
# wet-map output
row = layout.row()
- row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer:")
+ row.prop_search(surface, "output_name_b", ob.data, "vertex_colors", text="Wetmap layer")
if surface.output_exists(object=ob, index=1):
ic = 'ZOOMOUT'
else:
@@ -261,7 +261,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
elif surface_type == 'WEIGHT':
row = layout.row()
- row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group:")
+ row.prop_search(surface, "output_name_a", ob, "vertex_groups", text="Vertex Group")
if surface.output_exists(object=ob, index=0):
ic = 'ZOOMOUT'
else:
@@ -272,7 +272,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
# image format outputs
if surface.surface_format == 'IMAGE':
layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
- layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map:")
+ layout.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="UV Map")
layout.separator()
layout.prop(surface, "image_output_path", text="")
@@ -332,10 +332,10 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
elif surface.init_color_type == 'TEXTURE':
layout.prop(surface, "init_texture")
- layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map:")
+ layout.prop_search(surface, "init_layername", ob.data, "uv_textures", text="UV Map")
elif surface.init_color_type == 'VERTEX_COLOR':
- layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer:")
+ layout.prop_search(surface, "init_layername", ob.data, "vertex_colors", text="Color Layer")
class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index 79d676533a5..17366f59016 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -59,7 +59,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
col.label(text="Object:")
col.prop(softbody, "friction")
col.prop(softbody, "mass")
- col.prop_search(softbody, "vertex_group_mass", ob, "vertex_groups", text="Mass:")
+ col.prop_search(softbody, "vertex_group_mass", ob, "vertex_groups", text="Mass")
col = split.column()
col.label(text="Simulation:")
@@ -143,7 +143,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel):
col.prop(softbody, "plastic")
col.prop(softbody, "bend")
col.prop(softbody, "spring_length", text="Length")
- col.prop_search(softbody, "vertex_group_spring", ob, "vertex_groups", text="Springs:")
+ col.prop_search(softbody, "vertex_group_spring", ob, "vertex_groups", text="Springs")
col = split.column()
col.prop(softbody, "use_stiff_quads")
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 488f0416880..2494e49d812 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel, UIList
+from bpy.types import Panel, UIList
class RenderLayerButtonsPanel():
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 10574c88abb..049161fdce8 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -182,7 +182,6 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel):
layout = self.layout
scene = context.scene
- rd = scene.render
col = layout.column()
col.label(text="Display:")
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index 009309479ec..9aa137ca9ea 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -25,6 +25,7 @@ from bpy.types import (Brush,
Material,
Object,
ParticleSettings,
+ FreestyleLineStyle,
Texture,
World)
@@ -94,6 +95,10 @@ def context_tex_datablock(context):
if idblock:
return idblock
+ idblock = context.line_style
+ if idblock:
+ return idblock
+
if context.particle_system:
idblock = context.particle_system.settings
@@ -134,6 +139,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
context.world or
context.lamp or
context.texture or
+ context.line_style or
context.particle_system or
isinstance(context.space_data.pin_id, ParticleSettings) or
context.texture_user) and
@@ -952,11 +958,28 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
split.label(text="Object:")
split.prop(tex, "object", text="")
+ elif tex.texture_coords == 'ALONG_STROKE':
+ split = layout.split(percentage=0.3)
+ split.label(text="Use Tips:")
+ split.prop(tex, "use_tips", text="")
+
if isinstance(idblock, Brush):
if context.sculpt_object or context.image_paint_object:
brush_texture_settings(layout, idblock, context.sculpt_object)
else:
- if isinstance(idblock, Material):
+ if isinstance(idblock, FreestyleLineStyle):
+ split = layout.split(percentage=0.3)
+ split.label(text="Projection:")
+ split.prop(tex, "mapping", text="")
+
+ split = layout.split(percentage=0.3)
+ split.separator()
+ row = split.row()
+ row.prop(tex, "mapping_x", text="")
+ row.prop(tex, "mapping_y", text="")
+ row.prop(tex, "mapping_z", text="")
+
+ elif isinstance(idblock, Material):
split = layout.split(percentage=0.3)
split.label(text="Projection:")
split.prop(tex, "mapping", text="")
@@ -1129,6 +1152,15 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
factor_but(col, "use_map_kink", "kink_factor", "Kink")
factor_but(col, "use_map_rough", "rough_factor", "Rough")
+ elif isinstance(idblock, FreestyleLineStyle):
+ split = layout.split()
+
+ col = split.column()
+ factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
+ col = split.column()
+ factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
+
+
layout.separator()
if not isinstance(idblock, ParticleSettings):
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 42ad9daafa5..96ad70e0015 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -21,6 +21,7 @@
import bpy
from bpy.types import Panel, Header, Menu, UIList
from bpy.app.translations import pgettext_iface as iface_
+from bl_ui.properties_grease_pencil_common import GreasePencilPanel
class CLIP_UL_tracking_objects(UIList):
@@ -122,19 +123,20 @@ class CLIP_HT_header(Header):
row = layout.row()
row.template_ID(sc, "clip", open="clip.open")
- layout.prop(sc, "mode", text="")
+ if clip:
+ layout.prop(sc, "mode", text="")
- row = layout.row()
- row.template_ID(sc, "mask", new="mask.new")
+ row = layout.row()
+ row.template_ID(sc, "mask", new="mask.new")
- layout.prop(sc, "pivot_point", text="", icon_only=True)
+ layout.prop(sc, "pivot_point", text="", icon_only=True)
- row = layout.row(align=True)
- row.prop(toolsettings, "use_proportional_edit_mask",
- text="", icon_only=True)
- if toolsettings.use_proportional_edit_mask:
- row.prop(toolsettings, "proportional_edit_falloff",
+ row = layout.row(align=True)
+ row.prop(toolsettings, "use_proportional_edit_mask",
text="", icon_only=True)
+ if toolsettings.use_proportional_edit_mask:
+ row.prop(toolsettings, "proportional_edit_falloff",
+ text="", icon_only=True)
def draw(self, context):
layout = self.layout
@@ -260,7 +262,6 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
sc = context.space_data
clip = sc.clip
- settings = clip.tracking.settings
col = layout.column(align=True)
row = col.row(align=True)
@@ -334,6 +335,9 @@ class CLIP_PT_tracking_settings(CLIP_PT_tracking_panel, Panel):
sub.prop(settings, "default_frames_limit")
sub.prop(settings, "default_margin")
+ col = box.column()
+ col.prop(settings, "default_weight")
+
class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
@@ -366,10 +370,10 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
row.label(text="Clear:")
row.scale_x = 2.0
- props = row.operator("clip.clear_track_path", icon="BACK", text="")
+ props = row.operator("clip.clear_track_path", text="", icon='BACK')
props.action = 'UPTO'
- props = row.operator("clip.clear_track_path", icon="FORWARD", text="")
+ props = row.operator("clip.clear_track_path", text="", icon='FORWARD')
props.action = 'REMAINED'
col = layout.column()
@@ -377,10 +381,10 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
row.label(text="Refine:")
row.scale_x = 2.0
- props = row.operator("clip.refine_markers", icon='LOOP_BACK', text="")
+ props = row.operator("clip.refine_markers", text="", icon='LOOP_BACK')
props.backwards = True
- props = row.operator("clip.refine_markers", icon='LOOP_FORWARDS', text="")
+ props = row.operator("clip.refine_markers", text="", icon='LOOP_FORWARDS')
props.backwards = False
col = layout.column(align=True)
@@ -636,7 +640,6 @@ class CLIP_PT_plane_track(CLIP_PT_tracking_panel, Panel):
def draw(self, context):
layout = self.layout
- sc = context.space_data
clip = context.space_data.clip
active_track = clip.tracking.plane_tracks.active
@@ -764,11 +767,19 @@ class CLIP_PT_tracking_lens(Panel):
sub.prop(clip.tracking.camera, "focal_length_pixels")
sub.prop(clip.tracking.camera, "units", text="")
- col = layout.column(align=True)
+ col = layout.column()
col.label(text="Lens Distortion:")
- col.prop(clip.tracking.camera, "k1")
- col.prop(clip.tracking.camera, "k2")
- col.prop(clip.tracking.camera, "k3")
+ camera = clip.tracking.camera
+ col.prop(camera, "distortion_model", text="")
+ if camera.distortion_model == 'POLYNOMIAL':
+ col = layout.column(align=True)
+ col.prop(camera, "k1")
+ col.prop(camera, "k2")
+ col.prop(camera, "k3")
+ elif camera.distortion_model == 'DIVISION':
+ col = layout.column(align=True)
+ col.prop(camera, "division_k1")
+ col.prop(camera, "division_k2")
class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
@@ -789,7 +800,7 @@ class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
row.separator()
row.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
row.separator()
- row.prop(sc, "use_mute_footage", text="", icon="VISIBLE_IPO_ON", toggle=True)
+ row.prop(sc, "use_mute_footage", text="", icon='VISIBLE_IPO_ON', toggle=True)
col = layout.column(align=True)
col.prop(sc.clip_user, "use_render_undistorted", text="Render Undistorted")
@@ -1039,28 +1050,11 @@ class CLIP_PT_tools_mask(MASK_PT_tools, Panel):
# --- end mask ---
-class CLIP_PT_tools_grease_pencil(Panel):
+class CLIP_PT_tools_grease_pencil(GreasePencilPanel, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'TOOLS'
- bl_label = "Grease Pencil"
bl_category = "Grease Pencil"
- def draw(self, context):
- layout = self.layout
-
- col = layout.column(align=True)
-
- row = col.row(align=True)
- row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
- row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
-
- row = col.row(align=True)
- row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
- row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
-
- row = col.row(align=True)
- row.prop(context.tool_settings, "use_grease_pencil_sessions")
-
class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
@@ -1090,7 +1084,6 @@ class CLIP_PT_footage_info(CLIP_PT_clip_view_panel, Panel):
layout = self.layout
sc = context.space_data
- clip = sc.clip
col = layout.column()
col.template_movieclip_information(sc, "clip", sc.clip_user)
@@ -1154,6 +1147,7 @@ class CLIP_MT_view(Menu):
layout.operator_context = 'INVOKE_DEFAULT'
layout.prop(sc, "show_seconds")
+ layout.prop(sc, "show_locked_time")
layout.separator()
layout.separator()
@@ -1344,17 +1338,6 @@ class CLIP_MT_tracking_specials(Menu):
text="Unlock Tracks").action = 'UNLOCK'
-class CLIP_MT_select_mode(Menu):
- bl_label = "Select Mode"
-
- def draw(self, context):
- layout = self.layout
-
- layout.operator_context = 'INVOKE_REGION_WIN'
-
- layout.operator_enum("clip.mode_set", "mode")
-
-
class CLIP_MT_camera_presets(Menu):
"""Predefined tracking camera intrinsics"""
bl_label = "Camera Presets"
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 269c960ee7e..eeb08916416 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -173,6 +173,7 @@ class DOPESHEET_MT_view(Menu):
layout.prop(st, "use_marker_sync")
layout.prop(st, "show_seconds")
+ layout.prop(st, "show_locked_time")
layout.separator()
layout.operator("anim.previewrange_set")
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index e4fb53805b6..353c689b484 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -105,6 +105,7 @@ class GRAPH_MT_view(Menu):
layout.prop(st, "use_only_selected_keyframe_handles")
layout.prop(st, "show_seconds")
+ layout.prop(st, "show_locked_time")
layout.separator()
layout.operator("anim.previewrange_set")
@@ -227,6 +228,7 @@ class GRAPH_MT_key(Menu):
layout.separator()
layout.operator_menu_enum("graph.handle_type", "type", text="Handle Type")
layout.operator_menu_enum("graph.interpolation_type", "type", text="Interpolation Mode")
+ layout.operator_menu_enum("graph.easing_type", "type", text="Easing Type")
layout.separator()
layout.operator("graph.clean")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index fdc5be4db8d..f19e77eff8e 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -24,17 +24,20 @@ from bl_ui.properties_paint_common import (
brush_texture_settings,
brush_mask_texture_settings,
)
+from bl_ui.properties_grease_pencil_common import GreasePencilPanel
from bpy.app.translations import pgettext_iface as iface_
class ImagePaintPanel(UnifiedPaintPanel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
class BrushButtonsPanel:
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
@classmethod
def poll(cls, context):
@@ -43,6 +46,17 @@ class BrushButtonsPanel:
return sima.show_paint and toolsettings.brush
+class UVToolsPanel:
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
+
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return sima.show_uvedit and not context.tool_settings.use_uv_sculpt
+
+
class IMAGE_MT_view(Menu):
bl_label = "View"
@@ -57,7 +71,7 @@ class IMAGE_MT_view(Menu):
show_render = sima.show_render
layout.operator("image.properties", icon='MENU_PANEL')
- layout.operator("image.scopes", icon='MENU_PANEL')
+ layout.operator("image.toolshelf", icon='MENU_PANEL')
layout.separator()
@@ -282,7 +296,7 @@ class IMAGE_MT_uvs(Menu):
layout.prop(uv, "use_live_unwrap")
layout.operator("uv.unwrap")
layout.operator("uv.pin", text="Unpin").clear = True
- layout.operator("uv.pin")
+ layout.operator("uv.pin").clear = False
layout.separator()
@@ -444,7 +458,6 @@ class MASK_MT_editor_menus(Menu):
sima = context.space_data
ima = sima.image
- show_render = sima.show_render
show_uvedit = sima.show_uvedit
show_maskedit = sima.show_maskedit
@@ -466,6 +479,43 @@ class MASK_MT_editor_menus(Menu):
layout.menu("MASK_MT_mask")
+# -----------------------------------------------------------------------------
+# Mask (similar code in space_clip.py, keep in sync)
+# note! - panel placement does _not_ fit well with image panels... need to fix
+
+from bl_ui.properties_mask_common import (MASK_PT_mask,
+ MASK_PT_layers,
+ MASK_PT_spline,
+ MASK_PT_point,
+ MASK_PT_display,
+ MASK_PT_tools)
+
+
+class IMAGE_PT_mask(MASK_PT_mask, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+
+class IMAGE_PT_mask_layers(MASK_PT_layers, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+
+class IMAGE_PT_mask_display(MASK_PT_display, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+
+class IMAGE_PT_active_mask_spline(MASK_PT_spline, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+
+class IMAGE_PT_active_mask_point(MASK_PT_point, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+
class IMAGE_PT_image_properties(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
@@ -494,7 +544,7 @@ class IMAGE_PT_game_properties(Panel):
def poll(cls, context):
sima = context.space_data
# display even when not in game mode because these settings effect the 3d view
- return (sima and sima.image) # and (rd.engine == 'BLENDER_GAME')
+ return (sima and sima.image and not sima.show_maskedit) # and (rd.engine == 'BLENDER_GAME')
def draw(self, context):
layout = self.layout
@@ -526,112 +576,6 @@ class IMAGE_PT_game_properties(Panel):
col.prop(ima, "mapping", expand=True)
-class IMAGE_PT_view_histogram(Panel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
- bl_label = "Histogram"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
- def draw(self, context):
- layout = self.layout
-
- sima = context.space_data
- hist = sima.scopes.histogram
-
- layout.template_histogram(sima.scopes, "histogram")
- row = layout.row(align=True)
- row.prop(hist, "mode", expand=True)
- row.prop(hist, "show_line", text="")
-
-
-class IMAGE_PT_view_waveform(Panel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
- bl_label = "Waveform"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
- def draw(self, context):
- layout = self.layout
-
- sima = context.space_data
-
- layout.template_waveform(sima, "scopes")
- row = layout.split(percentage=0.75)
- row.prop(sima.scopes, "waveform_alpha")
- row.prop(sima.scopes, "waveform_mode", icon_only=True)
-
-
-class IMAGE_PT_view_vectorscope(Panel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
- bl_label = "Vectorscope"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
- def draw(self, context):
- layout = self.layout
-
- sima = context.space_data
- layout.template_vectorscope(sima, "scopes")
- layout.prop(sima.scopes, "vectorscope_alpha")
-
-
-class IMAGE_PT_sample_line(Panel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
- bl_label = "Sample Line"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
- def draw(self, context):
- layout = self.layout
-
- sima = context.space_data
- hist = sima.sample_histogram
-
- layout.operator("image.sample_line")
- layout.template_histogram(sima, "sample_histogram")
- row = layout.row(align=True)
- row.prop(hist, "mode", expand=True)
- row.prop(hist, "show_line", text="")
-
-
-class IMAGE_PT_scope_sample(Panel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
- bl_label = "Scope Samples"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return sima
-
- def draw(self, context):
- layout = self.layout
-
- sima = context.space_data
-
- row = layout.row()
- row.prop(sima.scopes, "use_full_resolution")
- sub = row.row()
- sub.active = not sima.scopes.use_full_resolution
- sub.prop(sima.scopes, "accuracy")
-
-
class IMAGE_PT_view_properties(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
@@ -692,9 +636,27 @@ class IMAGE_PT_view_properties(Panel):
sub.row().prop(uvedit, "draw_stretch_type", expand=True)
+class IMAGE_PT_tools_transform_uvs(Panel, UVToolsPanel):
+ bl_label = "Transform"
+
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return sima.show_uvedit and not context.tool_settings.use_uv_sculpt
+
+ def draw(self, context):
+ layout = self.layout
+
+ col = layout.column(align=True)
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
+ col.separator()
+
+ col.operator("transform.shear")
+
+
class IMAGE_PT_paint(Panel, ImagePaintPanel):
- bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI'
bl_label = "Paint"
@classmethod
@@ -796,7 +758,6 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
toolsettings = context.tool_settings.image_paint
brush = toolsettings.brush
- tex_slot = brush.texture_slot
col = layout.column()
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
@@ -812,7 +773,6 @@ class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
layout = self.layout
brush = context.tool_settings.image_paint.brush
- tex_slot_alpha = brush.mask_texture_slot
col = layout.column()
@@ -935,25 +895,26 @@ class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
layout.label(text="Brush Unset")
return
- col = layout.column()
- col.prop(toolsettings, "show_brush")
+ col = layout.column(align=True)
- col = col.column()
- col.prop(brush, "cursor_color_add", text="")
- col.active = toolsettings.show_brush
+ col.prop(toolsettings, "show_brush")
+ sub = col.column()
+ sub.active = toolsettings.show_brush
+ sub.prop(brush, "cursor_color_add", text="")
- layout.separator()
+ col.separator()
- col = layout.column(align=True)
col.prop(brush, "use_custom_icon")
- if brush.use_custom_icon:
- col.prop(brush, "icon_filepath", text="")
+ sub = col.column()
+ sub.active = brush.use_custom_icon
+ sub.prop(brush, "icon_filepath", text="")
class IMAGE_UV_sculpt_curve(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI'
+ bl_region_type = 'TOOLS'
bl_label = "UV Sculpt Curve"
+ bl_category = "Tools"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
@@ -982,7 +943,8 @@ class IMAGE_UV_sculpt_curve(Panel):
class IMAGE_UV_sculpt(Panel, ImagePaintPanel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
bl_label = "UV Sculpt"
@classmethod
@@ -1018,48 +980,130 @@ class IMAGE_UV_sculpt(Panel, ImagePaintPanel):
col.prop(toolsettings, "uv_relax_method")
-# -----------------------------------------------------------------------------
-# Mask (similar code in space_clip.py, keep in sync)
-# note! - panel placement does _not_ fit well with image panels... need to fix
+class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'TOOLS'
+ bl_category = 'Mask'
-from bl_ui.properties_mask_common import (MASK_PT_mask,
- MASK_PT_layers,
- MASK_PT_spline,
- MASK_PT_point,
- MASK_PT_display,
- MASK_PT_tools)
+# --- end mask ---
-class IMAGE_PT_mask(MASK_PT_mask, Panel):
+class IMAGE_PT_view_histogram(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
+ bl_region_type = 'TOOLS'
+ bl_label = "Histogram"
+ bl_category = "Scopes"
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return (sima and sima.image)
-class IMAGE_PT_mask_layers(MASK_PT_layers, Panel):
+ def draw(self, context):
+ layout = self.layout
+
+ sima = context.space_data
+ hist = sima.scopes.histogram
+
+ layout.template_histogram(sima.scopes, "histogram")
+ row = layout.row(align=True)
+ row.prop(hist, "mode", expand=True)
+ row.prop(hist, "show_line", text="")
+
+
+class IMAGE_PT_view_waveform(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
+ bl_region_type = 'TOOLS'
+ bl_label = "Waveform"
+ bl_category = "Scopes"
+
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return (sima and sima.image)
+ def draw(self, context):
+ layout = self.layout
-class IMAGE_PT_mask_display(MASK_PT_display, Panel):
+ sima = context.space_data
+
+ layout.template_waveform(sima, "scopes")
+ row = layout.split(percentage=0.75)
+ row.prop(sima.scopes, "waveform_alpha")
+ row.prop(sima.scopes, "waveform_mode", icon_only=True)
+
+
+class IMAGE_PT_view_vectorscope(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
+ bl_region_type = 'TOOLS'
+ bl_label = "Vectorscope"
+ bl_category = "Scopes"
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return (sima and sima.image)
-class IMAGE_PT_active_mask_spline(MASK_PT_spline, Panel):
+ def draw(self, context):
+ layout = self.layout
+
+ sima = context.space_data
+ layout.template_vectorscope(sima, "scopes")
+ layout.prop(sima.scopes, "vectorscope_alpha")
+
+
+class IMAGE_PT_sample_line(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
+ bl_region_type = 'TOOLS'
+ bl_label = "Sample Line"
+ bl_category = "Scopes"
+
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return (sima and sima.image)
+ def draw(self, context):
+ layout = self.layout
-class IMAGE_PT_active_mask_point(MASK_PT_point, Panel):
+ sima = context.space_data
+ hist = sima.sample_histogram
+
+ layout.operator("image.sample_line")
+ layout.template_histogram(sima, "sample_histogram")
+ row = layout.row(align=True)
+ row.prop(hist, "mode", expand=True)
+ row.prop(hist, "show_line", text="")
+
+
+class IMAGE_PT_scope_sample(Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'PREVIEW'
+ bl_region_type = 'TOOLS'
+ bl_label = "Scope Samples"
+ bl_category = "Scopes"
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ return sima
-class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
+ def draw(self, context):
+ layout = self.layout
+
+ sima = context.space_data
+
+ row = layout.row()
+ row.prop(sima.scopes, "use_full_resolution")
+ sub = row.row()
+ sub.active = not sima.scopes.use_full_resolution
+ sub.prop(sima.scopes, "accuracy")
+
+
+class IMAGE_PT_tools_grease_pencil(GreasePencilPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'UI' # is 'TOOLS' in the clip editor
+ bl_region_type = 'TOOLS'
+ bl_category = "Grease Pencil"
-# --- end mask ---
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index f5106ddfcdf..31881671fda 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -124,7 +124,6 @@ class INFO_MT_file(Menu):
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.save_homefile", icon='SAVE_PREFS')
- layout.operator_context = 'EXEC_AREA'
layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY')
layout.separator()
@@ -233,6 +232,7 @@ class INFO_MT_render(Menu):
layout.operator("render.opengl", text="OpenGL Render Image")
layout.operator("render.opengl", text="OpenGL Render Animation").animation = True
+ layout.menu("INFO_MT_opengl_render")
layout.separator()
@@ -240,6 +240,19 @@ class INFO_MT_render(Menu):
layout.operator("render.play_rendered_anim", icon='PLAY')
+class INFO_MT_opengl_render(Menu):
+ bl_label = "OpenGL Render Options"
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+
+ layout.prop(rd, "use_antialiasing")
+ layout.prop_menu_enum(rd, "antialiasing_samples")
+ layout.prop_menu_enum(rd, "alpha_mode")
+
+
class INFO_MT_window(Menu):
bl_label = "Window"
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index e41086f6da1..baadc69d9f6 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -74,12 +74,14 @@ class NLA_MT_view(Menu):
layout.prop(st, "show_frame_indicator")
layout.prop(st, "show_seconds")
+ layout.prop(st, "show_locked_time")
layout.prop(st, "show_strip_curves")
layout.separator()
layout.operator("anim.previewrange_set")
layout.operator("anim.previewrange_clear")
+ layout.operator("nla.previewrange_set")
layout.separator()
layout.operator("nla.view_all")
@@ -132,7 +134,8 @@ class NLA_MT_edit(Menu):
layout.operator_menu_enum("nla.snap", "type", text="Snap")
layout.separator()
- layout.operator("nla.duplicate")
+ layout.operator("nla.duplicate", text="Duplicate")
+ layout.operator("nla.duplicate", text="Linked Duplicate").linked = True
layout.operator("nla.split")
layout.operator("nla.delete")
@@ -145,6 +148,9 @@ class NLA_MT_edit(Menu):
layout.operator("nla.action_sync_length").active = False
layout.separator()
+ layout.operator("nla.make_single_user")
+
+ layout.separator()
layout.operator("nla.swap")
layout.operator("nla.move_up")
layout.operator("nla.move_down")
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 830bdf92ecc..959043f7931 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -164,7 +164,7 @@ class NODE_MT_view(Menu):
layout.operator("node.backimage_move", text="Backdrop move")
layout.operator("node.backimage_zoom", text="Backdrop zoom in").factor = 1.2
- layout.operator("node.backimage_zoom", text="Backdrop zoom out").factor = 0.833
+ layout.operator("node.backimage_zoom", text="Backdrop zoom out").factor = 0.83333
layout.operator("node.backimage_fit", text="Fit backdrop to available space")
layout.separator()
@@ -274,7 +274,6 @@ class NODE_PT_active_node_generic(Panel):
@classmethod
def poll(cls, context):
- space = context.space_data
return context.active_node is not None
def draw(self, context):
@@ -293,7 +292,6 @@ class NODE_PT_active_node_color(Panel):
@classmethod
def poll(cls, context):
- space = context.space_data
return context.active_node is not None
def draw_header(self, context):
@@ -323,7 +321,6 @@ class NODE_PT_active_node_properties(Panel):
@classmethod
def poll(cls, context):
- space = context.space_data
return context.active_node is not None
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index fcd70dd9236..b77078bf5d4 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -160,7 +160,16 @@ class SEQUENCER_MT_view(Menu):
if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text="Fit preview in window")
- layout.operator("sequencer.view_zoom_ratio", text="Show preview 1:1").ratio = 1.0
+
+ layout.separator()
+
+ ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
+
+ for a, b in ratios:
+ layout.operator("sequencer.view_zoom_ratio", text=iface_("Zoom %d:%d") % (a, b), translate=False).ratio = a / b
+
+ layout.separator()
+
layout.operator_context = 'INVOKE_DEFAULT'
# # XXX, invokes in the header view
@@ -486,7 +495,6 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- sequencer = context.scene.sequence_editor
strip = act_strip(context)
if strip.input_count > 0:
@@ -954,7 +962,10 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
row.prop(mod, "input_mask_type", expand=True)
if mod.input_mask_type == 'STRIP':
- box.prop_search(mod, "input_mask_strip", sequencer, "sequences", text="Mask")
+ sequences_object = sequencer
+ if sequencer.meta_stack:
+ sequences_object = sequencer.meta_stack[-1]
+ box.prop_search(mod, "input_mask_strip", sequences_object, "sequences", text="Mask")
else:
box.prop(mod, "input_mask_id")
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index c0d55536991..c96b8fd568e 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -122,15 +122,17 @@ class TIME_MT_view(Menu):
def draw(self, context):
layout = self.layout
+ scene = context.scene
st = context.space_data
layout.prop(st, "show_seconds")
+ layout.prop(st, "show_locked_time")
layout.operator("time.view_all")
layout.separator()
layout.prop(st, "show_frame_indicator")
- layout.prop(st, "show_only_selected")
+ layout.prop(scene, "show_keys_from_selected_only")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 72785fc2c15..18f7c53a616 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -61,7 +61,7 @@ class USERPREF_HT_header(Header):
layout.operator("wm.keyconfig_import")
layout.operator("wm.keyconfig_export")
elif userpref.active_section == 'ADDONS':
- layout.operator("wm.addon_install", icon="FILESEL")
+ layout.operator("wm.addon_install", icon='FILESEL')
layout.operator("wm.addon_refresh", icon='FILE_REFRESH')
layout.menu("USERPREF_MT_addons_dev_guides")
elif userpref.active_section == 'THEMES':
@@ -950,33 +950,39 @@ class USERPREF_MT_ndof_settings(Menu):
input_prefs = context.user_preferences.inputs
- layout.separator()
+ is_view3d = context.space_data.type == 'VIEW_3D'
+
layout.prop(input_prefs, "ndof_sensitivity")
layout.prop(input_prefs, "ndof_orbit_sensitivity")
- if context.space_data.type == 'VIEW_3D':
+ if is_view3d:
layout.separator()
layout.prop(input_prefs, "ndof_show_guide")
layout.separator()
- layout.label(text="Orbit options")
+ layout.label(text="Orbit style")
+ layout.row().prop(input_prefs, "ndof_view_navigate_method", text="")
layout.row().prop(input_prefs, "ndof_view_rotate_method", text="")
- layout.prop(input_prefs, "ndof_roll_invert_axis")
- layout.prop(input_prefs, "ndof_tilt_invert_axis")
- layout.prop(input_prefs, "ndof_rotate_invert_axis")
-
layout.separator()
- layout.label(text="Pan options")
- layout.prop(input_prefs, "ndof_panx_invert_axis")
- layout.prop(input_prefs, "ndof_pany_invert_axis")
- layout.prop(input_prefs, "ndof_panz_invert_axis")
+ layout.label(text="Orbit options")
+ layout.prop(input_prefs, "ndof_rotx_invert_axis")
+ layout.prop(input_prefs, "ndof_roty_invert_axis")
+ layout.prop(input_prefs, "ndof_rotz_invert_axis")
+
+ # view2d use pan/zoom
+ layout.separator()
+ layout.label(text="Pan options")
+ layout.prop(input_prefs, "ndof_panx_invert_axis")
+ layout.prop(input_prefs, "ndof_pany_invert_axis")
+ layout.prop(input_prefs, "ndof_panz_invert_axis")
+ layout.prop(input_prefs, "ndof_pan_yz_swap_axis")
- layout.label(text="Zoom options")
- layout.prop(input_prefs, "ndof_zoom_invert")
- layout.prop(input_prefs, "ndof_zoom_updown")
+ layout.label(text="Zoom options")
+ layout.prop(input_prefs, "ndof_zoom_invert")
+ if is_view3d:
layout.separator()
- layout.label(text="Fly options")
+ layout.label(text="Fly/Walk options")
layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
@@ -1093,6 +1099,7 @@ class USERPREF_PT_input(Panel):
sub.label(text="NDOF Device:")
sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity")
sub.prop(inputs, "ndof_orbit_sensitivity", text="NDOF Orbit Sensitivity")
+ sub.row().prop(inputs, "ndof_view_navigate_method", expand=True)
sub.row().prop(inputs, "ndof_view_rotate_method", expand=True)
row.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 1ebe9aa0f8a..a7856b340e5 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -30,8 +30,7 @@ class VIEW3D_HT_header(Header):
layout = self.layout
view = context.space_data
- mode_string = context.mode
- edit_object = context.edit_object
+ # mode_string = context.mode
obj = context.active_object
toolsettings = context.tool_settings
@@ -127,7 +126,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_select_paint_mask")
elif mesh.use_paint_mask_vertex and mode_string == 'PAINT_WEIGHT':
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
- elif mode_string not in {'EDIT_TEXT', 'SCULPT'}:
+ elif mode_string != 'SCULPT':
layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
if mode_string == 'OBJECT':
@@ -197,6 +196,7 @@ class VIEW3D_MT_transform_base(Menu):
layout.operator("transform.bend", text="Bend")
layout.operator("transform.push_pull", text="Push/Pull")
layout.operator("object.vertex_warp", text="Warp")
+ layout.operator("object.vertex_random", text="Randomize")
# Generic transform menu - geometry types
@@ -880,20 +880,13 @@ class INFO_MT_mesh_add(Menu):
bl_label = "Mesh"
def draw(self, context):
+ from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
+
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("mesh.primitive_plane_add", icon='MESH_PLANE', text="Plane")
- layout.operator("mesh.primitive_cube_add", icon='MESH_CUBE', text="Cube")
- layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle")
- layout.operator("mesh.primitive_uv_sphere_add", icon='MESH_UVSPHERE', text="UV Sphere")
- layout.operator("mesh.primitive_ico_sphere_add", icon='MESH_ICOSPHERE', text="Icosphere")
- layout.operator("mesh.primitive_cylinder_add", icon='MESH_CYLINDER', text="Cylinder")
- layout.operator("mesh.primitive_cone_add", icon='MESH_CONE', text="Cone")
- layout.separator()
- layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
- layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
- layout.operator("mesh.primitive_torus_add", icon='MESH_TORUS', text="Torus")
+
+ VIEW3D_PT_tools_add_object.draw_add_mesh(layout)
class INFO_MT_curve_add(Menu):
@@ -901,14 +894,12 @@ class INFO_MT_curve_add(Menu):
bl_label = "Curve"
def draw(self, context):
+ from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("curve.primitive_bezier_curve_add", icon='CURVE_BEZCURVE', text="Bezier")
- layout.operator("curve.primitive_bezier_circle_add", icon='CURVE_BEZCIRCLE', text="Circle")
- layout.operator("curve.primitive_nurbs_curve_add", icon='CURVE_NCURVE', text="Nurbs Curve")
- layout.operator("curve.primitive_nurbs_circle_add", icon='CURVE_NCIRCLE', text="Nurbs Circle")
- layout.operator("curve.primitive_nurbs_path_add", icon='CURVE_PATH', text="Path")
+
+ VIEW3D_PT_tools_add_object.draw_add_curve(layout)
class INFO_MT_surface_add(Menu):
@@ -916,15 +907,12 @@ class INFO_MT_surface_add(Menu):
bl_label = "Surface"
def draw(self, context):
+ from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve")
- layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle")
- layout.operator("surface.primitive_nurbs_surface_surface_add", icon='SURFACE_NSURFACE', text="NURBS Surface")
- layout.operator("surface.primitive_nurbs_surface_cylinder_add", icon='SURFACE_NCYLINDER', text="NURBS Cylinder")
- layout.operator("surface.primitive_nurbs_surface_sphere_add", icon='SURFACE_NSPHERE', text="NURBS Sphere")
- layout.operator("surface.primitive_nurbs_surface_torus_add", icon='SURFACE_NTORUS', text="NURBS Torus")
+
+ VIEW3D_PT_tools_add_object.draw_add_surface(layout)
class INFO_MT_metaball_add(Menu):
@@ -1365,18 +1353,23 @@ class VIEW3D_MT_make_single_user(Menu):
props = layout.operator("object.make_single_user", text="Object")
props.object = True
+ props.obdata = props.material = props.texture = props.animation = False
props = layout.operator("object.make_single_user", text="Object & Data")
props.object = props.obdata = True
+ props.material = props.texture = props.animation = False
props = layout.operator("object.make_single_user", text="Object & Data & Materials+Tex")
props.object = props.obdata = props.material = props.texture = True
+ props.animation = False
props = layout.operator("object.make_single_user", text="Materials+Tex")
props.material = props.texture = True
+ props.object = props.obdata = props.animation = False
props = layout.operator("object.make_single_user", text="Object Animation")
props.animation = True
+ props.object = props.obdata = props.material = props.texture = False
class VIEW3D_MT_make_links(Menu):
@@ -1793,7 +1786,7 @@ class VIEW3D_MT_pose(Menu):
layout.separator()
layout.operator_context = 'INVOKE_AREA'
- layout.operator("pose.armature_layers", text="Change Armature Layers...")
+ layout.operator("armature.armature_layers", text="Change Armature Layers...")
layout.operator("pose.bone_layers", text="Change Bone Layers...")
layout.separator()
@@ -2174,7 +2167,15 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout.separator()
+ op = layout.operator("mesh.mark_sharp", text="Shade Smooth")
+ op.use_verts = True
+ op.clear = True
+ layout.operator("mesh.mark_sharp", text="Shade Sharp").use_verts = True
+
+ layout.separator()
+
layout.operator("mesh.bevel").vertex_only = True
+ layout.operator("mesh.convex_hull")
layout.operator("mesh.vertices_smooth")
layout.operator("mesh.remove_doubles")
@@ -2216,7 +2217,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.separator()
- layout.operator("mesh.mark_sharp").clear = False
+ layout.operator("mesh.mark_sharp")
layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
layout.separator()
@@ -2318,8 +2319,10 @@ class VIEW3D_MT_edit_mesh_clean(Menu):
layout.separator()
- layout.operator("mesh.fill_holes")
+ layout.operator("mesh.dissolve_degenerate")
+ layout.operator("mesh.dissolve_limited")
layout.operator("mesh.vert_connect_nonplanar")
+ layout.operator("mesh.fill_holes")
class VIEW3D_MT_edit_mesh_delete(Menu):
@@ -2690,8 +2693,7 @@ class VIEW3D_PT_view3d_properties(Panel):
view = context.space_data
col = layout.column()
- col.active = bool(view.region_3d.view_perspective != 'CAMERA' or
- view.region_quadview)
+ col.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews)
col.prop(view, "lens")
col.label(text="Lock to Object:")
col.prop(view, "lock_object", text="")
@@ -2781,8 +2783,6 @@ class VIEW3D_PT_view3d_display(Panel):
view = context.space_data
scene = context.scene
- gs = scene.game_settings
- obj = context.object
col = layout.column()
col.prop(view, "show_only_render")
@@ -2814,11 +2814,10 @@ class VIEW3D_PT_view3d_display(Panel):
layout.separator()
- region = view.region_quadview
-
layout.operator("screen.region_quadview", text="Toggle Quad View")
- if region:
+ if view.region_quadviews:
+ region = view.region_quadviews[2]
col = layout.column()
col.prop(region, "lock_rotation")
row = col.row()
@@ -2890,11 +2889,12 @@ class VIEW3D_PT_view3d_motion_tracking(Panel):
col = layout.column()
col.active = view.show_reconstruction
- col.prop(view, "show_bundle_names")
- col.prop(view, "show_camera_path")
- col.label(text="Tracks:")
- col.prop(view, "tracks_draw_type", text="")
- col.prop(view, "tracks_draw_size", text="Size")
+ col.prop(view, "show_camera_path", text="Camera Path")
+ col.prop(view, "show_bundle_names", text="3D Marker Names")
+ col.label(text="Track Type and Size:")
+ row = col.row(align=True)
+ row.prop(view, "tracks_draw_type", text="")
+ row.prop(view, "tracks_draw_size", text="")
class VIEW3D_PT_view3d_meshdisplay(Panel):
@@ -2940,14 +2940,14 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
col.separator()
col.label(text="Normals:")
- row = col.row()
+ row = col.row(align=True)
- sub = row.row(align=True)
- sub.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
- sub.prop(mesh, "show_normal_face", text="", icon='FACESEL')
+ row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
+ row.prop(mesh, "show_normal_loop", text="", icon='VERTEXSEL')
+ row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
sub = row.row(align=True)
- sub.active = mesh.show_normal_vertex or mesh.show_normal_face
+ 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")
col.separator()
@@ -3142,7 +3142,7 @@ class VIEW3D_PT_transform_orientations(Panel):
if orientation:
row = layout.row(align=True)
row.prop(orientation, "name", text="")
- row.operator("transform.delete_orientation", text="", icon="X")
+ row.operator("transform.delete_orientation", text="", icon='X')
class VIEW3D_PT_etch_a_ton(Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 12b21d0d89f..0797592b4eb 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel
+from bl_ui.properties_grease_pencil_common import GreasePencilPanel
from bl_ui.properties_paint_common import (
UnifiedPaintPanel,
brush_texture_settings,
@@ -50,26 +51,6 @@ def draw_keyframing_tools(context, layout):
row.operator("anim.keyframe_delete_v3d", text="Remove")
-# Grease Pencil tools
-def draw_gpencil_tools(context, layout):
- col = layout.column(align=True)
-
- row = col.row(align=True)
- row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
- row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
- row = col.row(align=True)
- row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
- row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
-
- col.separator()
-
- col.prop(context.tool_settings, "use_grease_pencil_sessions")
-
- col.separator()
-
- col.label(text="Measure:")
- col.operator("view3d.ruler")
-
# ********** default tools for object-mode ****************
@@ -86,11 +67,8 @@ class VIEW3D_PT_tools_transform(View3DPanel, Panel):
col.operator("transform.rotate")
col.operator("transform.resize", text="Scale")
- active_object = context.active_object
- if active_object and active_object.type in {'MESH', 'CURVE', 'SURFACE'}:
-
- col = layout.column(align=True)
- col.operator("transform.mirror", text="Mirror")
+ col = layout.column(align=True)
+ col.operator("transform.mirror", text="Mirror")
class VIEW3D_PT_tools_object(View3DPanel, Panel):
@@ -105,23 +83,26 @@ class VIEW3D_PT_tools_object(View3DPanel, Panel):
col.operator("object.duplicate_move", text="Duplicate")
col.operator("object.duplicate_move_linked", text="Duplicate Linked")
- active_object = context.active_object
- if active_object and active_object.type in {'MESH', 'CURVE', 'SURFACE'}:
- col = layout.column(align=True)
- col.operator("object.join")
col.operator("object.delete")
- col = layout.column(align=True)
- if active_object and active_object.type in {'MESH', 'CURVE', 'SURFACE'}:
+ obj = context.active_object
+ if obj:
+ obj_type = obj.type
- col = layout.column(align=True)
- col.operator("object.origin_set", text="Set Origin")
+ if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE'}:
+ col = layout.column(align=True)
+ col.operator("object.join")
- col = layout.column(align=True)
- col.label(text="Shading:")
- row = col.row(align=True)
- row.operator("object.shade_smooth", text="Smooth")
- row.operator("object.shade_flat", text="Flat")
+ if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE', 'FONT', 'LATTICE'}:
+ col = layout.column(align=True)
+ col.operator_menu_enum("object.origin_set", "type", text="Set Origin")
+
+ if obj_type in {'MESH', 'CURVE', 'SURFACE'}:
+ col = layout.column(align=True)
+ col.label(text="Shading:")
+ row = col.row(align=True)
+ row.operator("object.shade_smooth", text="Smooth")
+ row.operator("object.shade_flat", text="Flat")
class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
@@ -142,45 +123,93 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
draw_repeat_tools(context, layout)
-class VIEW3D_PT_tools_add_mesh(View3DPanel, Panel):
+class VIEW3D_PT_tools_add_object(View3DPanel, Panel):
bl_category = "Create"
bl_context = "objectmode"
bl_label = "Add Primitive"
+ @staticmethod
+ def draw_add_mesh(layout, label=False):
+ if label:
+ layout.label(text="Primitives:")
+ layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE')
+ layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE')
+ layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
+ layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE')
+ layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE')
+ layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER')
+ layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE')
+ layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS')
+
+ if label:
+ layout.label(text="Special:")
+ else:
+ layout.separator()
+ layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID')
+ layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY')
+
+ @staticmethod
+ def draw_add_curve(layout, label=False):
+ if label:
+ layout.label(text="Bezier:")
+ layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
+ layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
+
+ if label:
+ layout.label(text="Nurbs:")
+ else:
+ layout.separator()
+ layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE')
+ layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE')
+ layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH')
+
+ @staticmethod
+ def draw_add_surface(layout):
+ layout.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon='SURFACE_NCURVE')
+ layout.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon='SURFACE_NCIRCLE')
+ layout.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon='SURFACE_NSURFACE')
+ layout.operator("surface.primitive_nurbs_surface_cylinder_add", text="Nurbs Cylinder", icon='SURFACE_NCYLINDER')
+ layout.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon='SURFACE_NSPHERE')
+ layout.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon='SURFACE_NTORUS')
+
+ @staticmethod
+ def draw_add_mball(layout):
+ layout.operator_enum("object.metaball_add", "type")
+
+ @staticmethod
+ def draw_add_lamp(layout):
+ layout.operator_enum("object.lamp_add", "type")
+
+ @staticmethod
+ def draw_add_other(layout):
+ layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
+ layout.operator("object.armature_add", text="Armature", icon='OUTLINER_OB_ARMATURE')
+ layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
+ layout.operator("object.empty_add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'PLAIN_AXES'
+ layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
+
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
col.label(text="Mesh:")
- col.operator("mesh.primitive_plane_add", text="Plane", icon="MESH_PLANE")
- col.operator("mesh.primitive_cube_add", text="Cube", icon="MESH_CUBE")
- col.operator("mesh.primitive_circle_add", text="Circle", icon="MESH_CIRCLE")
- col.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon="MESH_UVSPHERE")
- col.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon="MESH_ICOSPHERE")
- col.operator("mesh.primitive_cylinder_add", text="Cylinder", icon="MESH_CYLINDER")
- col.operator("mesh.primitive_cone_add", text="Cone", icon="MESH_CONE")
- col.operator("mesh.primitive_torus_add", text="Torus", icon="MESH_TORUS")
- col.operator("mesh.primitive_monkey_add", text="Monkey", icon="MESH_MONKEY")
+ self.draw_add_mesh(col)
col = layout.column(align=True)
col.label(text="Curve:")
- col.operator("curve.primitive_bezier_curve_add", text="Curve", icon="CURVE_BEZCURVE")
- col.operator("curve.primitive_bezier_circle_add", text="Circle", icon="CURVE_BEZCIRCLE")
- col.operator("curve.primitive_nurbs_path_add", text="Path", icon="CURVE_PATH")
+ self.draw_add_curve(col)
+
+ # not used here:
+ # draw_add_surface
+ # draw_add_mball
+ col = layout.column(align=True)
col.label(text="Lamp:")
- col.operator("object.lamp_add", text="Point", icon="LAMP_POINT").type = 'POINT'
- col.operator("object.lamp_add", text="Sun", icon="LAMP_SUN").type = 'SUN'
- col.operator("object.lamp_add", text="Spot", icon="LAMP_SPOT").type = 'SPOT'
- col.operator("object.lamp_add", text="Hemi", icon="LAMP_HEMI").type = 'HEMI'
- col.operator("object.lamp_add", text="Area", icon="LAMP_AREA").type = 'AREA'
+ self.draw_add_lamp(col)
+ col = layout.column(align=True)
col.label(text="Other:")
- col.operator("object.text_add", text="Text", icon="OUTLINER_OB_FONT")
- col.operator("object.armature_add", text="Armature", icon="OUTLINER_OB_ARMATURE")
- col.operator("object.add", text="Lattice", icon="OUTLINER_OB_LATTICE").type = 'LATTICE'
- col.operator("object.empty_add", text="Empty", icon="OUTLINER_OB_EMPTY").type = 'PLAIN_AXES'
- col.operator("object.camera_add", text="Camera", icon="OUTLINER_OB_CAMERA")
+ self.draw_add_other(col)
class VIEW3D_PT_tools_relations(View3DPanel, Panel):
@@ -240,7 +269,7 @@ class VIEW3D_PT_tools_animation(View3DPanel, Panel):
col.operator("nla.bake", text="Bake Action")
-class VIEW3D_PT_tools_rigidbody(View3DPanel, Panel):
+class VIEW3D_PT_tools_rigid_body(View3DPanel, Panel):
bl_category = "Physics"
bl_context = "objectmode"
bl_label = "Rigid Body Tools"
@@ -300,6 +329,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
row.operator("transform.vert_slide", text="Vertex")
col.operator("mesh.noise")
col.operator("mesh.vertices_smooth")
+ col.operator("object.vertex_random")
col = layout.column(align=True)
col.label(text="Add:")
@@ -342,20 +372,8 @@ class VIEW3D_PT_tools_add_mesh_edit(View3DPanel, Panel):
layout = self.layout
col = layout.column(align=True)
- col.label(text="Primitives:")
- col.operator("mesh.primitive_plane_add", text="Plane", icon="MESH_PLANE")
- col.operator("mesh.primitive_cube_add", text="Cube", icon="MESH_CUBE")
- col.operator("mesh.primitive_circle_add", text="Circle", icon="MESH_CIRCLE")
- col.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon="MESH_UVSPHERE")
- col.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon="MESH_ICOSPHERE")
- col.operator("mesh.primitive_cylinder_add", text="Cylinder", icon="MESH_CYLINDER")
- col.operator("mesh.primitive_cone_add", text="Cone", icon="MESH_CONE")
- col.operator("mesh.primitive_torus_add", text="Torus", icon="MESH_TORUS")
- col = layout.column(align=True)
- col.label(text="Special:")
- col.operator("mesh.primitive_grid_add", text="Grid", icon="MESH_GRID")
- col.operator("mesh.primitive_monkey_add", text="Monkey", icon="MESH_MONKEY")
+ VIEW3D_PT_tools_add_object.draw_add_mesh(col, label=True)
class VIEW3D_PT_tools_shading(View3DPanel, Panel):
@@ -367,10 +385,20 @@ class VIEW3D_PT_tools_shading(View3DPanel, Panel):
layout = self.layout
col = layout.column(align=True)
- col.label(text="Shading:")
+ col.label(text="Faces:")
row = col.row(align=True)
row.operator("mesh.faces_shade_smooth", text="Smooth")
row.operator("mesh.faces_shade_flat", text="Flat")
+ col.label(text="Edges:")
+ row = col.row(align=True)
+ row.operator("mesh.mark_sharp", text="Smooth").clear = True
+ row.operator("mesh.mark_sharp", text="Sharp")
+ col.label(text="Vertices:")
+ row = col.row(align=True)
+ op = row.operator("mesh.mark_sharp", text="Smooth")
+ op.use_verts = True
+ op.clear = True
+ row.operator("mesh.mark_sharp", text="Sharp").use_verts = True
col = layout.column(align=True)
col.label(text="Normals:")
@@ -483,6 +511,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
col.operator("curve.extrude_move", text="Extrude")
col.operator("curve.subdivide")
col.operator("curve.smooth")
+ col.operator("object.vertex_random")
draw_repeat_tools(context, layout)
@@ -497,14 +526,7 @@ class VIEW3D_PT_tools_add_curve_edit(View3DPanel, Panel):
col = layout.column(align=True)
- col.label(text="Bezier:")
- col.operator("curve.primitive_bezier_curve_add", text="Bezier Curve", icon="CURVE_BEZCURVE")
- col.operator("curve.primitive_bezier_circle_add", text="Bezier Circle", icon="CURVE_BEZCIRCLE")
-
- col.label(text="Nurbs:")
- col.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon="CURVE_NCURVE")
- col.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon="CURVE_NCIRCLE")
- col.operator("curve.primitive_nurbs_path_add", text="Nurbs Path", icon="CURVE_PATH")
+ VIEW3D_PT_tools_add_object.draw_add_curve(col, label=True)
# ********** default tools for editmode_surface ****************
@@ -543,6 +565,10 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
col.operator("curve.extrude", text="Extrude")
col.operator("curve.subdivide")
+ col = layout.column(align=True)
+ col.label(text="Deform:")
+ col.operator("object.vertex_random")
+
draw_repeat_tools(context, layout)
@@ -556,12 +582,7 @@ class VIEW3D_PT_tools_add_surface_edit(View3DPanel, Panel):
col = layout.column(align=True)
- col.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon="SURFACE_NCURVE")
- col.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon="SURFACE_NCIRCLE")
- col.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon="SURFACE_NSURFACE")
- col.operator("surface.primitive_nurbs_surface_cylinder_add", text="Nurbs Cylinder", icon="SURFACE_NCYLINDER")
- col.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon="SURFACE_NSPHERE")
- col.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon="SURFACE_NTORUS")
+ VIEW3D_PT_tools_add_object.draw_add_surface(col)
# ********** default tools for editmode_text ****************
@@ -592,19 +613,28 @@ class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
# ********** default tools for editmode_armature ****************
-class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
+class VIEW3D_PT_tools_armatureedit_transform(View3DPanel, Panel):
+ bl_category = "Tools"
bl_context = "armature_edit"
- bl_label = "Armature Tools"
+ bl_label = "Transform"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
- col.label(text="Transform:")
col.operator("transform.translate")
col.operator("transform.rotate")
col.operator("transform.resize", text="Scale")
+
+class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
+ bl_category = "Tools"
+ bl_context = "armature_edit"
+ bl_label = "Armature Tools"
+
+ def draw(self, context):
+ layout = self.layout
+
col = layout.column(align=True)
col.label(text="Bones:")
col.operator("armature.bone_primitive_add", text="Add")
@@ -616,10 +646,15 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
col.operator("armature.extrude_move")
col.operator("armature.subdivide", text="Subdivide")
+ col = layout.column(align=True)
+ col.label(text="Deform:")
+ col.operator("object.vertex_random")
+
draw_repeat_tools(context, layout)
class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
+ bl_category = "Options"
bl_context = "armature_edit"
bl_label = "Armature Options"
@@ -628,6 +663,7 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
self.layout.prop(arm, "use_mirror_x")
+
# ********** default tools for editmode_mball ****************
@@ -645,6 +681,10 @@ class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
col.operator("transform.rotate")
col.operator("transform.resize", text="Scale")
+ col = layout.column(align=True)
+ col.label(text="Deform:")
+ col.operator("object.vertex_random")
+
draw_repeat_tools(context, layout)
@@ -658,11 +698,7 @@ class VIEW3D_PT_tools_add_mball_edit(View3DPanel, Panel):
col = layout.column(align=True)
- col.operator("object.metaball_add", text="Ball", icon="META_BALL").type = 'BALL'
- col.operator("object.metaball_add", text="Capsule", icon="META_CAPSULE").type = 'CAPSULE'
- col.operator("object.metaball_add", text="Plane", icon="META_PLANE").type = 'PLANE'
- col.operator("object.metaball_add", text="Ellipsoid", icon="META_ELLIPSOID").type = 'ELLIPSOID'
- col.operator("object.metaball_add", text="Cube", icon="META_CUBE").type = 'CUBE'
+ VIEW3D_PT_tools_add_object.draw_add_mball(col)
# ********** default tools for editmode_lattice ****************
@@ -685,6 +721,10 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
col = layout.column(align=True)
col.operator("lattice.make_regular")
+ col = layout.column(align=True)
+ col.label(text="Deform:")
+ col.operator("object.vertex_random")
+
draw_repeat_tools(context, layout)
@@ -1060,7 +1100,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
settings = self.paint_settings(context)
brush = settings.brush
- tex_slot = brush.texture_slot
col = layout.column()
@@ -1084,7 +1123,6 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
layout = self.layout
brush = context.tool_settings.image_paint.brush
- tex_slot_alpha = brush.mask_texture_slot
col = layout.column()
@@ -1118,10 +1156,7 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
col.label(text="Stroke Method:")
- if context.sculpt_object:
- col.prop(brush, "sculpt_stroke_method", text="")
- else:
- col.prop(brush, "stroke_method", text="")
+ col.prop(brush, "stroke_method", text="")
if brush.use_anchor:
col.separator()
@@ -1212,9 +1247,9 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
-class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
+class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_label = "Topology"
+ bl_label = "Dyntopo"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
@@ -1230,19 +1265,27 @@ class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
brush = settings.brush
if context.sculpt_object.use_dynamic_topology_sculpting:
- layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dynamic")
+ layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dyntopo")
else:
- layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dynamic")
+ layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dyntopo")
col = layout.column()
col.active = context.sculpt_object.use_dynamic_topology_sculpting
sub = col.column(align=True)
sub.active = brush and brush.sculpt_tool not in ('MASK')
- sub.prop(sculpt, "detail_size")
+ if (sculpt.detail_type_method == 'CONSTANT'):
+ row = sub.row(align=True)
+ row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
+ row.prop(sculpt, "constant_detail")
+ else:
+ sub.prop(sculpt, "detail_size")
sub.prop(sculpt, "detail_refine_method", text="")
+ sub.prop(sculpt, "detail_type_method", text="")
col.separator()
col.prop(sculpt, "use_smooth_shading")
col.operator("sculpt.optimize")
+ if (sculpt.detail_type_method == 'CONSTANT'):
+ col.operator("sculpt.detail_flood_fill")
col.separator()
col.prop(sculpt, "symmetrize_direction")
col.operator("sculpt.symmetrize")
@@ -1259,6 +1302,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
def draw(self, context):
layout = self.layout
+ scene = context.scene
toolsettings = context.tool_settings
sculpt = toolsettings.sculpt
@@ -1269,6 +1313,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
col.label(text="Gravity:")
col.prop(sculpt, "gravity", slider=True, text="Factor")
col.prop(sculpt, "gravity_object")
+ col.separator()
layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
layout.prop(sculpt, "show_low_resolution")
@@ -1280,7 +1325,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_label = "Symmetry \ Lock"
+ bl_label = "Symmetry / Lock"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
@@ -1335,24 +1380,25 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
col = layout.column()
col.prop(settings, "show_brush")
- col = col.column()
- col.active = settings.show_brush
+ sub = col.column()
+ sub.active = settings.show_brush
if context.sculpt_object and context.tool_settings.sculpt:
if brush.sculpt_capabilities.has_secondary_color:
- col.row().prop(brush, "cursor_color_add", text="Add")
- col.row().prop(brush, "cursor_color_subtract", text="Subtract")
+ sub.row().prop(brush, "cursor_color_add", text="Add")
+ sub.row().prop(brush, "cursor_color_subtract", text="Subtract")
else:
- col.prop(brush, "cursor_color_add", text="")
+ sub.prop(brush, "cursor_color_add", text="")
else:
- col.prop(brush, "cursor_color_add", text="")
+ sub.prop(brush, "cursor_color_add", text="")
- layout.separator()
+ col.separator()
- col = layout.column(align=True)
+ col = col.column(align=True)
col.prop(brush, "use_custom_icon")
- if brush.use_custom_icon:
- col.prop(brush, "icon_filepath", text="")
+ sub = col.column()
+ sub.active = brush.use_custom_icon
+ sub.prop(brush, "icon_filepath", text="")
# ********** default tools for weight-paint ****************
@@ -1549,6 +1595,7 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
"""Default tools for particle mode"""
bl_context = "particlemode"
bl_label = "Options"
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
@@ -1614,13 +1661,10 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
# Grease Pencil tools
-class VIEW3D_PT_tools_greasepencil(View3DPanel, Panel):
+class VIEW3D_PT_tools_grease_pencil(GreasePencilPanel, Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
bl_category = "Grease Pencil"
- bl_label = "Grease Pencil"
-
- def draw(self, context):
- layout = self.layout
- draw_gpencil_tools(context, layout)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 6ade4911215..34c0739d50c 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -167,6 +167,7 @@ shader_node_categories = [
NodeItem("ShaderNodeHairInfo"),
NodeItem("ShaderNodeParticleInfo"),
NodeItem("ShaderNodeCameraData"),
+ NodeItem("ShaderNodeUVMap"),
NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[
@@ -349,6 +350,7 @@ compositor_node_categories = [
NodeItem("CompositorNodeTransform"),
NodeItem("CompositorNodeStabilize"),
NodeItem("CompositorNodePlaneTrackDeform"),
+ NodeItem("CompositorNodeCornerPin"),
]),
CompositorNodeCategory("CMP_GROUP", "Group", items=node_group_items),
CompositorNodeCategory("CMP_LAYOUT", "Layout", items=[
diff --git a/release/scripts/templates_py/custom_nodes.py b/release/scripts/templates_py/custom_nodes.py
index bf89c0debad..992ef734859 100644
--- a/release/scripts/templates_py/custom_nodes.py
+++ b/release/scripts/templates_py/custom_nodes.py
@@ -49,13 +49,15 @@ class MyCustomSocket(NodeSocket):
def draw_color(self, context, node):
return (1.0, 0.4, 0.216, 0.5)
+
# Mix-in class for all custom nodes in this tree type.
# Defines a poll function to enable instantiation.
-class MyCustomTreeNode :
+class MyCustomTreeNode:
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'CustomTreeType'
+
# Derived from the Node base type.
class MyCustomNode(Node, MyCustomTreeNode):
# === Basics ===
@@ -123,6 +125,7 @@ class MyCustomNode(Node, MyCustomTreeNode):
import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem
+
# our own base class with an appropriate poll function,
# so the categories only show up in our own tree type
class MyNodeCategory(NodeCategory):
@@ -143,12 +146,12 @@ node_categories = [
# NB: settings values are stored as string expressions,
# for this reason they should be converted to strings using repr()
NodeItem("CustomNodeType", label="Node A", settings={
- "myStringProperty" : repr("Lorem ipsum dolor sit amet"),
- "myFloatProperty" : repr(1.0),
+ "myStringProperty": repr("Lorem ipsum dolor sit amet"),
+ "myFloatProperty": repr(1.0),
}),
NodeItem("CustomNodeType", label="Node B", settings={
- "myStringProperty" : repr("consectetur adipisicing elit"),
- "myFloatProperty" : repr(2.0),
+ "myStringProperty": repr("consectetur adipisicing elit"),
+ "myFloatProperty": repr(2.0),
}),
]),
]
diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index eac76922187..4d0355047f4 100644
--- a/release/scripts/templates_py/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -16,7 +16,6 @@ def main(context, event, ray_max=10000.0):
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
ray_target = ray_origin + (view_vector * ray_max)
-
def visible_objects_and_duplis():
"""Loop over (object, matrix) pairs (mesh only)"""
diff --git a/release/scripts/templates_py/ui_panel.py b/release/scripts/templates_py/ui_panel.py
index cacdb83e815..855d05700c5 100644
--- a/release/scripts/templates_py/ui_panel.py
+++ b/release/scripts/templates_py/ui_panel.py
@@ -42,22 +42,22 @@ class LayoutDemoPanel(bpy.types.Panel):
col.label(text="Column Two:")
col.prop(scene, "frame_start")
col.prop(scene, "frame_end")
-
+
# Big render button
layout.label(text="Big Button:")
row = layout.row()
row.scale_y = 3.0
row.operator("render.render")
-
+
# Different sizes in a row
layout.label(text="Different button sizes:")
row = layout.row(align=True)
row.operator("render.render")
-
+
sub = row.row()
sub.scale_x = 2.0
sub.operator("render.render")
-
+
row.operator("render.render")
diff --git a/release/text/readme.html b/release/text/readme.html
index 7d79c8c3bad..f9cee7418f0 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -64,7 +64,7 @@ IRC <a href="irc://irc.freenode.net/#blenderchat"><span class="s4">#blenderchat<
<p class="p5"><span class="s3">Development <a href="http://www.blender.org/get-involved/developers/"><span class="s4">www.blender.org/get-involved/developers/</span></a><br>
GIT and Bug Tracker <a href="http://developer.blender.org/"><span class="s4">developer.blender.org/</span></a><br>
Get Involved <a href="http://www.blender.org/get-involved/"><span class="s4">www.blender.org/get-involved/</span></a><br>
-IRC <a href="irc://irc.freenode.net/#blendercoders"><span class="s4">#blendercoders on irc.freenode.net</span></a></span></p>
+IRC <a href="irc://irc.freenode.net/#blendercoders"><span class="s4">#blendercoders</span></a> on irc.freenode.net</span></p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p6">Blender is open-source and free for all to use.</p>
diff --git a/source/blender/avi/intern/avi_codecs.c b/source/blender/avi/intern/avi_codecs.c
index e43826064a6..c14d088c8ea 100644
--- a/source/blender/avi/intern/avi_codecs.c
+++ b/source/blender/avi/intern/avi_codecs.c
@@ -106,10 +106,8 @@ int avi_get_format_type(AviFormat format)
case AVI_FORMAT_AVI_RGB:
case AVI_FORMAT_MJPEG:
return FCC("vids");
- break;
default:
return 0;
- break;
}
}
@@ -120,13 +118,10 @@ int avi_get_format_fcc(AviFormat format)
case AVI_FORMAT_RGB32:
case AVI_FORMAT_AVI_RGB:
return FCC("DIB ");
- break;
case AVI_FORMAT_MJPEG:
return FCC("MJPG");
- break;
default:
return 0;
- break;
}
}
@@ -137,12 +132,9 @@ int avi_get_format_compression(AviFormat format)
case AVI_FORMAT_RGB32:
case AVI_FORMAT_AVI_RGB:
return 0;
- break;
case AVI_FORMAT_MJPEG:
return FCC("MJPG");
- break;
default:
return 0;
- break;
}
}
diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c
index a2d48c724de..857501c5796 100644
--- a/source/blender/avi/intern/avi_mjpeg.c
+++ b/source/blender/avi/intern/avi_mjpeg.c
@@ -57,8 +57,8 @@ static void add_huff_table(j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UI
memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
memcpy((*htblptr)->huffval, val, sizeof((*htblptr)->huffval));
- /* Initialize sent_table FALSE so table will be written to JPEG file. */
- (*htblptr)->sent_table = FALSE;
+ /* Initialize sent_table false so table will be written to JPEG file. */
+ (*htblptr)->sent_table = false;
}
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
@@ -165,7 +165,7 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign
dinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&dinfo);
jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize);
- jpeg_read_header(&dinfo, TRUE);
+ jpeg_read_header(&dinfo, true);
if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
std_huff_tables(&dinfo);
}
@@ -187,7 +187,7 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign
jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize - numbytes);
numbytes = 0;
- jpeg_read_header(&dinfo, TRUE);
+ jpeg_read_header(&dinfo, true);
if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
std_huff_tables(&dinfo);
}
@@ -224,21 +224,21 @@ static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned
jpeg_set_defaults(&cinfo);
jpeg_set_colorspace(&cinfo, JCS_YCbCr);
- jpeg_set_quality(&cinfo, quality, TRUE);
+ jpeg_set_quality(&cinfo, quality, true);
- cinfo.dc_huff_tbl_ptrs[0]->sent_table = TRUE;
- cinfo.dc_huff_tbl_ptrs[1]->sent_table = TRUE;
- cinfo.ac_huff_tbl_ptrs[0]->sent_table = TRUE;
- cinfo.ac_huff_tbl_ptrs[1]->sent_table = TRUE;
+ cinfo.dc_huff_tbl_ptrs[0]->sent_table = true;
+ cinfo.dc_huff_tbl_ptrs[1]->sent_table = true;
+ cinfo.ac_huff_tbl_ptrs[0]->sent_table = true;
+ cinfo.ac_huff_tbl_ptrs[1]->sent_table = true;
cinfo.comp_info[0].component_id = 0;
cinfo.comp_info[0].v_samp_factor = 1;
cinfo.comp_info[1].component_id = 1;
cinfo.comp_info[2].component_id = 2;
- cinfo.write_JFIF_header = FALSE;
+ cinfo.write_JFIF_header = false;
- jpeg_start_compress(&cinfo, FALSE);
+ jpeg_start_compress(&cinfo, false);
i = 0;
marker[i++] = 'A';
@@ -378,7 +378,7 @@ static void jpegmemdestmgr_init_destination(j_compress_ptr cinfo)
static boolean jpegmemdestmgr_empty_output_buffer(j_compress_ptr cinfo)
{
(void)cinfo; /* unused */
- return TRUE;
+ return true;
}
static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
@@ -422,7 +422,7 @@ static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo)
dinfo->src->next_input_byte = buf;
dinfo->src->bytes_in_buffer = 2;
- return TRUE;
+ return true;
}
static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skipcnt)
diff --git a/source/blender/avi/intern/avi_options.c b/source/blender/avi/intern/avi_options.c
index c552cbe8724..47c18831cbd 100644
--- a/source/blender/avi/intern/avi_options.c
+++ b/source/blender/avi/intern/avi_options.c
@@ -125,7 +125,6 @@ AviError AVI_set_compress_option(AviMovie *movie, int option_type, int stream, A
break;
default:
return AVI_ERROR_OPTION;
- break;
}
return AVI_ERROR_NONE;
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index e80f5d261f5..410b98ef6ae 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -163,11 +163,11 @@ void BLF_shadow_offset(int fontid, int x, int y);
/* Set the buffer, size and number of channels to draw, one thing to take care is call
* this function with NULL pointer when we finish, for example:
*
- * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, TRUE, NULL);
+ * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, true, NULL);
*
* ... set color, position and draw ...
*
- * BLF_buffer(NULL, NULL, NULL, 0, 0, FALSE, NULL);
+ * BLF_buffer(NULL, NULL, NULL, 0, 0, false, NULL);
*/
void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 04c75968bf3..03246501460 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -68,7 +68,7 @@
#define BLF_MAX_FONT 16
/* Font array. */
-static FontBLF *global_font[BLF_MAX_FONT] = {0};
+static FontBLF *global_font[BLF_MAX_FONT] = {NULL};
/* Default size and dpi, for BLF_draw_default. */
static int global_font_default = -1;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 4cb8d741cc1..6bc5cd3d797 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -54,8 +54,6 @@
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
#include "BLI_alloca.h"
-#include "BLI_linklist.h" /* linknode */
-#include "BLI_strict_flags.h"
#include "BLF_api.h"
@@ -64,6 +62,8 @@
#include "blf_internal_types.h"
#include "blf_internal.h"
+#include "BLI_strict_flags.h"
+
#include "GPU_immediate.h"
#include "GPU_state_latch.h"
@@ -151,10 +151,10 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
#define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode) \
- const short _has_kerning = FT_HAS_KERNING((_font)->face); \
+ const bool _has_kerning = FT_HAS_KERNING((_font)->face); \
const FT_UInt _kern_mode = (_has_kerning == 0) ? 0 : \
(((_font)->flags & BLF_KERNING_DEFAULT) ? \
- ft_kerning_default : FT_KERNING_UNFITTED) \
+ ft_kerning_default : (FT_UInt)FT_KERNING_UNFITTED) \
#define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x) \
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 623d8b7652a..2852b8161c8 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -42,7 +42,6 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BKE_global.h"
#include "DNA_userdef_types.h"
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index 0a288e08f4e..9f166e851b6 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -58,7 +58,7 @@ static unsigned char *unifont_mono_ttf = NULL;
static bli_off_t unifont_mono_size = 0;
#endif /* WITH_INTERNATIONAL */
-unsigned char *BLF_get_unifont(int *unifont_size_r)
+unsigned char *BLF_get_unifont(int *r_unifont_size)
{
#ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) {
@@ -75,11 +75,11 @@ unsigned char *BLF_get_unifont(int *unifont_size_r)
}
}
- *unifont_size_r = (int)unifont_size; /* assuming font file is less than 2GiB */
+ *r_unifont_size = (int)unifont_size; /* XXX jwilkins: assuming font file is less than 2GiB */
return unifont_ttf;
#else
- (void)unifont_size_r;
+ (void)r_unifont_size;
return NULL;
#endif
}
@@ -93,7 +93,7 @@ void BLF_free_unifont(void)
#endif
}
-unsigned char *BLF_get_unifont_mono(int *unifont_size_r)
+unsigned char *BLF_get_unifont_mono(int *r_unifont_size)
{
#ifdef WITH_INTERNATIONAL
if (unifont_mono_ttf == NULL) {
@@ -110,11 +110,11 @@ unsigned char *BLF_get_unifont_mono(int *unifont_size_r)
}
}
- *unifont_size_r = unifont_mono_size;
+ *r_unifont_size = unifont_mono_size;
return unifont_mono_ttf;
#else
- (void)unifont_size_r;
+ (void)r_unifont_size;
return NULL;
#endif
}
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index b3db0eacb73..12981040d63 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -161,7 +161,7 @@ typedef enum DMDrawFlag {
typedef enum DMForeachFlag {
DM_FOREACH_NOP = 0,
- DM_FOREACH_USE_NORMAL = (1 << 0), /* foreachMappedVert, foreachMappedFaceCenter */
+ DM_FOREACH_USE_NORMAL = (1 << 0), /* foreachMappedVert, foreachMappedLoop, foreachMappedFaceCenter */
} DMForeachFlag;
typedef enum DMDirtyFlag {
@@ -189,6 +189,8 @@ struct DerivedMesh {
DerivedMeshType type;
float auto_bump_scale;
DMDirtyFlag dirty;
+ int totmat; /* total materials. Will be valid only before object drawing. */
+ struct Material **mat; /* material array. Will be valid only before object drawing */
/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
char cd_flag;
@@ -196,6 +198,9 @@ struct DerivedMesh {
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
+ /** Calculate loop (split) normals */
+ void (*calcLoopNormals)(DerivedMesh *dm, const float split_angle);
+
/** Recalculates mesh tessellation */
void (*recalcTessellation)(DerivedMesh *dm);
@@ -213,9 +218,9 @@ struct DerivedMesh {
* of this function can be quite slow, iterating over all
* elements (editmesh)
*/
- void (*getVert)(DerivedMesh *dm, int index, struct MVert *vert_r);
- void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
- void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *face_r);
+ void (*getVert)(DerivedMesh *dm, int index, struct MVert *r_vert);
+ void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *r_edge);
+ void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *r_face);
/** Return a pointer to the entire array of verts/edges/face from the
* derived mesh. if such an array does not exist yet, it will be created,
@@ -231,11 +236,11 @@ struct DerivedMesh {
/** Copy all verts/edges/faces from the derived mesh into
* *{vert/edge/face}_r (must point to a buffer large enough)
*/
- void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
- void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
- void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *face_r);
- void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
- void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
+ void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert);
+ void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
+ void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *r_face);
+ void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop);
+ void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
/** Return a copy of all verts/edges/faces from the derived mesh
* it is the caller's responsibility to free the returned pointer
@@ -309,6 +314,15 @@ struct DerivedMesh {
const float v0co[3], const float v1co[3]),
void *userData);
+ /** Iterate over each mapped loop in the derived mesh, calling the given function
+ * with the original loop index and the mapped loops's new coordinate and normal.
+ */
+ void (*foreachMappedLoop)(DerivedMesh *dm,
+ void (*func)(void *userData, int vertex_index, int face_index,
+ const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag);
+
/** Iterate over each mapped face in the derived mesh, calling the
* given function with the original face and the mapped face's (or
* faces') center and normal.
@@ -323,21 +337,21 @@ struct DerivedMesh {
*
* Also called in Editmode
*/
- void (*getMinMax)(DerivedMesh *dm, float min_r[3], float max_r[3]);
+ void (*getMinMax)(DerivedMesh *dm, float r_min[3], float r_max[3]);
/** Direct Access Operations
* - Can be undefined
* - Must be defined for modifiers that only deform however */
/** Get vertex location, undefined if index is not valid */
- void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
+ void (*getVertCo)(DerivedMesh *dm, int index, float r_co[3]);
/** Fill the array (of length .getNumVerts()) with all vertex locations */
- void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
+ void (*getVertCos)(DerivedMesh *dm, float (*r_cos)[3]);
/** Get smooth vertex normal, undefined if index is not valid */
- void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
- void (*getPolyNo)(DerivedMesh *dm, int index, float no_r[3]);
+ void (*getVertNo)(DerivedMesh *dm, int index, float r_no[3]);
+ void (*getPolyNo)(DerivedMesh *dm, int index, float r_no[3]);
/** Get a map of vertices to faces
*/
@@ -359,7 +373,7 @@ struct DerivedMesh {
*
* Also called for *final* editmode DerivedMeshes
*/
- void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges);
+ void (*drawEdges)(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges);
/** Draw all loose edges (edges w/ no adjoining faces) */
void (*drawLooseEdges)(DerivedMesh *dm);
@@ -372,7 +386,7 @@ struct DerivedMesh {
* Also called for *final* editmode DerivedMeshes
*/
void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4],
- int fast, DMSetMaterial setMaterial);
+ bool fast, DMSetMaterial setMaterial);
/** Draw all faces using MTFace
* - Drawing options too complicated to enumerate, look at code.
@@ -390,7 +404,7 @@ struct DerivedMesh {
/** Draw mapped faces (no color, or texture)
* - Only if !setDrawOptions or
- * setDrawOptions(userData, mapped-face-index, drawSmooth_r)
+ * setDrawOptions(userData, mapped-face-index, r_drawSmooth)
* returns true
*
* If drawSmooth is set to true then vertex normals should be set and
@@ -453,7 +467,7 @@ struct DerivedMesh {
* - setFace is called to verify if a face must be hidden
*/
void (*drawMappedFacesMat)(DerivedMesh *dm,
- void (*setMaterial)(void *userData, int, void *attribs),
+ void (*setMaterial)(void *userData, int matnr, void *attribs),
bool (*setFace)(void *userData, int index), void *userData);
/** Release reference to the DerivedMesh. This function decides internally
@@ -585,6 +599,7 @@ void DM_ensure_tessface(DerivedMesh *dm);
void DM_update_tessface_data(DerivedMesh *dm);
+void DM_update_materials(DerivedMesh *dm, struct Object *ob);
/** interpolates vertex data from the vertices indexed by src_indices in the
* source mesh using the given weights and stores the result in the vertex
* indexed by dest_index in the dest mesh
@@ -677,9 +692,9 @@ DerivedMesh *editbmesh_get_derived_base(struct Object *, struct BMEditMesh *em);
DerivedMesh *editbmesh_get_derived_cage(struct Scene *scene, struct Object *,
struct BMEditMesh *em, CustomDataMask dataMask);
DerivedMesh *editbmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *,
- struct BMEditMesh *em, DerivedMesh **final_r,
+ struct BMEditMesh *em, DerivedMesh **r_final,
CustomDataMask dataMask);
-float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *numVerts_r))[3];
+float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *r_numVerts))[3];
bool editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em,
CustomDataMask dataMask, int build_shapekey_layers);
@@ -754,4 +769,10 @@ BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int
return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE;
}
+struct MVert *DM_get_vert_array(struct DerivedMesh *dm, bool *allocated);
+struct MEdge *DM_get_edge_array(struct DerivedMesh *dm, bool *allocated);
+struct MLoop *DM_get_loop_array(struct DerivedMesh *dm, bool *allocated);
+struct MPoly *DM_get_poly_array(struct DerivedMesh *dm, bool *allocated);
+struct MFace *DM_get_tessface_array(struct DerivedMesh *dm, bool *allocated);
+
#endif /* __BKE_DERIVEDMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
index 739a4e3eee6..9c09fffe0a0 100644
--- a/source/blender/blenkernel/BKE_addon.h
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -36,7 +36,7 @@ typedef struct bAddonPrefType {
ExtensionRNA ext;
} bAddonPrefType;
-bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet);
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, bool quiet);
void BKE_addon_pref_type_add(bAddonPrefType *apt);
void BKE_addon_pref_type_remove(bAddonPrefType *apt);
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index e87fef1c864..e49fe98aa14 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -71,5 +71,17 @@ struct ListBase *object_duplilist(struct EvaluationContext *eval_ctx, struct Sce
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
-#endif
+typedef struct DupliExtraData {
+ float obmat[4][4];
+} DupliExtraData;
+
+typedef struct DupliApplyData {
+ int num_objects;
+ DupliExtraData *extra;
+} DupliApplyData;
+DupliApplyData *duplilist_apply_matrix(struct ListBase *duplilist);
+void duplilist_restore_matrix(struct ListBase *duplilist, DupliApplyData *apply_data);
+void duplilist_free_apply_data(DupliApplyData *apply_data);
+
+#endif
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 675c04453fb..a2ad8455666 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -48,7 +48,7 @@ struct AnimMapper;
/* AnimData API */
/* Check if the given ID-block can have AnimData */
-short id_type_can_have_animdata(struct ID *id);
+bool id_type_can_have_animdata(struct ID *id);
/* Get AnimData from the given ID-block */
struct AnimData *BKE_animdata_from_id(struct ID *id);
@@ -57,7 +57,7 @@ struct AnimData *BKE_animdata_from_id(struct ID *id);
struct AnimData *BKE_id_add_animdata(struct ID *id);
/* Set active action used by AnimData from the given ID-block */
-short BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act);
+bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act);
/* Free AnimData */
void BKE_free_animdata(struct ID *id);
@@ -66,7 +66,7 @@ void BKE_free_animdata(struct ID *id);
struct AnimData *BKE_copy_animdata(struct AnimData *adt, const bool do_action);
/* Copy AnimData */
-int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_action);
+bool BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
void BKE_copy_animdata_id_action(struct ID *id);
@@ -106,12 +106,12 @@ void BKE_keyingsets_free(struct ListBase *list);
/* Fix all the paths for the the given ID + Action */
void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, const char *prefix, const char *oldName,
- const char *newName, int oldSubscript, int newSubscript, int verify_paths);
+ const char *newName, int oldSubscript, int newSubscript, bool verify_paths);
/* Fix all the paths for the given ID+AnimData */
void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, struct ID *ref_id, const char *prefix,
const char *oldName, const char *newName, int oldSubscript, int newSubscript,
- int verify_paths);
+ bool verify_paths);
/* Fix all the paths for the entire database... */
void BKE_all_animdata_fix_paths_rename(struct ID *ref_id, const char *prefix, const char *oldName, const char *newName);
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 60e03af5077..85329753844 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -93,7 +93,7 @@ void BKE_armature_where_is(struct bArmature *arm);
void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone);
void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm);
void BKE_pose_where_is(struct Scene *scene, struct Object *ob);
-void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, int do_extra);
+void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
/* get_objectspace_bone_matrix has to be removed still */
@@ -111,8 +111,8 @@ void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4],
void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
-void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], short use_compat);
-void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], short use_comat);
+void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], bool use_compat);
+void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], bool use_comat);
void BKE_pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 960ca1b1d20..e4ebe0e0ed5 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,11 +41,11 @@ 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 269
-#define BLENDER_SUBVERSION 10
+#define BLENDER_VERSION 270
+#define BLENDER_SUBVERSION 5
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
-#define BLENDER_MINVERSION 262
-#define BLENDER_MINSUBVERSION 0
+#define BLENDER_MINVERSION 270
+#define BLENDER_MINSUBVERSION 5
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
@@ -99,7 +99,7 @@ extern int BKE_undo_valid(const char *name);
extern void BKE_reset_undo(void);
extern void BKE_undo_number(struct bContext *C, int nr);
extern const char *BKE_undo_get_name(int nr, int *active);
-extern int BKE_undo_save_file(const char *filename);
+extern bool BKE_undo_save_file(const char *filename);
extern struct Main *BKE_undo_get_main(struct Scene **scene);
/* copybuffer */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 66eddea716d..1abd09d3a0f 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -73,7 +73,7 @@ float BKE_brush_curve_strength(struct Brush *br, float p, const float len); /* u
/* sampling */
float BKE_brush_sample_tex_3D(const struct Scene *scene, struct Brush *br, const float point[3],
float rgba[4], const int thread, struct ImagePool *pool);
-float BKE_brush_sample_masktex(const struct Scene *scene, struct Brush *br, const float point[3],
+float BKE_brush_sample_masktex(const struct Scene *scene, struct Brush *br, const float point[2],
const int thread, struct ImagePool *pool);
/* texture */
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 49ba9c9d875..01b401c6bcc 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -69,7 +69,7 @@ float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y);
typedef struct CameraParams {
/* lens */
- int is_ortho;
+ bool is_ortho;
float lens;
float ortho_scale;
float zoom;
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 4e6d69503c0..dffc2b665c2 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -100,6 +100,8 @@ void CDDM_calc_normals_mapping(struct DerivedMesh *dm);
void CDDM_calc_normals(struct DerivedMesh *dm);
void CDDM_calc_normals_tessface(struct DerivedMesh *dm);
+void CDDM_calc_loop_normals(struct DerivedMesh *dm, const float split_angle);
+
/* calculates edges for a CDDerivedMesh (from face data)
* this completely replaces the current edge data in the DerivedMesh
* builds edges from the tessellated face data.
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 1e7ac2815b0..757d63e6ec1 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -80,7 +80,7 @@ typedef struct Cloth {
struct MFace *mfaces;
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */
- struct EdgeHash *edgehash; /* used for selfcollisions (currently used as a 'set', value is ignored) */
+ struct EdgeSet *edgeset; /* used for selfcollisions */
int last_frame, pad4;
} Cloth;
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index a69a9601c9a..9234625a37c 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -55,7 +55,7 @@ void curvemapping_set_black_white(struct CurveMapping *cumap, con
#define CURVEMAP_SLOPE_POSITIVE 1
void curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope);
void curvemap_remove(struct CurveMap *cuma, const short flag);
-int curvemap_remove_point(struct CurveMap *cuma, struct CurveMapPoint *cmp);
+bool curvemap_remove_point(struct CurveMap *cuma, struct CurveMapPoint *cmp);
struct CurveMapPoint *curvemap_insert(struct CurveMap *cuma, float x, float y);
void curvemap_sethandle(struct CurveMap *cuma, int type);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index c79dc62bb61..87da74dc119 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -62,7 +62,7 @@ typedef struct bConstraintOb {
/* ---------------------------------------------------------------------------- */
/* Callback format for performing operations on ID-pointers for Constraints */
-typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, short isReference, void *userdata);
+typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, bool is_reference, void *userdata);
/* ....... */
@@ -98,7 +98,7 @@ typedef struct bConstraintTypeInfo {
/* for multi-target constraints: return that list; otherwise make a temporary list (returns number of targets) */
int (*get_constraint_targets)(struct bConstraint *con, struct ListBase *list);
/* for single-target constraints only: flush data back to source data, and the free memory used */
- void (*flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, short nocopy);
+ void (*flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, bool no_copy);
/* evaluation */
/* set the ct->matrix for the given constraint target (at the given ctime) */
@@ -108,50 +108,44 @@ typedef struct bConstraintTypeInfo {
} bConstraintTypeInfo;
/* Function Prototypes for bConstraintTypeInfo's */
-bConstraintTypeInfo *BKE_constraint_get_typeinfo(struct bConstraint *con);
-bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type);
+bConstraintTypeInfo *BKE_constraint_typeinfo_get(struct bConstraint *con);
+bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type);
-/* ---------------------------------------------------------------------------- */
-/* Useful macros for testing various common flag combinations */
-
-/* Constraint Target Macros */
-#define VALID_CONS_TARGET(ct) ((ct) && (ct->tar))
/* ---------------------------------------------------------------------------- */
/* Constraint function prototypes */
-void BKE_unique_constraint_name(struct bConstraint *con, struct ListBase *list);
+void BKE_constraint_unique_name(struct bConstraint *con, struct ListBase *list);
-void BKE_free_constraints(struct ListBase *list);
-void BKE_copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
-void BKE_relink_constraints(struct ListBase *list);
-void BKE_id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
-void BKE_free_constraint_data(struct bConstraint *con);
+void BKE_constraints_free(struct ListBase *list);
+void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern);
+void BKE_constraints_relink(struct ListBase *list);
+void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata);
+void BKE_constraint_free_data(struct bConstraint *con);
/* Constraint API function prototypes */
-struct bConstraint *BKE_constraints_get_active(struct ListBase *list);
-void BKE_constraints_set_active(ListBase *list, struct bConstraint *con);
-struct bConstraint *BKE_constraints_findByName(struct ListBase *list, const char *name);
+struct bConstraint *BKE_constraints_active_get(struct ListBase *list);
+void BKE_constraints_active_set(ListBase *list, struct bConstraint *con);
+struct bConstraint *BKE_constraints_find_name(struct ListBase *list, const char *name);
-struct bConstraint *BKE_add_ob_constraint(struct Object *ob, const char *name, short type);
-struct bConstraint *BKE_add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
+struct bConstraint *BKE_constraint_add_for_object(struct Object *ob, const char *name, short type);
+struct bConstraint *BKE_constraint_add_for_pose(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
-int BKE_remove_constraint(ListBase *list, struct bConstraint *con);
-void BKE_remove_constraints_type(ListBase *list, short type, short last_only);
+bool BKE_constraint_remove(ListBase *list, struct bConstraint *con);
/* Constraints + Proxies function prototypes */
-void BKE_extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
-short BKE_proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
+void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src);
+bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
-void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
+void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
-void BKE_get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
-void BKE_get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
-void BKE_solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+void BKE_constraint_target_matrix_get(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
+void BKE_constraint_targets_for_solving_get(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
+void BKE_constraints_solve(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 2834a37ca7a..e30c8ecee2b 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -185,7 +185,7 @@ enum {
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
ListBase CTX_data_collection_get(const bContext *C, const char *member);
-ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all);
+ListBase CTX_data_dir_get_ex(const bContext *C, const bool use_store, const bool use_rna, const bool use_all);
ListBase CTX_data_dir_get(const bContext *C);
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type);
@@ -234,6 +234,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
struct Main *CTX_data_main(const bContext *C);
struct Scene *CTX_data_scene(const bContext *C);
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
+struct FreestyleLineStyle *CTX_data_linestyle_from_scene(struct Scene *scene);
const char *CTX_data_mode_string(const bContext *C);
int CTX_data_mode_enum(const bContext *C);
diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h
new file mode 100644
index 00000000000..feed1594d90
--- /dev/null
+++ b/source/blender/blenkernel/BKE_crazyspace.h
@@ -0,0 +1,54 @@
+/*
+ * ***** 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) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BKE_crazyspace.h
+ * \ingroup bke
+ */
+
+#ifndef __BKE_CRAZYSPACE_H__
+#define __BKE_CRAZYSPACE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct Scene;
+struct Object;
+struct BMEditMesh;
+struct Mesh;
+
+/* crazyspace.c */
+float (*BKE_crazyspace_get_mapped_editverts(struct Scene *scene, struct Object *obedit))[3];
+void BKE_crazyspace_set_quats_editmesh(struct BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4],
+ const bool use_select);
+void BKE_crazyspace_set_quats_mesh(struct Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4]);
+int BKE_sculpt_get_first_deform_matrices(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
+void BKE_crazyspace_build_sculpt(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 850c387cd45..0f9f8cb2f08 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -43,6 +43,8 @@ struct Nurb;
struct Object;
struct Scene;
struct Path;
+struct TextBox;
+struct rctf;
typedef struct CurveCache {
ListBase disp;
@@ -95,7 +97,7 @@ void BKE_curve_nurb_vert_active_set(struct Curve *cu, struct Nurb *nu,
bool BKE_curve_nurb_vert_active_get(struct Curve *cu, struct Nurb **r_nu, void **r_vert);
void BKE_curve_nurb_vert_active_validate(struct Curve *cu);
-float (*BKE_curve_nurbs_vertexCos_get(struct ListBase *lb, int *numVerts_r))[3];
+float (*BKE_curve_nurbs_vertexCos_get(struct ListBase *lb, int *r_numVerts))[3];
void BK_curve_nurbs_vertexCos_apply(struct ListBase *lb, float (*vertexCos)[3]);
float (*BKE_curve_nurbs_keyVertexCos_get(struct ListBase *lb, float *key))[3];
@@ -109,20 +111,23 @@ float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob, int *r_numVer
float *BKE_curve_surf_make_orco(struct Object *ob);
void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
-void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp, int forRender, int renderResolution);
+void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp,
+ const bool for_render, const bool use_render_resolution);
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
+void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect);
+
/* ** Nurbs ** */
-int BKE_nurbList_index_get_co(struct ListBase *editnurb, const int index, float r_co[3]);
+bool BKE_nurbList_index_get_co(struct ListBase *editnurb, const int index, float r_co[3]);
int BKE_nurbList_verts_count(struct ListBase *nurb);
int BKE_nurbList_verts_count_without_handles(struct ListBase *nurb);
void BKE_nurbList_free(struct ListBase *lb);
void BKE_nurbList_duplicate(struct ListBase *lb1, struct ListBase *lb2);
-void BKE_nurbList_handles_set(struct ListBase *editnurb, short code);
+void BKE_nurbList_handles_set(struct ListBase *editnurb, const char code);
void BKE_nurbList_handles_recalculate(struct ListBase *editnurb, const bool calc_length, const char flag);
void BKE_nurbList_handles_autocalc(ListBase *editnurb, int flag);
@@ -144,6 +149,7 @@ void BKE_nurb_knot_calc_v(struct Nurb *nu);
/* nurb checks if they can be drawn, also clamp order func */
bool BKE_nurb_check_valid_u(struct Nurb *nu);
bool BKE_nurb_check_valid_v(struct Nurb *nu);
+bool BKE_nurb_check_valid_uv(struct Nurb *nu);
bool BKE_nurb_order_clamp_u(struct Nurb *nu);
bool BKE_nurb_order_clamp_v(struct Nurb *nu);
@@ -162,7 +168,8 @@ struct BPoint *BKE_nurb_bpoint_get_prev(struct Nurb *nu, struct BPoint *bp);
void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_normal[3]);
void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
-void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode);
+void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next,
+ const bool is_fcurve);
void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
void BKE_nurb_handles_calc(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 8a0f9f3fa67..58903b76a15 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -106,7 +106,7 @@ void DAG_scene_free(struct Scene *sce);
* not cause any updates but is used by external render engines to detect if for
* example a datablock was removed. */
-void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const bool do_time);
+void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const bool do_time, const bool do_invisible_flush);
void DAG_on_visible_update(struct Main *bmain, const bool do_time);
void DAG_id_tag_update(struct ID *id, short flag);
@@ -127,7 +127,7 @@ int DAG_id_type_tagged(struct Main *bmain, short idtype);
void DAG_scene_flush_update(struct Main *bmain, struct Scene *sce, unsigned int lay, const short do_time);
void DAG_ids_flush_tagged(struct Main *bmain);
-void DAG_ids_check_recalc(struct Main *bmain, struct Scene *scene, int time);
+void DAG_ids_check_recalc(struct Main *bmain, struct Scene *scene, bool time);
void DAG_ids_clear_recalc(struct Main *bmain);
/* Armature: sorts the bones according to dependencies between them */
@@ -157,7 +157,7 @@ void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Obje
/* ************************ DAG querying ********************* */
struct Object *DAG_get_node_object(void *node_v);
-const char *DAG_get_node_name(void *node_v);
+const char *DAG_get_node_name(struct Scene *scene, void *node_v);
short DAG_get_eval_flags_for_object(struct Scene *scene, void *object);
bool DAG_is_acyclic(struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 960b7adb9e5..7c5ad810dcb 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -88,9 +88,11 @@ void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *to
void BKE_displist_free(struct ListBase *lb);
bool BKE_displist_has_faces(struct ListBase *lb);
-void BKE_displist_make_surf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution);
-void BKE_displist_make_curveTypes(struct Scene *scene, struct Object *ob, int forOrco);
-void BKE_displist_make_curveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forOrco, int renderResolution);
+void BKE_displist_make_surf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution);
+void BKE_displist_make_curveTypes(struct Scene *scene, struct Object *ob, const bool for_orco);
+void BKE_displist_make_curveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **r_dm_final,
+ const bool for_orco, const bool use_render_resolution);
void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
void BKE_displist_make_mball(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
void BKE_displist_make_mball_forRender(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
@@ -101,7 +103,8 @@ void BKE_displist_fill(struct ListBase *dispbase, struct ListBase *to, const flo
float BKE_displist_calc_taper(struct Scene *scene, struct Object *taperobj, int cur, int tot);
/* add Orco layer to the displist object which has got derived mesh and return orco */
-float *BKE_displist_make_orco(struct Scene *scene, struct Object *ob, struct DerivedMesh *derivedFinal, int forRender, int renderResolution);
+float *BKE_displist_make_orco(struct Scene *scene, struct Object *ob, struct DerivedMesh *dm_final,
+ const bool for_render, const bool use_render_resolution);
void BKE_displist_minmax(struct ListBase *dispbase, float min[3], float max[3]);
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 310807370da..38c8cf12969 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -87,6 +87,7 @@ void BKE_editmesh_tessface_calc(BMEditMesh *em);
BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate);
BMEditMesh *BKE_editmesh_copy(BMEditMesh *em);
BMEditMesh *BKE_editmesh_from_object(struct Object *ob);
+void BKE_editmesh_free_derivedmesh(BMEditMesh *em);
void BKE_editmesh_free(BMEditMesh *em);
void BKE_editmesh_update_linked_customdata(BMEditMesh *em);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 13eca506d9e..0e86be9b97c 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -197,7 +197,10 @@ int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int
/* ************** F-Curves API ******************** */
-/* -------- Data Managemnt -------- */
+/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
+#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
+
+/* -------- Data Management -------- */
void free_fcurve(struct FCurve *fcu);
struct FCurve *copy_fcurve(struct FCurve *fcu);
@@ -250,7 +253,7 @@ void testhandles_fcurve(struct FCurve *fcu, const bool use_handle);
void sort_time_fcurve(struct FCurve *fcu);
short test_time_fcurve(struct FCurve *fcu);
-void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
+void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2]);
/* -------- Evaluation -------- */
diff --git a/source/blender/blenkernel/BKE_freestyle.h b/source/blender/blenkernel/BKE_freestyle.h
index 84a4bc255af..a3fcdd667e8 100644
--- a/source/blender/blenkernel/BKE_freestyle.h
+++ b/source/blender/blenkernel/BKE_freestyle.h
@@ -38,6 +38,11 @@
extern "C" {
#endif
+struct FreestyleConfig;
+struct FreestyleSettings;
+struct FreestyleLineSet;
+struct FreestyleModuleConfig;
+
/* FreestyleConfig */
void BKE_freestyle_config_init(FreestyleConfig *config);
void BKE_freestyle_config_free(FreestyleConfig *config);
@@ -50,7 +55,8 @@ void BKE_freestyle_module_move_up(FreestyleConfig *config, FreestyleModuleConfig
void BKE_freestyle_module_move_down(FreestyleConfig *config, FreestyleModuleConfig *module_conf);
/* FreestyleConfig.linesets */
-FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config);
+FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config, const char *name);
+bool BKE_freestyle_lineset_delete(FreestyleConfig *config, FreestyleLineSet *lineset);
FreestyleLineSet *BKE_freestyle_lineset_get_active(FreestyleConfig *config);
short BKE_freestyle_lineset_get_active_index(FreestyleConfig *config);
void BKE_freestyle_lineset_set_active_index(FreestyleConfig *config, short index);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 9494e36099c..a3a0f3516de 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -197,8 +197,6 @@ enum {
#define G_TRANSFORM_SEQ 4
#define G_TRANSFORM_FCURVES 8
-/* G.special1 */
-
/* Memory is allocated where? blender.c */
extern Global G;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index e36d4bab566..db052f5d879 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -60,9 +60,11 @@ void BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char
bool BKE_imbuf_alpha_test(struct ImBuf *ibuf);
int BKE_imbuf_write_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
-int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const short is_copy);
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, const short use_ext, const short use_frames);
-void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
+int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const bool is_copy);
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame,
+ const struct ImageFormatData *im_format, const bool use_ext, const bool use_frames);
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame,
+ const char imtype, const bool use_ext, const bool use_frames);
int BKE_add_image_extension(char *string, const struct ImageFormatData *im_format);
int BKE_add_image_extension_from_type(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
@@ -73,7 +75,7 @@ int BKE_imtype_supports_zbuf(const char imtype);
int BKE_imtype_supports_compress(const char imtype);
int BKE_imtype_supports_quality(const char imtype);
int BKE_imtype_requires_linear_float(const char imtype);
-char BKE_imtype_valid_channels(const char imtype);
+char BKE_imtype_valid_channels(const char imtype, bool write_file);
char BKE_imtype_valid_depths(const char imtype);
char BKE_imtype_from_arg(const char *arg);
@@ -162,7 +164,8 @@ struct Image *BKE_image_load(struct Main *bmain, const char *filepath);
struct Image *BKE_image_load_exists(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]);
+struct Image *BKE_image_add_generated(
+ struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 29d3673e2f0..8d8d3702634 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -59,10 +59,10 @@ void end_latt_deform(struct LatticeDeformData *lattice_deform_data);
bool object_deform_mball(struct Object *ob, struct ListBase *dispbase);
void outside_lattice(struct Lattice *lt);
-void curve_deform_verts(struct Object *cuOb, struct Object *target,
+void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target,
struct DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis);
-void curve_deform_vector(struct Object *cuOb, struct Object *target,
+void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target,
float orco[3], float vec[3], float mat[3][3], int no_rot_axis);
void lattice_deform_verts(struct Object *laOb, struct Object *target,
@@ -73,7 +73,7 @@ void armature_deform_verts(struct Object *armOb, struct Object *target,
float (*defMats)[3][3], int numVerts, int deformflag,
float (*prevCos)[3], const char *defgrp_name);
-float (*BKE_lattice_vertexcos_get(struct Object *ob, int *numVerts_r))[3];
+float (*BKE_lattice_vertexcos_get(struct Object *ob, int *r_numVerts))[3];
void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3]);
void BKE_lattice_modifiers_calc(struct Scene *scene, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 0a2ce0d3801..55c71ff49cf 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -49,6 +49,7 @@ struct PropertyRNA;
void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL();
void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
@@ -102,13 +103,6 @@ void BKE_library_make_local(struct Main *bmain, struct Library *lib, bool untagg
struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-#if 0
-void IDnames_to_pupstring(const char **str, const char *title, const char *extraops,
- struct ListBase *lb, struct ID *link, short *nr);
-void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops,
- struct ListBase *lb, struct ID *link, short *nr);
-#endif
-
void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
void set_free_notifier_reference_cb(void (*func)(const void *) );
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h
new file mode 100644
index 00000000000..50958f8ee80
--- /dev/null
+++ b/source/blender/blenkernel/BKE_library_query.h
@@ -0,0 +1,57 @@
+/*
+ * ***** 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 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey SHarybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_LIBRARY_QUERY_H__
+#define __BKE_LIBRARY_QUERY_H__
+
+/** \file BKE_library_query.h
+ * \ingroup bke
+ * \since March 2014
+ * \author sergey
+ */
+
+struct ID;
+
+/* Tips for the callback for cases it's gonna to modify the pointer. */
+enum {
+ IDWALK_NOP = 0,
+ IDWALK_NEVER_NULL = (1 << 0),
+ IDWALK_NEVER_SELF = (1 << 1),
+};
+
+/* Call a callback for each ID link which the given ID uses.
+ *
+ * Return 'false' if you want to stop iteration.
+ */
+typedef bool (*LibraryIDLinkCallback) (void *user_data, struct ID **id_pointer, int cd_flag);
+
+/* Flags for the foreach function itself. */
+enum {
+ IDWALK_READONLY = (1 << 0),
+};
+
+/* Loop over all of the ID's this datablock links to. */
+void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
+
+#endif /* __BKE_LIBRARY_QUERY_H__ */
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 691afaf8f16..3db4d9e7324 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -47,6 +47,20 @@ struct MovieClip;
struct MovieClipUser;
struct Scene;
+/* mask_ops.c */
+typedef enum {
+ MASK_WHICH_HANDLE_NONE = 0,
+ MASK_WHICH_HANDLE_STICK = 1,
+ MASK_WHICH_HANDLE_LEFT = 2,
+ MASK_WHICH_HANDLE_RIGHT = 3,
+ MASK_WHICH_HANDLE_BOTH = 4,
+} eMaskWhichHandle;
+
+typedef enum {
+ MASK_HANDLE_MODE_STICK = 1,
+ MASK_HANDLE_MODE_INDIVIDUAL_HANDLES = 2,
+} eMaskhandleMode;
+
struct MaskSplinePoint *BKE_mask_spline_point_array(struct MaskSpline *spline);
struct MaskSplinePoint *BKE_mask_spline_point_array_from_point(struct MaskSpline *spline, struct MaskSplinePoint *point_ref);
@@ -87,9 +101,9 @@ float BKE_mask_spline_project_co(struct MaskSpline *spline, struct MaskSplinePoi
float start_u, const float co[2], const eMaskSign sign);
/* point */
-bool BKE_mask_point_has_handle(struct MaskSplinePoint *point);
-void BKE_mask_point_handle(struct MaskSplinePoint *point, float handle[2]);
-void BKE_mask_point_set_handle(struct MaskSplinePoint *point, float loc[2], bool keep_direction,
+eMaskhandleMode BKE_mask_point_handles_mode_get(struct MaskSplinePoint *point);
+void BKE_mask_point_handle(struct MaskSplinePoint *point, eMaskWhichHandle which_handle, float handle[2]);
+void BKE_mask_point_set_handle(struct MaskSplinePoint *point, eMaskWhichHandle which_handle, float loc[2], bool keep_direction,
float orig_handle[2], float orig_vec[3][3]);
void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2]);
@@ -101,7 +115,7 @@ struct MaskSplinePointUW *BKE_mask_point_sort_uw(struct MaskSplinePoint *point,
void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w);
void BKE_mask_point_select_set(struct MaskSplinePoint *point, const bool do_select);
-void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const bool do_select);
+void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMaskWhichHandle which_handle, const bool do_select);
/* general */
struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
@@ -174,18 +188,20 @@ void BKE_mask_clipboard_copy_from_layer(struct MaskLayer *mask_layer);
bool BKE_mask_clipboard_is_empty(void);
void BKE_mask_clipboard_paste_to_layer(struct Main *bmain, struct MaskLayer *mask_layer);
-#define MASKPOINT_ISSEL_ANY(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f3) & SELECT)
-#define MASKPOINT_ISSEL_KNOT(p) ( (p)->bezt.f2 & SELECT)
-#define MASKPOINT_ISSEL_HANDLE_ONLY(p) ( (((p)->bezt.f1 | (p)->bezt.f3) & SELECT) && (((p)->bezt.f2 & SELECT) == 0) )
-#define MASKPOINT_ISSEL_HANDLE(p) ( (((p)->bezt.f1 | (p)->bezt.f3) & SELECT) )
+#define MASKPOINT_ISSEL_ANY(p) (( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f3) & SELECT) != 0)
+#define MASKPOINT_ISSEL_KNOT(p) (( (p)->bezt.f2 & SELECT) != 0)
+
+#define MASKPOINT_ISSEL_HANDLE(point, which_handle) \
+ (((which_handle == MASK_WHICH_HANDLE_STICK) ? \
+ ((((point)->bezt.f1 | (point)->bezt.f3) & SELECT)) : \
+ ((which_handle == MASK_WHICH_HANDLE_LEFT) ? \
+ ((point)->bezt.f1 & SELECT) : \
+ ((point)->bezt.f3 & SELECT))) != 0)
#define MASKPOINT_SEL_ALL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0
#define MASKPOINT_DESEL_ALL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0
#define MASKPOINT_INVSEL_ALL(p) { (p)->bezt.f1 ^= SELECT; (p)->bezt.f2 ^= SELECT; (p)->bezt.f3 ^= SELECT; } (void)0
-#define MASKPOINT_SEL_HANDLE(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0
-#define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0
-
#define MASK_RESOL_MAX 128
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index c866fbb7b13..89d310753fc 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -83,8 +83,8 @@ void assign_matarar(struct Object *ob, struct Material ***matar, short totcol);
short find_material_index(struct Object *ob, struct Material *ma);
-int object_add_material_slot(struct Object *ob);
-int object_remove_material_slot(struct Object *ob);
+bool object_add_material_slot(struct Object *ob);
+bool object_remove_material_slot(struct Object *ob);
/* rna api */
void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user);
@@ -98,7 +98,7 @@ void init_render_materials(struct Main *, int, float *);
void end_render_material(struct Material *);
void end_render_materials(struct Main *);
-int material_in_material(struct Material *parmat, struct Material *mat);
+bool material_in_material(struct Material *parmat, struct Material *mat);
void ramp_blend(int type, float r_col[3], const float fac, const float col[3]);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 7b1f39ab643..587dea5095c 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -79,7 +79,7 @@ int poly_find_loop_from_vert(const struct MPoly *poly,
const struct MLoop *loopstart,
unsigned vert);
-int poly_get_adj_loops_from_vert(unsigned adj_r[3], const struct MPoly *poly,
+int poly_get_adj_loops_from_vert(unsigned r_adj[3], const struct MPoly *poly,
const struct MLoop *mloop, unsigned vert);
int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
@@ -90,6 +90,7 @@ struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
struct Mesh *BKE_mesh_copy_ex(struct Main *bmain, struct Mesh *me);
struct Mesh *BKE_mesh_copy(struct Mesh *me);
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
+void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
void BKE_mesh_make_local(struct Mesh *me);
void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
@@ -126,6 +127,9 @@ bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const cha
float (*BKE_mesh_vertexCos_get(struct Mesh *me, int *r_numVerts))[3];
+struct Mesh *BKE_mesh_new_from_object(struct Main *bmain, struct Scene *sce, struct Object *ob,
+ int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
+
/* vertex level transformations & checks (no derived mesh) */
bool BKE_mesh_minmax(struct Mesh *me, float r_min[3], float r_max[3]);
@@ -152,23 +156,23 @@ void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
void BKE_mesh_calc_normals_mapping(
struct MVert *mverts, int numVerts,
- struct MLoop *mloop, struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3],
- struct MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3]);
+ struct MLoop *mloop, struct MPoly *mpolys, int numLoops, int numPolys, float (*r_polyNors)[3],
+ struct MFace *mfaces, int numFaces, const int *origIndexFace, float (*r_faceNors)[3]);
void BKE_mesh_calc_normals_mapping_ex(
struct MVert *mverts, int numVerts,
- struct MLoop *mloop, struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3],
- struct MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3],
+ struct MLoop *mloop, struct MPoly *mpolys, int numLoops, int numPolys, float (*r_polyNors)[3],
+ struct MFace *mfaces, int numFaces, const int *origIndexFace, float (*r_faceNors)[3],
const bool only_face_normals);
void BKE_mesh_calc_normals_poly(
struct MVert *mverts, int numVerts,
struct MLoop *mloop, struct MPoly *mpolys,
- int numLoops, int numPolys, float (*polyNors_r)[3],
+ int numLoops, int numPolys, float (*r_polyNors)[3],
const bool only_face_normals);
void BKE_mesh_calc_normals(struct Mesh *me);
void BKE_mesh_calc_normals_tessface(
struct MVert *mverts, int numVerts,
struct MFace *mfaces, int numFaces,
- float (*faceNors_r)[3]);
+ float (*r_faceNors)[3]);
void BKE_mesh_normals_loop_split(
struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
@@ -191,7 +195,7 @@ void BKE_mesh_calc_poly_center(
struct MVert *mvarray, float cent[3]);
float BKE_mesh_calc_poly_area(
struct MPoly *mpoly, struct MLoop *loopstart,
- struct MVert *mvarray, const float polynormal[3]);
+ struct MVert *mvarray);
void BKE_mesh_calc_poly_angles(
struct MPoly *mpoly, struct MLoop *loopstart,
struct MVert *mvarray, float angles[]);
@@ -214,7 +218,7 @@ void BKE_mesh_loops_to_mface_corners(
struct CustomData *pdata, unsigned int lindex[4], int findex,
const int polyindex, const int mf_len,
const int numTex, const int numCol,
- const bool hasPCol, const bool hasOrigSpace);
+ const bool hasPCol, const bool hasOrigSpace, const bool hasLNor);
void BKE_mesh_loops_to_tessdata(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
@@ -233,8 +237,8 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata,
int totedge_i, int totface_i, int totloop_i, int totpoly_i,
struct MEdge *medge, struct MFace *mface,
- int *totloop_r, int *totpoly_r,
- struct MLoop **mloop_r, struct MPoly **mpoly_r);
+ int *r_totloop, int *r_totpoly,
+ struct MLoop **r_mloop, struct MPoly **r_mpoly);
/* flush flags */
void BKE_mesh_flush_hidden_from_verts_ex(
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 25dee613d20..3b2bafa799f 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -345,7 +345,7 @@ struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type)
struct ModifierData *modifiers_findByName(struct Object *ob, const char *name);
void modifiers_clearErrors(struct Object *ob);
int modifiers_getCageIndex(struct Scene *scene, struct Object *ob,
- int *lastPossibleCageIndex_r, int virtual_);
+ int *r_lastPossibleCageIndex, bool is_virtual);
bool modifiers_isModifierEnabled(struct Object *ob, int modifierType);
bool modifiers_isSoftbodyEnabled(struct Object *ob);
@@ -359,7 +359,6 @@ bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
bool modifiers_isPreview(struct Object *ob);
-void modifier_skin_customdata_ensure(struct Object *ob);
typedef struct CDMaskLink {
struct CDMaskLink *next;
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 344797dd15a..0c29179aa1c 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -47,8 +47,8 @@ void free_nlastrip(ListBase *strips, struct NlaStrip *strip);
void free_nlatrack(ListBase *tracks, struct NlaTrack *nlt);
void free_nladata(ListBase *tracks);
-struct NlaStrip *copy_nlastrip(struct NlaStrip *strip);
-struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt);
+struct NlaStrip *copy_nlastrip(struct NlaStrip *strip, const bool use_same_action);
+struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt, const bool use_same_actions);
void copy_nladata(ListBase *dst, ListBase *src);
struct NlaTrack *add_nlatrack(struct AnimData *adt, struct NlaTrack *prev);
@@ -62,13 +62,13 @@ struct NlaStrip *add_nla_soundstrip(struct Scene *scene, struct Speaker *spk);
bool BKE_nlastrips_has_space(ListBase *strips, float start, float end);
void BKE_nlastrips_sort_strips(ListBase *strips);
-short BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
+bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
-void BKE_nlastrips_make_metas(ListBase *strips, short temp);
-void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp);
+void BKE_nlastrips_make_metas(ListBase *strips, bool is_temp);
+void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp);
void BKE_nlastrips_clear_metastrip(ListBase *strips, struct NlaStrip *strip);
-short BKE_nlameta_add_strip(struct NlaStrip *mstrip, struct NlaStrip *strip);
+bool BKE_nlameta_add_strip(struct NlaStrip *mstrip, struct NlaStrip *strip);
void BKE_nlameta_flush_transforms(struct NlaStrip *mstrip);
/* ............ */
@@ -81,24 +81,24 @@ void BKE_nlatrack_solo_toggle(struct AnimData *adt, struct NlaTrack *nlt);
bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
-short BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip);
+bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip);
-short BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]);
+bool BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]);
/* ............ */
struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
-short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
+bool BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
/* ............ */
-short BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt);
-short BKE_nlatracks_have_animated_strips(ListBase *tracks);
+bool BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt);
+bool BKE_nlatracks_have_animated_strips(ListBase *tracks);
void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip);
void BKE_nla_validate_state(struct AnimData *adt);
@@ -107,7 +107,7 @@ void BKE_nla_validate_state(struct AnimData *adt);
void BKE_nla_action_pushdown(struct AnimData *adt);
-short BKE_nla_tweakmode_enter(struct AnimData *adt);
+bool BKE_nla_tweakmode_enter(struct AnimData *adt);
void BKE_nla_tweakmode_exit(struct AnimData *adt);
/* ----------------------------- */
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 59ea921e11e..13a32ee1528 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -44,6 +44,7 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "RNA_types.h"
@@ -459,7 +460,7 @@ void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry);
void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry);
-int nodeAttachNodeCheck(struct bNode *node, struct bNode *parent);
+bool nodeAttachNodeCheck(struct bNode *node, struct bNode *parent);
void nodeAttachNode(struct bNode *node, struct bNode *parent);
void nodeDetachNode(struct bNode *node);
@@ -469,7 +470,7 @@ int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock,
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to);
int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
-void nodeSetSelected(struct bNode *node, int select);
+void nodeSetSelected(struct bNode *node, bool select);
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node);
struct bNode *nodeGetActive(struct bNodeTree *ntree);
struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
@@ -520,7 +521,7 @@ int BKE_node_instance_hash_size(bNodeInstanceHash *hash);
void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash);
void BKE_node_instance_hash_tag(bNodeInstanceHash *hash, void *value);
-int BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key);
+bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key);
void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp);
typedef GHashIterator bNodeInstanceHashIterator;
@@ -542,7 +543,7 @@ BLI_INLINE bool BKE_node_instance_hash_iterator_done(bNode
/* Node Previews */
int BKE_node_preview_used(struct bNode *node);
-bNodePreview *BKE_node_preview_verify(struct bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, int create);
+bNodePreview *BKE_node_preview_verify(struct bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create);
bNodePreview *BKE_node_preview_copy(struct bNodePreview *preview);
void BKE_node_preview_free(struct bNodePreview *preview);
void BKE_node_preview_init_tree(struct bNodeTree *ntree, int xsize, int ysize, int create_previews);
@@ -632,6 +633,7 @@ struct NodeTreeIterStore {
Tex *tex;
Lamp *lamp;
World *world;
+ FreestyleLineStyle *linestyle;
};
void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain);
@@ -744,6 +746,7 @@ struct ShadeResult;
#define SH_NODE_COMBHSV 184
#define SH_NODE_BSDF_HAIR 185
#define SH_NODE_LAMP 186
+#define SH_NODE_UVMAP 187
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
@@ -897,6 +900,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
#define CMP_NODE_MAP_RANGE 319
#define CMP_NODE_PLANETRACKDEFORM 320
+#define CMP_NODE_CORNERPIN 321
/* channel toggles */
#define CMP_CHAN_RGB 1
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 72c4c21d587..c0da816ca59 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -55,7 +55,7 @@ void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
-struct SoftBody *copy_softbody(struct SoftBody *sb, int copy_caches);
+struct SoftBody *copy_softbody(struct SoftBody *sb, bool copy_caches);
struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
void BKE_object_copy_particlesystems(struct Object *obn, struct Object *ob);
void BKE_object_copy_softbody(struct Object *obn, struct Object *ob);
@@ -92,12 +92,12 @@ void *BKE_object_obdata_add_from_type(struct Main *bmain, int type);
void BKE_object_lod_add(struct Object *ob);
void BKE_object_lod_sort(struct Object *ob);
bool BKE_object_lod_remove(struct Object *ob, int level);
-bool BKE_object_lod_update(struct Object *ob, float camera_position[3]);
+void BKE_object_lod_update(struct Object *ob, const float camera_position[3]);
bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene);
struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene);
struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
-struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
+struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches);
struct Object *BKE_object_copy(struct Object *ob);
void BKE_object_make_local(struct Object *ob);
bool BKE_object_is_libdata(struct Object *ob);
@@ -129,7 +129,7 @@ bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], c
struct BoundBox *BKE_object_boundbox_get(struct Object *ob);
void BKE_object_dimensions_get(struct Object *ob, float vec[3]);
-void BKE_object_dimensions_set(struct Object *ob, const float *value);
+void BKE_object_dimensions_set(struct Object *ob, const float value[3]);
void BKE_object_empty_draw_type_set(struct Object *ob, const int value);
void BKE_object_boundbox_flag(struct Object *ob, int flag, int set);
void BKE_object_minmax(struct Object *ob, float r_min[3], float r_max[3], const bool use_hidden);
@@ -167,7 +167,8 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx,
struct Scene *scene, struct Object *ob,
- struct RigidBodyWorld *rbw);
+ struct RigidBodyWorld *rbw,
+ const bool do_proxy_update);
void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 2f166dd2dac..0061280684f 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -47,6 +47,7 @@ struct Object;
struct Paint;
struct PBVH;
struct Scene;
+struct Sculpt;
struct StrokeCache;
struct Tex;
struct ImagePool;
@@ -103,8 +104,9 @@ void BKE_paint_brush_set(struct Paint *paint, struct Brush *br);
/* testing face select mode
* Texture paint could be removed since selected faces are not used
* however hiding faces is useful */
-bool paint_facesel_test(struct Object *ob);
-bool paint_vertsel_test(struct Object *ob);
+bool BKE_paint_select_face_test(struct Object *ob);
+bool BKE_paint_select_vert_test(struct Object *ob);
+bool BKE_paint_select_elem_test(struct Object *ob);
/* partial visibility */
bool paint_is_face_hidden(const struct MFace *f, const struct MVert *mvert);
@@ -125,7 +127,7 @@ typedef struct SculptSession {
struct MPoly *mpoly;
struct MLoop *mloop;
int totvert, totpoly;
- float *face_normals;
+ float (*face_normals)[3];
struct KeyBlock *kb;
float *vmask;
@@ -134,7 +136,9 @@ typedef struct SculptSession {
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
- int bm_smooth_shading;
+ int cd_vert_node_offset;
+ int cd_face_node_offset;
+ bool bm_smooth_shading;
/* Undo/redo log for dynamic topology sculpting */
struct BMLog *bm_log;
@@ -143,13 +147,13 @@ typedef struct SculptSession {
bool show_diffuse_color;
/* Paiting on deformed mesh */
- int modifiers_active; /* object is deformed with some modifiers */
+ bool modifiers_active; /* object is deformed with some modifiers */
float (*orig_cos)[3]; /* coords of undeformed mesh */
float (*deform_cos)[3]; /* coords of deformed mesh but without stroke displacement */
float (*deform_imats)[3][3]; /* crazyspace deformation matrices */
/* Partial redraw */
- int partial_redraw;
+ bool partial_redraw;
/* Used to cache the render of the active texture */
unsigned int texcache_side, *texcache, texcache_actual;
@@ -162,15 +166,25 @@ typedef struct SculptSession {
struct StrokeCache *cache;
/* last paint/sculpt stroke location */
- int last_stroke_valid;
+ bool last_stroke_valid;
float last_stroke[3];
float average_stroke_accum[3];
int average_stroke_counter;
} SculptSession;
-void free_sculptsession(struct Object *ob);
-void free_sculptsession_deformMats(struct SculptSession *ss);
-void sculptsession_bm_to_me(struct Object *ob, int reorder);
-void sculptsession_bm_to_me_for_render(struct Object *object);
+void BKE_free_sculptsession(struct Object *ob);
+void BKE_free_sculptsession_deformMats(struct SculptSession *ss);
+void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
+void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
+void BKE_sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
+ bool need_pmap, bool need_mask);
+struct MultiresModifierData *BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob);
+int BKE_sculpt_mask_layers_ensure(struct Object *ob,
+ struct MultiresModifierData *mmd);
+
+enum {
+ SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
+ SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1)
+};
#endif
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index b6be72fadd3..6b8e50494c7 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -34,6 +34,8 @@
* \ingroup bke
*/
+#include "BLI_utildefines.h"
+
#include "DNA_particle_types.h"
#include "DNA_object_types.h"
@@ -70,9 +72,6 @@ struct EdgeHash;
/* OpenMP: Can only advance one variable within loop definition. */
#define LOOP_DYNAMIC_PARTICLES for (p = 0; p < psys->totpart; p++) if ((pa = psys->particles + p)->state.time > 0.0f)
-#define PSYS_FRAND_COUNT 1024
-#define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT]
-
/* fast but sure way to get the modifier*/
#define PARTICLE_PSMD ParticleSystemModifierData * psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
@@ -247,6 +246,34 @@ typedef struct ParticleDrawData {
#define PARTICLE_DRAW_DATA_UPDATED 1
+#define PSYS_FRAND_COUNT 1024
+extern unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+extern unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+extern float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
+
+void psys_init_rng(void);
+
+BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
+{
+ /* XXX far from ideal, this simply scrambles particle random numbers a bit
+ * to avoid obvious correlations.
+ * Can't use previous psys->frand arrays because these require initialization
+ * inside psys_check_enabled, which wreaks havok in multithreaded depgraph updates.
+ */
+ unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+ unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+ return PSYS_FRAND_BASE[(offset + seed * multiplier) % PSYS_FRAND_COUNT];
+}
+
+BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float vec[3])
+{
+ unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+ unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+ vec[0] = PSYS_FRAND_BASE[(offset + (seed + 0) * multiplier) % PSYS_FRAND_COUNT];
+ vec[1] = PSYS_FRAND_BASE[(offset + (seed + 1) * multiplier) % PSYS_FRAND_COUNT];
+ vec[2] = PSYS_FRAND_BASE[(offset + (seed + 2) * multiplier) % PSYS_FRAND_COUNT];
+}
+
/* ----------- functions needed outside particlesystem ---------------- */
/* particle.c */
int count_particles(struct ParticleSystem *psys);
@@ -276,7 +303,7 @@ void psys_free(struct Object *ob, struct ParticleSystem *psys);
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
-int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
+bool psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], struct MCol *mc);
@@ -306,7 +333,7 @@ void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effecto
float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
-void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel);
+void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, const bool vel);
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 26b9420d676..619b1afe765 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -67,10 +67,10 @@ void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, int totgrid,
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
unsigned int **grid_hidden);
-void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
- struct BMLog *log);
+void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset);
void BKE_pbvh_free(PBVH *bvh);
+void BKE_pbvh_free_layer_disp(PBVH *bvh);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
@@ -93,10 +93,15 @@ void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original);
-int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
+bool BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist);
+bool BKE_pbvh_bmesh_node_raycast_detail(
+ PBVHNode *node,
+ const float ray_start[3], const float ray_normal[3],
+ float *detail, float *dist);
+
/* for orthographic cameras, project the far away ray segment points to the root node so
* we can have better precision. */
void BKE_pbvh_raycast_project_ray_root(PBVH *bvh, bool original, float ray_start[3],
@@ -106,7 +111,7 @@ void BKE_pbvh_raycast_project_ray_root(PBVH *bvh, bool original, float ray_start
void BKE_pbvh_node_draw(PBVHNode *node, void *data);
void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- int (*setMaterial)(int, void *attribs), bool wireframe);
+ int (*setMaterial)(int matnr, void *attribs), bool wireframe);
/* PBVH Access */
typedef enum {
@@ -123,6 +128,10 @@ void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3]);
/* multires hidden data, only valid for type == PBVH_GRIDS */
unsigned int **BKE_pbvh_grid_hidden(const PBVH *bvh);
+int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
+ int *grid_indices, int totgrid,
+ int gridsize);
+
/* multires level, only valid for type == PBVH_GRIDS */
void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
@@ -134,7 +143,7 @@ typedef enum {
PBVH_Subdivide = 1,
PBVH_Collapse = 2,
} PBVHTopologyUpdateMode;
-int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
const float center[3], float radius);
/* Node Access */
@@ -180,6 +189,7 @@ bool BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
struct GSet *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node);
struct GSet *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node);
+struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node);
void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node);
void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
@@ -187,7 +197,7 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]);
-void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r_totface);
void BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, void **gridfaces,
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
@@ -256,10 +266,6 @@ typedef struct PBVHVertexIter {
float *mask;
} PBVHVertexIter;
-#ifdef _MSC_VER
-#pragma warning (disable:4127) // conditional expression is constant
-#endif
-
void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
PBVHVertexIter *vi, int mode);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index d5131fcd19e..99579086e25 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -304,7 +304,7 @@ struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
void BKE_ptcache_free_mem(struct ListBase *mem_cache);
void BKE_ptcache_free(struct PointCache *cache);
void BKE_ptcache_free_list(struct ListBase *ptcaches);
-struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, struct ListBase *ptcaches_old, int copy_data);
+struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, struct ListBase *ptcaches_old, bool copy_data);
/********************** Baking *********************/
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 101fc463375..2acfeca233e 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -64,7 +64,7 @@ void BKE_reports_print(ReportList *reports, ReportType level);
Report *BKE_reports_last_displayable(ReportList *reports);
-int BKE_reports_contain(ReportList *reports, ReportType level);
+bool BKE_reports_contain(ReportList *reports, ReportType level);
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header);
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 52042649dc4..a10a3f3f59f 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -117,6 +117,7 @@ void BKE_scene_frame_set(struct Scene *scene, double cfra);
/* ** Scene evaluation ** */
void BKE_scene_update_tagged(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay);
+void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay, bool do_invisible_flush);
struct SceneRenderLayer *BKE_scene_add_render_layer(struct Scene *sce, const char *name);
bool BKE_scene_remove_render_layer(struct Main *main, struct Scene *scene, struct SceneRenderLayer *srl);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 0cbb9215868..17193bbefbf 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -62,14 +62,14 @@ typedef struct SeqIterator {
int valid;
} SeqIterator;
-void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_pointer);
+void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, bool use_pointer);
void BKE_sequence_iterator_next(SeqIterator *iter);
void BKE_sequence_iterator_end(SeqIterator *iter);
#define SEQP_BEGIN(_ed, _seq) \
{ \
SeqIterator iter_macro; \
- for (BKE_sequence_iterator_begin(_ed, &iter_macro, 1); \
+ for (BKE_sequence_iterator_begin(_ed, &iter_macro, true); \
iter_macro.valid; \
BKE_sequence_iterator_next(&iter_macro)) \
{ \
@@ -78,7 +78,7 @@ void BKE_sequence_iterator_end(SeqIterator *iter);
#define SEQ_BEGIN(ed, _seq) \
{ \
SeqIterator iter_macro; \
- for (BKE_sequence_iterator_begin(ed, &iter_macro, 0); \
+ for (BKE_sequence_iterator_begin(ed, &iter_macro, false); \
iter_macro.valid; \
BKE_sequence_iterator_next(&iter_macro)) \
{ \
@@ -99,6 +99,7 @@ typedef struct SeqRenderData {
int motion_blur_samples;
float motion_blur_shutter;
bool skip_cache;
+ bool is_proxy_render;
} SeqRenderData;
SeqRenderData BKE_sequencer_new_render_data(struct EvaluationContext *eval_ctx, struct Main *bmain,
@@ -115,8 +116,8 @@ enum {
};
struct SeqEffectHandle {
- short multithreaded;
- short supports_mask;
+ bool multithreaded;
+ bool supports_mask;
/* constructors & destructor */
/* init is _only_ called on first creation */
@@ -184,7 +185,7 @@ void BKE_sequencer_give_ibuf_prefetch_request(const SeqRenderData *context, floa
* sequencer color space functions
* ********************************************************************** */
-void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, int make_float);
+void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float);
void BKE_sequencer_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf);
void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]);
@@ -227,11 +228,11 @@ struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
/* intern */
void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change);
-int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, struct Sequence *seq, float cfra);
+bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, struct Sequence *seq, float cfra);
struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq);
void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context, short *stop, short *do_update, float *progress);
-void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, short stop);
+void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
/* **********************************************************************
* seqcache.c
@@ -275,7 +276,7 @@ void BKE_sequencer_preprocessed_cache_cleanup_sequence(struct Sequence *seq);
/* intern */
struct SeqEffectHandle BKE_sequence_get_blend(struct Sequence *seq);
-void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, int force);
+void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, bool force);
/* extern */
struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq);
@@ -288,8 +289,8 @@ int BKE_sequence_effect_get_supports_mask(int seq_type);
*/
/* for transform but also could use elsewhere */
-int BKE_sequence_tx_get_final_left(struct Sequence *seq, int metaclip);
-int BKE_sequence_tx_get_final_right(struct Sequence *seq, int metaclip);
+int BKE_sequence_tx_get_final_left(struct Sequence *seq, bool metaclip);
+int BKE_sequence_tx_get_final_right(struct Sequence *seq, bool metaclip);
void BKE_sequence_tx_set_final_left(struct Sequence *seq, int val);
void BKE_sequence_tx_set_final_right(struct Sequence *seq, int val);
void BKE_sequence_tx_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag);
@@ -308,7 +309,7 @@ void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, cons
bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
-void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, int for_render);
+void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render);
struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
@@ -330,7 +331,7 @@ bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
-struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, int recursive);
+struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, bool recursive);
/* api for adding new sequence strips */
typedef struct SeqLoadInfo {
@@ -409,7 +410,7 @@ typedef struct SequenceModifierTypeInfo {
struct SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type);
struct SequenceModifierData *BKE_sequence_modifier_new(struct Sequence *seq, const char *name, int type);
-int BKE_sequence_modifier_remove(struct Sequence *seq, struct SequenceModifierData *smd);
+bool BKE_sequence_modifier_remove(struct Sequence *seq, struct SequenceModifierData *smd);
void BKE_sequence_modifier_clear(struct Sequence *seq);
void BKE_sequence_modifier_free(struct SequenceModifierData *smd);
void BKE_sequence_modifier_unique_name(struct Sequence *seq, struct SequenceModifierData *smd);
@@ -420,7 +421,7 @@ void BKE_sequence_modifier_list_copy(struct Sequence *seqn, struct Sequence *seq
int BKE_sequence_supports_modifiers(struct Sequence *seq);
/* internal filters */
-struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_input_type, struct Sequence *mask_sequence, struct Mask *mask_id, int cfra, int make_float);
-void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, short make_float, struct ImBuf *mask_input);
+struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_input_type, struct Sequence *mask_sequence, struct Mask *mask_id, int cfra, bool make_float);
+void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, bool make_float, struct ImBuf *mask_input);
#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 6e85d9ee0a0..59de43af907 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -122,7 +122,7 @@ typedef struct ShrinkwrapCalcData {
} ShrinkwrapCalcData;
void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, bool forRender);
+ float (*vertexCos)[3], int numVerts, bool for_render);
/*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
@@ -134,9 +134,10 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object
* Thus it provides an easy way to cast the same ray across several trees
* (where each tree was built on its own coords space)
*/
-int BKE_shrinkwrap_project_normal(char options, const float vert[3], const float dir[3],
- const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
- BVHTree_RayCastCallback callback, void *userdata);
+bool BKE_shrinkwrap_project_normal(
+ char options, const float vert[3], const float dir[3],
+ const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback, void *userdata);
/*
* NULL initializers to local data
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 64f0b97c3f0..50ca5fcdf7b 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -134,12 +134,12 @@ void sound_free_waveform(struct bSound *sound);
void sound_read_waveform(struct bSound *sound);
-void sound_update_scene(struct Scene *scene);
+void sound_update_scene(struct Main *bmain, struct Scene *scene);
void *sound_get_factory(void *sound);
float sound_get_length(struct bSound *sound);
-int sound_is_jack_supported(void);
+bool sound_is_jack_supported(void);
-#endif
+#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index ab8b8b29915..3dae4087866 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -69,7 +69,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
float (*vertCos)[3],
SubsurfFlags flags);
-void subsurf_calculate_limit_positions(struct Mesh *me, float (*positions_r)[3]);
+void subsurf_calculate_limit_positions(struct Mesh *me, float (*r_positions)[3]);
/* get gridsize from 'level', level must be greater than zero */
int BKE_ccg_gridsize(int level);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 7d7fad1c58d..4f77e4f5a23 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -94,9 +94,9 @@ void txt_do_redo (struct Text *text);
void txt_split_curline (struct Text *text);
void txt_backspace_char (struct Text *text);
void txt_backspace_word (struct Text *text);
-int txt_add_char (struct Text *text, unsigned int add);
-int txt_add_raw_char (struct Text *text, unsigned int add);
-int txt_replace_char (struct Text *text, unsigned int add);
+bool txt_add_char (struct Text *text, unsigned int add);
+bool txt_add_raw_char (struct Text *text, unsigned int add);
+bool txt_replace_char (struct Text *text, unsigned int add);
void txt_unindent (struct Text *text);
void txt_comment (struct Text *text);
void txt_indent (struct Text *text);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 6a5b5626b50..4ad84dceb53 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -41,6 +41,7 @@ struct bNode;
struct Brush;
struct ColorBand;
struct EnvMap;
+struct FreestyleLineStyle;
struct HaloRen;
struct Lamp;
struct LampRen;
@@ -85,19 +86,21 @@ void BKE_texture_make_local(struct Tex *tex);
struct Tex *give_current_object_texture(struct Object *ob);
struct Tex *give_current_material_texture(struct Material *ma);
struct Tex *give_current_lamp_texture(struct Lamp *la);
+struct Tex *give_current_linestyle_texture(struct FreestyleLineStyle *linestyle);
struct Tex *give_current_world_texture(struct World *world);
struct Tex *give_current_brush_texture(struct Brush *br);
struct Tex *give_current_particle_texture(struct ParticleSettings *part);
struct bNode *give_current_material_texture_node(struct Material *ma);
-int give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act);
+bool give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act);
void set_active_mtex(struct ID *id, short act);
void set_current_brush_texture(struct Brush *br, struct Tex *tex);
void set_current_world_texture(struct World *wo, struct Tex *tex);
void set_current_material_texture(struct Material *ma, struct Tex *tex);
void set_current_lamp_texture(struct Lamp *la, struct Tex *tex);
+void set_current_linestyle_texture(struct FreestyleLineStyle *linestyle, struct Tex *tex);
void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex);
bool has_current_material_texture(struct Material *ma);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 4d41640527f..6d155ba37de 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -175,7 +175,8 @@ void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tra
int framenr, float mat[4][4]);
/* **** Distortion/Undistortion **** */
-struct MovieDistortion *BKE_tracking_distortion_new(void);
+struct MovieDistortion *BKE_tracking_distortion_new(struct MovieTracking *tracking,
+ int calibration_width, int calibration_height);
void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking,
int calibration_width, int calibration_height);
void BKE_tracking_distortion_set_threads(struct MovieDistortion *distortion, int threads);
@@ -271,6 +272,9 @@ void BKE_tracking_dopesheet_update(struct MovieTracking *tracking);
(((sc)->flag & SC_SHOW_MARKER_PATTERN) && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) || \
(((sc)->flag & SC_SHOW_MARKER_SEARCH) && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))))
+#define PLANE_TRACK_VIEW_SELECTED(plane_track) ((((plane_track)->flag & PLANE_TRACK_HIDDEN) == 0) && \
+ ((plane_track)->flag & SELECT))
+
#define MARKER_VISIBLE(sc, track, marker) (((marker)->flag & MARKER_DISABLED) == 0 || ((sc)->flag & SC_HIDE_DISABLED) == 0 || (sc->clip->tracking.act_track == track))
#define TRACK_CLEAR_UPTO 0
diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h
index 0610c23a6b2..703e84b3798 100644
--- a/source/blender/blenkernel/BKE_writeffmpeg.h
+++ b/source/blender/blenkernel/BKE_writeffmpeg.h
@@ -80,7 +80,6 @@ void BKE_ffmpeg_image_type_verify(struct RenderData *rd, struct ImageFormatData
void BKE_ffmpeg_codec_settings_verify(struct RenderData *rd);
bool BKE_ffmpeg_alpha_channel_is_supported(struct RenderData *rd);
-struct IDProperty *BKE_ffmpeg_property_add(struct RenderData *Rd, const char *type, int opt_index, int parent_index);
int BKE_ffmpeg_property_add_string(struct RenderData *rd, const char *type, const char *str);
void BKE_ffmpeg_property_del(struct RenderData *rd, void *type, void *prop_);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index ab891a244fa..28faa4f5327 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -78,7 +78,8 @@ set(SRC
intern/colortools.c
intern/constraint.c
intern/context.c
- intern/curve.c
+ intern/crazyspace.c
+ intern/curve.c
intern/customdata.c
intern/customdata_file.c
intern/deform.c
@@ -107,6 +108,7 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
+ intern/library_query.c
intern/linestyle.c
intern/mask.c
intern/mask_evaluate.c
@@ -190,6 +192,7 @@ set(SRC
BKE_colortools.h
BKE_constraint.h
BKE_context.h
+ BKE_crazyspace.h
BKE_curve.h
BKE_customdata.h
BKE_customdata_file.h
@@ -214,6 +217,7 @@ set(SRC
BKE_lamp.h
BKE_lattice.h
BKE_library.h
+ BKE_library_query.h
BKE_linestyle.h
BKE_main.h
BKE_mask.h
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index e61d47e87f4..0ab633701c1 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -129,6 +129,7 @@ typedef struct DagForest {
int numNodes;
bool is_acyclic;
int time; /* for flushing/tagging, compare with node->lasttime */
+ bool ugly_hack_sorry; /* prevent type check */
} DagForest;
// queue operations
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 560bebd280b..6cda0a1bc33 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -300,6 +300,22 @@ BLI_INLINE int ccg_edgebase(int level)
#define NormCopy(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] = _b[0]; _a[1] = _b[1]; _a[2] = _b[2]; } (void)0
#define NormAdd(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] += _b[0]; _a[1] += _b[1]; _a[2] += _b[2]; } (void)0
+BLI_INLINE void Normalize(float no[3])
+{
+ const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
+
+ if (length > EPSILON) {
+ const float length_inv = 1.0f / length;
+
+ no[0] *= length_inv;
+ no[1] *= length_inv;
+ no[2] *= length_inv;
+ }
+ else {
+ NormZero(no);
+ }
+}
+
/***/
enum {
@@ -806,24 +822,12 @@ static void _face_calcIFNo(CCGFace *f, int lvl, int S, int x, int y, float no[3]
float *d = _face_getIFCo(f, lvl, S, x + 0, y + 1, levels, dataSize);
float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
- float length;
no[0] = b_dY * a_cZ - b_dZ * a_cY;
no[1] = b_dZ * a_cX - b_dX * a_cZ;
no[2] = b_dX * a_cY - b_dY * a_cX;
- length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
-
- if (length > EPSILON) {
- float invLength = 1.0f / length;
-
- no[0] *= invLength;
- no[1] *= invLength;
- no[2] *= invLength;
- }
- else {
- NormZero(no);
- }
+ Normalize(no);
}
static void _face_free(CCGFace *f, CCGSubSurf *ss)
@@ -1418,7 +1422,9 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
return eCCGError_None;
}
+#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize)
#define VERT_getNo(e, lvl) _vert_getNo(v, lvl, vertDataSize, normalDataOffset)
+#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize)
#define EDGE_getNo(e, lvl, x) _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)
#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
@@ -1519,7 +1525,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
/* XXX can I reduce the number of normalisations here? */
for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
CCGVert *v = (CCGVert *) effectedV[ptrIdx];
- float length, *no = VERT_getNo(v, lvl);
+ float *no = VERT_getNo(v, lvl);
NormZero(no);
@@ -1528,18 +1534,12 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
NormAdd(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f, v), gridSize - 1, gridSize - 1));
}
- length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
-
- if (length > EPSILON) {
- float invLength = 1.0f / length;
- no[0] *= invLength;
- no[1] *= invLength;
- no[2] *= invLength;
- }
- else {
- NormZero(no);
+ if (UNLIKELY(v->numFaces == 0)) {
+ NormCopy(no, VERT_getCo(v, lvl));
}
+ Normalize(no);
+
for (i = 0; i < v->numFaces; i++) {
CCGFace *f = v->faces[i];
NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f, v), gridSize - 1, gridSize - 1), no);
@@ -1590,17 +1590,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
for (y = 0; y < gridSize; y++) {
for (x = 0; x < gridSize; x++) {
float *no = FACE_getIFNo(f, lvl, S, x, y);
- float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
-
- if (length > EPSILON) {
- float invLength = 1.0f / length;
- no[0] *= invLength;
- no[1] *= invLength;
- no[2] *= invLength;
- }
- else {
- NormZero(no);
- }
+ Normalize(no);
}
}
@@ -1633,15 +1623,15 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
int x;
for (x = 0; x < edgeSize; x++) {
- NormZero(EDGE_getNo(e, lvl, x));
+ float *no = EDGE_getNo(e, lvl, x);
+ NormCopy(no, EDGE_getCo(e, lvl, x));
+ Normalize(no);
}
}
}
}
#undef FACE_getIFNo
-#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize)
-#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize)
#define FACE_getIECo(f, lvl, S, x) _face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize)
#define FACE_getIFCo(f, lvl, S, x, y) _face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize)
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index aeabd054b8b..da6e9d570c9 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -39,21 +39,18 @@
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_armature_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h" // N_T
+#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
-#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_displist.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
+#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
@@ -62,8 +59,6 @@
#include "BKE_paint.h"
#include "BKE_texture.h"
#include "BKE_multires.h"
-#include "BKE_armature.h"
-#include "BKE_particle.h"
#include "BKE_bvhutils.h"
#include "BKE_deform.h"
#include "BKE_global.h" /* For debug flag, DM_update_tessface_data() func. */
@@ -348,6 +343,12 @@ int DM_release(DerivedMesh *dm)
CustomData_free(&dm->loopData, dm->numLoopData);
CustomData_free(&dm->polyData, dm->numPolyData);
+ if (dm->mat) {
+ MEM_freeN(dm->mat);
+ dm->mat = NULL;
+ dm->totmat = 0;
+ }
+
return 1;
}
else {
@@ -391,6 +392,12 @@ void DM_ensure_normals(DerivedMesh *dm)
BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0);
}
+static void DM_calc_loop_normals(DerivedMesh *dm, float split_angle)
+{
+ dm->calcLoopNormals(dm, split_angle);
+ dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+}
+
/* note: until all modifiers can take MPoly's as input,
* use this at the start of modifiers */
void DM_ensure_tessface(DerivedMesh *dm)
@@ -445,7 +452,8 @@ void DM_update_tessface_data(DerivedMesh *dm)
if (CustomData_has_layer(fdata, CD_MTFACE) ||
CustomData_has_layer(fdata, CD_MCOL) ||
CustomData_has_layer(fdata, CD_PREVIEW_MCOL) ||
- CustomData_has_layer(fdata, CD_ORIGSPACE))
+ CustomData_has_layer(fdata, CD_ORIGSPACE) ||
+ CustomData_has_layer(fdata, CD_TESSLOOPNORMAL))
{
loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
@@ -481,6 +489,23 @@ void DM_update_tessface_data(DerivedMesh *dm)
dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS;
}
+void DM_update_materials(DerivedMesh *dm, Object *ob)
+{
+ int i, totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */
+ dm->totmat = totmat;
+
+ /* invalidate old materials */
+ if (dm->mat)
+ MEM_freeN(dm->mat);
+
+ dm->mat = MEM_callocN(totmat * sizeof(*dm->mat), "DerivedMesh.mat");
+
+ for (i = 1; i < totmat; i++) {
+ dm->mat[i] = give_current_material(ob, i);
+ }
+}
+
+
void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
{
/* dm might depend on me, so we need to do everything with a local copy */
@@ -969,7 +994,7 @@ static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm,
totvert = dm->getNumVerts(dm);
if (orcodm) {
- orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco");
+ orco = MEM_callocN(sizeof(float[3]) * totvert, "dm orco");
free = 1;
if (orcodm->getNumVerts(orcodm) == totvert)
@@ -1114,7 +1139,7 @@ static void calc_weightpaint_vert_color(
if (was_a_nonzero == false) {
show_alert_color = true;
}
- else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
+ else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == false) {
input /= defbase_sel_tot; /* get the average */
}
}
@@ -1401,7 +1426,7 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
if ((dm->type == DM_TYPE_CDDM) &&
- ((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == FALSE))
+ ((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == false))
{
/* if normals are dirty we want to calculate vertex normals too */
CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
@@ -1441,11 +1466,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
#if 0 /* XXX Will re-enable this when we have global mod stack options. */
const bool do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol;
#endif
- const bool do_final_wmcol = FALSE;
+ const bool do_final_wmcol = false;
const bool do_init_wmcol = ((dataMask & CD_MASK_PREVIEW_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol);
/* XXX Same as above... For now, only weights preview in WPaint mode. */
const bool do_mod_wmcol = do_init_wmcol;
+ const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH);
+ const float loop_normals_split_angle = me->smoothresh;
+
VirtualModifierData virtualModifierData;
ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0;
@@ -1527,7 +1555,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
if (deform_r) {
*deform_r = CDDM_from_mesh(me);
-
+
if (build_shapekey_layers)
add_shapekey_layers(dm, me, ob);
@@ -1564,13 +1592,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
continue;
}
if (sculpt_mode &&
- (!has_multires || multires_applied || ob->sculpt->bm))
+ (!has_multires || multires_applied || sculpt_dyntopo))
{
bool unsupported = false;
if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) {
/* If multires is on level 0 skip it silently without warning message. */
- continue;
+ if (!sculpt_dyntopo)
+ continue;
}
if (sculpt_dyntopo && !useRenderParams)
@@ -1582,9 +1611,15 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
unsupported |= multires_applied;
if (unsupported) {
- modifier_setError(md, "Not supported in sculpt mode");
+ if (sculpt_dyntopo)
+ modifier_setError(md, "Not supported in dyntopo");
+ else
+ modifier_setError(md, "Not supported in sculpt mode");
continue;
}
+ else {
+ modifier_setError(md, "Hide, Mask and optimized display disabled");
+ }
}
if (needMapping && !modifier_supportsMapping(md)) continue;
if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
@@ -1840,47 +1875,13 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO);
}
- {
- /* calculating normals can re-calculate tessfaces in some cases */
-#if 0
- int num_tessface = finaldm->getNumTessFaces(finaldm);
-#endif
- /* --------------------------------------------------------------------- */
- /* First calculate the polygon and vertex normals, re-tessellation
- * copies these into the tessface's normal layer */
-
-
- /* comment because this causes a bug when deform is applied after a
- * bug when applied after a subsurf modifier (SubSurf -> Cast) for eg,
- * it also looks like this isn't even needed since code above recalc's
- * normals - campbell */
-#if 0
- finaldm->calcNormals(finaldm);
-#endif
+ if (do_loop_normals) {
+ /* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
+ DM_calc_loop_normals(finaldm, loop_normals_split_angle);
+ }
- /* Re-tessellation is necessary to push render data (uvs, textures, colors)
- * from loops and polys onto the tessfaces. This may be currently be
- * redundant in cases where the render mode doesn't use these inputs, but
- * ideally eventually tessellation would happen on-demand, and this is one
- * of the primary places it would be needed. */
-#if 0
- if (num_tessface == 0 && finaldm->getNumTessFaces(finaldm) == 0)
-#else
- if (finaldm->getNumTessFaces(finaldm) == 0) /* || !CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX)) */
-#endif
- {
- finaldm->recalcTessellation(finaldm);
- }
- /* Even if tessellation is not needed, some modifiers might have modified CD layers
- * (like mloopcol or mloopuv), hence we have to update those. */
- else if (finaldm->dirty & DM_DIRTY_TESS_CDLAYERS) {
- /* A tessellation already exists, it should always have a CD_ORIGINDEX. */
- BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX));
- DM_update_tessface_data(finaldm);
- }
- /* Need to watch this, it can cause issues, see bug [#29338] */
- /* take care with this block, we really need testing frameworks */
- /* --------------------------------------------------------------------- */
+ {
+ DM_ensure_tessface(finaldm);
/* without this, drawing ngon tri's faces will show ugly tessellated face
* normals and will also have to calculate normals on the fly, try avoid
@@ -1889,8 +1890,11 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
* which deals with drawing differently.
*
* Only calc vertex normals if they are flagged as dirty.
+ * If using loop normals, poly nors have already been computed.
*/
- dm_ensure_display_normals(finaldm);
+ if (!do_loop_normals) {
+ dm_ensure_display_normals(finaldm);
+ }
}
#ifdef WITH_GAMEENGINE
@@ -1918,14 +1922,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
BLI_linklist_free((LinkNode *)datamasks, NULL);
}
-float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
+float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *r_numVerts))[3]
{
BMIter iter;
BMVert *eve;
float (*cos)[3];
int i;
- *numVerts_r = em->bm->totvert;
+ *r_numVerts = em->bm->totvert;
cos = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "vertexcos");
@@ -1957,7 +1961,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
ModifierData *md, *previewmd = NULL;
float (*deformedVerts)[3] = NULL;
CustomDataMask mask, previewmask = 0, append_mask = 0;
- DerivedMesh *dm, *orcodm = NULL;
+ DerivedMesh *dm = NULL, *orcodm = NULL;
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
CDMaskLink *datamasks, *curr;
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1967,19 +1971,21 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
#if 0 /* XXX Will re-enable this when we have global mod stack options. */
const bool do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol;
#endif
- const bool do_final_wmcol = FALSE;
+ const bool do_final_wmcol = false;
const bool do_init_wmcol = ((((Mesh *)ob->data)->drawflag & ME_DRAWEIGHT) && !do_final_wmcol);
const bool do_init_statvis = ((((Mesh *)ob->data)->drawflag & ME_DRAW_STATVIS) && !do_init_wmcol);
const bool do_mod_wmcol = do_init_wmcol;
VirtualModifierData virtualModifierData;
+ const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH);
+ const float loop_normals_split_angle = ((Mesh *)(ob->data))->smoothresh;
+
modifiers_clearErrors(ob);
if (cage_r && cageIndex == -1) {
*cage_r = getEditDerivedBMesh(em, ob, NULL);
}
- dm = NULL;
md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
/* copied from mesh_calc_modifiers */
@@ -2187,6 +2193,14 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
DM_update_statvis_color(scene, ob, *final_r);
}
+ if (do_loop_normals) {
+ /* Compute loop normals */
+ DM_calc_loop_normals(*final_r, loop_normals_split_angle);
+ if (cage_r && *cage_r && (*cage_r != *final_r)) {
+ DM_calc_loop_normals(*cage_r, loop_normals_split_angle);
+ }
+ }
+
/* --- */
/* BMESH_ONLY, ensure tessface's used for drawing,
* but don't recalculate if the last modifier in the stack gives us tessfaces
@@ -2204,8 +2218,10 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
}
/* --- */
- /* same as mesh_calc_modifiers */
- dm_ensure_display_normals(*final_r);
+ /* same as mesh_calc_modifiers (if using loop normals, poly nors have already been computed). */
+ if (!do_loop_normals) {
+ dm_ensure_display_normals(*final_r);
+ }
/* add an orco layer if needed */
if (dataMask & CD_MASK_ORCO)
@@ -2222,7 +2238,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
int build_shapekey_layers)
{
Object *obact = scene->basact ? scene->basact->object : NULL;
- int editing = paint_facesel_test(ob);
+ bool editing = BKE_paint_select_face_test(ob);
/* weight paint and face select need original indices because of selection buffer drawing */
int needMapping = (ob == obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)));
@@ -2244,7 +2260,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
if ((ob->mode & OB_MODE_SCULPT) && ob->sculpt) {
/* create PBVH immediately (would be created on the fly too,
* but this avoids waiting on first stroke) */
- ob->sculpt->pbvh = ob->derivedFinal->getPBVH(ob, ob->derivedFinal);
+
+ BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false);
}
BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS));
@@ -2255,18 +2272,7 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C
BKE_object_free_derived_caches(obedit);
BKE_object_sculpt_modifiers_changed(obedit);
- if (em->derivedFinal) {
- if (em->derivedFinal != em->derivedCage) {
- em->derivedFinal->needsFree = 1;
- em->derivedFinal->release(em->derivedFinal);
- }
- em->derivedFinal = NULL;
- }
- if (em->derivedCage) {
- em->derivedCage->needsFree = 1;
- em->derivedCage->release(em->derivedCage);
- em->derivedCage = NULL;
- }
+ BKE_editmesh_free_derivedmesh(em);
editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
DM_set_object_boundbox(obedit, em->derivedFinal);
@@ -2285,7 +2291,7 @@ static CustomDataMask object_get_datamask(Scene *scene, Object *ob)
if (ob == actob) {
/* check if we need tfaces & mcols due to face select or texture paint */
- if (paint_facesel_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) {
+ if (BKE_paint_select_face_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
}
@@ -2425,7 +2431,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
/***/
-DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **r_final,
CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
@@ -2439,7 +2445,7 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit,
editbmesh_build_data(scene, obedit, em, dataMask);
}
- *final_r = em->derivedFinal;
+ *r_final = em->derivedFinal;
if (em->derivedFinal) { BLI_assert(!(em->derivedFinal->dirty & DM_DIRTY_NORMALS)); }
return em->derivedCage;
}
@@ -2528,7 +2534,8 @@ DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
/* ******************* GLSL ******************** */
typedef struct {
- float *precomputedFaceNormals;
+ float (*precomputedFaceNormals)[3];
+ short (*precomputedLoopNormals)[4][3];
MTFace *mtface; /* texture coordinates */
MFace *mface; /* indices */
MVert *mvert; /* vertices & normals */
@@ -2580,11 +2587,14 @@ static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const i
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+ const bool smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH) != 0;
- const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH);
- if (!smoothnormal) { // flat
+ if (pMesh->precomputedLoopNormals) {
+ normal_short_to_float_v3(r_no, pMesh->precomputedLoopNormals[face_num][vert_index]);
+ }
+ else if (!smoothnormal) { // flat
if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, &pMesh->precomputedFaceNormals[3 * face_num]);
+ copy_v3_v3(r_no, pMesh->precomputedFaceNormals[face_num]);
}
else {
MFace *mf = &pMesh->mface[face_num];
@@ -2624,12 +2634,17 @@ void DM_add_tangent_layer(DerivedMesh *dm)
MFace *mface;
float (*orco)[3] = NULL, (*tangent)[4];
int /* totvert, */ totface;
- float *nors;
+ float (*fnors)[3];
+ short (*tlnors)[4][3];
if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
return;
- nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ fnors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
+ * have to check this is valid...
+ */
+ tlnors = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
/* check we have all the needed layers */
/* totvert = dm->getNumVerts(dm); */ /* UNUSED */
@@ -2655,7 +2670,8 @@ void DM_add_tangent_layer(DerivedMesh *dm)
SMikkTSpaceContext sContext = {NULL};
SMikkTSpaceInterface sInterface = {NULL};
- mesh2tangent.precomputedFaceNormals = nors;
+ mesh2tangent.precomputedFaceNormals = fnors;
+ mesh2tangent.precomputedLoopNormals = tlnors;
mesh2tangent.mtface = mtface;
mesh2tangent.mface = mface;
mesh2tangent.mvert = mvert;
@@ -2779,9 +2795,9 @@ void DM_calc_auto_bump_scale(DerivedMesh *dm)
int t;
for (t = 0; t < nr_tris_to_pile; t++) {
float f2x_area_uv;
- float *p0 = verts[indices[t * 3 + 0]];
- float *p1 = verts[indices[t * 3 + 1]];
- float *p2 = verts[indices[t * 3 + 2]];
+ const float *p0 = verts[indices[t * 3 + 0]];
+ const float *p1 = verts[indices[t * 3 + 1]];
+ const float *p2 = verts[indices[t * 3 + 2]];
float edge_t0[2], edge_t1[2];
sub_v2_v2v2(edge_t0, tex_coords[indices[t * 3 + 1]], tex_coords[indices[t * 3 + 0]]);
@@ -3083,7 +3099,7 @@ static void navmesh_DM_drawFacesTex(DerivedMesh *dm,
static void navmesh_DM_drawFacesSolid(DerivedMesh *dm,
float (*partial_redraw_planes)[4],
- int UNUSED(fast), DMSetMaterial setMaterial)
+ bool UNUSED(fast), DMSetMaterial setMaterial)
{
(void) partial_redraw_planes;
(void) setMaterial;
@@ -3336,3 +3352,84 @@ bool DM_is_valid(DerivedMesh *dm)
}
#endif /* NDEBUG */
+
+/* -------------------------------------------------------------------- */
+
+MVert *DM_get_vert_array(DerivedMesh *dm, bool *allocated)
+{
+ CustomData *vert_data = dm->getVertDataLayout(dm);
+ MVert *mvert = CustomData_get_layer(vert_data, CD_MVERT);
+ *allocated = false;
+
+ if (mvert == NULL) {
+ mvert = MEM_mallocN(sizeof(MVert) * dm->getNumVerts(dm), "dmvh vert data array");
+ dm->copyVertArray(dm, mvert);
+ *allocated = true;
+ }
+
+ return mvert;
+}
+
+MEdge *DM_get_edge_array(DerivedMesh *dm, bool *allocated)
+{
+ CustomData *edge_data = dm->getEdgeDataLayout(dm);
+ MEdge *medge = CustomData_get_layer(edge_data, CD_MEDGE);
+ *allocated = false;
+
+ if (medge == NULL) {
+ medge = MEM_mallocN(sizeof(MEdge) * dm->getNumEdges(dm), "dm medge data array");
+ dm->copyEdgeArray(dm, medge);
+ *allocated = true;
+ }
+
+ return medge;
+}
+
+MLoop *DM_get_loop_array(DerivedMesh *dm, bool *allocated)
+{
+ CustomData *loop_data = dm->getEdgeDataLayout(dm);
+ MLoop *mloop = CustomData_get_layer(loop_data, CD_MLOOP);
+ *allocated = false;
+
+ if (mloop == NULL) {
+ mloop = MEM_mallocN(sizeof(MLoop) * dm->getNumLoops(dm), "dm loop data array");
+ dm->copyLoopArray(dm, mloop);
+ *allocated = true;
+ }
+
+ return mloop;
+}
+
+MPoly *DM_get_poly_array(DerivedMesh *dm, bool *allocated)
+{
+ CustomData *poly_data = dm->getPolyDataLayout(dm);
+ MPoly *mpoly = CustomData_get_layer(poly_data, CD_MPOLY);
+ *allocated = false;
+
+ if (mpoly == NULL) {
+ mpoly = MEM_mallocN(sizeof(MPoly) * dm->getNumPolys(dm), "dm poly data array");
+ dm->copyPolyArray(dm, mpoly);
+ *allocated = true;
+ }
+
+ return mpoly;
+}
+
+MFace *DM_get_tessface_array(DerivedMesh *dm, bool *allocated)
+{
+ CustomData *tessface_data = dm->getTessFaceDataLayout(dm);
+ MFace *mface = CustomData_get_layer(tessface_data, CD_MFACE);
+ *allocated = false;
+
+ if (mface == NULL) {
+ int numTessFaces = dm->getNumTessFaces(dm);
+
+ if (numTessFaces > 0) {
+ mface = MEM_mallocN(sizeof(MFace) * numTessFaces, "bvh mface data array");
+ dm->copyTessFaceArray(dm, mface);
+ *allocated = true;
+ }
+ }
+
+ return mface;
+}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 3a32cad0873..3219219bee5 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -96,8 +96,8 @@ typedef struct tMakeLocalActionContext {
bAction *act; /* original action */
bAction *act_new; /* new action */
- int is_lib; /* some action users were libraries */
- int is_local; /* some action users were not libraries */
+ bool is_lib; /* some action users were libraries */
+ bool is_local; /* some action users were not libraries */
} tMakeLocalActionContext;
/* helper function for BKE_action_make_local() - local/lib init step */
@@ -106,8 +106,8 @@ static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr)
tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
if (adt->action == mlac->act) {
- if (id->lib) mlac->is_lib = TRUE;
- else mlac->is_local = TRUE;
+ if (id->lib) mlac->is_lib = true;
+ else mlac->is_local = true;
}
}
@@ -129,7 +129,7 @@ static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr)
// does copy_fcurve...
void BKE_action_make_local(bAction *act)
{
- tMakeLocalActionContext mlac = {act, NULL, FALSE, FALSE};
+ tMakeLocalActionContext mlac = {act, NULL, false, false};
Main *bmain = G.main;
if (act->id.lib == NULL)
@@ -143,7 +143,7 @@ void BKE_action_make_local(bAction *act)
BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
- if (mlac.is_local && mlac.is_lib == FALSE) {
+ if (mlac.is_local && mlac.is_lib == false) {
id_clear_lib_data(bmain, &act->id);
}
else if (mlac.is_local && mlac.is_lib) {
@@ -588,14 +588,6 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
outPose = MEM_callocN(sizeof(bPose), "pose");
BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
- if (outPose->chanbase.first) {
- bPoseChannel *pchan;
- for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
- if (pchan->custom) {
- id_us_plus(&pchan->custom->id);
- }
- }
- }
outPose->iksolver = src->iksolver;
outPose->ikdata = NULL;
@@ -603,8 +595,18 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
outPose->avs = src->avs;
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
+
+ if (pchan->custom) {
+ id_us_plus(&pchan->custom->id);
+ }
+
+ /* warning, O(n2) here, but it's a rarely used feature. */
+ if (pchan->custom_tx) {
+ pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
+ }
+
if (copy_constraints) {
- BKE_copy_constraints(&listb, &pchan->constraints, TRUE); // BKE_copy_constraints NULLs listb
+ BKE_constraints_copy(&listb, &pchan->constraints, true); // BKE_constraints_copy NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
@@ -727,7 +729,7 @@ void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user)
pchan->mpath = NULL;
}
- BKE_free_constraints(&pchan->constraints);
+ BKE_constraints_free(&pchan->constraints);
if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
@@ -843,7 +845,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
pchan->iklinweight = pchan_from->iklinweight;
/* constraints */
- BKE_copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
+ BKE_constraints_copy(&pchan->constraints, &pchan_from->constraints, true);
/* id-properties */
if (pchan->prop) {
@@ -1037,7 +1039,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
/* get extents for this curve */
/* TODO: allow enabling/disabling this? */
- calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE);
+ calc_fcurve_range(fcu, &nmin, &nmax, false, true);
/* compare to the running tally */
min = min_ff(min, nmin);
@@ -1127,7 +1129,7 @@ short action_get_item_transforms(bAction *act, Object *ob, bPoseChannel *pchan,
* - we cannot use the groups, since they may not be grouped in that way...
*/
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- char *bPtr = NULL, *pPtr = NULL;
+ const char *bPtr = NULL, *pPtr = NULL;
/* if enough flags have been found, we can stop checking unless we're also getting the curves */
if ((flags == ACT_TRANS_ALL) && (curves == NULL))
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
index 129bc4657b4..119fa266908 100644
--- a/source/blender/blenkernel/intern/addon.c
+++ b/source/blender/blenkernel/intern/addon.c
@@ -43,7 +43,7 @@
static GHash *global_addonpreftype_hash = NULL;
-bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet)
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, bool quiet)
{
if (idname[0]) {
bAddonPrefType *apt;
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 40903140de4..631e587099d 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -316,7 +316,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
Base *base, *last = NULL;
/* only stuff that moves or needs display still */
- DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
+ DAG_scene_update_flags(G.main, scene, scene->lay, true, false);
/* find the last object with the tag
* - all those afterwards are assumed to not be relevant for our calculations
@@ -536,6 +536,9 @@ void calc_curvepath(Object *ob, ListBase *nurbs)
bevp = bevpfirst;
bevpn = bevp + 1;
bevplast = bevpfirst + (bl->nr - 1);
+ if (UNLIKELY(bevpn > bevplast)) {
+ bevpn = cycl ? bevpfirst : bevplast;
+ }
fp = dist + 1;
maxdist = dist + tot;
fac = 1.0f / ((float)path->len - 1.0f);
@@ -546,17 +549,23 @@ void calc_curvepath(Object *ob, ListBase *nurbs)
d = ((float)a) * fac;
/* we're looking for location (distance) 'd' in the array */
- while ((d >= *fp) && fp < maxdist) {
- fp++;
- if (bevp < bevplast) bevp++;
- bevpn = bevp + 1;
- if (UNLIKELY(bevpn > bevplast)) {
- bevpn = cycl ? bevpfirst : bevplast;
+ if (LIKELY(tot > 0)) {
+ while ((fp < maxdist) && (d >= *fp)) {
+ fp++;
+ if (bevp < bevplast) bevp++;
+ bevpn = bevp + 1;
+ if (UNLIKELY(bevpn > bevplast)) {
+ bevpn = cycl ? bevpfirst : bevplast;
+ }
}
+
+ fac1 = (*(fp) - d) / (*(fp) - *(fp - 1));
+ fac2 = 1.0f - fac1;
+ }
+ else {
+ fac1 = 1.0f;
+ fac2 = 0.0f;
}
-
- fac1 = (*(fp) - d) / (*(fp) - *(fp - 1));
- fac2 = 1.0f - fac1;
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa;
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5c50b9d6bec..6a9c4c851b2 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -74,7 +74,7 @@
/* Getter/Setter -------------------------------------------- */
/* Check if ID can have AnimData */
-short id_type_can_have_animdata(ID *id)
+bool id_type_can_have_animdata(ID *id)
{
/* sanity check */
if (id == NULL)
@@ -157,10 +157,10 @@ AnimData *BKE_id_add_animdata(ID *id)
/* Action Setter --------------------------------------- */
/* Called when user tries to change the active action of an AnimData block (via RNA, Outliner, etc.) */
-short BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
+bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
{
AnimData *adt = BKE_animdata_from_id(id);
- short ok = 0;
+ bool ok = false;
/* animdata validity check */
if (adt == NULL) {
@@ -279,7 +279,7 @@ AnimData *BKE_copy_animdata(AnimData *adt, const bool do_action)
return dadt;
}
-int BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
+bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
{
AnimData *adt;
@@ -386,10 +386,10 @@ void BKE_relink_animdata(AnimData *adt)
* < basepath: (str) shorter path fragment to look for
* > returns (bool) whether there is a match
*/
-static short animpath_matches_basepath(const char path[], const char basepath[])
+static bool animpath_matches_basepath(const char path[], const char basepath[])
{
/* we need start of path to be basepath */
- return (path && basepath) && (strstr(path, basepath) == path);
+ return (path && basepath) && STRPREFIX(path, basepath);
}
/* Move F-Curves in src action to dst action, setting up all the necessary groups
@@ -567,7 +567,7 @@ static bool check_rna_path_is_valid(ID *owner_id, const char *path)
/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate
* NOTE: we assume that oldName and newName have [" "] padding around them
*/
-static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, int verify_paths)
+static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, bool verify_paths)
{
char *prefixPtr = strstr(oldpath, prefix);
char *oldNamePtr = strstr(oldpath, oldName);
@@ -581,7 +581,7 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o
/* if we haven't aren't able to resolve the path now, try again after fixing it */
if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) {
DynStr *ds = BLI_dynstr_new();
- char *postfixPtr = oldNamePtr + oldNameLen;
+ const char *postfixPtr = oldNamePtr + oldNameLen;
char *newPath = NULL;
char oldChar;
@@ -626,14 +626,14 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o
/* Check RNA-Paths for a list of F-Curves */
static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
- const char *oldKey, const char *newKey, ListBase *curves, int verify_paths)
+ const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
{
FCurve *fcu;
/* we need to check every curve... */
for (fcu = curves->first; fcu; fcu = fcu->next) {
if (fcu->rna_path) {
- char *old_path = fcu->rna_path;
+ const char *old_path = fcu->rna_path;
/* firstly, handle the F-Curve's own path */
fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
@@ -654,7 +654,7 @@ static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char
/* Check RNA-Paths for a list of Drivers */
static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName,
- const char *oldKey, const char *newKey, ListBase *curves, int verify_paths)
+ const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
{
FCurve *fcu;
@@ -695,7 +695,7 @@ static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix
/* Fix all RNA-Paths for Actions linked to NLA Strips */
static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
- const char *oldKey, const char *newKey, ListBase *strips, int verify_paths)
+ const char *oldKey, const char *newKey, ListBase *strips, bool verify_paths)
{
NlaStrip *strip;
@@ -720,7 +720,7 @@ static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const ch
* i.e. pose.bones["Bone"]
*/
void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, const char *prefix, const char *oldName,
- const char *newName, int oldSubscript, int newSubscript, int verify_paths)
+ const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
{
char *oldN, *newN;
@@ -759,7 +759,7 @@ void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, const char *prefix,
* i.e. pose.bones["Bone"]
*/
void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, const char *prefix, const char *oldName,
- const char *newName, int oldSubscript, int newSubscript, int verify_paths)
+ const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
{
NlaTrack *nlt;
char *oldN, *newN;
@@ -894,7 +894,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
AnimData *adt = BKE_animdata_from_id(id); \
NtId_Type *ntp = (NtId_Type *)id; \
if (ntp->nodetree) { \
- AnimData *adt2 = BKE_animdata_from_id((ID *)ntp); \
+ AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
if (adt2) func(id, adt2, user_data); \
} \
if (adt) func(id, adt, user_data); \
@@ -1259,7 +1259,7 @@ void BKE_keyingsets_free(ListBase *list)
* - path: original path string (as stored in F-Curve data)
* - dst: destination string to write data to
*/
-static short animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst)
+static bool animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst)
{
/* is there a valid remapping table to use? */
#if 0
@@ -1279,7 +1279,7 @@ static short animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **ds
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
/* Write the given value to a setting using RNA, and return success */
-static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_index, float value)
+static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_index, float value)
{
PropertyRNA *prop;
PointerRNA new_ptr;
@@ -1291,7 +1291,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
/* set value - only for animatable numerical values */
if (RNA_property_animateable(&new_ptr, prop)) {
int array_len = RNA_property_array_length(&new_ptr, prop);
- int written = FALSE;
+ bool written = false;
if (array_len && array_index >= array_len) {
if (G.debug & G_DEBUG) {
@@ -1308,13 +1308,13 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
if (array_len) {
if (RNA_property_boolean_get_index(&new_ptr, prop, array_index) != ANIMSYS_FLOAT_AS_BOOL(value)) {
RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value));
- written = TRUE;
+ written = true;
}
}
else {
if (RNA_property_boolean_get(&new_ptr, prop) != ANIMSYS_FLOAT_AS_BOOL(value)) {
RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value));
- written = TRUE;
+ written = true;
}
}
break;
@@ -1322,13 +1322,13 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
if (array_len) {
if (RNA_property_int_get_index(&new_ptr, prop, array_index) != (int)value) {
RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
- written = TRUE;
+ written = true;
}
}
else {
if (RNA_property_int_get(&new_ptr, prop) != (int)value) {
RNA_property_int_set(&new_ptr, prop, (int)value);
- written = TRUE;
+ written = true;
}
}
break;
@@ -1336,20 +1336,20 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
if (array_len) {
if (RNA_property_float_get_index(&new_ptr, prop, array_index) != value) {
RNA_property_float_set_index(&new_ptr, prop, array_index, value);
- written = TRUE;
+ written = true;
}
}
else {
if (RNA_property_float_get(&new_ptr, prop) != value) {
RNA_property_float_set(&new_ptr, prop, value);
- written = TRUE;
+ written = true;
}
}
break;
case PROP_ENUM:
if (RNA_property_enum_get(&new_ptr, prop) != (int)value) {
RNA_property_enum_set(&new_ptr, prop, (int)value);
- written = TRUE;
+ written = true;
}
break;
default:
@@ -1401,7 +1401,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
* where some channels will not exist, but shouldn't lock up Action */
if (G.debug & G_DEBUG) {
printf("Animato: Invalid path. ID = '%s', '%s[%d]'\n",
- (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+ (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
path, array_index);
}
return 0;
@@ -1409,11 +1409,11 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
}
/* Simple replacement based data-setting of the FCurve using RNA */
-static short animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
+static bool animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
{
char *path = NULL;
- short free_path = 0;
- short ok = 0;
+ bool free_path = false;
+ bool ok = false;
/* get path, remapped as appropriate to work in its new environment */
free_path = animsys_remap_path(remap, fcu->rna_path, &path);
@@ -1463,7 +1463,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
*/
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
ChannelDriver *driver = fcu->driver;
- short ok = 0;
+ bool ok = false;
/* check if this driver's curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
@@ -1798,7 +1798,7 @@ static void nlaevalchan_value_init(NlaEvalChannel *nec)
}
/* verify that an appropriate NlaEvalChannel for this F-Curve exists */
-static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes, FCurve *fcu)
+static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes, FCurve *fcu, bool *newChan)
{
NlaEvalChannel *nec;
NlaStrip *strip = nes->strip;
@@ -1841,19 +1841,29 @@ static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, ListBase *channels, N
/* initialise value using default value of property [#35856] */
nlaevalchan_value_init(nec);
+ *newChan = true;
}
+ else
+ *newChan = false;
/* we can now return */
return nec;
}
/* accumulate (i.e. blend) the given value on to the channel it affects */
-static void nlaevalchan_accumulate(NlaEvalChannel *nec, NlaEvalStrip *nes, float value)
+static void nlaevalchan_accumulate(NlaEvalChannel *nec, NlaEvalStrip *nes, float value, bool newChan)
{
NlaStrip *strip = nes->strip;
short blendmode = strip->blendmode;
float inf = strip->influence;
+ /* for replace blend mode, and if this is the first strip,
+ * just replace the value regardless of the influence */
+ if (newChan && blendmode == NLASTRIP_MODE_REPLACE) {
+ nec->value = value;
+ return;
+ }
+
/* if this is being performed as part of transition evaluation, incorporate
* an additional weighting factor for the influence
*/
@@ -1915,7 +1925,7 @@ static void nlaevalchan_buffers_accumulate(ListBase *channels, ListBase *tmp_buf
* otherwise, add the current channel to the buffer for efficiency
*/
if (necd)
- nlaevalchan_accumulate(necd, nes, nec->value);
+ nlaevalchan_accumulate(necd, nes, 0, nec->value);
else {
BLI_remlink(tmp_buffer, nec);
BLI_addtail(channels, nec);
@@ -2014,6 +2024,7 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, ListBase *channels, Li
for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
NlaEvalChannel *nec;
float value = 0.0f;
+ bool newChan;
/* check if this curve should be skipped */
if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))
@@ -2035,9 +2046,9 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr, ListBase *channels, Li
/* get an NLA evaluation channel to work with, and accumulate the evaluated value with the value(s)
* stored in this channel if it has been used already
*/
- nec = nlaevalchan_verify(ptr, channels, nes, fcu);
+ nec = nlaevalchan_verify(ptr, channels, nes, fcu, &newChan);
if (nec)
- nlaevalchan_accumulate(nec, nes, value);
+ nlaevalchan_accumulate(nec, nes, value, newChan);
}
/* free temporary storage */
@@ -2106,7 +2117,6 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr, ListBase *channels, Li
/* evaluate meta-strip */
static void nlastrip_evaluate_meta(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
- ListBase tmp_channels = {NULL, NULL};
ListBase tmp_modifiers = {NULL, NULL};
NlaStrip *strip = nes->strip;
NlaEvalStrip *tmp_nes;
@@ -2119,26 +2129,23 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr, ListBase *channels, ListBase
*
* NOTE: keep this in sync with animsys_evaluate_nla()
*/
-
+
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
/* find the child-strip to evaluate */
evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime);
- if (tmp_nes == NULL)
- return;
-
- /* evaluate child-strip into tmp_channels buffer before accumulating
- * in the accumulation buffer
- */
- nlastrip_evaluate(ptr, &tmp_channels, &tmp_modifiers, tmp_nes);
-
- /* accumulate temp-buffer and full-buffer, using the 'real' strip */
- nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
- /* free temp eval-strip */
- MEM_freeN(tmp_nes);
+ /* directly evaluate child strip into accumulation buffer...
+ * - there's no need to use a temporary buffer (as it causes issues [T40082])
+ */
+ if (tmp_nes) {
+ nlastrip_evaluate(ptr, channels, &tmp_modifiers, tmp_nes);
+
+ /* free temp eval-strip */
+ MEM_freeN(tmp_nes);
+ }
/* unlink this strip's modifiers from the parent's modifiers again */
nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
@@ -2148,7 +2155,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr, ListBase *channels, ListBase
void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
NlaStrip *strip = nes->strip;
-
+
/* to prevent potential infinite recursion problems (i.e. transition strip, beside meta strip containing a transition
* several levels deep inside it), we tag the current strip as being evaluated, and clear this when we leave
*/
@@ -2238,6 +2245,9 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
ListBase estrips = {NULL, NULL};
NlaEvalStrip *nes;
+ NlaStrip dummy_strip = {NULL}; /* dummy strip for active action */
+
+
/* 1. get the stack of strips to evaluate at current time (influence calculated here) */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
/* stop here if tweaking is on and this strip is the tweaking track (it will be the first one that's 'disabled')... */
@@ -2255,7 +2265,7 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
* - used for mainly for still allowing normal action evaluation...
*/
if (nlt->strips.first)
- has_strips = 1;
+ has_strips = true;
/* otherwise, get strip to evaluate for this channel */
nes = nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime);
@@ -2271,7 +2281,6 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
/* if there are strips, evaluate action as per NLA rules */
if ((has_strips) || (adt->actstrip)) {
/* make dummy NLA strip, and add that to the stack */
- NlaStrip dummy_strip = {NULL};
ListBase dummy_trackslist;
dummy_trackslist.first = dummy_trackslist.last = &dummy_strip;
@@ -2294,6 +2303,9 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
dummy_strip.blendmode = adt->act_blendmode;
dummy_strip.extendmode = adt->act_extendmode;
dummy_strip.influence = adt->act_influence;
+
+ /* NOTE: must set this, or else the default setting overrides, and this setting doesn't work */
+ dummy_strip.flag |= NLASTRIP_FLAG_USR_INFLUENCE;
}
/* add this to our list of evaluation strips */
@@ -2302,7 +2314,10 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
else {
/* special case - evaluate as if there isn't any NLA data */
/* TODO: this is really just a stop-gap measure... */
+ if (G.debug & G_DEBUG) printf("NLA Eval: Stopgap for active action on NLA Stack - no strips case\n");
+
animsys_evaluate_action(ptr, adt->action, adt->remap, ctime);
+ BLI_freelistN(&estrips);
return;
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index caec93a6627..fda252e81fd 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -47,7 +47,6 @@
#include "DNA_mesh_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_nla_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -137,7 +136,7 @@ void BKE_armature_free(bArmature *arm)
void BKE_armature_make_local(bArmature *arm)
{
Main *bmain = G.main;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
Object *ob;
if (arm->id.lib == NULL)
@@ -150,13 +149,13 @@ void BKE_armature_make_local(bArmature *arm)
for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
if (ob->data == arm) {
if (ob->id.lib)
- is_lib = TRUE;
+ is_lib = true;
else
- is_local = TRUE;
+ is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &arm->id);
}
else if (is_local && is_lib) {
@@ -594,7 +593,6 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info
Mat4 b_bone[MAX_BBONE_SUBDIV], b_bone_rest[MAX_BBONE_SUBDIV];
Mat4 *b_bone_mats;
DualQuat *b_bone_dual_quats = NULL;
- float tmat[4][4] = MAT4_UNITY;
int a;
b_bone_spline_setup(pchan, 0, b_bone);
@@ -620,6 +618,8 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info
* - transform back into global space */
for (a = 0; a < bone->segments; a++) {
+ float tmat[4][4];
+
invert_m4_m4(tmat, b_bone_rest[a].mat);
mul_serie_m4(b_bone_mats[a + 1].mat, pchan->chan_mat, bone->arm_mat, b_bone[a].mat, tmat, b_bone_mats[0].mat,
@@ -674,7 +674,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3
sub_v3_v3v3(pdelta, vec, b1);
a = dot_v3v3(bdelta, pdelta);
- hsqr = dot_v3v3(pdelta, pdelta);
+ hsqr = len_squared_v3(pdelta);
if (a < 0.0f) {
/* If we're past the end of the bone, do a spherical field attenuation thing */
@@ -827,7 +827,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
const short invert_vgroup = deformflag & ARM_DEF_INVERT_VGROUP;
int defbase_tot = 0; /* safety for vertexgroup index overflow */
int i, target_totvert = 0; /* safety for vertexgroup overflow */
- int use_dverts = FALSE;
+ bool use_dverts = false;
int armature_def_nr;
int totchan;
@@ -888,10 +888,10 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
if (ELEM(target->type, OB_MESH, OB_LATTICE)) {
/* if we have a DerivedMesh, only use dverts if it has them */
if (dm) {
- use_dverts = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);
+ use_dverts = (dm->getVertDataArray(dm, CD_MDEFORMVERT) != NULL);
}
else if (dverts) {
- use_dverts = TRUE;
+ use_dverts = true;
}
if (use_dverts) {
@@ -1108,10 +1108,11 @@ void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[
* pose-channel into its local space (i.e. 'visual'-keyframing) */
void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outloc[3])
{
- float xLocMat[4][4] = MAT4_UNITY;
+ float xLocMat[4][4];
float nLocMat[4][4];
/* build matrix for location */
+ unit_m4(xLocMat);
copy_v3_v3(xLocMat[3], inloc);
/* get bone-space cursor matrix and extract location */
@@ -1277,10 +1278,11 @@ void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float
* pose-channel into its local space (i.e. 'visual'-keyframing) */
void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], float outloc[3])
{
- float xLocMat[4][4] = MAT4_UNITY;
+ float xLocMat[4][4];
float nLocMat[4][4];
/* build matrix for location */
+ unit_m4(xLocMat);
copy_v3_v3(xLocMat[3], inloc);
/* get bone-space cursor matrix and extract location */
@@ -1294,19 +1296,19 @@ void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inm
/* recalculate pose matrix with only parent transformations,
* bone loc/sca/rot is ignored, scene and frame are not used. */
- BKE_pose_where_is_bone(NULL, ob, &work_pchan, 0.0f, FALSE);
+ BKE_pose_where_is_bone(NULL, ob, &work_pchan, 0.0f, false);
/* find the matrix, need to remove the bone transforms first so this is
* calculated as a matrix to set rather then a difference ontop of whats
* already there. */
unit_m4(outmat);
- BKE_pchan_apply_mat4(&work_pchan, outmat, FALSE);
+ BKE_pchan_apply_mat4(&work_pchan, outmat, false);
BKE_armature_mat_pose_to_bone(&work_pchan, inmat, outmat);
}
/* same as BKE_object_mat3_to_rot() */
-void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compat)
+void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], bool use_compat)
{
switch (pchan->rotmode) {
case ROT_MODE_QUAT:
@@ -1326,7 +1328,7 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compa
/* Apply a 4x4 matrix to the pose bone,
* similar to BKE_object_apply_mat4() */
-void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], short use_compat)
+void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], bool use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
@@ -1414,6 +1416,7 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float
* pose_mat(b)= arm_mat(b) * chan_mat(b)
*
* *************************************************************************** */
+
/* Computes vector and roll based on a rotation.
* "mat" must contain only a rotation, and no scaling. */
void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll)
@@ -1433,52 +1436,101 @@ void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll)
}
}
-/* Calculates the rest matrix of a bone based
- * On its vector and a roll around that vector */
+/* Calculates the rest matrix of a bone based on its vector and a roll around that vector. */
+/* Given v = (v.x, v.y, v.z) our (normalized) bone vector, we want the rotation matrix M
+ * from the Y axis (so that M * (0, 1, 0) = v).
+ * -> The rotation axis a lays on XZ plane, and it is orthonormal to v, hence to the projection of v onto XZ plane.
+ * -> a = (v.z, 0, -v.x)
+ * We know a is eigenvector of M (so M * a = a).
+ * Finally, we have w, such that M * w = (0, 1, 0) (i.e. the vector that will be aligned with Y axis once transformed).
+ * We know w is symmetric to v by the Y axis.
+ * -> w = (-v.x, v.y, -v.z)
+ *
+ * Solving this, we get (x, y and z being the components of v):
+ * ┌ (x^2 * y + z^2) / (x^2 + z^2), x, x * z * (y - 1) / (x^2 + z^2) ┐
+ * M = │ x * (y^2 - 1) / (x^2 + z^2), y, z * (y^2 - 1) / (x^2 + z^2) │
+ * └ x * z * (y - 1) / (x^2 + z^2), z, (x^2 + z^2 * y) / (x^2 + z^2) ┘
+ *
+ * This is stable as long as v (the bone) is not too much aligned with +/-Y (i.e. x and z components
+ * are not too close to 0).
+ *
+ * Since v is normalized, we have x^2 + y^2 + z^2 = 1, hence x^2 + z^2 = 1 - y^2 = (1 - y)(1 + y).
+ * This allows to simplifies M like this:
+ * ┌ 1 - x^2 / (1 + y), x, -x * z / (1 + y) ┐
+ * M = │ -x, y, -z │
+ * └ -x * z / (1 + y), z, 1 - z^2 / (1 + y) ┘
+ *
+ * Written this way, we see the case v = +Y is no more a singularity. The only one remaining is the bone being
+ * aligned with -Y.
+ *
+ * Let's handle the asymptotic behavior when bone vector is reaching the limit of y = -1. Each of the four corner
+ * elements can vary from -1 to 1, depending on the axis a chosen for doing the rotation. And the "rotation" here
+ * is in fact established by mirroring XZ plane by that given axis, then inversing the Y-axis.
+ * For sufficiently small x and z, and with y approaching -1, all elements but the four corner ones of M
+ * will degenerate. So let's now focus on these corner elements.
+ *
+ * We rewrite M so that it only contains its four corner elements, and combine the 1 / (1 + y) factor:
+ * ┌ 1 + y - x^2, -x * z ┐
+ * M* = 1 / (1 + y) * │ │
+ * └ -x * z, 1 + y - z^2 ┘
+ *
+ * When y is close to -1, computing 1 / (1 + y) will cause severe numerical instability, so we ignore it and
+ * normalize M instead. We know y^2 = 1 - (x^2 + z^2), and y < 0, hence y = -sqrt(1 - (x^2 + z^2)).
+ * Since x and z are both close to 0, we apply the binomial expansion to the first order:
+ * y = -sqrt(1 - (x^2 + z^2)) = -1 + (x^2 + z^2) / 2. Which gives:
+ * ┌ z^2 - x^2, -2 * x * z ┐
+ * M* = 1 / (x^2 + z^2) * │ │
+ * └ -2 * x * z, x^2 - z^2 ┘
+ */
void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
{
- float nor[3], axis[3], target[3] = {0, 1, 0};
+#define THETA_THRESHOLD_NEGY 1.0e-9f
+#define THETA_THRESHOLD_NEGY_CLOSE 1.0e-5f
+
+ float nor[3];
float theta;
float rMatrix[3][3], bMatrix[3][3];
normalize_v3_v3(nor, vec);
- /* Find Axis & Amount for bone matrix */
- cross_v3_v3v3(axis, target, nor);
+ theta = 1.0f + nor[1];
- /* was 0.0000000000001, caused bug [#23954], smaller values give unstable
- * roll when toggling editmode.
+ /* With old algo, 1.0e-13f caused T23954 and T31333, 1.0e-6f caused T27675 and T30438,
+ * so using 1.0e-9f as best compromise.
*
- * was 0.00001, causes bug [#27675], with 0.00000495,
- * so a value inbetween these is needed.
+ * New algo is supposed much more precise, since less complex computations are performed,
+ * but it uses two different threshold values...
*
- * was 0.000001, causes bug [#30438] (which is same as [#27675, imho).
- * Resetting it to org value seems to cause no more [#23954]...
- *
- * was 0.0000000000001, caused bug [#31333], smaller values give unstable
- * roll when toggling editmode again...
- * No good value here, trying 0.000000001 as best compromise. :/
+ * Note: When theta is close to zero, we have to check we do have non-null X/Z components as well
+ * (due to float precision errors, we can have nor = (0.0, 0.99999994, 0.0)...).
*/
- if (dot_v3v3(axis, axis) > 1.0e-9f) {
- /* if nor is *not* a multiple of target ... */
- normalize_v3(axis);
-
- theta = angle_normalized_v3v3(target, nor);
-
- /* Make Bone matrix*/
- axis_angle_normalized_to_mat3(bMatrix, axis, theta);
+ if (theta > THETA_THRESHOLD_NEGY_CLOSE || ((nor[0] || nor[2]) && theta > THETA_THRESHOLD_NEGY)) {
+ /* nor is *not* -Y.
+ * We got these values for free... so be happy with it... ;)
+ */
+ bMatrix[0][1] = -nor[0];
+ bMatrix[1][0] = nor[0];
+ bMatrix[1][1] = nor[1];
+ bMatrix[1][2] = nor[2];
+ bMatrix[2][1] = -nor[2];
+ if (theta > THETA_THRESHOLD_NEGY_CLOSE) {
+ /* If nor is far enough from -Y, apply the general case. */
+ bMatrix[0][0] = 1 - nor[0] * nor[0] / theta;
+ bMatrix[2][2] = 1 - nor[2] * nor[2] / theta;
+ bMatrix[2][0] = bMatrix[0][2] = -nor[0] * nor[2] / theta;
+ }
+ else {
+ /* If nor is too close to -Y, apply the special case. */
+ theta = nor[0] * nor[0] + nor[2] * nor[2];
+ bMatrix[0][0] = (nor[0] + nor[2]) * (nor[0] - nor[2]) / -theta;
+ bMatrix[2][2] = -bMatrix[0][0];
+ bMatrix[2][0] = bMatrix[0][2] = 2.0f * nor[0] * nor[2] / theta;
+ }
}
else {
- /* if nor is a multiple of target ... */
- float updown;
-
- /* point same direction, or opposite? */
- updown = (dot_v3v3(target, nor) > 0) ? 1.0f : -1.0f;
-
- /* I think this should work... */
- bMatrix[0][0] = updown; bMatrix[0][1] = 0.0; bMatrix[0][2] = 0.0;
- bMatrix[1][0] = 0.0; bMatrix[1][1] = updown; bMatrix[1][2] = 0.0;
- bMatrix[2][0] = 0.0; bMatrix[2][1] = 0.0; bMatrix[2][2] = 1.0;
+ /* If nor is -Y, simple symmetry by Z axis. */
+ unit_m3(bMatrix);
+ bMatrix[0][0] = bMatrix[1][1] = -1.0;
}
/* Make Roll matrix */
@@ -1486,6 +1538,9 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
/* Combine and output result */
mul_m3_m3m3(mat, rMatrix, bMatrix);
+
+#undef THETA_THRESHOLD_NEGY
+#undef THETA_THRESHOLD_NEGY_CLOSE
}
@@ -1615,16 +1670,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
*
- * Note for BKE_copy_constraints: when copying constraints, disable 'do_extern' otherwise
+ * Note for BKE_constraints_copy: when copying constraints, disable 'do_extern' otherwise
* we get the libs direct linked in this blend.
*/
- BKE_extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- BKE_copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
+ BKE_constraints_proxylocal_extract(&proxylocal_constraints, &pchan->constraints);
+ BKE_constraints_copy(&pchanw.constraints, &pchanp->constraints, false);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1768,7 +1823,7 @@ typedef struct tSplineIK_Tree {
int type; /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */
- short free_points; /* free the point positions array */
+ bool free_points; /* free the point positions array */
short chainlen; /* number of bones in the chain */
float *points; /* parametric positions for the joints along the curve */
@@ -1791,7 +1846,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
bSplineIKConstraint *ikData = NULL;
float boneLengths[255], *jointPoints;
float totLength = 0.0f;
- short free_joints = 0;
+ bool free_joints = 0;
int segcount = 0;
/* find the SplineIK constraint */
@@ -2261,13 +2316,13 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
int do_modif;
for (strip = armob->nlastrips.first; strip; strip = strip->next) {
- do_modif = FALSE;
+ do_modif = false;
if (scene_cfra >= strip->start && scene_cfra <= strip->end)
- do_modif = TRUE;
+ do_modif = true;
if ((scene_cfra > strip->end) && (strip->flag & ACTSTRIP_HOLDLASTFRAME)) {
- do_modif = TRUE;
+ do_modif = true;
/* if there are any other strips active, ignore modifiers for this strip -
* 'hold' option should only hold action modifiers if there are
@@ -2277,7 +2332,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
if (scene_cfra >= strip2->start && scene_cfra <= strip2->end) {
if (!(strip2->flag & ACTSTRIP_MUTE))
- do_modif = FALSE;
+ do_modif = false;
}
}
@@ -2286,7 +2341,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
for (strip2 = strip->next; strip2; strip2 = strip2->next) {
if (scene_cfra < strip2->start) continue;
if ((strip2->flag & ACTSTRIP_HOLDLASTFRAME) && !(strip2->flag & ACTSTRIP_MUTE)) {
- do_modif = FALSE;
+ do_modif = false;
}
}
}
@@ -2306,7 +2361,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
if (strcmp(pchan->name, amod->channel) == 0) {
float mat4[4][4], mat3[3][3];
- curve_deform_vector(amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
+ curve_deform_vector(scene, amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
copy_m4_m4(mat4, pchan->pose_mat);
mul_m4_m3m4(pchan->pose_mat, mat3, mat4);
@@ -2390,7 +2445,7 @@ void BKE_pose_where_is_bone_tail(bPoseChannel *pchan)
/* pchan is validated, as having bone and parent pointer
* 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers.
*/
-void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, int do_extra)
+void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
{
/* This gives a chan_mat with actions (ipos) results. */
if (do_extra)
@@ -2429,7 +2484,7 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float
cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
- BKE_solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
+ BKE_constraints_solve(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
/* cleanup after Constraint Solving
* - applies matrix back to pchan, and frees temporary struct used
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index ed48bf5f3a4..8b87f5b0cea 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -29,15 +29,15 @@
* \ingroup bke
*/
+#ifndef _GNU_SOURCE
+/* Needed for O_NOFOLLOW on some platforms. */
+# define _GNU_SOURCE 1
+#endif
#ifndef _WIN32
# include <unistd.h> // for read close
#else
# include <io.h> // for open close read
-# define open _open
-# define read _read
-# define close _close
-# define write _write
#endif
#include <stdlib.h>
@@ -52,12 +52,9 @@
#include "DNA_userdef_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
@@ -69,7 +66,6 @@
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -504,20 +500,22 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report
int BKE_read_file_userdef(const char *filepath, ReportList *reports)
{
BlendFileData *bfd;
- int retval = 0;
-
+ int retval = BKE_READ_FILE_FAIL;
+
bfd = BLO_read_from_file(filepath, reports);
- if (bfd->user) {
- retval = BKE_READ_FILE_OK_USERPREFS;
-
- /* only here free userdef themes... */
- BKE_userdef_free();
-
- U = *bfd->user;
- MEM_freeN(bfd->user);
+ if (bfd) {
+ if (bfd->user) {
+ retval = BKE_READ_FILE_OK_USERPREFS;
+
+ /* only here free userdef themes... */
+ BKE_userdef_free();
+
+ U = *bfd->user;
+ MEM_freeN(bfd->user);
+ }
+ BKE_main_free(bfd->main);
+ MEM_freeN(bfd);
}
- BKE_main_free(bfd->main);
- MEM_freeN(bfd);
return retval;
}
@@ -554,7 +552,7 @@ int blender_test_break(void)
blender_test_break_cb();
}
- return (G.is_break == TRUE);
+ return (G.is_break == true);
}
@@ -598,7 +596,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
if (success) {
/* important not to update time here, else non keyed tranforms are lost */
- DAG_on_visible_update(G.main, FALSE);
+ DAG_on_visible_update(G.main, false);
}
return success;
@@ -798,13 +796,16 @@ const char *BKE_undo_get_name(int nr, int *active)
return NULL;
}
-/* saves .blend using undo buffer, returns 1 == success */
-int BKE_undo_save_file(const char *filename)
+/**
+ * Saves .blend using undo buffer.
+ *
+ * \return success.
+ */
+bool BKE_undo_save_file(const char *filename)
{
UndoElem *uel;
MemFileChunk *chunk;
- const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL;
- int file;
+ int file, oflags;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
return 0;
@@ -816,16 +817,21 @@ int BKE_undo_save_file(const char *filename)
return 0;
}
- /* first try create the file, if it exists call without 'O_CREAT',
- * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
- errno = 0;
- file = BLI_open(filename, flag, 0666);
- if (file < 0) {
- if (errno == EEXIST) {
- errno = 0;
- file = BLI_open(filename, flag & ~O_CREAT, 0666);
- }
- }
+ /* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK,
+ * however if this is ever executed explicitly by the user, we may want to allow writing to symlinks.
+ */
+
+ oflags = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
+#ifdef O_NOFOLLOW
+ /* use O_NOFOLLOW to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
+ oflags |= O_NOFOLLOW;
+#else
+ /* TODO(sergey): How to deal with symlinks on windows? */
+# ifndef _MSC_VER
+# warning "Symbolic links will be followed on undo save, possibly causing CVE-2008-1103"
+# endif
+#endif
+ file = BLI_open(filename, oflags, 0666);
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index a8d64ea9fb6..5731455fc01 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -255,8 +255,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
//check boids in own system
if (acbr->options & BRULE_ACOLL_WITH_BOIDS) {
- neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, pa->prev_state.co, pa->prev_state.ave,
- &ptn, acbr->look_ahead * len_v3(pa->prev_state.vel));
+ neighbors = BLI_kdtree_range_search__normal(
+ bbd->sim->psys->tree, pa->prev_state.co, pa->prev_state.ave,
+ &ptn, acbr->look_ahead * len_v3(pa->prev_state.vel));
if (neighbors > 1) for (n=1; n<neighbors; n++) {
copy_v3_v3(co1, pa->prev_state.co);
copy_v3_v3(vel1, pa->prev_state.vel);
@@ -302,8 +303,10 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
if (epsys) {
- neighbors = BLI_kdtree_range_search(epsys->tree, pa->prev_state.co, pa->prev_state.ave,
- &ptn, acbr->look_ahead * len_v3(pa->prev_state.vel));
+ neighbors = BLI_kdtree_range_search__normal(
+ epsys->tree, pa->prev_state.co, pa->prev_state.ave,
+ &ptn, acbr->look_ahead * len_v3(pa->prev_state.vel));
+
if (neighbors > 0) for (n=0; n<neighbors; n++) {
copy_v3_v3(co1, pa->prev_state.co);
copy_v3_v3(vel1, pa->prev_state.vel);
@@ -358,8 +361,9 @@ static int rule_separate(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues
ParticleTarget *pt;
float len = 2.0f * val->personal_space * pa->size + 1.0f;
float vec[3] = {0.0f, 0.0f, 0.0f};
- int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, pa->prev_state.co, NULL,
- &ptn, 2.0f * val->personal_space * pa->size);
+ int neighbors = BLI_kdtree_range_search(
+ bbd->sim->psys->tree, pa->prev_state.co,
+ &ptn, 2.0f * val->personal_space * pa->size);
int ret = 0;
if (neighbors > 1 && ptn[1].dist!=0.0f) {
@@ -377,8 +381,9 @@ static int rule_separate(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues
ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
if (epsys) {
- neighbors = BLI_kdtree_range_search(epsys->tree, pa->prev_state.co, NULL,
- &ptn, 2.0f * val->personal_space * pa->size);
+ neighbors = BLI_kdtree_range_search(
+ epsys->tree, pa->prev_state.co,
+ &ptn, 2.0f * val->personal_space * pa->size);
if (neighbors > 0 && ptn[0].dist < len) {
sub_v3_v3v3(vec, pa->prev_state.co, ptn[0].co);
@@ -398,7 +403,7 @@ static int rule_flock(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues *UN
{
KDTreeNearest ptn[11];
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
- int neighbors = BLI_kdtree_find_nearest_n(bbd->sim->psys->tree, pa->state.co, pa->prev_state.ave, ptn, 11);
+ int neighbors = BLI_kdtree_find_nearest_n__normal(bbd->sim->psys->tree, pa->state.co, pa->prev_state.ave, ptn, 11);
int n;
int ret = 0;
@@ -625,8 +630,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
int n, ret = 0;
/* calculate own group strength */
- int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, pa->prev_state.co, NULL,
- &ptn, fbr->distance);
+ int neighbors = BLI_kdtree_range_search(
+ bbd->sim->psys->tree, pa->prev_state.co,
+ &ptn, fbr->distance);
for (n=0; n<neighbors; n++) {
bpa = bbd->sim->psys->particles[ptn[n].index].boid;
health += bpa->data.health;
@@ -642,8 +648,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
if (epsys) {
epars = epsys->particles;
- neighbors = BLI_kdtree_range_search(epsys->tree, pa->prev_state.co, NULL,
- &ptn, fbr->distance);
+ neighbors = BLI_kdtree_range_search(
+ epsys->tree, pa->prev_state.co,
+ &ptn, fbr->distance);
health = 0.0f;
@@ -970,8 +977,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
bbd->wanted_speed = 0.0f;
/* create random seed for every particle & frame */
- rand = (int)(PSYS_FRAND(psys->seed + p) * 1000);
- rand = (int)(PSYS_FRAND((int)bbd->cfra + rand) * 1000);
+ rand = (int)(psys_frand(psys, psys->seed + p) * 1000);
+ rand = (int)(psys_frand(psys, (int)bbd->cfra + rand) * 1000);
set_boid_values(&val, bbd->part->boids, pa);
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index e23dfaf8fea..f7597903c6f 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -578,13 +578,14 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
SEQ_BEGIN(scene->ed, seq)
{
if (SEQ_HAS_PATH(seq)) {
- if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) {
- rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name,
+ StripElem *se = seq->strip->stripdata;
+
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) {
+ rewrite_path_fixed_dirfile(seq->strip->dir, se->name,
visit_cb, absbase, bpath_user_data);
}
- else if (seq->type == SEQ_TYPE_IMAGE) {
+ else if ((seq->type == SEQ_TYPE_IMAGE) && se) {
/* might want an option not to loop over all strips */
- StripElem *se = seq->strip->stripdata;
int len = MEM_allocN_len(se) / sizeof(*se);
int i;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 4885798efb7..967e89e0dd1 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -38,7 +38,6 @@
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
-#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_paint.h"
@@ -212,7 +211,7 @@ void BKE_brush_make_local(Brush *brush)
Main *bmain = G.main;
Scene *scene;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
if (brush->id.lib == NULL) return;
@@ -225,12 +224,12 @@ void BKE_brush_make_local(Brush *brush)
for (scene = bmain->scene.first; scene && ELEM(0, is_lib, is_local); scene = scene->id.next) {
if (BKE_paint_brush(&scene->toolsettings->imapaint.paint) == brush) {
- if (scene->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (scene->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &brush->id);
extern_local_brush(brush);
@@ -450,7 +449,7 @@ void BKE_brush_curve_preset(Brush *b, int preset)
b->curve->preset = preset;
curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
- curvemapping_changed(b->curve, FALSE);
+ curvemapping_changed(b->curve, false);
}
int BKE_brush_texture_set_nr(Brush *brush, int nr)
@@ -561,11 +560,8 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
x /= (br->stencil_dimension[0]);
y /= (br->stencil_dimension[1]);
- x *= mtex->size[0];
- y *= mtex->size[1];
-
- co[0] = x + mtex->ofs[0];
- co[1] = y + mtex->ofs[1];
+ co[0] = x;
+ co[1] = y;
co[2] = 0.0f;
hasrgb = externtex(mtex, co, &intensity,
@@ -621,11 +617,8 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
y = flen * sinf(angle);
}
- x *= mtex->size[0];
- y *= mtex->size[1];
-
- co[0] = x + mtex->ofs[0];
- co[1] = y + mtex->ofs[1];
+ co[0] = x;
+ co[1] = y;
co[2] = 0.0f;
hasrgb = externtex(mtex, co, &intensity,
@@ -640,22 +633,16 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
rgba[2] = intensity;
rgba[3] = 1.0f;
}
- else {
- if (br->mtex.tex->type == TEX_IMAGE && br->mtex.tex->ima) {
- ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(br->mtex.tex->ima, &br->mtex.tex->iuser, pool);
- /* For consistency, sampling always returns color in linear space */
- if (tex_ibuf && tex_ibuf->rect_float == NULL) {
- IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, tex_ibuf->rect_colorspace);
- }
- BKE_image_pool_release_ibuf(br->mtex.tex->ima, tex_ibuf, pool);
- }
+ /* For consistency, sampling always returns color in linear space */
+ else if (ups->do_linear_conversion) {
+ IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ups->colorspace);
}
return intensity;
}
float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
- const float point[3],
+ const float point[2],
const int thread,
struct ImagePool *pool)
{
@@ -690,11 +677,8 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
x /= (br->mask_stencil_dimension[0]);
y /= (br->mask_stencil_dimension[1]);
- x *= mtex->size[0];
- y *= mtex->size[1];
-
- co[0] = x + mtex->ofs[0];
- co[1] = y + mtex->ofs[1];
+ co[0] = x;
+ co[1] = y;
co[2] = 0.0f;
externtex(mtex, co, &intensity,
@@ -750,11 +734,8 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
y = flen * sinf(angle);
}
- x *= mtex->size[0];
- y *= mtex->size[1];
-
- co[0] = x + mtex->ofs[0];
- co[1] = y + mtex->ofs[1];
+ co[0] = x;
+ co[1] = y;
co[2] = 0.0f;
externtex(mtex, co, &intensity,
@@ -985,8 +966,9 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_sec
{
unsigned int *texcache = NULL;
MTex *mtex = (use_secondary) ? &br->mask_mtex : &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
+ float intensity;
+ float rgba[4];
+ int ix, iy;
int side = half_side * 2;
if (mtex->tex) {
@@ -1003,19 +985,13 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_sec
/* This is copied from displace modifier code */
/* TODO(sergey): brush are always cacheing with CM enabled for now. */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL, true);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
+ externtex(mtex, co, &intensity,
+ rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
((char *)texcache)[(iy * side + ix) * 4] =
((char *)texcache)[(iy * side + ix) * 4 + 1] =
((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
+ ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(intensity * 255.0f);
}
}
}
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 7838fac09b5..f85a91b66cb 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -111,7 +111,7 @@ float nearest_point_in_tri_surface_squared(
B0 = dot_v3v3(diff, e0);
B1 = dot_v3v3(diff, e1);
C = dot_v3v3(diff, diff);
- Det = fabs(A00 * A11 - A01 * A01);
+ Det = fabsf(A00 * A11 - A01 * A01);
S = A01 * B1 - A11 * B0;
T = A01 * B0 - A00 * B1;
@@ -371,7 +371,7 @@ static void mesh_faces_nearest_point(void *userdata, int index, const float co[3
MVert *vert = data->vert;
MFace *face = data->face + index;
- float *t0, *t1, *t2, *t3;
+ const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
@@ -406,7 +406,7 @@ static void editmesh_faces_nearest_point(void *userdata, int index, const float
BMEditMesh *em = data->em_evil;
const BMLoop **ltri = (const BMLoop **)em->looptris[index];
- float *t0, *t1, *t2;
+ const float *t0, *t1, *t2;
t0 = ltri[0]->v->co;
t1 = ltri[1]->v->co;
t2 = ltri[2]->v->co;
@@ -433,7 +433,7 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r
MVert *vert = data->vert;
MFace *face = data->face + index;
- float *t0, *t1, *t2, *t3;
+ const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
@@ -471,7 +471,7 @@ static void editmesh_faces_spherecast(void *userdata, int index, const BVHTreeRa
BMEditMesh *em = data->em_evil;
const BMLoop **ltri = (const BMLoop **)em->looptris[index];
- float *t0, *t1, *t2;
+ const float *t0, *t1, *t2;
t0 = ltri[0]->v->co;
t1 = ltri[1]->v->co;
t2 = ltri[2]->v->co;
@@ -503,7 +503,7 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3
MEdge *edge = data->edge + index;
float nearest_tmp[3], dist_sq;
- float *t0, *t1;
+ const float *t0, *t1;
t0 = vert[edge->v1].co;
t1 = vert[edge->v2].co;
@@ -519,55 +519,6 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3
}
}
-static MVert *get_dm_vert_data_array(DerivedMesh *dm, bool *allocated)
-{
- CustomData *vert_data = dm->getVertDataLayout(dm);
- MVert *mvert = CustomData_get_layer(vert_data, CD_MVERT);
- *allocated = false;
-
- if (mvert == NULL) {
- mvert = MEM_mallocN(sizeof(MVert) * dm->getNumVerts(dm), "bvh vert data array");
- dm->copyVertArray(dm, mvert);
- *allocated = true;
- }
-
- return mvert;
-}
-
-static MEdge *get_dm_edge_data_array(DerivedMesh *dm, bool *allocated)
-{
- CustomData *edge_data = dm->getEdgeDataLayout(dm);
- MEdge *medge = CustomData_get_layer(edge_data, CD_MEDGE);
- *allocated = false;
-
- if (medge == NULL) {
- medge = MEM_mallocN(sizeof(MEdge) * dm->getNumEdges(dm), "bvh medge data array");
- dm->copyEdgeArray(dm, medge);
- *allocated = true;
- }
-
- return medge;
-}
-
-static MFace *get_dm_tessface_data_array(DerivedMesh *dm, bool *allocated)
-{
- CustomData *tessface_data = dm->getTessFaceDataLayout(dm);
- MFace *mface = CustomData_get_layer(tessface_data, CD_MFACE);
- *allocated = false;
-
- if (mface == NULL) {
- int numTessFaces = dm->getNumTessFaces(dm);
-
- if (numTessFaces > 0) {
- mface = MEM_mallocN(sizeof(MFace) * numTessFaces, "bvh mface data array");
- dm->copyTessFaceArray(dm, mface);
- *allocated = true;
- }
- }
-
- return mface;
-}
-
/*
* BVH builders
*/
@@ -582,7 +533,7 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float e
tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_VERTICES);
BLI_rw_mutex_unlock(&cache_rwlock);
- vert = get_dm_vert_data_array(dm, &vert_allocated);
+ vert = DM_get_vert_array(dm, &vert_allocated);
/* Not in cache */
if (tree == NULL) {
@@ -629,7 +580,7 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float e
data->vert = vert;
data->vert_allocated = vert_allocated;
- data->face = get_dm_tessface_data_array(dm, &data->face_allocated);
+ data->face = DM_get_tessface_array(dm, &data->face_allocated);
data->sphere_radius = epsilon;
}
@@ -657,8 +608,8 @@ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *dm, float e
BLI_rw_mutex_unlock(&cache_rwlock);
if (em == NULL) {
- vert = get_dm_vert_data_array(dm, &vert_allocated);
- face = get_dm_tessface_data_array(dm, &face_allocated);
+ vert = DM_get_vert_array(dm, &vert_allocated);
+ face = DM_get_tessface_array(dm, &face_allocated);
}
/* Not in cache */
@@ -827,8 +778,8 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_EDGES);
BLI_rw_mutex_unlock(&cache_rwlock);
- vert = get_dm_vert_data_array(dm, &vert_allocated);
- edge = get_dm_edge_data_array(dm, &edge_allocated);
+ vert = DM_get_vert_array(dm, &vert_allocated);
+ edge = DM_get_edge_array(dm, &edge_allocated);
/* Not in cache */
if (tree == NULL) {
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 3290f0eae8e..b20ba40c0dd 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -84,7 +84,7 @@ void BKE_camera_make_local(Camera *cam)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -99,12 +99,12 @@ void BKE_camera_make_local(Camera *cam)
for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
if (ob->data == cam) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &cam->id);
}
else if (is_local && is_lib) {
@@ -198,6 +198,10 @@ void BKE_camera_params_init(CameraParams *params)
params->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
params->zoom = 1.0f;
+
+ /* fallback for non camera objects */
+ params->clipsta = 0.1f;
+ params->clipsta = 100.0f;
}
void BKE_camera_params_from_object(CameraParams *params, Object *ob)
@@ -210,7 +214,7 @@ void BKE_camera_params_from_object(CameraParams *params, Object *ob)
Camera *cam = ob->data;
if (cam->type == CAM_ORTHO)
- params->is_ortho = TRUE;
+ params->is_ortho = true;
params->lens = cam->lens;
params->ortho_scale = cam->ortho_scale;
@@ -269,7 +273,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView
params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality
params->clipsta = -params->clipend;
- params->is_ortho = TRUE;
+ params->is_ortho = true;
/* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
params->zoom = 2.0f;
@@ -450,7 +454,7 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
float dummy_drawsize;
const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
- BKE_camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale,
+ BKE_camera_view_frame_ex(scene, camera, false, 1.0, dummy_scale,
dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 4f1bb87ebef..69b85a95a60 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -91,7 +91,7 @@ typedef struct {
/* Cached */
struct PBVH *pbvh;
- int pbvh_draw;
+ bool pbvh_draw;
/* Mesh connectivity */
MeshElemMap *pmap;
@@ -131,90 +131,90 @@ static int cdDM_getNumPolys(DerivedMesh *dm)
return dm->numPolyData;
}
-static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
+static void cdDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- *vert_r = cddm->mvert[index];
+ *r_vert = cddm->mvert[index];
}
-static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
+static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- *edge_r = cddm->medge[index];
+ *r_edge = cddm->medge[index];
}
-static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
+static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- *face_r = cddm->mface[index];
+ *r_face = cddm->mface[index];
}
-static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
+static void cdDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
+ memcpy(r_vert, cddm->mvert, sizeof(*r_vert) * dm->numVertData);
}
-static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
+static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
+ memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData);
}
-static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
+static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numTessFaceData);
+ memcpy(r_face, cddm->mface, sizeof(*r_face) * dm->numTessFaceData);
}
-static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
+static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
+ memcpy(r_loop, cddm->mloop, sizeof(*r_loop) * dm->numLoopData);
}
-static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
+static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
+ memcpy(r_poly, cddm->mpoly, sizeof(*r_poly) * dm->numPolyData);
}
-static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
+static void cdDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
int i;
if (dm->numVertData) {
for (i = 0; i < dm->numVertData; i++) {
- minmax_v3v3_v3(min_r, max_r, cddm->mvert[i].co);
+ minmax_v3v3_v3(r_min, r_max, cddm->mvert[i].co);
}
}
else {
- zero_v3(min_r);
- zero_v3(max_r);
+ zero_v3(r_min);
+ zero_v3(r_max);
}
}
-static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
+static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- copy_v3_v3(co_r, cddm->mvert[index].co);
+ copy_v3_v3(r_co, cddm->mvert[index].co);
}
-static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
+static void cdDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
{
MVert *mv = CDDM_get_verts(dm);
int i;
for (i = 0; i < dm->numVertData; i++, mv++)
- copy_v3_v3(cos_r[i], mv->co);
+ copy_v3_v3(r_cos[i], mv->co);
}
-static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
+static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- normal_short_to_float_v3(no_r, cddm->mvert[index].no);
+ normal_short_to_float_v3(r_no, cddm->mvert[index].no);
}
static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
@@ -232,24 +232,39 @@ static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
return cddm->pmap;
}
-static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
+static bool check_sculpt_object_deformed(Object *object, bool for_construction)
{
- CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- Mesh *me = ob->data;
- int deformed = 0;
+ bool deformed = false;
- /* active modifiers means extra deformation, which can't be handled correct
+ /* Active modifiers means extra deformation, which can't be handled correct
* on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
- * stuff and show final DerivedMesh so user would see actual object shape */
- deformed |= ob->sculpt->modifiers_active;
+ * stuff and show final DerivedMesh so user would see actual object shape.
+ */
+ deformed |= object->sculpt->modifiers_active;
- /* as in case with modifiers, we can't synchronize deformation made against
- * PBVH and non-locked keyblock, so also use PBVH only for brushes and
- * final DM to give final result to user */
- deformed |= ob->sculpt->kb && (ob->shapeflag & OB_SHAPE_LOCK) == 0;
+ if (for_construction) {
+ deformed |= object->sculpt->kb != NULL;
+ }
+ else {
+ /* As in case with modifiers, we can't synchronize deformation made against
+ * PBVH and non-locked keyblock, so also use PBVH only for brushes and
+ * final DM to give final result to user.
+ */
+ deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0;
+ }
- if (deformed)
- return 0;
+ return deformed;
+}
+
+static bool can_pbvh_draw(Object *ob, DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
+ Mesh *me = ob->data;
+ bool deformed = check_sculpt_object_deformed(ob, false);
+
+ if (deformed) {
+ return false;
+ }
return cddm->mvert == me->mvert || ob->sculpt->kb;
}
@@ -274,11 +289,14 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
/* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
if (!cddm->pbvh && ob->sculpt->bm) {
cddm->pbvh = BKE_pbvh_new();
- cddm->pbvh_draw = TRUE;
+ cddm->pbvh_draw = true;
BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
ob->sculpt->bm_smooth_shading,
- ob->sculpt->bm_log);
+ ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset,
+ ob->sculpt->cd_face_node_offset);
+
+ pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
}
@@ -286,21 +304,20 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
* this derivedmesh is just original mesh. it's the multires subsurf dm
* that this is actually for, to support a pbvh on a modified mesh */
if (!cddm->pbvh && ob->type == OB_MESH) {
- SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
- int deformed = 0;
+ bool deformed;
cddm->pbvh = BKE_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
- pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
-
BKE_mesh_tessface_ensure(me);
BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
- deformed = ss->modifiers_active || me->key;
+ pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
+
+ deformed = check_sculpt_object_deformed(ob, true);
if (deformed && ob->derivedDeform) {
DerivedMesh *deformdm = ob->derivedDeform;
@@ -308,7 +325,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
int totvert;
totvert = deformdm->getNumVerts(deformdm);
- vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
+ vertCos = MEM_mallocN(totvert * sizeof(float[3]), "cdDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
@@ -437,7 +454,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
}
}
-static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
+static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MVert *mvert = cddm->mvert;
@@ -484,7 +501,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int prevstart = 0;
int prevdraw = 1;
- int draw = TRUE;
+ bool draw = true;
GPU_edge_setup(dm);
if (!GPU_buffer_legacy(dm)) {
@@ -492,10 +509,10 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
(drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
{
- draw = TRUE;
+ draw = true;
}
else {
- draw = FALSE;
+ draw = false;
}
if (prevdraw != draw) {
if (prevdraw > 0 && (i - prevstart) > 0) {
@@ -565,27 +582,22 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
static void cdDM_drawFacesSolid(DerivedMesh *dm,
float (*partial_redraw_planes)[4],
- int UNUSED(fast), DMSetMaterial setMaterial)
+ bool UNUSED(fast), DMSetMaterial setMaterial)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
- float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
-#define PASSVERT(index) { \
- if (shademodel == GL_SMOOTH) { \
- short *no = mvert[index].no; \
- gpuNormal3sv(no); \
- } \
- gpuVertex3fv(mvert[index].co); \
-} (void)0
-
if (cddm->pbvh && cddm->pbvh_draw) {
if (dm->numTessFaceData) {
float (*face_nors)[3] = (float(*)[3])CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial, false);
+ BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
+ setMaterial, false);
+ GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
}
return;
@@ -600,8 +612,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
new_matnr = mface->mat_nr + 1;
- new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
-
+ new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
+
if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) {
gpuEnd();
@@ -618,7 +630,20 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
}
if (drawCurrentMat) {
- if (shademodel == GL_FLAT) {
+ if (lnors) {
+ gpuNormal3sv((const GLshort *)lnors[0][0]);
+ gpuVertex3fv(mvert[mface->v1].co);
+ gpuNormal3sv((const GLshort *)lnors[0][1]);
+ gpuVertex3fv(mvert[mface->v2].co);
+ gpuNormal3sv((const GLshort *)lnors[0][2]);
+ gpuVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ gpuNormal3sv((const GLshort *)lnors[0][3]);
+ gpuVertex3fv(mvert[mface->v4].co);
+ }
+ lnors++;
+ }
+ else if (shademodel == GL_FLAT) {
if (nors) {
gpuNormal3fv(nors);
}
@@ -633,13 +658,24 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
}
gpuNormal3fv(nor);
}
+ gpuVertex3fv(mvert[mface->v1].co);
+ gpuVertex3fv(mvert[mface->v2].co);
+ gpuVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ gpuVertex3fv(mvert[mface->v4].co);
+ }
}
-
- PASSVERT(mface->v1);
- PASSVERT(mface->v2);
- PASSVERT(mface->v3);
- if (mface->v4) {
- PASSVERT(mface->v4);
+ else { /* shademodel == GL_SMOOTH */
+ gpuNormal3sv(mvert[mface->v1].no);
+ gpuVertex3fv(mvert[mface->v1].co);
+ gpuNormal3sv(mvert[mface->v2].no);
+ gpuVertex3fv(mvert[mface->v2].co);
+ gpuNormal3sv(mvert[mface->v3].no);
+ gpuVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ gpuNormal3sv(mvert[mface->v4].no);
+ gpuVertex3fv(mvert[mface->v4].co);
+ }
}
}
@@ -661,7 +697,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
for (a = 0; a < dm->drawObject->totmaterial; a++) {
- if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
+ if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
dm->drawObject->materials[a].totpoint);
}
@@ -673,7 +709,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
GPU_buffer_unbind();
}
-#undef PASSVERT
+ // SSS Disable Smooth
+ GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH); // XXX jwilkins: why would this be needed?
}
static void cdDM_drawFacesTex_common(DerivedMesh *dm,
@@ -685,7 +722,8 @@ 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);
- float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
MCol *mcol;
int i, orig;
@@ -778,7 +816,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
cp = (unsigned char *) &mcol[i * 4];
- if (!(mf->flag & ME_SMOOTH)) {
+ if (!(lnors || (mf->flag & ME_SMOOTH))) {
if (nors) {
gpuNormal3fv(nors);
}
@@ -799,28 +837,33 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if (tf) gpuTexCoord2fv(tf[i].uv[0]);
if (cp) gpuColor3ub(cp[3], cp[2], cp[1]);
mvert = &mv[mf->v1];
- if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
+ if (lnors) gpuNormal3sv((const GLshort *)lnors[0][0]);
+ else if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
gpuVertex3fv(mvert->co);
-
+
if (tf) gpuTexCoord2fv(tf[i].uv[1]);
if (cp) gpuColor3ub(cp[7], cp[6], cp[5]);
mvert = &mv[mf->v2];
- if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
+ if (lnors) gpuNormal3sv((const GLshort *)lnors[0][1]);
+ else if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
gpuVertex3fv(mvert->co);
if (tf) gpuTexCoord2fv(tf[i].uv[2]);
if (cp) gpuColor3ub(cp[11], cp[10], cp[9]);
mvert = &mv[mf->v3];
- if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
+ if (lnors) gpuNormal3sv((const GLshort *)lnors[0][2]);
+ else if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
gpuVertex3fv(mvert->co);
if (mf->v4) {
if (tf) gpuTexCoord2fv(tf[i].uv[3]);
if (cp) gpuColor3ub(cp[15], cp[14], cp[13]);
mvert = &mv[mf->v4];
- if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
+ if (lnors) gpuNormal3sv((const GLshort *)lnors[0][3]);
+ else if (mf->flag & ME_SMOOTH) gpuNormal3sv(mvert->no);
gpuVertex3fv(mvert->co);
}
+ if (lnors) lnors++;
gpuEnd();
}
@@ -928,8 +971,9 @@ static void cdDM_drawMappedFaces(
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MVert *mv = cddm->mvert;
MFace *mf = cddm->mface;
- float *nors;
MCol *mcol;
+ const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int *index;
int colType;
int useColors = flag & DM_DRAW_USE_COLORS;
@@ -989,9 +1033,10 @@ static void cdDM_drawMappedFaces(
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
+ // XXX jwilkins: This look is really bad since it does so many state changes
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
- DMDrawOption draw_option;
+ int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH);
+ DMDrawOption draw_option = DM_DRAW_OPTION_NORMALLY;
orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
@@ -1014,16 +1059,33 @@ static void cdDM_drawMappedFaces(
}
else {
// SSS Enable Smooth
+ /* normals are used to change shading, so choose smooth so smooth shading will work (XXX jwilkins: rewrote to say what I think was meant */
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
}
if (useColors && mcol)
cp = (unsigned char *)&mcol[i * 4];
- /* normals are used to change shading, so choose smooth so smooth shading will work (XXX jwilkins: rewrote to say what I think was meant */
-
gpuBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
- if (!drawSmooth) {
+
+ if (lnors) {
+ if (cp) gpuColor3ub(cp[3], cp[2], cp[1]);
+ gpuNormal3sv((const GLshort *)lnors[0][0]);
+ gpuVertex3fv(mv[mf->v1].co);
+ if (cp) gpuColor3ub(cp[7], cp[6], cp[5]);
+ gpuNormal3sv((const GLshort *)lnors[0][1]);
+ gpuVertex3fv(mv[mf->v2].co);
+ if (cp) gpuColor3ub(cp[11], cp[10], cp[9]);
+ gpuNormal3sv((const GLshort *)lnors[0][2]);
+ gpuVertex3fv(mv[mf->v3].co);
+ if (mf->v4) {
+ if (cp) gpuColor3ub(cp[15], cp[14], cp[13]);
+ gpuNormal3sv((const GLshort *)lnors[0][3]);
+ gpuVertex3fv(mv[mf->v4].co);
+ }
+ lnors++;
+ }
+ else if (!drawSmooth) {
if (nors) {
gpuNormal3fv(nors);
}
@@ -1275,7 +1337,8 @@ static void cddm_unformat_attrib_vertex(void)
gpuImmediateUnlock();
}
-static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
+static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert,
+ short (*lnor)[3], int smoothnormal)
{
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int b;
@@ -1334,9 +1397,13 @@ static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int
}
/* vertex normal */
- if (smoothnormal)
+ if (lnor) {
+ gpuNormal3sv((const GLshort *)lnor);
+ }
+ else if (smoothnormal) {
gpuNormal3sv(mvert[index].no);
-
+ }
+
/* vertex coordinate */
gpuVertex3fv(mvert[index].co);
}
@@ -1353,7 +1420,9 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
MFace *mface = cddm->mface;
/* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
- int a, b, do_draw, matnr, new_matnr;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ int a, b, matnr, new_matnr;
+ bool do_draw;
int orig;
/* double lookup */
@@ -1379,7 +1448,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
cdDM_update_normals_from_pbvh(dm);
matnr = -1;
- do_draw = FALSE;
+ do_draw = false;
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
@@ -1392,7 +1461,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
gpuBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- const int smoothnormal = (mface->flag & ME_SMOOTH);
+ const int smoothnormal = lnors || (mface->flag & ME_SMOOTH);
+ short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
new_matnr = mface->mat_nr + 1;
if (new_matnr != matnr) {
@@ -1440,21 +1510,29 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
}
}
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
+ if (lnors) {
+ ln1 = &lnors[0][0];
+ ln2 = &lnors[0][1];
+ ln3 = &lnors[0][2];
+ ln4 = &lnors[0][3];
+ lnors++;
+ }
+
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
if (mface->v4)
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal);
else
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
}
gpuEnd();
cddm_unformat_attrib_vertex();
}
else {
GPUBuffer *buffer = NULL;
- char *varray = NULL;
+ const char *varray = NULL;
int numdata = 0, elementsize = 0, offset;
int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
int i;
@@ -1559,6 +1637,52 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
}
}
+ if (do_draw && numdata != 0) {
+ offset = 0;
+ if (attribs.totorco && attribs.orco.array) {
+ copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
+ offset += sizeof(float) * 3;
+ }
+ for (b = 0; b < attribs.tottface; b++) {
+ if (attribs.tface[b].array) {
+ MTFace *tf = &attribs.tface[b].array[a];
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
+
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
+ offset += sizeof(float) * 2;
+ }
+ }
+ for (b = 0; b < attribs.totmcol; b++) {
+ if (attribs.mcol[b].array) {
+ MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 1];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 2];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
+ offset += sizeof(unsigned char) * 4;
+ }
+ }
+ if (attribs.tottang && attribs.tang.array) {
+ const float *tang = attribs.tang.array[a * 4 + 0];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
+ tang = attribs.tang.array[a * 4 + 1];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
+ tang = attribs.tang.array[a * 4 + 2];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
+ offset += sizeof(float) * 4;
+ }
+ (void)offset;
+ }
+ curface++;
+ if (mface->v4) {
if (do_draw && numdata != 0) {
offset = 0;
if (attribs.totorco && attribs.orco.array) {
@@ -1593,7 +1717,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
}
}
if (attribs.tottang && attribs.tang.array) {
- float *tang = attribs.tang.array[a * 4 + 0];
+ const float *tang = attribs.tang.array[a * 4 + 2];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
tang = attribs.tang.array[a * 4 + 1];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
@@ -1680,7 +1804,7 @@ static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
}
static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
- void (*setMaterial)(void *userData, int, void *attribs),
+ void (*setMaterial)(void *userData, int matnr, void *attribs),
bool (*setFace)(void *userData, int index), void *userData)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
@@ -1689,6 +1813,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
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);
int a, matnr, new_matnr;
int orig;
@@ -1725,7 +1850,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
gpuBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mf++) {
- const int smoothnormal = (mf->flag & ME_SMOOTH);
+ const int smoothnormal = lnors || (mf->flag & ME_SMOOTH);
+ short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
/* material */
new_matnr = mf->mat_nr + 1;
@@ -1767,15 +1893,23 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
}
}
+ if (lnors) {
+ ln1 = &lnors[0][0];
+ ln2 = &lnors[0][1];
+ ln3 = &lnors[0][2];
+ ln4 = &lnors[0][3];
+ lnors++;
+ }
+
/* vertices */
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, ln1, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, ln2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal);
if (mf->v4)
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, ln4, smoothnormal);
else
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal);
}
gpuEnd();
cddm_unformat_attrib_vertex();
@@ -1819,7 +1953,7 @@ static void cdDM_foreachMappedVert(
DMForeachFlag flag)
{
MVert *mv = CDDM_get_verts(dm);
- int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ const int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
int i;
if (index) {
@@ -1859,6 +1993,35 @@ static void cdDM_foreachMappedEdge(
}
}
+static void cdDM_foreachMappedLoop(
+ DerivedMesh *dm,
+ void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
+{
+ /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
+ * return loop data from bmesh itself. */
+ const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
+
+ const MVert *mv = CDDM_get_verts(dm);
+ const MLoop *ml = CDDM_get_loops(dm);
+ const MPoly *mp = CDDM_get_polys(dm);
+ const int *v_index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ const int *f_index = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
+ int p_idx, i;
+
+ for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
+ for (i = 0; i < mp->totloop; ++i, ++ml) {
+ const int v_idx = v_index ? v_index[ml->v] : ml->v;
+ const int f_idx = f_index ? f_index[p_idx] : p_idx;
+ const float *no = lnors ? *lnors++ : NULL;
+ if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
+ func(userData, v_idx, f_idx, mv[ml->v].co, no);
+ }
+ }
+ }
+}
+
static void cdDM_foreachMappedFaceCenter(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float cent[3], const float no[3]),
@@ -1972,6 +2135,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
dm->calcNormals = CDDM_calc_normals;
+ dm->calcLoopNormals = CDDM_calc_loop_normals;
dm->recalcTessellation = CDDM_recalc_tessellation;
dm->getVertCos = cdDM_getVertCos;
@@ -1998,6 +2162,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->foreachMappedVert = cdDM_foreachMappedVert;
dm->foreachMappedEdge = cdDM_foreachMappedEdge;
+ dm->foreachMappedLoop = cdDM_foreachMappedLoop;
dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
dm->release = cdDM_release;
@@ -2330,6 +2495,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps,
mloop->e = BM_elem_index_get(l_iter->e);
CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
+ BM_elem_index_set(l_iter, j); /* set_inline */
+
j++;
mloop++;
} while ((l_iter = l_iter->next) != l_first);
@@ -2338,7 +2505,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps,
if (add_orig) *index++ = i;
}
- bm->elem_index_dirty &= ~BM_FACE;
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
@@ -2523,8 +2690,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const bool only_face_normals)
CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
}
-
- face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
+ face_nors = MEM_mallocN(sizeof(*face_nors) * dm->numTessFaceData, "face_nors");
/* calculate face normals */
BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
@@ -2532,8 +2698,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const bool only_face_normals)
CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors,
only_face_normals);
- CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
- face_nors, dm->numTessFaceData);
+ CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numTessFaceData);
cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
}
@@ -2587,6 +2752,48 @@ void CDDM_calc_normals(DerivedMesh *dm)
#endif
+void CDDM_calc_loop_normals(DerivedMesh *dm, const float split_angle)
+{
+ MVert *mverts = dm->getVertArray(dm);
+ MEdge *medges = dm->getEdgeArray(dm);
+ MLoop *mloops = dm->getLoopArray(dm);
+ MPoly *mpolys = dm->getPolyArray(dm);
+
+ CustomData *ldata, *pdata;
+
+ float (*lnors)[3];
+ float (*pnors)[3];
+
+ const int numVerts = dm->getNumVerts(dm);
+ const int numEdges = dm->getNumEdges(dm);
+ const int numLoops = dm->getNumLoops(dm);
+ const int numPolys = dm->getNumPolys(dm);
+
+ ldata = dm->getLoopDataLayout(dm);
+ if (CustomData_has_layer(ldata, CD_NORMAL)) {
+ lnors = CustomData_get_layer(ldata, CD_NORMAL);
+ }
+ else {
+ lnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, numLoops);
+ }
+
+ /* Compute poly (always needed) and vert normals. */
+ /* Note we can't use DM_ensure_normals, since it won't keep computed poly nors... */
+ pdata = dm->getPolyDataLayout(dm);
+ pnors = CustomData_get_layer(pdata, CD_NORMAL);
+ if (!pnors) {
+ pnors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys);
+ }
+ BKE_mesh_calc_normals_poly(mverts, numVerts, mloops, mpolys, numLoops, numPolys, pnors,
+ (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
+
+ dm->dirty &= ~DM_DIRTY_NORMALS;
+
+ BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
+ mpolys, pnors, numPolys, split_angle);
+}
+
+
void CDDM_calc_normals_tessface(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
@@ -2743,11 +2950,11 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
/* skip faces with all vertices merged */
{
- int all_vertices_merged = TRUE;
+ bool all_vertices_merged = true;
for (j = 0; j < mp->totloop; j++, ml++) {
if (vtargetmap[ml->v] == -1) {
- all_vertices_merged = FALSE;
+ all_vertices_merged = false;
break;
}
}
@@ -2867,33 +3074,28 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
CustomData edgeData;
- EdgeHashIterator *ehi;
+ EdgeSetIterator *ehi;
MFace *mf = cddm->mface;
MEdge *med;
- EdgeHash *eh;
+ EdgeSet *eh;
int i, *index, numEdges, numFaces = dm->numTessFaceData;
- eh = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
+ eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
for (i = 0; i < numFaces; i++, mf++) {
- if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
- BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
- BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
+ BLI_edgeset_reinsert(eh, mf->v1, mf->v2);
+ BLI_edgeset_reinsert(eh, mf->v2, mf->v3);
if (mf->v4) {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
- BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
- BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
+ BLI_edgeset_reinsert(eh, mf->v3, mf->v4);
+ BLI_edgeset_reinsert(eh, mf->v4, mf->v1);
}
else {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
- BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+ BLI_edgeset_reinsert(eh, mf->v3, mf->v1);
}
}
- numEdges = BLI_edgehash_size(eh);
+ numEdges = BLI_edgeset_size(eh);
/* write new edges into a temporary CustomData */
CustomData_reset(&edgeData);
@@ -2903,16 +3105,16 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm)
med = CustomData_get_layer(&edgeData, CD_MEDGE);
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
- for (ehi = BLI_edgehashIterator_new(eh), i = 0;
- BLI_edgehashIterator_isDone(ehi) == FALSE;
- BLI_edgehashIterator_step(ehi), i++, med++, index++)
+ for (ehi = BLI_edgesetIterator_new(eh), i = 0;
+ BLI_edgesetIterator_isDone(ehi) == false;
+ BLI_edgesetIterator_step(ehi), i++, med++, index++)
{
- BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
+ BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2);
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
*index = ORIGINDEX_NONE;
}
- BLI_edgehashIterator_free(ehi);
+ BLI_edgesetIterator_free(ehi);
/* free old CustomData and assign new one */
CustomData_free(&dm->edgeData, dm->numEdgeData);
@@ -2921,7 +3123,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm)
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
- BLI_edgehash_free(eh, NULL);
+ BLI_edgeset_free(eh);
}
/* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
@@ -2936,7 +3138,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
EdgeHash *eh;
unsigned int eh_reserve;
int v1, v2;
- int *eindex;
+ const int *eindex;
int i, j, *index;
const int numFaces = dm->numPolyData;
const int numLoops = dm->numLoopData;
@@ -2958,9 +3160,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
for (j = 0; j < mp->totloop; j++, ml++) {
v1 = ml->v;
v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
- if (!BLI_edgehash_haskey(eh, v1, v2)) {
- BLI_edgehash_insert(eh, v1, v2, NULL);
- }
+ BLI_edgehash_reinsert(eh, v1, v2, NULL);
}
}
@@ -2976,7 +3176,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
for (ehi = BLI_edgehashIterator_new(eh), i = 0;
- BLI_edgehashIterator_isDone(ehi) == FALSE;
+ BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
{
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 3ab522ac24b..f5c7f9e4501 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -621,8 +621,8 @@ void cloth_free_modifier(ClothModifierData *clmd )
if ( cloth->mfaces )
MEM_freeN ( cloth->mfaces );
- if (cloth->edgehash)
- BLI_edgehash_free ( cloth->edgehash, NULL );
+ if (cloth->edgeset)
+ BLI_edgeset_free(cloth->edgeset);
/*
@@ -690,8 +690,8 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
if ( cloth->mfaces )
MEM_freeN ( cloth->mfaces );
- if (cloth->edgehash)
- BLI_edgehash_free ( cloth->edgehash, NULL );
+ if (cloth->edgeset)
+ BLI_edgeset_free(cloth->edgeset);
/*
@@ -854,7 +854,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->old_solver_type = 255;
// clmd->clothObject->old_collision_type = 255;
cloth = clmd->clothObject;
- clmd->clothObject->edgehash = NULL;
+ clmd->clothObject->edgeset = NULL;
}
else if (!clmd->clothObject) {
modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject");
@@ -1062,9 +1062,9 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNode **edgelist)
cloth_free_edgelist(edgelist, cloth->numverts);
- if (cloth->edgehash) {
- BLI_edgehash_free(cloth->edgehash, NULL);
- cloth->edgehash = NULL;
+ if (cloth->edgeset) {
+ BLI_edgeset_free(cloth->edgeset);
+ cloth->edgeset = NULL;
}
}
@@ -1123,20 +1123,20 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
MFace *mface = dm->getTessFaceArray (dm);
int index2 = 0; // our second vertex index
LinkNode **edgelist = NULL;
- EdgeHash *edgehash = NULL;
+ EdgeSet *edgeset = NULL;
LinkNode *search = NULL, *search2 = NULL;
// error handling
if ( numedges==0 )
return 0;
- /* NOTE: handling ownership of springs and edgehash is quite sloppy
+ /* NOTE: handling ownership of springs and edgeset is quite sloppy
* currently they are never initialized but assert just to be sure */
BLI_assert(cloth->springs == NULL);
- BLI_assert(cloth->edgehash == NULL);
+ BLI_assert(cloth->edgeset == NULL);
cloth->springs = NULL;
- cloth->edgehash = NULL;
+ cloth->edgeset = NULL;
edgelist = MEM_callocN ( sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc" );
@@ -1149,13 +1149,14 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
if ( spring ) {
spring_verts_ordered_set(spring, medge[i].v1, medge[i].v2);
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW && medge[i].flag & ME_LOOSEEDGE) {
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW && medge[i].flag & ME_LOOSEEDGE) {
// handle sewing (loose edges will be pulled together)
spring->restlen = 0.0f;
spring->stiffness = 1.0f;
spring->type = CLOTH_SPRING_TYPE_SEWING;
- } else {
- if(clmd->sim_parms->vgroup_shrink > 0)
+ }
+ else {
+ if (clmd->sim_parms->vgroup_shrink > 0)
shrink_factor = 1.0f - ((cloth->verts[spring->ij].shrink_factor + cloth->verts[spring->kl].shrink_factor) / 2.0f);
else
shrink_factor = 1.0f - clmd->sim_parms->shrink_min;
@@ -1200,7 +1201,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
}
spring_verts_ordered_set(spring, mface[i].v1, mface[i].v3);
- if(clmd->sim_parms->vgroup_shrink > 0)
+ if (clmd->sim_parms->vgroup_shrink > 0)
shrink_factor = 1.0f - ((cloth->verts[spring->ij].shrink_factor + cloth->verts[spring->kl].shrink_factor) / 2.0f);
else
shrink_factor = 1.0f - clmd->sim_parms->shrink_min;
@@ -1224,7 +1225,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
}
spring_verts_ordered_set(spring, mface[i].v2, mface[i].v4);
- if(clmd->sim_parms->vgroup_shrink > 0)
+ if (clmd->sim_parms->vgroup_shrink > 0)
shrink_factor = 1.0f - ((cloth->verts[spring->ij].shrink_factor + cloth->verts[spring->kl].shrink_factor) / 2.0f);
else
shrink_factor = 1.0f - clmd->sim_parms->shrink_min;
@@ -1239,8 +1240,8 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
BLI_linklist_prepend ( &cloth->springs, spring );
}
- edgehash = BLI_edgehash_new_ex(__func__, numedges);
- cloth->edgehash = edgehash;
+ edgeset = BLI_edgeset_new_ex(__func__, numedges);
+ cloth->edgeset = edgeset;
if (numfaces) {
// bending springs
@@ -1258,7 +1259,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
// check for existing spring
// check also if startpoint is equal to endpoint
if ((index2 != tspring2->ij) &&
- !BLI_edgehash_haskey(edgehash, tspring2->ij, index2))
+ !BLI_edgeset_haskey(edgeset, tspring2->ij, index2))
{
spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
@@ -1271,7 +1272,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest);
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
- BLI_edgehash_insert(edgehash, spring->ij, spring->kl, NULL);
+ BLI_edgeset_insert(edgeset, spring->ij, spring->kl);
bend_springs++;
BLI_linklist_prepend ( &cloth->springs, spring );
@@ -1320,16 +1321,16 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
/* note: the edges may already exist so run reinsert */
- /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
+ /* insert other near springs in edgeset AFTER bending springs are calculated (for selfcolls) */
for (i = 0; i < numedges; i++) { /* struct springs */
- BLI_edgehash_reinsert(edgehash, medge[i].v1, medge[i].v2, NULL);
+ BLI_edgeset_reinsert(edgeset, medge[i].v1, medge[i].v2);
}
for (i = 0; i < numfaces; i++) { /* edge springs */
if (mface[i].v4) {
- BLI_edgehash_reinsert(edgehash, mface[i].v1, mface[i].v3, NULL);
+ BLI_edgeset_reinsert(edgeset, mface[i].v1, mface[i].v3);
- BLI_edgehash_reinsert(edgehash, mface[i].v2, mface[i].v4, NULL);
+ BLI_edgeset_reinsert(edgeset, mface[i].v2, mface[i].v4);
}
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 393632117bc..cedd9eae597 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -34,7 +34,6 @@
#include "DNA_cloth_types.h"
#include "DNA_group_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
@@ -44,16 +43,9 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
-#include "BLI_ghash.h"
-#include "BLI_memarena.h"
-#include "BLI_rand.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_cloth.h"
-#include "BKE_global.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_scene.h"
#ifdef WITH_BULLET
@@ -863,7 +855,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
- if (BLI_edgehash_haskey(cloth->edgehash, i, j)) {
+ if (BLI_edgeset_haskey(cloth->edgeset, i, j)) {
continue;
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index e2cb0118e50..c6d07a959d1 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -47,7 +47,6 @@
#include "BKE_colortools.h"
#include "BKE_curve.h"
#include "BKE_fcurve.h"
-#include "BKE_paint.h"
#include "IMB_colormanagement.h"
@@ -183,14 +182,14 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con
/* ********** NOTE: requires curvemapping_changed() call after ******** */
/* remove specified point */
-int curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point)
+bool curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point)
{
CurveMapPoint *cmp;
int a, b, removed = 0;
/* must have 2 points minimum */
if (cuma->totpoint <= 2)
- return FALSE;
+ return false;
cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points");
@@ -759,7 +758,7 @@ void curvemapping_changed_all(CurveMapping *cumap)
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve) {
cumap->cur = a;
- curvemapping_changed(cumap, FALSE);
+ curvemapping_changed(cumap, false);
}
}
@@ -961,7 +960,7 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorM
const ColorManagedDisplaySettings *display_settings)
{
int i, x, y;
- float *fp;
+ const float *fp;
float rgb[3];
unsigned char *cp;
@@ -1024,7 +1023,7 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
int x, y, c;
unsigned int nl, na, nr, ng, nb;
double divl, diva, divr, divg, divb;
- float *rf = NULL;
+ const float *rf = NULL;
unsigned char *rc = NULL;
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
int savedlines, saveline;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 1397a7d4824..52cfa92ceaf 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -46,18 +46,15 @@
#include "BLF_translation.h"
#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
-#include "DNA_text_types.h"
#include "DNA_tracking_types.h"
#include "DNA_movieclip_types.h"
@@ -65,7 +62,6 @@
#include "BKE_action.h"
#include "BKE_anim.h" /* for the curve calculation part */
#include "BKE_armature.h"
-#include "BKE_blender.h"
#include "BKE_bvhutils.h"
#include "BKE_camera.h"
#include "BKE_constraint.h"
@@ -75,11 +71,9 @@
#include "BKE_DerivedMesh.h" /* for geometry targets */
#include "BKE_cdderivedmesh.h" /* for geometry targets */
#include "BKE_object.h"
-#include "BKE_ipo.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_idprop.h"
-#include "BKE_mesh.h"
#include "BKE_shrinkwrap.h"
#include "BKE_editmesh.h"
#include "BKE_tracking.h"
@@ -89,6 +83,17 @@
# include "BPY_extern.h"
#endif
+/* ---------------------------------------------------------------------------- */
+/* Useful macros for testing various common flag combinations */
+
+/* Constraint Target Macros */
+#define VALID_CONS_TARGET(ct) ((ct) && (ct->tar))
+
+/* Workaround for cyclic depenndnecy with curves.
+ * In such case curve_cache might not be ready yet,
+ */
+#define CYCLIC_DEPENDENCY_WORKAROUND
+
/* ************************ Constraints - General Utilities *************************** */
/* These functions here don't act on any specific constraints, and are therefore should/will
* not require any of the special function-pointers afforded by the relevant constraint
@@ -98,7 +103,7 @@
/* -------------- Naming -------------- */
/* Find the first available, non-duplicate name for a given constraint */
-void BKE_unique_constraint_name(bConstraint *con, ListBase *list)
+void BKE_constraint_unique_name(bConstraint *con, ListBase *list)
{
BLI_uniquename(list, con, DATA_("Const"), '.', offsetof(bConstraint, name), sizeof(con->name));
}
@@ -307,7 +312,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
if (ob->parent) {
/* 'subtract' parent's effects from owner */
mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
- invert_m4_m4(imat, diff_mat);
+ invert_m4_m4_safe(imat, diff_mat);
mul_m4_m4m4(mat, imat, mat);
}
else {
@@ -318,7 +323,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
normalize_m4(diff_mat);
zero_v3(diff_mat[3]);
- invert_m4_m4(imat, diff_mat);
+ invert_m4_m4_safe(imat, diff_mat);
mul_m4_m4m4(mat, imat, mat);
}
}
@@ -449,7 +454,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
Lattice *lt = (Lattice *)ob->data;
DispList *dl = ob->curve_cache ? BKE_displist_find(&ob->curve_cache->disp, DL_VERTS) : NULL;
- float *co = dl ? dl->verts : NULL;
+ const float *co = dl ? dl->verts : NULL;
BPoint *bp = lt->def;
MDeformVert *dv = lt->dvert;
@@ -660,11 +665,11 @@ static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bCo
* (Hopefully all compilers will be happy with the lines with just a space on them. Those are
* really just to help this code easier to read)
*/
-#define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
+#define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, no_copy) \
{ \
if (ct) { \
bConstraintTarget *ctn = ct->next; \
- if (nocopy == 0) { \
+ if (no_copy == 0) { \
datatar = ct->tar; \
BLI_strncpy(datasubtarget, ct->subtarget, sizeof(datasubtarget)); \
con->tarspace = (char)ct->space; \
@@ -681,11 +686,11 @@ static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bCo
* (Hopefully all compilers will be happy with the lines with just a space on them. Those are
* really just to help this code easier to read)
*/
-#define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
+#define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, no_copy) \
{ \
if (ct) { \
bConstraintTarget *ctn = ct->next; \
- if (nocopy == 0) { \
+ if (no_copy == 0) { \
datatar = ct->tar; \
con->tarspace = (char)ct->space; \
} \
@@ -712,7 +717,7 @@ static void childof_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
bChildOfConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int childof_get_tars(bConstraint *con, ListBase *list)
@@ -730,14 +735,14 @@ static int childof_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void childof_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void childof_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bChildOfConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -847,7 +852,7 @@ static void trackto_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
bTrackToConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int trackto_get_tars(bConstraint *con, ListBase *list)
@@ -865,14 +870,14 @@ static int trackto_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void trackto_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void trackto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bTrackToConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -1025,10 +1030,10 @@ static void kinematic_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bKinematicConstraint *data = con->data;
/* chain target */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
/* poletarget */
- func(con, (ID **)&data->poletar, FALSE, userdata);
+ func(con, (ID **)&data->poletar, false, userdata);
}
static int kinematic_get_tars(bConstraint *con, ListBase *list)
@@ -1047,15 +1052,15 @@ static int kinematic_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void kinematic_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bKinematicConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
- SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
+ SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, no_copy);
}
}
@@ -1117,7 +1122,7 @@ static void followpath_id_looper(bConstraint *con, ConstraintIDFunc func, void *
bFollowPathConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int followpath_get_tars(bConstraint *con, ListBase *list)
@@ -1135,22 +1140,22 @@ static int followpath_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void followpath_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bFollowPathConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy);
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
}
}
-static void followpath_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bFollowPathConstraint *data = con->data;
- if (VALID_CONS_TARGET(ct)) {
+ if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
Curve *cu = ct->tar->data;
float vec[4], dir[3], radius;
float totmat[4][4] = MAT4_UNITY;
@@ -1162,6 +1167,12 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob),
* currently for paths to work it needs to go through the bevlist/displist system (ton)
*/
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ if (ct->tar->curve_cache == NULL) {
+ BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
+ }
+#endif
+
if (ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) {
float quat[4];
if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
@@ -1459,7 +1470,7 @@ static void loclike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
bLocateLikeConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int loclike_get_tars(bConstraint *con, ListBase *list)
@@ -1477,14 +1488,14 @@ static int loclike_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void loclike_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void loclike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bLocateLikeConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -1549,7 +1560,7 @@ static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
bRotateLikeConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int rotlike_get_tars(bConstraint *con, ListBase *list)
@@ -1567,14 +1578,14 @@ static int rotlike_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void rotlike_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void rotlike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bRotateLikeConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -1661,7 +1672,7 @@ static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *us
bSizeLikeConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int sizelike_get_tars(bConstraint *con, ListBase *list)
@@ -1679,14 +1690,14 @@ static int sizelike_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void sizelike_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void sizelike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bSizeLikeConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -1750,7 +1761,7 @@ static void translike_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bTransLikeConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int translike_get_tars(bConstraint *con, ListBase *list)
@@ -1768,14 +1779,14 @@ static int translike_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void translike_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bTransLikeConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -1913,20 +1924,29 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
/* targets */
for (ct = data->targets.first; ct; ct = ct->next)
- func(con, (ID **)&ct->tar, FALSE, userdata);
+ func(con, (ID **)&ct->tar, false, userdata);
/* script */
- func(con, (ID **)&data->text, TRUE, userdata);
+ func(con, (ID **)&data->text, true, userdata);
}
/* Whether this approach is maintained remains to be seen (aligorith) */
-static void pycon_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef WITH_PYTHON
bPythonConstraint *data = con->data;
#endif
if (VALID_CONS_TARGET(ct)) {
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ /* special exception for curves - depsgraph issues */
+ if (ct->tar->type == OB_CURVE) {
+ if (ct->tar->curve_cache == NULL) {
+ BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
+ }
+ }
+#endif
+
/* firstly calculate the matrix the normal way, then let the py-function override
* this matrix if it needs to do so
*/
@@ -1997,10 +2017,10 @@ static void actcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
bActionConstraint *data = con->data;
/* target */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
/* action */
- func(con, (ID **)&data->act, TRUE, userdata);
+ func(con, (ID **)&data->act, true, userdata);
}
static int actcon_get_tars(bConstraint *con, ListBase *list)
@@ -2018,14 +2038,14 @@ static int actcon_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void actcon_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bActionConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -2164,7 +2184,7 @@ static void locktrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bLockTrackConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int locktrack_get_tars(bConstraint *con, ListBase *list)
@@ -2182,14 +2202,14 @@ static int locktrack_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void locktrack_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void locktrack_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bLockTrackConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -2471,7 +2491,7 @@ static void distlimit_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bDistLimitConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int distlimit_get_tars(bConstraint *con, ListBase *list)
@@ -2489,14 +2509,14 @@ static int distlimit_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void distlimit_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void distlimit_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bDistLimitConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -2598,7 +2618,7 @@ static void stretchto_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bStretchToConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int stretchto_get_tars(bConstraint *con, ListBase *list)
@@ -2616,14 +2636,14 @@ static int stretchto_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void stretchto_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void stretchto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bStretchToConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -2669,7 +2689,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
switch (data->volmode) {
/* volume preserving scaling */
case VOLUME_XZ:
- scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge * (data->orglength / dist));
+ scale[0] = 1.0f - sqrtf(data->bulge) + sqrtf(data->bulge * (data->orglength / dist));
scale[2] = scale[0];
break;
case VOLUME_X:
@@ -2770,7 +2790,7 @@ static void minmax_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
bMinMaxConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int minmax_get_tars(bConstraint *con, ListBase *list)
@@ -2788,14 +2808,14 @@ static int minmax_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void minmax_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void minmax_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bMinMaxConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -2912,8 +2932,8 @@ static void rbj_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdat
bRigidBodyJointConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
- func(con, (ID **)&data->child, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
+ func(con, (ID **)&data->child, false, userdata);
}
static int rbj_get_tars(bConstraint *con, ListBase *list)
@@ -2931,14 +2951,14 @@ static int rbj_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void rbj_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void rbj_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bRigidBodyJointConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy);
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
}
}
@@ -2964,7 +2984,7 @@ static void clampto_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
bClampToConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int clampto_get_tars(bConstraint *con, ListBase *list)
@@ -2982,19 +3002,27 @@ static int clampto_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void clampto_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bClampToConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy);
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
}
}
-static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ if (VALID_CONS_TARGET(ct)) {
+ if (ct->tar->curve_cache == NULL) {
+ BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
+ }
+ }
+#endif
+
/* technically, this isn't really needed for evaluation, but we don't know what else
* might end up calling this...
*/
@@ -3018,7 +3046,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
INIT_MINMAX(curveMin, curveMax);
/* XXX - don't think this is good calling this here - campbell */
- BKE_object_minmax(ct->tar, curveMin, curveMax, TRUE);
+ BKE_object_minmax(ct->tar, curveMin, curveMax, true);
/* get targetmatrix */
if (data->tar->curve_cache && data->tar->curve_cache->path && data->tar->curve_cache->path->data) {
@@ -3136,7 +3164,7 @@ static void transform_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bTransformConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int transform_get_tars(bConstraint *con, ListBase *list)
@@ -3154,14 +3182,14 @@ static int transform_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void transform_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void transform_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bTransformConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -3172,13 +3200,14 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* only evaluate if there is a target */
if (VALID_CONS_TARGET(ct)) {
+ float *from_min, *from_max, *to_min, *to_max;
float loc[3], eul[3], size[3];
float dvec[3], sval[3];
int i;
/* obtain target effect */
switch (data->from) {
- case 2: /* scale */
+ case TRANS_SCALE:
mat4_to_size(dvec, ct->matrix);
if (is_negative_m4(ct->matrix)) {
@@ -3189,13 +3218,19 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
*/
negate_v3(dvec);
}
+ from_min = data->from_min_scale;
+ from_max = data->from_max_scale;
break;
- case 1: /* rotation (convert to degrees first) */
+ case TRANS_ROTATION:
mat4_to_eulO(dvec, cob->rotOrder, ct->matrix);
- mul_v3_fl(dvec, RAD2DEGF(1.0f)); /* rad -> deg */
+ from_min = data->from_min_rot;
+ from_max = data->from_max_rot;
break;
- default: /* location */
+ case TRANS_LOCATION:
+ default:
copy_v3_v3(dvec, ct->matrix[3]);
+ from_min = data->from_min;
+ from_max = data->from_max;
break;
}
@@ -3207,8 +3242,8 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* determine where in range current transforms lie */
if (data->expo) {
for (i = 0; i < 3; i++) {
- if (data->from_max[i] - data->from_min[i])
- sval[i] = (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
+ if (from_max[i] - from_min[i])
+ sval[i] = (dvec[i] - from_min[i]) / (from_max[i] - from_min[i]);
else
sval[i] = 0.0f;
}
@@ -3216,9 +3251,9 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
else {
/* clamp transforms out of range */
for (i = 0; i < 3; i++) {
- CLAMP(dvec[i], data->from_min[i], data->from_max[i]);
- if (data->from_max[i] - data->from_min[i])
- sval[i] = (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
+ CLAMP(dvec[i], from_min[i], from_max[i]);
+ if (from_max[i] - from_min[i])
+ sval[i] = (dvec[i] - from_min[i]) / (from_max[i] - from_min[i]);
else
sval[i] = 0.0f;
}
@@ -3227,32 +3262,30 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* apply transforms */
switch (data->to) {
- case 2: /* scaling */
- for (i = 0; i < 3; i++)
- size[i] = data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i]));
+ case TRANS_SCALE:
+ to_min = data->to_min_scale;
+ to_max = data->to_max_scale;
+ for (i = 0; i < 3; i++) {
+ /* multiply with original scale (so that it can still be scaled) */
+ size[i] *= to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
+ }
break;
- case 1: /* rotation */
+ case TRANS_ROTATION:
+ to_min = data->to_min_rot;
+ to_max = data->to_max_rot;
for (i = 0; i < 3; i++) {
- float tmin, tmax;
- float val;
-
- tmin = data->to_min[i];
- tmax = data->to_max[i];
-
- /* all values here should be in degrees */
- val = tmin + (sval[(int)data->map[i]] * (tmax - tmin));
-
- /* now convert final value back to radians, and add to original rotation (so that it can still be rotated) */
- eul[i] += DEG2RADF(val);
+ /* add to original rotation (so that it can still be rotated) */
+ eul[i] += to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
}
break;
- default: /* location */
- /* get new location */
- for (i = 0; i < 3; i++)
- loc[i] = (data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])));
-
- /* add original location back on (so that it can still be moved) */
- add_v3_v3v3(loc, cob->matrix[3], loc);
+ case TRANS_LOCATION:
+ default:
+ to_min = data->to_min;
+ to_max = data->to_max;
+ for (i = 0; i < 3; i++) {
+ /* add to original location (so that it can still be moved) */
+ loc[i] += (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])));
+ }
break;
}
@@ -3283,7 +3316,7 @@ static void shrinkwrap_id_looper(bConstraint *con, ConstraintIDFunc func, void *
bShrinkwrapConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->target, FALSE, userdata);
+ func(con, (ID **)&data->target, false, userdata);
}
static void shrinkwrap_new_data(void *cdata)
@@ -3309,13 +3342,13 @@ static int shrinkwrap_get_tars(bConstraint *con, ListBase *list)
}
-static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bShrinkwrapConstraint *data = con->data;
bConstraintTarget *ct = list->first;
- SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy);
+ SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, no_copy);
}
}
@@ -3355,7 +3388,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
if (treeData.tree == NULL) {
- fail = TRUE;
+ fail = true;
break;
}
@@ -3397,13 +3430,13 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
mul_mat3_m4_v3(mat, no);
if (normalize_v3(no) < FLT_EPSILON) {
- fail = TRUE;
+ fail = true;
break;
}
bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
if (treeData.tree == NULL) {
- fail = TRUE;
+ fail = true;
break;
}
@@ -3411,7 +3444,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
if (BKE_shrinkwrap_project_normal(0, co, no, &transform, treeData.tree, &hit,
treeData.raycast_callback, &treeData) == false)
{
- fail = TRUE;
+ fail = true;
break;
}
copy_v3_v3(co, hit.co);
@@ -3423,7 +3456,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
target->release(target);
- if (fail == TRUE) {
+ if (fail == true) {
/* Don't move the point */
zero_v3(co);
}
@@ -3474,7 +3507,7 @@ static void damptrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
bDampTrackConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int damptrack_get_tars(bConstraint *con, ListBase *list)
@@ -3492,14 +3525,14 @@ static int damptrack_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void damptrack_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void damptrack_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bDampTrackConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -3619,7 +3652,7 @@ static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *us
bSplineIKConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int splineik_get_tars(bConstraint *con, ListBase *list)
@@ -3637,19 +3670,27 @@ static int splineik_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void splineik_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bSplineIKConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy);
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
}
}
-static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ if (VALID_CONS_TARGET(ct)) {
+ if (ct->tar->curve_cache == NULL) {
+ BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
+ }
+ }
+#endif
+
/* technically, this isn't really needed for evaluation, but we don't know what else
* might end up calling this...
*/
@@ -3679,7 +3720,7 @@ static void pivotcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *us
bPivotConstraint *data = con->data;
/* target only */
- func(con, (ID **)&data->tar, FALSE, userdata);
+ func(con, (ID **)&data->tar, false, userdata);
}
static int pivotcon_get_tars(bConstraint *con, ListBase *list)
@@ -3697,14 +3738,14 @@ static int pivotcon_get_tars(bConstraint *con, ListBase *list)
return 0;
}
-static void pivotcon_flush_tars(bConstraint *con, ListBase *list, short nocopy)
+static void pivotcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
{
if (con && list) {
bPivotConstraint *data = con->data;
bConstraintTarget *ct = list->first;
/* the following macro is used for all standard single-target constraints */
- SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy);
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
}
}
@@ -3810,9 +3851,9 @@ static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bFollowTrackConstraint *data = con->data;
- func(con, (ID **)&data->clip, TRUE, userdata);
- func(con, (ID **)&data->camera, FALSE, userdata);
- func(con, (ID **)&data->depth_ob, FALSE, userdata);
+ func(con, (ID **)&data->clip, true, userdata);
+ func(con, (ID **)&data->camera, false, userdata);
+ func(con, (ID **)&data->depth_ob, false, userdata);
}
static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4046,7 +4087,7 @@ static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bCameraSolverConstraint *data = con->data;
- func(con, (ID **)&data->clip, TRUE, userdata);
+ func(con, (ID **)&data->clip, true, userdata);
}
static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4102,8 +4143,8 @@ static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bObjectSolverConstraint *data = con->data;
- func(con, (ID **)&data->clip, FALSE, userdata);
- func(con, (ID **)&data->camera, FALSE, userdata);
+ func(con, (ID **)&data->clip, false, userdata);
+ func(con, (ID **)&data->camera, false, userdata);
}
static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4207,7 +4248,7 @@ static void constraints_init_typeinfo(void)
/* This function should be used for getting the appropriate type-info when only
* a constraint type is known
*/
-bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type)
+bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type)
{
/* initialize the type-info list? */
if (CTI_INIT) {
@@ -4232,11 +4273,11 @@ bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type)
/* This function should always be used to get the appropriate type-info, as it
* has checks which prevent segfaults in some weird cases.
*/
-bConstraintTypeInfo *BKE_constraint_get_typeinfo(bConstraint *con)
+bConstraintTypeInfo *BKE_constraint_typeinfo_get(bConstraint *con)
{
/* only return typeinfo for valid constraints */
if (con)
- return BKE_get_constraint_typeinfo(con->type);
+ return BKE_constraint_typeinfo_from_type(con->type);
else
return NULL;
}
@@ -4248,10 +4289,10 @@ bConstraintTypeInfo *BKE_constraint_get_typeinfo(bConstraint *con)
/* ---------- Data Management ------- */
-/* helper function for BKE_free_constraint_data() - unlinks references */
-static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
+/* helper function for BKE_constraint_free_data() - unlinks references */
+static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool is_reference, void *UNUSED(userData))
{
- if (*idpoin && isReference)
+ if (*idpoin && is_reference)
id_us_min(*idpoin);
}
@@ -4259,10 +4300,10 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isRe
* be sure to run BIK_clear_data() when freeing an IK constraint,
* unless DAG_relations_tag_update is called.
*/
-void BKE_free_constraint_data(bConstraint *con)
+void BKE_constraint_free_data(bConstraint *con)
{
if (con->data) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti) {
/* perform any special freeing constraint may have */
@@ -4280,13 +4321,13 @@ void BKE_free_constraint_data(bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void BKE_free_constraints(ListBase *list)
+void BKE_constraints_free(ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
for (con = list->first; con; con = con->next)
- BKE_free_constraint_data(con);
+ BKE_constraint_free_data(con);
/* Free the whole list */
BLI_freelistN(list);
@@ -4294,10 +4335,10 @@ void BKE_free_constraints(ListBase *list)
/* Remove the specified constraint from the given constraint stack */
-int BKE_remove_constraint(ListBase *list, bConstraint *con)
+bool BKE_constraint_remove(ListBase *list, bConstraint *con)
{
if (con) {
- BKE_free_constraint_data(con);
+ BKE_constraint_free_data(con);
BLI_freelinkN(list, con);
return 1;
}
@@ -4305,33 +4346,13 @@ int BKE_remove_constraint(ListBase *list, bConstraint *con)
return 0;
}
-/* Remove all the constraints of the specified type from the given constraint stack */
-void BKE_remove_constraints_type(ListBase *list, short type, short last_only)
-{
- bConstraint *con, *conp;
-
- if (list == NULL)
- return;
-
- /* remove from the end of the list to make it faster to find the last instance */
- for (con = list->last; con; con = conp) {
- conp = con->prev;
-
- if (con->type == type) {
- BKE_remove_constraint(list, con);
- if (last_only)
- return;
- }
- }
-}
-
/* ......... */
/* Creates a new constraint, initializes its data, and returns it */
static bConstraint *add_new_constraint_internal(const char *name, short type)
{
bConstraint *con = MEM_callocN(sizeof(bConstraint), "Constraint");
- bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(type);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(type);
const char *newName;
/* Set up a generic constraint datablock */
@@ -4381,17 +4402,17 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
* (otherwise unique-naming code will fail, since it assumes element exists in list)
*/
BLI_addtail(list, con);
- BKE_unique_constraint_name(con, list);
+ BKE_constraint_unique_name(con, list);
/* if the target list is a list on some PoseChannel belonging to a proxy-protected
* Armature layer, we must tag newly added constraints with a flag which allows them
* to persist after proxy syncing has been done
*/
- if (BKE_proxylocked_constraints_owner(ob, pchan))
+ if (BKE_constraints_proxylocked_owner(ob, pchan))
con->flag |= CONSTRAINT_PROXY_LOCAL;
/* make this constraint the active one */
- BKE_constraints_set_active(list, con);
+ BKE_constraints_active_set(list, con);
}
/* set type+owner specific immutable settings */
@@ -4415,7 +4436,7 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
/* ......... */
/* Add new constraint for the given bone */
-bConstraint *BKE_add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+bConstraint *BKE_constraint_add_for_pose(Object *ob, bPoseChannel *pchan, const char *name, short type)
{
if (pchan == NULL)
return NULL;
@@ -4424,15 +4445,15 @@ bConstraint *BKE_add_pose_constraint(Object *ob, bPoseChannel *pchan, const char
}
/* Add new constraint for the given object */
-bConstraint *BKE_add_ob_constraint(Object *ob, const char *name, short type)
+bConstraint *BKE_constraint_add_for_object(Object *ob, const char *name, short type)
{
return add_new_constraint(ob, NULL, name, type);
}
/* ......... */
-/* helper for BKE_relink_constraints() - call ID_NEW() on every ID reference the constraint has */
-static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userdata))
+/* helper for BKE_constraints_relink() - call ID_NEW() on every ID reference the constraint has */
+static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, bool UNUSED(is_reference), void *UNUSED(userdata))
{
/* ID_NEW() expects a struct with inline "id" member as first
* since we've got the actual ID block, let's just inline this
@@ -4445,20 +4466,20 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED
}
/* Reassign links that constraints have to other data (called during file loading?) */
-void BKE_relink_constraints(ListBase *conlist)
+void BKE_constraints_relink(ListBase *conlist)
{
/* just a wrapper around ID-loop for just calling ID_NEW() on all ID refs */
- BKE_id_loop_constraints(conlist, con_relink_id_cb, NULL);
+ BKE_constraints_id_loop(conlist, con_relink_id_cb, NULL);
}
/* Run the given callback on all ID-blocks in list of constraints */
-void BKE_id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
+void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *userdata)
{
bConstraint *con;
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti) {
if (cti->id_looper)
@@ -4469,23 +4490,23 @@ void BKE_id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *use
/* ......... */
-/* helper for BKE_copy_constraints(), to be used for making sure that ID's are valid */
-static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
+/* helper for BKE_constraints_copy(), to be used for making sure that ID's are valid */
+static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, bool UNUSED(is_reference), void *UNUSED(userData))
{
if (*idpoin && (*idpoin)->lib)
id_lib_extern(*idpoin);
}
-/* helper for BKE_copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
-static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
+/* helper for BKE_constraints_copy(), to be used for making sure that usercounts of copied ID's are fixed up */
+static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool is_reference, void *UNUSED(userData))
{
/* increment usercount if this is a reference type */
- if ((*idpoin) && (isReference))
+ if ((*idpoin) && (is_reference))
id_us_plus(*idpoin);
}
/* duplicate all of the constraints in a constraint stack */
-void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
+void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
{
bConstraint *con, *srccon;
@@ -4493,7 +4514,7 @@ void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
BLI_duplicatelist(dst, src);
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
@@ -4520,13 +4541,13 @@ void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
/* ......... */
-bConstraint *BKE_constraints_findByName(ListBase *list, const char *name)
+bConstraint *BKE_constraints_find_name(ListBase *list, const char *name)
{
return BLI_findstring(list, name, offsetof(bConstraint, name));
}
/* finds the 'active' constraint in a constraint stack */
-bConstraint *BKE_constraints_get_active(ListBase *list)
+bConstraint *BKE_constraints_active_get(ListBase *list)
{
bConstraint *con;
@@ -4543,7 +4564,7 @@ bConstraint *BKE_constraints_get_active(ListBase *list)
}
/* Set the given constraint as the active one (clearing all the others) */
-void BKE_constraints_set_active(ListBase *list, bConstraint *con)
+void BKE_constraints_active_set(ListBase *list, bConstraint *con)
{
bConstraint *c;
@@ -4560,7 +4581,7 @@ void BKE_constraints_set_active(ListBase *list, bConstraint *con)
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
-void BKE_extract_proxylocal_constraints(ListBase *dst, ListBase *src)
+void BKE_constraints_proxylocal_extract(ListBase *dst, ListBase *src)
{
bConstraint *con, *next;
@@ -4577,7 +4598,7 @@ void BKE_extract_proxylocal_constraints(ListBase *dst, ListBase *src)
}
/* Returns if the owner of the constraint is proxy-protected */
-short BKE_proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
+bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
{
/* Currently, constraints can only be on object or bone level */
if (ob && ob->proxy) {
@@ -4606,9 +4627,9 @@ short BKE_proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void BKE_get_constraint_target_matrix(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
+void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintOb *cob;
bConstraintTarget *ct;
@@ -4673,9 +4694,9 @@ void BKE_get_constraint_target_matrix(Scene *scene, bConstraint *con, int index,
}
/* Get the list of targets required for solving a constraint */
-void BKE_get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
@@ -4708,7 +4729,7 @@ void BKE_get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob
* BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
@@ -4720,7 +4741,7 @@ void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* loop over available constraints, solving and blending them */
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
/* these we can skip completely (invalid constraints...) */
@@ -4743,7 +4764,7 @@ void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
/* prepare targets for constraint solving */
- BKE_get_constraint_targets_for_solving(con, cob, &targets, ctime);
+ BKE_constraint_targets_for_solving_get(con, cob, &targets, ctime);
/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index a63807f4bcb..89ba2e9d68b 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -36,6 +36,7 @@
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -47,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "BKE_freestyle.h"
#include "RNA_access.h"
@@ -232,18 +234,31 @@ struct bContextDataResult {
short type; /* 0: normal, 1: seq */
};
-static void *ctx_wm_python_context_get(const bContext *C, const char *member, void *fall_through)
+static void *ctx_wm_python_context_get(
+ const bContext *C,
+ const char *member, const StructRNA *member_type,
+ void *fall_through)
{
#ifdef WITH_PYTHON
if (UNLIKELY(C && CTX_py_dict_get(C))) {
bContextDataResult result;
memset(&result, 0, sizeof(bContextDataResult));
BPY_context_member_get((bContext *)C, member, &result);
- if (result.ptr.data)
- return result.ptr.data;
+
+ if (result.ptr.data) {
+ if (RNA_struct_is_a(result.ptr.type, member_type)) {
+ return result.ptr.data;
+ }
+ else {
+ printf("PyContext '%s' is a '%s', expected a '%s'\n",
+ member,
+ RNA_struct_identifier(result.ptr.type),
+ RNA_struct_identifier(member_type));
+ }
+ }
}
#else
- (void)C, (void)member;
+ (void)C, (void)member, (void)member_type;
#endif
/* don't allow UI context access from non-main threads */
@@ -258,7 +273,7 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
bScreen *sc;
ScrArea *sa;
ARegion *ar;
- int done = FALSE, recursion = C->data.recursion;
+ int done = 0, recursion = C->data.recursion;
int ret = 0;
memset(result, 0, sizeof(bContextDataResult));
@@ -291,7 +306,7 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
entry = BLI_rfindstring(&C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
if (entry) {
result->ptr = entry->ptr;
- done = TRUE;
+ done = 1;
}
}
if (done != 1 && recursion < 2 && (ar = CTX_wm_region(C))) {
@@ -435,11 +450,11 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB
return ret;
}
-static void data_dir_add(ListBase *lb, const char *member, const short use_all)
+static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
{
LinkData *link;
- if ((use_all == FALSE) && strcmp(member, "scene") == 0) /* exception */
+ if ((use_all == false) && strcmp(member, "scene") == 0) /* exception */
return;
if (BLI_findstring(lb, member, offsetof(LinkData, data)))
@@ -456,7 +471,7 @@ static void data_dir_add(ListBase *lb, const char *member, const short use_all)
* \param use_rna Use Include the properties from 'RNA_Context'
* \param use_all Don't skip values (currently only "scene")
*/
-ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all)
+ListBase CTX_data_dir_get_ex(const bContext *C, const bool use_store, const bool use_rna, const bool use_all)
{
bContextDataResult result;
ListBase lb;
@@ -526,7 +541,7 @@ ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const sho
ListBase CTX_data_dir_get(const bContext *C)
{
- return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE);
+ return CTX_data_dir_get_ex(C, true, false, false);
}
bool CTX_data_equals(const char *member, const char *str)
@@ -608,17 +623,17 @@ wmWindowManager *CTX_wm_manager(const bContext *C)
wmWindow *CTX_wm_window(const bContext *C)
{
- return ctx_wm_python_context_get(C, "window", C->wm.window);
+ return ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window);
}
bScreen *CTX_wm_screen(const bContext *C)
{
- return ctx_wm_python_context_get(C, "screen", C->wm.screen);
+ return ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen);
}
ScrArea *CTX_wm_area(const bContext *C)
{
- return ctx_wm_python_context_get(C, "area", C->wm.area);
+ return ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area);
}
SpaceLink *CTX_wm_space_data(const bContext *C)
@@ -629,7 +644,7 @@ SpaceLink *CTX_wm_space_data(const bContext *C)
ARegion *CTX_wm_region(const bContext *C)
{
- return ctx_wm_python_context_get(C, "region", C->wm.region);
+ return ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region);
}
void *CTX_wm_region_data(const bContext *C)
@@ -1077,3 +1092,15 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
return ctx_data_collection_get(C, "visible_pose_bones", list);
}
+FreestyleLineStyle *CTX_data_linestyle_from_scene(Scene *scene)
+{
+ SceneRenderLayer *actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ FreestyleConfig *config = &actsrl->freestyleConfig;
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(config);
+
+ if (lineset) {
+ return lineset->linestyle;
+ }
+
+ return NULL;
+}
diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 399b0f86d5f..3fde1cdd710 100644
--- a/source/blender/editors/util/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -25,8 +25,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/editors/util/crazyspace.c
- * \ingroup edutil
+/** \file blender/blenkernel/intern/crazyspace.c
+ * \ingroup bke
*/
@@ -42,24 +42,37 @@
#include "BLI_math.h"
#include "BLI_bitmap.h"
+#include "BKE_crazyspace.h"
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_mesh.h"
#include "BKE_editmesh.h"
-#include "ED_util.h"
-
typedef struct {
float (*vertexcos)[3];
BLI_bitmap *vertex_visit;
} MappedUserData;
-BLI_INLINE void tan_calc_v3(float a[3], const float b[3], const float c[3])
+BLI_INLINE void tan_calc_quat_v3(
+ float r_quat[4],
+ const float co_1[3], const float co_2[3], const float co_3[3])
{
- a[0] = b[0] + 0.2f * (b[0] - c[0]);
- a[1] = b[1] + 0.2f * (b[1] - c[1]);
- a[2] = b[2] + 0.2f * (b[2] - c[2]);
+ float vec_u[3], vec_v[3];
+ float nor[3];
+
+ sub_v3_v3v3(vec_u, co_1, co_2);
+ sub_v3_v3v3(vec_v, co_1, co_3);
+
+ cross_v3_v3v3(nor, vec_u, vec_v);
+
+ if (normalize_v3(nor) > FLT_EPSILON) {
+ const float zero_vec[3] = {0.0f};
+ tri_to_quat_ex(r_quat, zero_vec, vec_u, vec_v, nor);
+ }
+ else {
+ unit_qt(r_quat);
+ }
}
static void set_crazy_vertex_quat(
@@ -67,16 +80,10 @@ static void set_crazy_vertex_quat(
const float co_1[3], const float co_2[3], const float co_3[3],
const float vd_1[3], const float vd_2[3], const float vd_3[3])
{
- float vec_u[3], vec_v[3];
float q1[4], q2[4];
- tan_calc_v3(vec_u, co_1, co_2);
- tan_calc_v3(vec_v, co_1, co_3);
- tri_to_quat(q1, co_1, vec_u, vec_v);
-
- tan_calc_v3(vec_u, vd_1, vd_2);
- tan_calc_v3(vec_v, vd_1, vd_3);
- tri_to_quat(q2, vd_1, vec_u, vec_v);
+ tan_calc_quat_v3(q1, co_1, co_2, co_3);
+ tan_calc_quat_v3(q2, vd_1, vd_2, vd_3);
sub_qt_qtqt(r_quat, q2, q1);
}
@@ -111,7 +118,7 @@ static int modifiers_disable_subsurf_temporary(Object *ob)
}
/* disable subsurf temporal, get mapped cos, and enable it */
-float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
+float (*BKE_crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
{
Mesh *me = obedit->data;
DerivedMesh *dm;
@@ -146,7 +153,8 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
return vertexcos;
}
-void crazyspace_set_quats_editmesh(BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4])
+void BKE_crazyspace_set_quats_editmesh(BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4],
+ const bool use_select)
{
BMFace *f;
BMIter iter;
@@ -166,8 +174,12 @@ void crazyspace_set_quats_editmesh(BMEditMesh *em, float (*origcos)[3], float (*
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT) || BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN))
+ if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN) ||
+ BM_elem_flag_test(l_iter->v, BM_ELEM_TAG) ||
+ (use_select && !BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)))
+ {
continue;
+ }
if (!BM_elem_flag_test(l_iter->v, BM_ELEM_TAG)) {
const float *co_prev, *co_curr, *co_next; /* orig */
@@ -203,7 +215,7 @@ void crazyspace_set_quats_editmesh(BMEditMesh *em, float (*origcos)[3], float (*
}
}
-void crazyspace_set_quats_mesh(Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4])
+void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4])
{
int i;
MVert *mvert;
@@ -316,7 +328,7 @@ int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em
return numleft;
}
-int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+int BKE_sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
@@ -375,9 +387,9 @@ int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformma
return numleft;
}
-void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+void BKE_crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
- int totleft = sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
+ int totleft = BKE_sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
if (totleft) {
/* there are deformation modifier which doesn't support deformation matrices
@@ -409,7 +421,7 @@ void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3
quats = MEM_mallocN(me->totvert * sizeof(*quats), "crazy quats");
- crazyspace_set_quats_mesh(me, origVerts, deformedVerts, quats);
+ BKE_crazyspace_set_quats_mesh(me, origVerts, deformedVerts, quats);
for (i = 0; i < me->totvert; i++) {
float qmat[3][3], tmat[3][3];
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 2454c104755..14fd44e594a 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -51,7 +51,6 @@
#include "DNA_object_types.h"
#include "BKE_animsys.h"
-#include "BKE_anim.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_font.h"
@@ -182,6 +181,8 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
cu->type = type;
cu->bevfac1 = 0.0f;
cu->bevfac2 = 1.0f;
+ cu->bevfac1_mapping = CU_BEVFAC_MAP_RESOLU;
+ cu->bevfac2_mapping = CU_BEVFAC_MAP_RESOLU;
cu->bb = BKE_boundbox_alloc_unit();
@@ -254,7 +255,7 @@ void BKE_curve_make_local(Curve *cu)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - when there are only lib users: don't do
* - when there are only local users: set flag
@@ -272,12 +273,12 @@ void BKE_curve_make_local(Curve *cu)
for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
if (ob->data == cu) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &cu->id);
extern_local_curve(cu);
}
@@ -435,7 +436,7 @@ void BKE_curve_texspace_get(Curve *cu, float r_loc[3], float r_rot[3], float r_s
if (r_size) copy_v3_v3(r_size, cu->size);
}
-int BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
+bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
{
Nurb *nu;
int tot = 0;
@@ -446,20 +447,20 @@ int BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
tot_nu = nu->pntsu;
if (index - tot < tot_nu) {
copy_v3_v3(r_co, nu->bezt[index - tot].vec[1]);
- return TRUE;
+ return true;
}
}
else {
tot_nu = nu->pntsu * nu->pntsv;
if (index - tot < tot_nu) {
copy_v3_v3(r_co, nu->bp[index - tot].vec);
- return TRUE;
+ return true;
}
}
tot += tot_nu;
}
- return FALSE;
+ return false;
}
int BKE_nurbList_verts_count(ListBase *nurb)
@@ -699,19 +700,13 @@ void BKE_nurb_minmax(Nurb *nu, bool use_radius, float min[3], float max[3])
/* be sure to call makeknots after this */
void BKE_nurb_points_add(Nurb *nu, int number)
{
- BPoint *tmp = nu->bp;
+ BPoint *bp;
int i;
- nu->bp = (BPoint *)MEM_mallocN((nu->pntsu + number) * sizeof(BPoint), "rna_Curve_spline_points_add");
-
- if (tmp) {
- memmove(nu->bp, tmp, nu->pntsu * sizeof(BPoint));
- MEM_freeN(tmp);
- }
- memset(nu->bp + nu->pntsu, 0, number * sizeof(BPoint));
+ nu->bp = MEM_recallocN(nu->bp, (nu->pntsu + number) * sizeof(BPoint));
- for (i = 0, tmp = nu->bp + nu->pntsu; i < number; i++, tmp++) {
- tmp->radius = 1.0f;
+ for (i = 0, bp = &nu->bp[nu->pntsu]; i < number; i++, bp++) {
+ bp->radius = 1.0f;
}
nu->pntsu += number;
@@ -719,19 +714,13 @@ void BKE_nurb_points_add(Nurb *nu, int number)
void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
{
- BezTriple *tmp = nu->bezt;
+ BezTriple *bezt;
int i;
- nu->bezt = (BezTriple *)MEM_mallocN((nu->pntsu + number) * sizeof(BezTriple), "rna_Curve_spline_points_add");
-
- if (tmp) {
- memmove(nu->bezt, tmp, nu->pntsu * sizeof(BezTriple));
- MEM_freeN(tmp);
- }
- memset(nu->bezt + nu->pntsu, 0, number * sizeof(BezTriple));
+ nu->bezt = MEM_recallocN(nu->bp, (nu->pntsu + number) * sizeof(BezTriple));
- for (i = 0, tmp = nu->bezt + nu->pntsu; i < number; i++, tmp++) {
- tmp->radius = 1.0f;
+ for (i = 0, bezt = &nu->bezt[nu->pntsu]; i < number; i++, bezt++) {
+ bezt->radius = 1.0f;
}
nu->pntsu += number;
@@ -1492,12 +1481,12 @@ float *BKE_curve_surf_make_orco(Object *ob)
for (b = 0; b < sizeu; b++) {
int use_b = b;
if (b == sizeu - 1 && (nu->flagu & CU_NURB_CYCLIC))
- use_b = FALSE;
+ use_b = false;
for (a = 0; a < sizev; a++) {
int use_a = a;
if (a == sizev - 1 && (nu->flagv & CU_NURB_CYCLIC))
- use_a = FALSE;
+ use_a = false;
tdata = _tdata + 3 * (use_b * (nu->pntsv * resolv) + use_a);
@@ -1596,7 +1585,7 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts)
fp[2] = 0.0;
}
else {
- float *vert;
+ const float *vert;
int realv = v % dl->nr;
int realu = u % dl->parts;
@@ -1620,7 +1609,8 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts)
/* ***************** BEVEL ****************** */
-void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRender, int renderResolution)
+void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp,
+ const bool for_render, const bool use_render_resolution)
{
DispList *dl, *dlnew;
Curve *bevcu, *cu;
@@ -1643,13 +1633,16 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende
facx = cu->bevobj->size[0];
facy = cu->bevobj->size[1];
- if (forRender) {
- BKE_displist_make_curveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0, renderResolution);
+ if (for_render) {
+ BKE_displist_make_curveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution);
dl = bevdisp.first;
}
+ else if (cu->bevobj->curve_cache) {
+ dl = cu->bevobj->curve_cache->disp.first;
+ }
else {
BLI_assert(cu->bevobj->curve_cache != NULL);
- dl = cu->bevobj->curve_cache->disp.first;
+ dl = NULL;
}
while (dl) {
@@ -1923,12 +1916,13 @@ static int vergxcobev(const void *a1, const void *a2)
/* this function cannot be replaced with atan2, but why? */
-static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *sina, float *cosa)
+static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2,
+ float *r_sina, float *r_cosa)
{
float t01, t02, x3, y3;
- t01 = (float)sqrt(x1 * x1 + y1 * y1);
- t02 = (float)sqrt(x2 * x2 + y2 * y2);
+ t01 = sqrtf(x1 * x1 + y1 * y1);
+ t02 = sqrtf(x2 * x2 + y2 * y2);
if (t01 == 0.0f)
t01 = 1.0f;
if (t02 == 0.0f)
@@ -1956,13 +1950,13 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
y3 = -x1;
}
else {
- t01 = (float)sqrt(x3 * x3 + y3 * y3);
+ t01 = sqrtf(x3 * x3 + y3 * y3);
x3 /= t01;
y3 /= t01;
}
- *sina = -y3 / t02;
- *cosa = x3 / t02;
+ *r_sina = -y3 / t02;
+ *r_cosa = x3 / t02;
}
@@ -2523,7 +2517,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
float min, inp;
struct BevelSort *sortdata, *sd, *sd1;
int a, b, nr, poly, resolu = 0, len = 0;
- int do_tilt, do_radius, do_weight;
+ bool do_tilt, do_radius, do_weight;
bool is_editmode = false;
ListBase *bev;
@@ -2551,7 +2545,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */
- do_weight = TRUE;
+ do_weight = true;
/* check we are a single point? also check we are not a surface and that the orderu is sane,
* enforced in the UI but can go wrong possibly */
@@ -2584,7 +2578,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevp->alfa = bp->alfa;
bevp->radius = bp->radius;
bevp->weight = bp->weight;
- bevp->split_tag = TRUE;
+ bevp->split_tag = true;
bevp++;
bp++;
}
@@ -2624,8 +2618,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevp->alfa = prevbezt->alfa;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
- bevp->split_tag = TRUE;
- bevp->dupe_tag = FALSE;
+ bevp->split_tag = true;
+ bevp->dupe_tag = false;
bevp++;
bl->nr++;
bl->dupe_nr = 1;
@@ -2658,13 +2652,13 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* indicate with handlecodes double points */
if (prevbezt->h1 == prevbezt->h2) {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT)
- bevp->split_tag = TRUE;
+ bevp->split_tag = true;
}
else {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT)
- bevp->split_tag = TRUE;
+ bevp->split_tag = true;
else if (prevbezt->h2 == 0 || prevbezt->h2 == HD_VECT)
- bevp->split_tag = TRUE;
+ bevp->split_tag = true;
}
bl->nr += resolu;
bevp += resolu;
@@ -2730,7 +2724,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
if (fabsf(bevp0->vec[0] - bevp1->vec[0]) < 0.00001f) {
if (fabsf(bevp0->vec[1] - bevp1->vec[1]) < 0.00001f) {
if (fabsf(bevp0->vec[2] - bevp1->vec[2]) < 0.00001f) {
- bevp0->dupe_tag = TRUE;
+ bevp0->dupe_tag = true;
bl->dupe_nr++;
}
}
@@ -2865,7 +2859,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* 2D Curves */
for (bl = bev->first; bl; bl = bl->next) {
if (bl->nr < 2) {
- /* do nothing */
+ BevPoint *bevp = (BevPoint *)(bl + 1);
+ unit_qt(bevp->quat);
}
else if (bl->nr == 2) { /* 2 pnt, treat separate */
make_bevel_list_segment_2D(bl);
@@ -2879,7 +2874,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* 3D Curves */
for (bl = bev->first; bl; bl = bl->next) {
if (bl->nr < 2) {
- /* do nothing */
+ BevPoint *bevp = (BevPoint *)(bl + 1);
+ unit_qt(bevp->quat);
}
else if (bl->nr == 2) { /* 2 pnt, treat separate */
make_bevel_list_segment_3D(bl);
@@ -2893,17 +2889,17 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* ****************** HANDLES ************** */
-/*
- * handlecodes:
- * 0: nothing, 1:auto, 2:vector, 3:aligned
- */
-
-/* mode: is not zero when FCurve, is 2 when forced horizontal for autohandles */
-static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode, int skip_align)
+static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *next,
+ bool is_fcurve, bool skip_align)
{
+ /* defines to avoid confusion */
+#define p2_h1 (p2 - 3)
+#define p2_h2 (p2 + 3)
+
float *p1, *p2, *p3, pt[3];
float dvec_a[3], dvec_b[3];
float len, len_a, len_b;
+ float len_ratio;
const float eps = 1e-5;
if (bezt->h1 == 0 && bezt->h2 == 0) {
@@ -2936,7 +2932,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
sub_v3_v3v3(dvec_a, p2, p1);
sub_v3_v3v3(dvec_b, p3, p2);
- if (mode != 0) {
+ if (is_fcurve) {
len_a = dvec_a[0];
len_b = dvec_b[0];
}
@@ -2948,16 +2944,25 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
if (len_a == 0.0f) len_a = 1.0f;
if (len_b == 0.0f) len_b = 1.0f;
+ len_ratio = len_a / len_b;
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) || ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */
float tvec[3];
tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
tvec[2] = dvec_b[2] / len_b + dvec_a[2] / len_a;
- len = len_v3(tvec) * 2.5614f;
+
+ if (is_fcurve) {
+ len = tvec[0];
+ }
+ else {
+ len = len_v3(tvec);
+ }
+ len *= 2.5614f;
if (len != 0.0f) {
- int leftviolate = 0, rightviolate = 0; /* for mode==2 */
+ /* only for fcurves */
+ bool leftviolate = false, rightviolate = false;
if (len_a > 5.0f * len_b)
len_a = 5.0f * len_b;
@@ -2966,7 +2971,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
len_a /= len;
- madd_v3_v3v3fl(p2 - 3, p2, tvec, -len_a);
+ madd_v3_v3v3fl(p2_h1, p2, tvec, -len_a);
if ((bezt->h1 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */
float ydiff1 = prev->vec[1][1] - bezt->vec[1][1];
@@ -2992,7 +2997,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
}
if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
len_b /= len;
- madd_v3_v3v3fl(p2 + 3, p2, tvec, len_b);
+ madd_v3_v3v3fl(p2_h2, p2, tvec, len_b);
if ((bezt->h2 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */
float ydiff1 = prev->vec[1][1] - bezt->vec[1][1];
@@ -3000,7 +3005,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
if ( (ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f) ) {
bezt->vec[2][1] = bezt->vec[1][1];
}
- else { /* andles should not be beyond y coord of two others */
+ else { /* handles should not be beyond y coord of two others */
if (ydiff1 <= 0.0f) {
if (next->vec[1][1] < bezt->vec[2][1]) {
bezt->vec[2][1] = next->vec[1][1];
@@ -3017,89 +3022,115 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
}
}
if (leftviolate || rightviolate) { /* align left handle */
- float h1[3], h2[3];
- float dot;
+ BLI_assert(is_fcurve);
+#if 0
+ if (is_fcurve)
+#endif
+ {
+ /* simple 2d calculation */
+ float h1_x = p2_h1[0] - p2[0];
+ float h2_x = p2[0] - p2_h2[0];
- sub_v3_v3v3(h1, p2 - 3, p2);
- sub_v3_v3v3(h2, p2, p2 + 3);
+ if (leftviolate) {
+ p2_h2[1] = p2[1] + ((p2[1] - p2_h1[1]) / h1_x) * h2_x;
+ }
+ else {
+ p2_h1[1] = p2[1] + ((p2[1] - p2_h2[1]) / h2_x) * h1_x;
+ }
+ }
+#if 0
+ else {
+ float h1[3], h2[3];
+ float dot;
- len_a = normalize_v3(h1);
- len_b = normalize_v3(h2);
+ sub_v3_v3v3(h1, p2_h1, p2);
+ sub_v3_v3v3(h2, p2, p2_h2);
- dot = dot_v3v3(h1, h2);
+ len_a = normalize_v3(h1);
+ len_b = normalize_v3(h2);
- if (leftviolate) {
- mul_v3_fl(h1, dot * len_b);
- sub_v3_v3v3(p2 + 3, p2, h1);
- }
- else {
- mul_v3_fl(h2, dot * len_a);
- add_v3_v3v3(p2 - 3, p2, h2);
+ dot = dot_v3v3(h1, h2);
+
+ if (leftviolate) {
+ mul_v3_fl(h1, dot * len_b);
+ sub_v3_v3v3(p2_h2, p2, h1);
+ }
+ else {
+ mul_v3_fl(h2, dot * len_a);
+ add_v3_v3v3(p2_h1, p2, h2);
+ }
}
+#endif
}
}
}
if (bezt->h1 == HD_VECT) { /* vector */
- madd_v3_v3v3fl(p2 - 3, p2, dvec_a, -1.0f / 3.0f);
+ madd_v3_v3v3fl(p2_h1, p2, dvec_a, -1.0f / 3.0f);
}
if (bezt->h2 == HD_VECT) {
- madd_v3_v3v3fl(p2 + 3, p2, dvec_b, 1.0f / 3.0f);
+ madd_v3_v3v3fl(p2_h2, p2, dvec_b, 1.0f / 3.0f);
}
- if (skip_align) {
+ if (skip_align || (!ELEM(HD_ALIGN, bezt->h1, bezt->h2) && !ELEM(HD_ALIGN_DOUBLESIDE, bezt->h1, bezt->h2))) {
/* handles need to be updated during animation and applying stuff like hooks,
* but in such situations it's quite difficult to distinguish in which order
* align handles should be aligned so skip them for now */
return;
}
- len_b = len_v3v3(p2, p2 + 3);
- len_a = len_v3v3(p2, p2 - 3);
- if (len_a == 0.0f)
- len_a = 1.0f;
- if (len_b == 0.0f)
- len_b = 1.0f;
+ len_a = len_v3v3(p2, p2_h1);
+ len_b = len_v3v3(p2, p2_h2);
+ if (is_fcurve == false) {
+ if (len_a == 0.0f)
+ len_a = 1.0f;
+ if (len_b == 0.0f)
+ len_b = 1.0f;
+ len_ratio = len_a / len_b;
+ }
if (bezt->f1 & SELECT) { /* order of calculation */
- if (bezt->h2 == HD_ALIGN) { /* aligned */
+ if (ELEM(bezt->h2, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) { /* aligned */
if (len_a > eps) {
- len = len_b / len_a;
- p2[3] = p2[0] + len * (p2[0] - p2[-3]);
- p2[4] = p2[1] + len * (p2[1] - p2[-2]);
- p2[5] = p2[2] + len * (p2[2] - p2[-1]);
+ len = 1.0f / len_ratio;
+ p2_h2[0] = p2[0] + len * (p2[0] - p2_h1[0]);
+ p2_h2[1] = p2[1] + len * (p2[1] - p2_h1[1]);
+ p2_h2[2] = p2[2] + len * (p2[2] - p2_h1[2]);
}
}
- if (bezt->h1 == HD_ALIGN) {
+ if (ELEM(bezt->h1, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) {
if (len_b > eps) {
- len = len_a / len_b;
- p2[-3] = p2[0] + len * (p2[0] - p2[3]);
- p2[-2] = p2[1] + len * (p2[1] - p2[4]);
- p2[-1] = p2[2] + len * (p2[2] - p2[5]);
+ len = len_ratio;
+ p2_h1[0] = p2[0] + len * (p2[0] - p2_h2[0]);
+ p2_h1[1] = p2[1] + len * (p2[1] - p2_h2[1]);
+ p2_h1[2] = p2[2] + len * (p2[2] - p2_h2[2]);
}
}
}
else {
- if (bezt->h1 == HD_ALIGN) {
+ if (ELEM(bezt->h1, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) {
if (len_b > eps) {
- len = len_a / len_b;
- p2[-3] = p2[0] + len * (p2[0] - p2[3]);
- p2[-2] = p2[1] + len * (p2[1] - p2[4]);
- p2[-1] = p2[2] + len * (p2[2] - p2[5]);
+ len = len_ratio;
+ p2_h1[0] = p2[0] + len * (p2[0] - p2_h2[0]);
+ p2_h1[1] = p2[1] + len * (p2[1] - p2_h2[1]);
+ p2_h1[2] = p2[2] + len * (p2[2] - p2_h2[2]);
}
}
- if (bezt->h2 == HD_ALIGN) { /* aligned */
+ if (ELEM(bezt->h2, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) { /* aligned */
if (len_a > eps) {
- len = len_b / len_a;
- p2[3] = p2[0] + len * (p2[0] - p2[-3]);
- p2[4] = p2[1] + len * (p2[1] - p2[-2]);
- p2[5] = p2[2] + len * (p2[2] - p2[-1]);
+ len = 1.0f / len_ratio;
+ p2_h2[0] = p2[0] + len * (p2[0] - p2_h1[0]);
+ p2_h2[1] = p2[1] + len * (p2[1] - p2_h1[1]);
+ p2_h2[2] = p2[2] + len * (p2[2] - p2_h1[2]);
}
}
}
+
+#undef p2_h1
+#undef p2_h2
}
-static void calchandlesNurb_intern(Nurb *nu, int skip_align)
+static void calchandlesNurb_intern(Nurb *nu, bool skip_align)
{
BezTriple *bezt, *prev, *next;
int a;
@@ -3131,14 +3162,14 @@ static void calchandlesNurb_intern(Nurb *nu, int skip_align)
}
}
-void BKE_nurb_handle_calc(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
+void BKE_nurb_handle_calc(BezTriple *bezt, BezTriple *prev, BezTriple *next, const bool is_fcurve)
{
- calchandleNurb_intern(bezt, prev, next, mode, FALSE);
+ calchandleNurb_intern(bezt, prev, next, is_fcurve, false);
}
void BKE_nurb_handles_calc(Nurb *nu) /* first, if needed, set handle flags */
{
- calchandlesNurb_intern(nu, FALSE);
+ calchandlesNurb_intern(nu, false);
}
/* similar to BKE_nurb_handle_calc but for curves and
@@ -3305,7 +3336,7 @@ void BKE_nurbList_handles_autocalc(ListBase *editnurb, int flag)
}
}
-void BKE_nurbList_handles_set(ListBase *editnurb, short code)
+void BKE_nurbList_handles_set(ListBase *editnurb, const char code)
{
/* code==1: set autohandle */
/* code==2: set vectorhandle */
@@ -3316,9 +3347,8 @@ void BKE_nurbList_handles_set(ListBase *editnurb, short code)
Nurb *nu;
BezTriple *bezt;
int a;
- short ok = 0;
- if (code == 1 || code == 2) {
+ if (ELEM(code, HD_AUTO, HD_VECT)) {
nu = editnurb->first;
while (nu) {
if (nu->type == CU_BEZIER) {
@@ -3345,46 +3375,46 @@ void BKE_nurbList_handles_set(ListBase *editnurb, short code)
}
}
else {
+ char h_new = HD_FREE;
+
/* there is 1 handle not FREE: FREE it all, else make ALIGNED */
- nu = editnurb->first;
if (code == 5) {
- ok = HD_ALIGN;
+ h_new = HD_ALIGN;
}
else if (code == 6) {
- ok = HD_FREE;
+ h_new = HD_FREE;
}
else {
/* Toggle */
- while (nu) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- if ((bezt->f1 & SELECT) && bezt->h1) ok = 1;
- if ((bezt->f3 & SELECT) && bezt->h2) ok = 1;
- if (ok) break;
+ if (((bezt->f1 & SELECT) && bezt->h1 != HD_FREE) ||
+ ((bezt->f3 & SELECT) && bezt->h2 != HD_FREE))
+ {
+ h_new = HD_AUTO;
+ break;
+ }
bezt++;
}
}
- nu = nu->next;
}
- if (ok) ok = HD_FREE;
- else ok = HD_ALIGN;
+ h_new = (h_new == HD_FREE) ? HD_ALIGN : HD_FREE;
}
- nu = editnurb->first;
- while (nu) {
+ for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- if (bezt->f1 & SELECT) bezt->h1 = ok;
- if (bezt->f3 & SELECT) bezt->h2 = ok;
+ if (bezt->f1 & SELECT) bezt->h1 = h_new;
+ if (bezt->f3 & SELECT) bezt->h2 = h_new;
bezt++;
}
BKE_nurb_handles_calc(nu);
}
- nu = nu->next;
}
}
}
@@ -3564,8 +3594,10 @@ void BKE_nurb_direction_switch(Nurb *nu)
a = KNOTSU(nu);
fp1 = nu->knotsu;
fp2 = tempf = MEM_mallocN(sizeof(float) * a, "switchdirect");
+ a--;
+ fp2[a] = fp1[a];
while (a--) {
- fp2[0] = fabs(fp1[1] - fp1[0]);
+ fp2[0] = fabsf(fp1[1] - fp1[0]);
fp1++;
fp2++;
}
@@ -3602,9 +3634,9 @@ void BKE_nurb_direction_switch(Nurb *nu)
}
-float (*BKE_curve_nurbs_vertexCos_get(ListBase *lb, int *numVerts_r))[3]
+float (*BKE_curve_nurbs_vertexCos_get(ListBase *lb, int *r_numVerts))[3]
{
- int i, numVerts = *numVerts_r = BKE_nurbList_verts_count(lb);
+ int i, numVerts = *r_numVerts = BKE_nurbList_verts_count(lb);
float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos) * numVerts, "cu_vcos");
Nurb *nu;
@@ -3633,7 +3665,7 @@ float (*BKE_curve_nurbs_vertexCos_get(ListBase *lb, int *numVerts_r))[3]
void BK_curve_nurbs_vertexCos_apply(ListBase *lb, float (*vertexCos)[3])
{
- float *co = vertexCos[0];
+ const float *co = vertexCos[0];
Nurb *nu;
int i;
@@ -3655,7 +3687,7 @@ void BK_curve_nurbs_vertexCos_apply(ListBase *lb, float (*vertexCos)[3])
}
}
- calchandlesNurb_intern(nu, TRUE);
+ calchandlesNurb_intern(nu, true);
}
}
@@ -3719,8 +3751,6 @@ void BKE_curve_nurbs_keyVertexTilts_apply(ListBase *lb, float *key)
bool BKE_nurb_check_valid_u(struct Nurb *nu)
{
- if (nu == NULL)
- return false;
if (nu->pntsu <= 1)
return false;
if (nu->type != CU_NURBS)
@@ -3741,8 +3771,6 @@ bool BKE_nurb_check_valid_u(struct Nurb *nu)
}
bool BKE_nurb_check_valid_v(struct Nurb *nu)
{
- if (nu == NULL)
- return false;
if (nu->pntsv <= 1)
return false;
if (nu->type != CU_NURBS)
@@ -3763,11 +3791,21 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu)
return true;
}
+bool BKE_nurb_check_valid_uv(struct Nurb *nu)
+{
+ if (!BKE_nurb_check_valid_u(nu))
+ return false;
+ if ((nu->pntsv > 1) && !BKE_nurb_check_valid_v(nu))
+ return false;
+
+ return true;
+}
+
bool BKE_nurb_order_clamp_u(struct Nurb *nu)
{
bool changed = false;
if (nu->pntsu < nu->orderu) {
- nu->orderu = nu->pntsu;
+ nu->orderu = max_ii(2, nu->pntsu);
changed = true;
}
if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) {
@@ -3781,7 +3819,7 @@ bool BKE_nurb_order_clamp_v(struct Nurb *nu)
{
bool changed = false;
if (nu->pntsv < nu->orderv) {
- nu->orderv = nu->pntsv;
+ nu->orderv = max_ii(2, nu->pntsv);
changed = true;
}
if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) {
@@ -3851,7 +3889,7 @@ bool BKE_nurb_type_convert(Nurb *nu, const short type, const bool use_handles)
bp++;
}
else {
- char *f = &bezt->f1;
+ const char *f = &bezt->f1;
for (c = 0; c < 3; c++, f++) {
copy_v3_v3(bp->vec, bezt->vec[c]);
bp->vec[3] = 1.0;
@@ -4187,3 +4225,12 @@ void BKE_curve_material_index_clear(Curve *cu)
}
}
}
+
+void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect)
+{
+ r_rect->xmin = (cu->xof * cu->fsize) + tb->x;
+ r_rect->ymax = (cu->yof * cu->fsize) + tb->y + cu->fsize;
+
+ r_rect->xmax = r_rect->xmin + tb->w;
+ r_rect->ymin = r_rect->ymax - tb->h;
+}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index fffd11505a5..fd4350123b4 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -49,7 +49,6 @@
#include "BLI_path_util.h"
#include "BLI_math.h"
#include "BLI_mempool.h"
-#include "BLI_alloca.h"
#include "BLF_translation.h"
@@ -1059,6 +1058,19 @@ static void layerInterp_mvert_skin(void **sources, const float *weights,
vs->flag &= ~MVERT_SKIN_ROOT;
}
+static void layerSwap_flnor(void *data, const int *corner_indices)
+{
+ short (*flnors)[4][3] = data;
+ short nors[4][3];
+ int i = 4;
+
+ while (i--) {
+ copy_v3_v3_short(nors[i], (*flnors)[corner_indices[i]]);
+ }
+
+ memcpy(flnors, nors, sizeof(nors));
+}
+
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@@ -1170,6 +1182,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(FreestyleFace), "FreestyleFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
/* 39: CD_MLOOPTANGENT */
{sizeof(float[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 40: CD_TESSLOOPNORMAL */
+ {sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
};
/* note, numbers are from trunk and need updating for bmesh */
@@ -1185,7 +1199,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
/* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
/* 35-36 */ "CDGridPaintMask", "CDMVertSkin",
- /* 37-38 */ "CDFreestyleEdge", "CDFreestyleFace", "CDMLoopTangent",
+ /* 37-40 */ "CDFreestyleEdge", "CDFreestyleFace", "CDMLoopTangent", "CDTessLoopNormal",
};
@@ -1217,9 +1231,9 @@ const CustomDataMask CD_MASK_BMESH =
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
-const CustomDataMask CD_MASK_FACECORNERS =
+const CustomDataMask CD_MASK_FACECORNERS = /* XXX Not used anywhere! */
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
- CD_MASK_MLOOPCOL;
+ CD_MASK_MLOOPCOL | CD_MASK_NORMAL | CD_MASK_MLOOPTANGENT;
const CustomDataMask CD_MASK_EVERYTHING =
CD_MASK_MVERT | CD_MASK_MSTICKY /* DEPRECATED */ | CD_MASK_MDEFORMVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_NORMAL /* | CD_MASK_POLYINDEX */ | CD_MASK_PROP_FLT |
@@ -1229,7 +1243,9 @@ const CustomDataMask CD_MASK_EVERYTHING =
CD_MASK_MPOLY | CD_MASK_MLOOP | CD_MASK_SHAPE_KEYINDEX | CD_MASK_SHAPEKEY | CD_MASK_BWEIGHT | CD_MASK_CREASE |
CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_BM_ELEM_PYPTR |
/* BMESH ONLY END */
- CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+ CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN |
+ CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
+ CD_MASK_MLOOPTANGENT | CD_MASK_TESSLOOPNORMAL;
static const LayerTypeInfo *layerType_getInfo(int type)
{
@@ -1649,6 +1665,8 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
(alloctype == CD_DUPLICATE) ||
(alloctype == CD_REFERENCE));
+ BLI_assert(size >= 0);
+
if (!typeInfo->defaultname && CustomData_has_layer(data, type))
return &data->layers[CustomData_get_layer_index(data, type)];
@@ -1968,7 +1986,7 @@ static void CustomData_copy_data_layer(const CustomData *source, CustomData *des
int src_offset;
int dest_offset;
- char *src_data = source->layers[src_i].data;
+ const char *src_data = source->layers[src_i].data;
char *dest_data = dest->layers[dest_i].data;
typeInfo = layerType_getInfo(source->layers[src_i].type);
@@ -2281,6 +2299,9 @@ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *l
else if (fdata->layers[i].type == CD_MDISPS) {
CustomData_add_layer_named(ldata, CD_MDISPS, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
}
+ else if (fdata->layers[i].type == CD_TESSLOOPNORMAL) {
+ CustomData_add_layer_named(ldata, CD_NORMAL, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
+ }
}
}
@@ -2302,6 +2323,9 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
CustomData_add_layer_named(fdata, CD_ORIGSPACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
}
+ else if (ldata->layers[i].type == CD_NORMAL) {
+ CustomData_add_layer_named(fdata, CD_TESSLOOPNORMAL, CD_CALLOC, NULL, total, ldata->layers[i].name);
+ }
}
CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
@@ -2406,7 +2430,7 @@ void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
/* If there are no layers, no pool is needed just yet */
if (data->totlayer) {
- data->pool = BLI_mempool_create(data->totsize, totelem, chunksize, BLI_MEMPOOL_SYSMALLOC);
+ data->pool = BLI_mempool_create(data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP);
}
}
@@ -2587,7 +2611,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
if (dest->layers[dest_i].type == source->layers[src_i].type &&
strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0)
{
- char *src_data = (char *)src_block + source->layers[src_i].offset;
+ const char *src_data = (char *)src_block + source->layers[src_i].offset;
char *dest_data = (char *)*dest_block + dest->layers[dest_i].offset;
typeInfo = layerType_getInfo(source->layers[src_i].type);
@@ -2906,7 +2930,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = dest->layers[dest_i].offset;
- char *src_data = source->layers[src_i].data;
+ const char *src_data = source->layers[src_i].data;
char *dest_data = (char *)*dest_block + offset;
typeInfo = layerType_getInfo(dest->layers[dest_i].type);
@@ -2956,7 +2980,7 @@ void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = source->layers[src_i].offset;
- char *src_data = (char *)src_block + offset;
+ const char *src_data = (char *)src_block + offset;
char *dest_data = dest->layers[dest_i].data;
typeInfo = layerType_getInfo(dest->layers[dest_i].type);
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 82b6dded29c..d072088ac8e 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -359,7 +359,7 @@ void defvert_normalize_lock_map(
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
tot_weight += dw->weight;
}
else {
@@ -377,7 +377,7 @@ void defvert_normalize_lock_map(
float scalar = (1.0f / tot_weight) * lock_iweight;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
dw->weight *= scalar;
/* in case of division errors with very low weights */
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index fdeefad795b..21579098266 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -64,7 +64,6 @@
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
-#include "BKE_group.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -305,6 +304,7 @@ DagForest *dag_init(void)
DagForest *forest;
/* use callocN to init all zero */
forest = MEM_callocN(sizeof(DagForest), "DAG root");
+ forest->ugly_hack_sorry = true;
return forest;
}
@@ -507,7 +507,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -795,7 +795,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* object constraints */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -995,7 +995,6 @@ DagNode *dag_find_node(DagForest *forest, void *fob)
return NULL;
}
-static int ugly_hack_sorry = 1; /* prevent type check */
static int dag_print_dependencies = 0; /* debugging */
/* no checking of existence, use dag_find_node first or dag_get_node */
@@ -1008,7 +1007,7 @@ DagNode *dag_add_node(DagForest *forest, void *fob)
node->ob = fob;
node->color = DAG_WHITE;
- if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */
+ if (forest->ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */
if (forest->numNodes) {
((DagNode *) forest->DagNode.last)->next = node;
forest->DagNode.last = node;
@@ -1116,28 +1115,28 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
fob1->child = itA;
}
-static const char *dag_node_name(DagNode *node)
+static const char *dag_node_name(DagForest *dag, DagNode *node)
{
if (node->ob == NULL)
return "null";
- else if (ugly_hack_sorry)
+ else if (dag->ugly_hack_sorry)
return ((ID *)(node->ob))->name + 2;
else
return ((bPoseChannel *)(node->ob))->name;
}
-static void dag_node_print_dependencies(DagNode *node)
+static void dag_node_print_dependencies(DagForest *dag, DagNode *node)
{
DagAdjList *itA;
- printf("%s depends on:\n", dag_node_name(node));
+ printf("%s depends on:\n", dag_node_name(dag, node));
for (itA = node->parent; itA; itA = itA->next)
- printf(" %s through %s\n", dag_node_name(itA->node), itA->name);
+ printf(" %s through %s\n", dag_node_name(dag, itA->node), itA->name);
printf("\n");
}
-static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
+static int dag_node_print_dependency_recurs(DagForest *dag, DagNode *node, DagNode *endnode)
{
DagAdjList *itA;
@@ -1150,8 +1149,8 @@ static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
return 1;
for (itA = node->parent; itA; itA = itA->next) {
- if (dag_node_print_dependency_recurs(itA->node, endnode)) {
- printf(" %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name);
+ if (dag_node_print_dependency_recurs(dag, itA->node, endnode)) {
+ printf(" %s depends on %s through %s.\n", dag_node_name(dag, node), dag_node_name(dag, itA->node), itA->name);
return 1;
}
}
@@ -1166,8 +1165,8 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode,
for (node = dag->DagNode.first; node; node = node->next)
node->color = DAG_WHITE;
- printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
- dag_node_print_dependency_recurs(startnode, endnode);
+ printf(" %s depends on %s through %s.\n", dag_node_name(dag, endnode), dag_node_name(dag, startnode), name);
+ dag_node_print_dependency_recurs(dag, startnode, endnode);
printf("\n");
}
@@ -1201,7 +1200,7 @@ static void dag_check_cycle(DagForest *dag)
/* debugging print */
if (dag_print_dependencies)
for (node = dag->DagNode.first; node; node = node->next)
- dag_node_print_dependencies(node);
+ dag_node_print_dependencies(dag, node);
/* tag nodes unchecked */
for (node = dag->DagNode.first; node; node = node->next)
@@ -1368,6 +1367,124 @@ static void dag_scene_free(Scene *sce)
}
}
+/* Chech whether object data needs to be evaluated before it
+ * might be used by others.
+ *
+ * Means that mesh object needs to have proper derivedFinal,
+ * curves-typed objects are to have proper curve cache.
+ *
+ * Other objects or objects which are tagged for data update are
+ * not considered to be in need of evaluation.
+ */
+static bool check_object_needs_evaluation(Object *object)
+{
+ if (object->recalc & OB_RECALC_ALL) {
+ /* Object is tagged for update anyway, no need to re-tag it. */
+ return false;
+ }
+
+ if (object->type == OB_MESH) {
+ return object->derivedFinal == NULL;
+ }
+ else if (ELEM5(object->type, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
+ return object->curve_cache == NULL;
+ }
+
+ return false;
+}
+
+/* Check whether object data is tagged for update. */
+static bool check_object_tagged_for_update(Object *object)
+{
+ if (object->recalc & OB_RECALC_ALL) {
+ return true;
+ }
+
+ if (ELEM6(object->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
+ ID *data_id = object->data;
+ return (data_id->flag & (LIB_ID_RECALC_DATA | LIB_ID_RECALC)) != 0;
+ }
+
+ return false;
+}
+
+/* Flush changes from tagged objects in the scene to their
+ * dependencies which are not evaluated yet.
+ *
+ * This is needed to ensure all the dependencies are met
+ * before objects gets handled by object_handle_update(),
+ *
+ * This is needed when visible layers are changed or changing
+ * scene graph layout which involved usage of objects which
+ * aren't in the scene or weren't visible yet.
+ */
+static void dag_invisible_dependencies_flush(Scene *scene)
+{
+ DagNode *root_node = scene->theDag->DagNode.first, *node;
+ DagNodeQueue *queue;
+
+ for (node = root_node; node != NULL; node = node->next) {
+ node->color = DAG_WHITE;
+ }
+
+ queue = queue_create(DAGQUEUEALLOC);
+
+ for (node = root_node; node != NULL; node = node->next) {
+ if (node->color == DAG_WHITE) {
+ push_stack(queue, node);
+ node->color = DAG_GRAY;
+
+ while (queue->count) {
+ DagNode *current_node = get_top_node_queue(queue);
+ DagAdjList *itA;
+ bool skip = false;
+
+ for (itA = current_node->child; itA; itA = itA->next) {
+ if (itA->node->color == DAG_WHITE) {
+ itA->node->color = DAG_GRAY;
+ push_stack(queue, itA->node);
+ skip = true;
+ break;
+ }
+ }
+
+ if (!skip) {
+ current_node = pop_queue(queue);
+
+ if (current_node->type == ID_OB) {
+ Object *current_object = current_node->ob;
+ if (check_object_needs_evaluation(current_object)) {
+ for (itA = current_node->child; itA; itA = itA->next) {
+ if (itA->node->type == ID_OB) {
+ Object *object = itA->node->ob;
+ if (check_object_tagged_for_update(object)) {
+ current_object->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
+ }
+ }
+ }
+ }
+ }
+ node->color = DAG_BLACK;
+ }
+ }
+ }
+ }
+
+ queue_delete(queue);
+}
+
+static void dag_invisible_dependencies_check_flush(Main *bmain, Scene *scene)
+{
+ if (DAG_id_type_tagged(bmain, ID_OB) ||
+ DAG_id_type_tagged(bmain, ID_ME) || /* Mesh */
+ DAG_id_type_tagged(bmain, ID_CU) || /* Curve */
+ DAG_id_type_tagged(bmain, ID_MB) || /* MetaBall */
+ DAG_id_type_tagged(bmain, ID_LT)) /* Lattice */
+ {
+ dag_invisible_dependencies_flush(scene);
+ }
+}
+
/* sort the base list on dependency order */
static void dag_scene_build(Main *bmain, Scene *sce)
{
@@ -1461,6 +1578,12 @@ static void dag_scene_build(Main *bmain, Scene *sce)
/* temporal...? */
sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
+
+ /* Make sure that new dependencies which came from invisble layers
+ * are tagged for update (if they're needed for objects which were
+ * tagged for update).
+ */
+ dag_invisible_dependencies_check_flush(bmain, sce);
}
/* clear all dependency graphs */
@@ -1854,7 +1977,7 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
if (ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2007,7 +2130,7 @@ static void dag_group_update_flags(Main *bmain, Scene *scene, Group *group, cons
/* flag all objects that need recalc, for changes in time for example */
/* do_time: make this optional because undo resets objects to their animated locations without this */
-void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const bool do_time)
+void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const bool do_time, const bool do_invisible_flush)
{
Base *base;
Object *ob;
@@ -2062,7 +2185,10 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const b
group->id.flag &= ~LIB_DOIT;
}
}
-
+
+ if (do_invisible_flush) {
+ dag_invisible_dependencies_check_flush(bmain, scene);
+ }
}
/* struct returned by DagSceneLayer */
@@ -2148,10 +2274,12 @@ static void dag_group_on_visible_update(Group *group)
for (go = group->gobject.first; go; go = go->next) {
if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
go->ob->recalc |= OB_RECALC_DATA;
+ go->ob->id.flag |= LIB_DOIT;
lib_id_recalc_tag(G.main, &go->ob->id);
}
if (go->ob->proxy_from) {
go->ob->recalc |= OB_RECALC_OB;
+ go->ob->id.flag |= LIB_DOIT;
lib_id_recalc_tag(G.main, &go->ob->id);
}
@@ -2175,7 +2303,7 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
Object *ob;
DagNode *node;
unsigned int lay = dsl->layer, oblay;
-
+
/* derivedmeshes and displists are not saved to file so need to be
* remade, tag them so they get remade in the scene update loop,
* note armature poses or object matrices are preserved and do not
@@ -2199,7 +2327,7 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
ob->proxy->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
}
- if (ob->dup_group)
+ if (ob->dup_group)
dag_group_on_visible_update(ob->dup_group);
}
}
@@ -2207,7 +2335,7 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
BKE_main_id_tag_idcode(bmain, ID_GR, false);
/* now tag update flags, to ensure deformers get calculated on redraw */
- DAG_scene_update_flags(bmain, scene, lay, do_time);
+ DAG_scene_update_flags(bmain, scene, lay, do_time, true);
scene->lay_updated |= lay;
}
@@ -2352,7 +2480,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
for (obt = bmain->object.first; obt; obt = obt->id.next) {
bConstraint *con;
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
CONSTRAINT_TYPE_OBJECTSOLVER))
{
@@ -2406,7 +2534,8 @@ void DAG_ids_flush_tagged(Main *bmain)
ListBase listbase;
DagSceneLayer *dsl;
ListBase *lbarray[MAX_LIBARRAY];
- int a, do_flush = FALSE;
+ int a;
+ bool do_flush = false;
/* get list of visible scenes and layers */
dag_current_scene_layers(bmain, &listbase);
@@ -2430,7 +2559,7 @@ void DAG_ids_flush_tagged(Main *bmain)
for (dsl = listbase.first; dsl; dsl = dsl->next)
dag_id_flush_update(bmain, dsl->scene, id);
- do_flush = TRUE;
+ do_flush = true;
}
}
}
@@ -2445,10 +2574,11 @@ void DAG_ids_flush_tagged(Main *bmain)
BLI_freelistN(&listbase);
}
-void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
+void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
{
ListBase *lbarray[MAX_LIBARRAY];
- int a, updated = 0;
+ int a;
+ bool updated = false;
/* loop over all ID types */
a = set_listbasepointers(bmain, lbarray);
@@ -2459,14 +2589,8 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
/* we tag based on first ID type character to avoid
* looping over all ID's in case there are no tags */
- if (id &&
-#ifdef WITH_FREESTYLE
- /* XXX very weak... added check for '27' to ignore freestyle added objects */
- id->name[2] > 27 &&
-#endif
- bmain->id_tag_update[id->name[0]])
- {
- updated = 1;
+ if (id && bmain->id_tag_update[id->name[0]]) {
+ updated = true;
break;
}
}
@@ -2707,7 +2831,7 @@ void DAG_pose_sort(Object *ob)
int skip = 0;
dag = dag_init();
- ugly_hack_sorry = 0; /* no ID structs */
+ dag->ugly_hack_sorry = false; /* no ID structs */
rootnode = dag_add_node(dag, NULL); /* node->ob becomes NULL */
@@ -2723,7 +2847,7 @@ void DAG_pose_sort(Object *ob)
addtoroot = 0;
}
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2834,8 +2958,6 @@ void DAG_pose_sort(Object *ob)
free_forest(dag);
MEM_freeN(dag);
-
- ugly_hack_sorry = 1;
}
/* ************************ DAG FOR THREADED UPDATE ********************* */
@@ -2954,14 +3076,14 @@ Object *DAG_get_node_object(void *node_v)
}
/* Returns node name, used for debug output only, atm. */
-const char *DAG_get_node_name(void *node_v)
+const char *DAG_get_node_name(Scene *scene, void *node_v)
{
DagNode *node = node_v;
- return dag_node_name(node);
+ return dag_node_name(scene->theDag, node);
}
-short DAG_get_eval_flags_for_object(struct Scene *scene, void *object)
+short DAG_get_eval_flags_for_object(Scene *scene, void *object)
{
DagNode *node;
@@ -2975,7 +3097,7 @@ short DAG_get_eval_flags_for_object(struct Scene *scene, void *object)
return 0;
}
- node = dag_find_node(scene->theDag, object);;
+ node = dag_find_node(scene->theDag, object);
if (node) {
return node->eval_flags;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 5234b2b3219..3c502cc79e2 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -40,7 +40,6 @@
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_material_types.h"
#include "DNA_vfont_types.h"
#include "BLI_blenlib.h"
@@ -54,9 +53,7 @@
#include "BKE_displist.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_object.h"
-#include "BKE_main.h"
#include "BKE_mball.h"
-#include "BKE_material.h"
#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_anim.h"
@@ -302,7 +299,8 @@ bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, i
/* ****************** make displists ********************* */
-static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender, int renderResolution)
+static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase,
+ const bool for_render, const bool use_render_resolution)
{
Nurb *nu;
DispList *dl;
@@ -310,12 +308,12 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i
BPoint *bp;
float *data;
int a, len, resolu;
- const int editmode = (!forRender && (cu->editnurb || cu->editfont));
+ const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
nu = nubase->first;
while (nu) {
- if (nu->hide == 0 || editmode == 0) {
- if (renderResolution && cu->resolu_ren != 0)
+ if (nu->hide == 0 || editmode == false) {
+ if (use_render_resolution && cu->resolu_ren != 0)
resolu = cu->resolu_ren;
else
resolu = nu->resolu;
@@ -597,7 +595,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
while (dl) {
if (dl->type == DL_SURF) {
if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U) == 0) {
- if ( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) {
+ if ((cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) {
dlnew = MEM_callocN(sizeof(DispList), "filldisp");
BLI_addtail(&front, dlnew);
dlnew->verts = fp1 = MEM_mallocN(sizeof(float) * 3 * dl->parts, "filldisp1");
@@ -749,14 +747,15 @@ void BKE_displist_make_mball_forRender(EvaluationContext *eval_ctx, Scene *scene
object_deform_mball(ob, dispbase);
}
-static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int renderResolution, int editmode)
+static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob,
+ const bool use_render_resolution, const bool editmode)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
ModifierData *pretessellatePoint;
int required_mode;
- if (renderResolution)
+ if (use_render_resolution)
required_mode = eModifierMode_Render;
else
required_mode = eModifierMode_Realtime;
@@ -791,29 +790,31 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int re
}
static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb,
- int forRender, int renderResolution)
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
ModifierData *pretessellatePoint;
Curve *cu = ob->data;
int numVerts = 0;
- const int editmode = (!forRender && (cu->editnurb || cu->editfont));
+ const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
ModifierApplyFlag app_flag = 0;
float (*deformedVerts)[3] = NULL;
float *keyVerts = NULL;
int required_mode;
+ modifiers_clearErrors(ob);
+
if (editmode)
app_flag |= MOD_APPLY_USECACHE;
- if (renderResolution) {
+ if (use_render_resolution) {
app_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
else
required_mode = eModifierMode_Realtime;
- pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode);
+ pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
if (editmode)
required_mode |= eModifierMode_Editmode;
@@ -888,7 +889,7 @@ static float (*displist_get_allverts(ListBase *dispbase, int *totvert))[3]
static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
{
DispList *dl;
- float *fp;
+ const float *fp;
fp = (float *)allverts;
for (dl = dispbase->first; dl; dl = dl->next) {
@@ -899,28 +900,28 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
}
static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
- ListBase *dispbase, DerivedMesh **derivedFinal,
- int forRender, int renderResolution)
+ ListBase *dispbase, DerivedMesh **r_dm_final,
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
ModifierData *pretessellatePoint;
Curve *cu = ob->data;
int required_mode = 0, totvert = 0;
- int editmode = (!forRender && (cu->editnurb || cu->editfont));
+ const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
DerivedMesh *dm = NULL, *ndm;
float (*vertCos)[3] = NULL;
- int useCache = !forRender;
+ int useCache = !for_render;
ModifierApplyFlag app_flag = 0;
- if (renderResolution) {
+ if (use_render_resolution) {
app_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
else
required_mode = eModifierMode_Realtime;
- pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode);
+ pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
if (editmode)
required_mode |= eModifierMode_Editmode;
@@ -929,8 +930,8 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
md = pretessellatePoint->next;
}
- if (derivedFinal && *derivedFinal) {
- (*derivedFinal)->release(*derivedFinal);
+ if (r_dm_final && *r_dm_final) {
+ (*r_dm_final)->release(*r_dm_final);
}
for (; md; md = md->next) {
@@ -965,7 +966,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
}
}
else {
- if (!derivedFinal) {
+ if (!r_dm_final) {
/* makeDisplistCurveTypes could be used for beveling, where derived mesh
* is totally unnecessary, so we could stop modifiers applying
* when we found constructive modifier but derived mesh is unwanted result
@@ -1032,7 +1033,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
}
}
- if (derivedFinal) {
+ if (r_dm_final) {
if (dm) {
/* see: mesh_calc_modifiers */
if (dm->getNumTessFaces(dm) == 0) {
@@ -1048,7 +1049,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
}
}
- (*derivedFinal) = dm;
+ (*r_dm_final) = dm;
}
}
@@ -1124,7 +1125,8 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
-static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender, int renderResolution)
+static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render, const bool use_render_resolution)
{
/* this function represents logic of mesh's orcodm calculation
* for displist-based objects
@@ -1134,18 +1136,18 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina
ModifierData *pretessellatePoint;
Curve *cu = ob->data;
int required_mode;
- int editmode = (!forRender && (cu->editnurb || cu->editfont));
+ const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
DerivedMesh *ndm, *orcodm = NULL;
ModifierApplyFlag app_flag = MOD_APPLY_ORCO;
- if (renderResolution) {
+ if (use_render_resolution) {
app_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
else
required_mode = eModifierMode_Realtime;
- pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode);
+ pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);
if (editmode)
required_mode |= eModifierMode_Editmode;
@@ -1185,13 +1187,14 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina
}
/* add an orco layer if needed */
- add_orco_dm(ob, derivedFinal, orcodm);
+ add_orco_dm(ob, dm_final, orcodm);
orcodm->release(orcodm);
}
void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution)
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
ListBase nubase = {NULL, NULL};
Nurb *nu;
@@ -1200,21 +1203,21 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
float *data;
int len;
- if (!forRender && cu->editnurb) {
+ if (!for_render && cu->editnurb) {
BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu));
}
else {
BKE_nurbList_duplicate(&nubase, &cu->nurb);
}
- if (!forOrco)
- curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
+ if (!for_orco)
+ curve_calc_modifiers_pre(scene, ob, &nubase, for_render, use_render_resolution);
for (nu = nubase.first; nu; nu = nu->next) {
- if (forRender || nu->hide == 0) {
+ if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
int resolu = nu->resolu, resolv = nu->resolv;
- if (renderResolution) {
+ if (use_render_resolution) {
if (cu->resolu_ren)
resolu = cu->resolu_ren;
if (cu->resolv_ren)
@@ -1273,17 +1276,17 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
}
}
- if (!forOrco) {
- curve_calc_modifiers_post(scene, ob, &nubase, dispbase, derivedFinal,
- forRender, renderResolution);
+ if (!for_orco) {
+ curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final,
+ for_render, use_render_resolution);
}
BKE_nurbList_free(&nubase);
}
-static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispList *dlb, float bev_blend, float widfac, float fac, float **data_r)
+static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispList *dlb, float bev_blend, float widfac, float fac, float **r_data)
{
- float *fp, *data = *data_r;
+ float *fp, *data = *r_data;
int b;
fp = dlb->verts;
@@ -1334,7 +1337,7 @@ static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispLis
}
}
- *data_r = data;
+ *r_data = data;
}
static void fillBevelCap(Nurb *nu, DispList *dlb, float *prev_fp, ListBase *dispbase)
@@ -1359,8 +1362,146 @@ static void fillBevelCap(Nurb *nu, DispList *dlb, float *prev_fp, ListBase *disp
BLI_addtail(dispbase, dl);
}
+
+static void calc_bevfac_spline_mapping(BevList *bl, float bevfac, float spline_length, const float *bevp_array,
+ int *r_bev, float *r_blend)
+{
+ float len = 0.0f;
+ int i;
+ for (i = 0; i < bl->nr; i++) {
+ *r_bev = i;
+ *r_blend = (bevfac * spline_length - len) / bevp_array[i];
+ if (len + bevp_array[i] > bevfac * spline_length) {
+ break;
+ }
+ len += bevp_array[i];
+ }
+}
+
+static void calc_bevfac_mapping(Curve *cu, BevList *bl, int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
+{
+ BevPoint *bevp, *bevl;
+ float l, startf, endf, tmpf = 0.0, sum = 0.0, total_length = 0.0f;
+ float *bevp_array = NULL;
+ float *segments = NULL;
+ int end = 0, i, j, segcount = (int)(bl->nr / cu->resolu);
+
+ if ((cu->bevfac1_mapping != CU_BEVFAC_MAP_RESOLU) ||
+ (cu->bevfac2_mapping != CU_BEVFAC_MAP_RESOLU))
+ {
+ bevp_array = MEM_mallocN(sizeof(*bevp_array) * (bl->nr - 1), "bevp_dists");
+ segments = MEM_callocN(sizeof(*segments) * segcount, "bevp_segmentlengths");
+ bevp = (BevPoint *)(bl + 1);
+ bevp++;
+ for (i = 1, j = 0; i < bl->nr; bevp++, i++) {
+ sum = 0.0f;
+ bevl = bevp - 1;
+ bevp_array[i - 1] = len_v3v3(bevp->vec, bevl->vec);
+ total_length += bevp_array[i - 1];
+ tmpf += bevp_array[i - 1];
+ if ((i % cu->resolu) == 0 || (bl->nr - 1) == i) {
+ segments[j++] = tmpf;
+ tmpf = 0.0f;
+ }
+ }
+ }
+
+ switch (cu->bevfac1_mapping) {
+ case CU_BEVFAC_MAP_RESOLU:
+ {
+ const float start_fl = cu->bevfac1 * (bl->nr - 1);
+ *r_start = (int)start_fl;
+
+ *r_firstblend = 1.0f - (start_fl - (*r_start));
+ break;
+ }
+ case CU_BEVFAC_MAP_SEGMENT:
+ {
+ const float start_fl = cu->bevfac1 * (bl->nr - 1);
+ *r_start = (int)start_fl;
+
+ for (i = 0; i < segcount; i++) {
+ l = segments[i] / total_length;
+ if (sum + l > cu->bevfac1) {
+ startf = i * cu->resolu + (cu->bevfac1 - sum) / l * cu->resolu;
+ *r_start = (int) startf;
+ *r_firstblend = 1.0f - (startf - *r_start);
+ break;
+ }
+ sum += l;
+ }
+ break;
+ }
+ case CU_BEVFAC_MAP_SPLINE:
+ {
+ calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, bevp_array, r_start, r_firstblend);
+ *r_firstblend = 1.0f - *r_firstblend;
+ break;
+ }
+ }
+
+ sum = 0.0f;
+ switch (cu->bevfac2_mapping) {
+ case CU_BEVFAC_MAP_RESOLU:
+ {
+ const float end_fl = cu->bevfac2 * (bl->nr - 1);
+ end = (int)end_fl;
+
+ *r_steps = 2 + end - *r_start;
+ *r_lastblend = end_fl - end;
+ break;
+ }
+ case CU_BEVFAC_MAP_SEGMENT:
+ {
+ const float end_fl = cu->bevfac2 * (bl->nr - 1);
+ end = (int)end_fl;
+
+ *r_steps = end - *r_start + 2;
+ for (i = 0; i < segcount; i++) {
+ l = segments[i] / total_length;
+ if (sum + l > cu->bevfac2) {
+ endf = i * cu->resolu + (cu->bevfac2 - sum) / l * cu->resolu;
+ end = (int)endf;
+ *r_lastblend = (endf - end);
+ *r_steps = end - *r_start + 2;
+ break;
+ }
+ sum += l;
+ }
+ break;
+ }
+ case CU_BEVFAC_MAP_SPLINE:
+ {
+ calc_bevfac_spline_mapping(bl, cu->bevfac2, total_length, bevp_array, &end, r_lastblend);
+ *r_steps = end - *r_start + 2;
+ break;
+ }
+ }
+
+ if (end < *r_start) {
+ SWAP(int, *r_start, end);
+ tmpf = *r_lastblend;
+ *r_lastblend = 1.0f - *r_firstblend;
+ *r_firstblend = 1.0f - tmpf;
+ *r_steps = end - *r_start + 2;
+ }
+
+ if (*r_start + *r_steps > bl->nr) {
+ *r_steps = bl->nr - *r_start;
+ *r_lastblend = 1.0f;
+ }
+
+ if (bevp_array) {
+ MEM_freeN(bevp_array);
+ }
+ if (segments) {
+ MEM_freeN(segments);
+ }
+}
+
static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution)
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
Curve *cu = ob->data;
@@ -1368,7 +1509,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
if (!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
if (ob->type == OB_SURF) {
- BKE_displist_make_surf(scene, ob, dispbase, derivedFinal, forRender, forOrco, renderResolution);
+ BKE_displist_make_surf(scene, ob, dispbase, r_dm_final, for_render, for_orco, use_render_resolution);
}
else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
ListBase dlbev;
@@ -1376,8 +1517,14 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
BLI_freelistN(&(ob->curve_cache->bev));
- if (ob->curve_cache->path) free_path(ob->curve_cache->path);
- ob->curve_cache->path = NULL;
+ /* We only re-evlauate path if evaluation is not happening for orco.
+ * If the calculation happens for orco, we should never free data which
+ * was needed before and only not needed for orco calculation.
+ */
+ if (!for_orco) {
+ if (ob->curve_cache->path) free_path(ob->curve_cache->path);
+ ob->curve_cache->path = NULL;
+ }
if (ob->type == OB_FONT) {
BKE_vfont_to_curve_nubase(G.main, ob, FO_EDIT, &nubase);
@@ -1386,17 +1533,17 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu));
}
- if (!forOrco)
- curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
+ if (!for_orco)
+ curve_calc_modifiers_pre(scene, ob, &nubase, for_render, use_render_resolution);
- BKE_curve_bevelList_make(ob, &nubase, forRender != FALSE);
+ BKE_curve_bevelList_make(ob, &nubase, for_render != false);
/* If curve has no bevel will return nothing */
- BKE_curve_bevel_make(scene, ob, &dlbev, forRender, renderResolution);
+ BKE_curve_bevel_make(scene, ob, &dlbev, for_render, use_render_resolution);
/* no bevel or extrude, and no width correction? */
if (!dlbev.first && cu->width == 1.0f) {
- curve_to_displist(cu, &nubase, dispbase, forRender, renderResolution);
+ curve_to_displist(cu, &nubase, dispbase, for_render, use_render_resolution);
}
else {
float widfac = cu->width - 1.0f;
@@ -1448,25 +1595,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
ListBase top_capbase = {NULL, NULL};
float bottom_no[3] = {0.0f};
float top_no[3] = {0.0f};
+ float firstblend = 0.0f, lastblend = 0.0f;
+ int i, start, steps;
+
+ calc_bevfac_mapping(cu, bl, &start, &firstblend, &steps, &lastblend);
for (dlb = dlbev.first; dlb; dlb = dlb->next) {
- const float bevfac1 = min_ff(cu->bevfac1, cu->bevfac2);
- const float bevfac2 = max_ff(cu->bevfac1, cu->bevfac2);
- float firstblend = 0.0f, lastblend = 0.0f;
- int i, start, steps;
-
- if (bevfac2 - bevfac1 == 0.0f)
- continue;
-
- start = (int)(bevfac1 * (bl->nr - 1));
- steps = 2 + (int)((bevfac2) * (bl->nr - 1)) - start;
- firstblend = 1.0f - (bevfac1 * (bl->nr - 1) - (int)(bevfac1 * (bl->nr - 1)));
- lastblend = bevfac2 * (bl->nr - 1) - (int)(bevfac2 * (bl->nr - 1));
-
- if (start + steps > bl->nr) {
- steps = bl->nr - start;
- lastblend = 1.0f;
- }
/* for each part of the bevel use a separate displblock */
dl = MEM_callocN(sizeof(DispList), "makeDispListbev1");
@@ -1571,7 +1705,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, &nubase, dispbase);
}
- if (!forOrco) {
+ if (!for_orco) {
if ((cu->flag & CU_PATH) ||
DAG_get_eval_flags_for_object(scene, ob) & DAG_EVAL_NEED_CURVE_PATH)
{
@@ -1579,8 +1713,8 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
}
- if (!forOrco)
- curve_calc_modifiers_post(scene, ob, &nubase, dispbase, derivedFinal, forRender, renderResolution);
+ if (!for_orco)
+ curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution);
if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
curve_to_filledpoly(cu, &nubase, dispbase);
@@ -1590,7 +1724,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
}
-void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco)
+void BKE_displist_make_curveTypes(Scene *scene, Object *ob, const bool for_orco)
{
ListBase *dispbase;
@@ -1608,19 +1742,19 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco)
dispbase = &(ob->curve_cache->disp);
- do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco, 0);
+ do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, for_orco, 0);
boundbox_displist_object(ob);
}
void BKE_displist_make_curveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **derivedFinal, int forOrco, int renderResolution)
+ DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution)
{
if (ob->curve_cache == NULL) {
ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for MBall");
}
- do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco, renderResolution);
+ do_makeDispListCurveTypes(scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution);
}
void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
@@ -1633,18 +1767,20 @@ void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob
}
/* add Orco layer to the displist object which has got derived mesh and return orco */
-float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender, int renderResolution)
+float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render,
+ const bool use_render_resolution)
{
float *orco;
- if (derivedFinal == NULL)
- derivedFinal = ob->derivedFinal;
+ if (dm_final == NULL)
+ dm_final = ob->derivedFinal;
- if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
- curve_calc_orcodm(scene, ob, derivedFinal, forRender, renderResolution);
+ if (!dm_final->getVertDataArray(dm_final, CD_ORCO)) {
+ curve_calc_orcodm(scene, ob, dm_final, for_render, use_render_resolution);
}
- orco = derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
+ orco = dm_final->getVertDataArray(dm_final, CD_ORCO);
if (orco) {
orco = MEM_dupallocN(orco);
@@ -1656,7 +1792,7 @@ float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFina
void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3])
{
DispList *dl;
- float *vert;
+ const float *vert;
int a, tot = 0;
int doit = 0;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 997876dcd58..11737bccef2 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -48,20 +48,15 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h" /* bvh tree */
-#include "BKE_blender.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_constraint.h"
-#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_colortools.h"
#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_dynamicpaint.h"
#include "BKE_effect.h"
@@ -297,12 +292,12 @@ DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas)
void dynamicPaint_resetPreview(DynamicPaintCanvasSettings *canvas)
{
DynamicPaintSurface *surface = canvas->surfaces.first;
- int done = FALSE;
+ bool done = false;
for (; surface; surface = surface->next) {
if (!done && dynamicPaint_surfaceHasColorPreview(surface)) {
surface->flags |= MOD_DPAINT_PREVIEW;
- done = TRUE;
+ done = true;
}
else
surface->flags &= ~MOD_DPAINT_PREVIEW;
@@ -323,7 +318,7 @@ static void dynamicPaint_setPreview(DynamicPaintSurface *t_surface)
bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *ob, int output)
{
- char *name;
+ const char *name;
if (output == 0)
name = surface->output_name;
@@ -536,7 +531,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, int parent
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
@@ -1678,7 +1673,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Deri
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
MVert *mvert = result->getVertArray(result);
int i;
- float *value = (float *)sData->type_data;
+ const float *value = (float *)sData->type_data;
#pragma omp parallel for schedule(static)
for (i = 0; i < sData->total_points; i++) {
@@ -2103,7 +2098,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
float closest_point[2], lambda, dir_vec[2];
int target_uv1, target_uv2, final_pixel[2], final_index;
- float *s_uv1, *s_uv2, *t_uv1, *t_uv2;
+ const float *s_uv1, *s_uv2, *t_uv1, *t_uv2;
pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)w;
pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)h;
@@ -2235,11 +2230,13 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface)
{
/* Antialias jitter point relative coords */
- float jitter5sample[10] = {0.0f, 0.0f,
- -0.2f, -0.4f,
- 0.2f, 0.4f,
- 0.4f, -0.2f,
- -0.4f, 0.3f};
+ const float jitter5sample[10] = {
+ 0.0f, 0.0f,
+ -0.2f, -0.4f,
+ 0.2f, 0.4f,
+ 0.4f, -0.2f,
+ -0.4f, 0.3f,
+ };
int ty;
int w, h;
int numOfFaces;
@@ -2901,7 +2898,7 @@ static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay
MFace *face = data->face + index;
short quad = 0;
- float *t0, *t1, *t2, *t3;
+ const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
@@ -2937,7 +2934,7 @@ static void mesh_faces_nearest_point_dp(void *userdata, int index, const float c
MFace *face = data->face + index;
short quad = 0;
- float *t0, *t1, *t2, *t3;
+ const float *t0, *t1, *t2, *t3;
t0 = vert[face->v1].co;
t1 = vert[face->v2].co;
t2 = vert[face->v3].co;
@@ -3716,7 +3713,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
/* make sure particle is close enough to canvas */
if (!boundIntersectPoint(&grid->grid_bounds, pa->state.co, range)) continue;
- BLI_kdtree_insert(tree, p, pa->state.co, NULL);
+ BLI_kdtree_insert(tree, p, pa->state.co);
/* calc particle system bounds */
boundInsert(&part_bb, pa->state.co);
@@ -3773,7 +3770,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
float smooth_range, part_solidradius;
/* Find nearest particle and get distance to it */
- BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, NULL, &nearest);
+ BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, &nearest);
/* if outside maximum range, no other particle can influence either */
if (nearest.dist > range) continue;
@@ -3813,7 +3810,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
/* Make gcc happy! */
dist = max_range;
- particles = BLI_kdtree_range_search(tree, bData->realCoord[bData->s_pos[index]].v, NULL,
+ particles = BLI_kdtree_range_search(tree, bData->realCoord[bData->s_pos[index]].v,
&nearest, max_range);
/* Find particle that produces highest influence */
@@ -4133,7 +4130,7 @@ static void surface_determineForceTargetPoints(PaintSurfaceData *sData, int inde
closest_d[0] = 1.0f - closest_d[1];
/* and multiply depending on how deeply force intersects surface */
- temp = fabs(force_intersect);
+ temp = fabsf(force_intersect);
CLAMP(temp, 0.0f, 1.0f);
mul_v2_fl(closest_d, acosf(temp) / (float)M_PI_2);
}
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index a5333945089..0d29e154923 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -55,7 +55,6 @@
#include "BLI_jitter.h"
#include "BLI_bitmap.h"
-#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -177,6 +176,31 @@ static void emDM_calcNormals(DerivedMesh *dm)
dm->dirty &= ~DM_DIRTY_NORMALS;
}
+static void emDM_calcLoopNormals(DerivedMesh *dm, const float split_angle)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+ BMesh *bm = bmdm->em->bm;
+ const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
+ float (*loopNos)[3];
+
+ /* calculate loop normals from poly and vertex normals */
+ emDM_ensureVertNormals(bmdm);
+ emDM_ensurePolyNormals(bmdm);
+ dm->dirty &= ~DM_DIRTY_NORMALS;
+
+ vertexCos = bmdm->vertexCos;
+ vertexNos = bmdm->vertexNos;
+ polyNos = bmdm->polyNos;
+
+ loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
+ if (!loopNos) {
+ DM_add_loop_layer(dm, CD_NORMAL, CD_CALLOC, NULL);
+ loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
+ }
+
+ BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, split_angle, loopNos);
+}
+
static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
{
/* do nothing */
@@ -279,8 +303,8 @@ static void emDM_drawMappedEdges(DerivedMesh *dm,
gpuEnd();
}
static void emDM_drawEdges(DerivedMesh *dm,
- int UNUSED(drawLooseEdges),
- int UNUSED(drawAllEdges))
+ bool UNUSED(drawLooseEdges),
+ bool UNUSED(drawAllEdges))
{
emDM_drawMappedEdges(dm, NULL, NULL);
}
@@ -363,6 +387,39 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
gpuImmediateUnformat();
}
+static void emDM_foreachMappedLoop(
+ DerivedMesh *dm,
+ void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
+{
+ /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
+ * return loop data from bmesh itself. */
+ const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
+
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+ BMesh *bm = bmdm->em->bm;
+ BMFace *efa;
+ BMIter iter;
+
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ int f_idx;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, f_idx) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ const BMVert *eve = l_iter->v;
+ const int v_idx = BM_elem_index_get(eve);
+ const float *no = lnors ? *lnors++ : NULL;
+ func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+}
+
static void emDM_foreachMappedFaceCenter(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no[3]),
@@ -421,6 +478,7 @@ static void emDM_drawMappedFaces(
int i, flush;
const int useNormals = (flag & DM_DRAW_USE_NORMALS) && GPU_basic_needs_normals(); /* could be passed as an arg */
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
unsigned char(*color_vert_array)[4] = em->derivedVertColor;
unsigned char(*color_face_array)[4] = em->derivedFaceColor;
@@ -470,14 +528,14 @@ static void emDM_drawMappedFaces(
polyNos = bmdm->polyNos;
}
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
for (i = 0; i < tottri; i++) {
BMLoop **ltri = looptris[i];
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
draw_option = (!setDrawOptions ?
DM_DRAW_OPTION_NORMALLY :
@@ -544,14 +602,16 @@ static void emDM_drawMappedFaces(
}
else {
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[0]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[1]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[2]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
}
}
@@ -571,7 +631,7 @@ static void emDM_drawMappedFaces(
}
}
else {
- BM_mesh_elem_index_ensure(bm, BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE);
poly_prev = GL_TRIANGLES;
gpuBegin(GL_TRIANGLES);
@@ -581,7 +641,7 @@ static void emDM_drawMappedFaces(
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
draw_option = (!setDrawOptions ?
DM_DRAW_OPTION_NORMALLY :
@@ -649,14 +709,16 @@ static void emDM_drawMappedFaces(
}
else {
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[0]->r));
- gpuNormal3fv(ltri[0]->v->no);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else gpuNormal3fv(ltri[0]->v->no);
gpuVertex3fv(ltri[0]->v->co);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[1]->r));
- gpuNormal3fv(ltri[1]->v->no);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else gpuNormal3fv(ltri[1]->v->no);
gpuVertex3fv(ltri[1]->v->co);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[2]->r));
- gpuNormal3fv(ltri[2]->v->no);
- gpuVertex3fv(ltri[2]->v->co);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else gpuNormal3fv(ltri[2]->v->no);
}
}
@@ -715,6 +777,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
BMesh *bm = em->bm;
struct BMLoop *(*looptris)[3] = em->looptris;
BMFace *efa;
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
MLoopUV *luv[3], dummyluv = {{0}};
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
@@ -758,14 +821,14 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
vertexNos = bmdm->vertexNos;
polyNos = bmdm->polyNos;
- BM_mesh_elem_index_ensure(bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
+ int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
DMDrawOption draw_option;
efa = ltri[0]->f;
@@ -807,32 +870,33 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
else {
gpuTexCoord2fv(luv[0]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[0]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
gpuTexCoord2fv(luv[1]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[1]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
gpuTexCoord2fv(luv[2]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[2]->r));
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
}
gpuEnd();
}
}
}
else {
- BM_mesh_elem_index_ensure(bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
+ int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
DMDrawOption draw_option;
efa = ltri[0]->f;
@@ -874,18 +938,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
else {
gpuTexCoord2fv(luv[0]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[0]->r));
- gpuNormal3fv(ltri[0]->v->no);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else gpuNormal3fv(ltri[0]->v->no);
gpuVertex3fv(ltri[0]->v->co);
gpuTexCoord2fv(luv[1]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[1]->r));
- gpuNormal3fv(ltri[1]->v->no);
- gpuVertex3fv(ltri[1]->v->co);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else gpuNormal3fv(ltri[1]->v->no);
gpuTexCoord2fv(luv[2]->uv);
if (has_vcol_any) gpuColor3ubv((const GLubyte *)&(lcol[2]->r));
- gpuNormal3fv(ltri[2]->v->no);
- gpuVertex3fv(ltri[2]->v->co);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else gpuNormal3fv(ltri[2]->v->no);
}
gpuEnd();
}
@@ -927,7 +992,7 @@ static void emDM_drawMappedFacesTex(DerivedMesh *dm,
* ... because the material may use layer names to select different UV's
* see: [#34378]
*/
-static void emdm_pass_attrib_vertex_glsl(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face)
+static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const BMLoop *loop, const int index_in_face)
{
BMVert *eve = loop->v;
int i;
@@ -1052,14 +1117,16 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
const float (*vertexCos)[3] = bmdm->vertexCos;
const float (*vertexNos)[3];
const float (*polyNos)[3];
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
BMFace *efa;
DMVertexAttribs attribs;
GPUVertexAttribs gattribs;
- int i, matnr, new_matnr, do_draw;
+ int i, matnr, new_matnr, fi;
+ bool do_draw;
- do_draw = FALSE;
+ do_draw = false;
matnr = -1;
memset(&attribs, 0, sizeof(attribs));
@@ -1073,23 +1140,26 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
+
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP))
continue;
new_matnr = efa->mat_nr + 1;
if (new_matnr != matnr) {
+ if (matnr != -1)
+ glEnd();
+
do_draw = setMaterial(matnr = new_matnr, &gattribs);
if (do_draw) {
emdm_unformat_attrib_vertex();
@@ -1098,58 +1168,52 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
emdm_format_attrib_vertex(&attribs);
}
- }
- if (do_draw) {
gpuBegin(GL_TRIANGLES);
- if (!drawSmooth) {
- if (vertexCos) gpuNormal3fv(polyNos[BM_elem_index_get(efa)]);
- else gpuNormal3fv(efa->no);
+ }
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
- else gpuVertex3fv(ltri[0]->v->co);
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
- else gpuVertex3fv(ltri[1]->v->co);
+ if (do_draw) {
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
- else gpuVertex3fv(ltri[2]->v->co);
- }
- else {
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
- if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
- }
- else {
- gpuNormal3fv(ltri[0]->v->no);
- gpuVertex3fv(ltri[0]->v->co);
- }
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
+ /* draw face */
+ drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+
+ if (!drawSmooth) {
if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
+ gpuNormal3fv(polyNos[BM_elem_index_get(efa)]);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
+ }
}
else {
- gpuNormal3fv(ltri[1]->v->no);
- gpuVertex3fv(ltri[1]->v->co);
+ gpuNormal3fv(efa->no);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ gpuVertex3fv(ltri[fi]->v->co);
+ }
}
-
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
+ }
+ else {
if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
+ for (fi = 0; fi < 3; fi++) {
+ const int j = BM_elem_index_get(ltri[fi]->v);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else gpuNormal3fv(vertexNos[j]);
+ gpuVertex3fv(vertexCos[j]);
+ }
}
else {
- gpuNormal3fv(ltri[2]->v->no);
- gpuVertex3fv(ltri[2]->v->co);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else gpuNormal3fv(ltri[fi]->v->no);
+ gpuVertex3fv(ltri[fi]->v->co);
+ }
}
}
- gpuEnd();
}
}
@@ -1157,16 +1221,20 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
// SSS Disable Smooth
GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH); /* restore Blender default */
+
+ if (matnr != -1) {
+ gpuEnd();
+ }
}
static void emDM_drawFacesGLSL(DerivedMesh *dm,
- int (*setMaterial)(int, void *attribs))
+ int (*setMaterial)(int matnr, void *attribs))
{
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
}
static void emDM_drawMappedFacesMat(DerivedMesh *dm,
- void (*setMaterial)(void *userData, int, void *attribs),
+ void (*setMaterial)(void *userData, int matnr, void *attribs),
bool (*setFace)(void *userData, int index), void *userData)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
@@ -1176,10 +1244,11 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
const float (*vertexCos)[3] = bmdm->vertexCos;
const float (*vertexNos)[3];
const float (*polyNos)[3];
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
BMFace *efa;
DMVertexAttribs attribs = {{{NULL}}};
GPUVertexAttribs gattribs;
- int i, matnr, new_matnr;
+ int i, matnr, new_matnr, fi;
matnr = -1;
@@ -1194,14 +1263,13 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
/* face hiding */
if (setFace && !setFace(userData, BM_elem_index_get(efa)))
@@ -1210,61 +1278,57 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
/* material */
new_matnr = efa->mat_nr + 1;
if (new_matnr != matnr) {
+ if (matnr != -1)
+ glEnd();
+
setMaterial(userData, matnr = new_matnr, &gattribs);
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
- }
-
- /* face */
- gpuBegin(GL_TRIANGLES);
- if (!drawSmooth) {
- if (vertexCos) gpuNormal3fv(polyNos[BM_elem_index_get(efa)]);
- else gpuNormal3fv(efa->no);
-
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
- else gpuVertex3fv(ltri[0]->v->co);
-
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
- else gpuVertex3fv(ltri[1]->v->co);
-
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
- if (vertexCos) gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
- else gpuVertex3fv(ltri[2]->v->co);
+ gpuBegin(GL_TRIANGLES);
}
- else {
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
- if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
- }
- else {
- gpuNormal3fv(ltri[0]->v->no);
- gpuVertex3fv(ltri[0]->v->co);
- }
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
+ /* draw face */
+ drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+
+ if (!drawSmooth) {
if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
+ gpuNormal3fv(polyNos[BM_elem_index_get(efa)]);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
+ }
}
else {
- gpuNormal3fv(ltri[1]->v->no);
- gpuVertex3fv(ltri[1]->v->co);
+ gpuNormal3fv(efa->no);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ gpuVertex3fv(ltri[fi]->v->co);
+ }
}
-
- emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
+ }
+ else {
if (vertexCos) {
- gpuNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
- gpuVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
+ for (fi = 0; fi < 3; fi++) {
+ const int j = BM_elem_index_get(ltri[fi]->v);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else gpuNormal3fv(vertexNos[j]);
+ gpuVertex3fv(vertexCos[j]);
+ }
}
else {
- gpuNormal3fv(ltri[2]->v->no);
- gpuVertex3fv(ltri[2]->v->co);
+ for (fi = 0; fi < 3; fi++) {
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
+ if (lnors) gpuNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else gpuNormal3fv(ltri[fi]->v->no);
+ gpuVertex3fv(ltri[fi]->v->co);
+ }
}
}
- gpuEnd();
+ }
+
+ if (matnr != -1) {
+ glEnd();
}
// SSS Disable Smooth
@@ -1333,7 +1397,7 @@ static int emDM_getNumPolys(DerivedMesh *dm)
static void bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *r_vert)
{
- float *f;
+ const float *f;
copy_v3_v3(r_vert->co, ev->co);
@@ -1443,7 +1507,7 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
BMEdge *e;
- float *f;
+ const float *f;
if (UNLIKELY(index < 0 || index >= bm->totedge)) {
BLI_assert(!"error in emDM_getEdge");
@@ -1634,7 +1698,7 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
if (type == CD_MTFACE || type == CD_MCOL) {
const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
int index;
- char *data, *bmdata;
+ const char *data, *bmdata;
index = CustomData_get_layer_index(&bm->pdata, type_from);
if (index != -1) {
@@ -1680,6 +1744,31 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
}
}
+ /* Special handling for CD_TESSLOOPNORMAL, we generate it on demand as well. */
+ if (type == CD_TESSLOOPNORMAL) {
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
+
+ if (lnors) {
+ BMLoop *(*looptris)[3] = bmdm->em->looptris;
+ short (*tlnors)[4][3], (*tlnor)[4][3];
+ int index, i, j;
+
+ DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
+ index = CustomData_get_layer_index(&dm->faceData, type);
+ dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
+
+ tlnor = tlnors = DM_get_tessface_data_layer(dm, type);
+
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ for (i = 0; i < bmdm->em->tottri; i++, tlnor++, looptris++) {
+ for (j = 0; j < 3; j++) {
+ normal_float_to_short_v3((*tlnor)[j], lnors[BM_elem_index_get((*looptris)[j])]);
+ }
+ }
+ }
+ }
+
return datalayer;
}
@@ -1809,9 +1898,11 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
bmdm->dm.calcNormals = emDM_calcNormals;
+ bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
bmdm->dm.recalcTessellation = emDM_recalcTessellation;
bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
+ bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
@@ -1886,9 +1977,11 @@ static void statvis_calc_overhang(
float dir[3];
int index;
const float minmax_irange = 1.0f / (max - min);
+ bool is_max;
/* fallback */
- const char col_fallback[4] = {64, 64, 64, 255};
+ unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
+ unsigned char col_fallback_max[4] = {0, 0, 0, 255}; /* max color */
BLI_assert(min <= max);
@@ -1899,12 +1992,19 @@ static void statvis_calc_overhang(
normalize_v3(dir);
}
+ /* fallback max */
+ {
+ float fcol[3];
+ weight_to_rgb(fcol, 1.0f);
+ rgb_float_to_uchar(col_fallback_max, fcol);
+ }
+
/* now convert into global space */
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
float fac = angle_normalized_v3v3(polyNos ? polyNos[index] : f->no, dir) / (float)M_PI;
/* remap */
- if (fac >= min && fac <= max) {
+ if ((is_max = (fac <= max)) && (fac >= min)) {
float fcol[3];
fac = (fac - min) * minmax_irange;
fac = 1.0f - fac;
@@ -1913,7 +2013,8 @@ static void statvis_calc_overhang(
rgb_float_to_uchar(r_face_colors[index], fcol);
}
else {
- copy_v4_v4_char((char *)r_face_colors[index], (const char *)col_fallback);
+ unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
+ copy_v4_v4_char((char *)r_face_colors[index], (const char *)fallback);
}
}
}
@@ -1963,7 +2064,7 @@ static void statvis_calc_thickness(
if (use_jit) {
int j;
BLI_assert(samples < 32);
- BLI_jitter_init(jit_ofs[0], samples);
+ BLI_jitter_init(jit_ofs, samples);
for (j = 0; j < samples; j++) {
uv_from_jitter_v2(jit_ofs[j]);
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c
index 88cef0ec031..2247b91df1d 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -36,8 +36,6 @@
#include "DNA_mesh_types.h"
#include "BLI_math.h"
-#include "BLI_memarena.h"
-#include "BLI_scanfill.h"
#include "BKE_editmesh.h"
#include "BKE_cdderivedmesh.h"
@@ -187,21 +185,24 @@ void BKE_editmesh_update_linked_customdata(BMEditMesh *em)
}
}
-/*does not free the BMEditMesh struct itself*/
-void BKE_editmesh_free(BMEditMesh *em)
+void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
{
- if (em->derivedFinal) {
- if (em->derivedFinal != em->derivedCage) {
- em->derivedFinal->needsFree = 1;
- em->derivedFinal->release(em->derivedFinal);
- }
- em->derivedFinal = NULL;
- }
if (em->derivedCage) {
em->derivedCage->needsFree = 1;
em->derivedCage->release(em->derivedCage);
- em->derivedCage = NULL;
}
+ if (em->derivedFinal && em->derivedFinal != em->derivedCage) {
+ em->derivedFinal->needsFree = 1;
+ em->derivedFinal->release(em->derivedFinal);
+ }
+
+ em->derivedCage = em->derivedFinal = NULL;
+}
+
+/*does not free the BMEditMesh struct itself*/
+void BKE_editmesh_free(BMEditMesh *em)
+{
+ BKE_editmesh_free_derivedmesh(em);
BKE_editmesh_color_free(em);
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 018a9198f34..76ea340ecbd 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -31,8 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_object_types.h"
-
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
@@ -217,11 +215,8 @@ static void bmbvh_ray_cast_cb(void *userdata, int index, const BVHTreeRay *ray,
copy_v3_v3(hit->no, ltri[0]->f->no);
- copy_v3_v3(hit->co, ray->direction);
- normalize_v3(hit->co);
- mul_v3_fl(hit->co, dist);
- add_v3_v3(hit->co, ray->origin);
-
+ madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
+
copy_v2_v2(bmcb_data->uv, uv);
}
}
@@ -310,10 +305,7 @@ static void bmbvh_find_face_segment_cb(void *userdata, int index, const BVHTreeR
copy_v3_v3(hit->no, ltri[0]->f->no);
- copy_v3_v3(hit->co, ray->direction);
- normalize_v3(hit->co);
- mul_v3_fl(hit->co, dist);
- add_v3_v3(hit->co, ray->origin);
+ madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
copy_v2_v2(bmcb_data->uv, uv);
}
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index fc18a204526..e28152dbc1a 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -37,15 +37,9 @@
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
#include "DNA_group_types.h"
-#include "DNA_ipo_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lattice_types.h"
#include "DNA_listBase.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_particle_types.h"
@@ -55,33 +49,18 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_noise.h"
-#include "BLI_jitter.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
#include "PIL_time.h"
-#include "BKE_action.h"
#include "BKE_anim.h" /* needed for where_on_path */
-#include "BKE_armature.h"
-#include "BKE_blender.h"
#include "BKE_collision.h"
-#include "BKE_constraint.h"
#include "BKE_curve.h"
-#include "BKE_deform.h"
-#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_group.h"
-#include "BKE_ipo.h"
-#include "BKE_key.h"
-#include "BKE_lattice.h"
-#include "BKE_mesh.h"
-#include "BKE_material.h"
-#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -94,7 +73,6 @@
/* fluid sim particle import */
#ifdef WITH_MOD_FLUID
-#include "DNA_object_fluidsim.h"
#include "LBM_fluidsim.h"
#include <zlib.h>
#include <string.h>
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index bcdb066a965..65b9d2159df 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -45,6 +45,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_easing.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -350,13 +351,10 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
/* ----------------- Finding Keyframes/Extents -------------------------- */
-/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
-#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
-
-/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
+/* Binary search algorithm for finding where to insert BezTriple, with optional argument for precision required.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
*/
-int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *r_replace)
+static int binarysearch_bezt_index_ex(BezTriple array[], float frame, int arraylen, float threshold, bool *r_replace)
{
int start = 0, end = arraylen;
int loopbreaker = 0, maxloop = arraylen * 2;
@@ -378,7 +376,7 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *
/* 'First' Keyframe (when only one keyframe, this case is used) */
framenum = array[0].vec[1][0];
- if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
+ if (IS_EQT(frame, framenum, threshold)) {
*r_replace = true;
return 0;
}
@@ -387,7 +385,7 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *
/* 'Last' Keyframe */
framenum = array[(arraylen - 1)].vec[1][0];
- if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
+ if (IS_EQT(frame, framenum, threshold)) {
*r_replace = true;
return (arraylen - 1);
}
@@ -405,7 +403,7 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *
float midfra = array[mid].vec[1][0];
/* check if exactly equal to midpoint */
- if (IS_EQT(frame, midfra, BEZT_BINARYSEARCH_THRESH)) {
+ if (IS_EQT(frame, midfra, threshold)) {
*r_replace = true;
return mid;
}
@@ -429,13 +427,23 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *
return start;
}
+
+/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, bool *r_replace)
+{
+ /* this is just a wrapper which uses the default threshold */
+ return binarysearch_bezt_index_ex(array, frame, arraylen, BEZT_BINARYSEARCH_THRESH, r_replace);
+}
+
/* ...................................... */
/* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple **last,
const bool do_sel_only)
{
- short found = FALSE;
+ bool found = false;
/* init outputs */
*first = NULL;
@@ -455,7 +463,7 @@ static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple
for (i = 0; i < fcu->totvert; bezt++, i++) {
if (BEZSELECTED(bezt)) {
*first = bezt;
- found = TRUE;
+ found = true;
break;
}
}
@@ -465,7 +473,7 @@ static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple
for (i = 0; i < fcu->totvert; bezt--, i++) {
if (BEZSELECTED(bezt)) {
*last = bezt;
- found = TRUE;
+ found = true;
break;
}
}
@@ -474,7 +482,7 @@ static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple
/* just full array */
*first = fcu->bezt;
*last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, sizeof(BezTriple), fcu->totvert);
- found = TRUE;
+ found = true;
}
return found;
@@ -517,7 +525,7 @@ bool calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa
BezTriple *bezt;
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
- if ((do_sel_only == FALSE) || BEZSELECTED(bezt)) {
+ if ((do_sel_only == false) || BEZSELECTED(bezt)) {
if (include_handles) {
yminv = min_ffff(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
ymaxv = max_ffff(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
@@ -527,7 +535,7 @@ bool calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa
ymaxv = max_ff(ymaxv, bezt->vec[1][1]);
}
- foundvert = TRUE;
+ foundvert = true;
}
}
}
@@ -549,7 +557,7 @@ bool calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa
if (fpt->vec[1] > ymaxv)
ymaxv = fpt->vec[1];
- foundvert = TRUE;
+ foundvert = true;
}
}
}
@@ -581,7 +589,7 @@ bool calc_fcurve_range(FCurve *fcu, float *start, float *end,
const bool do_sel_only, const bool do_min_length)
{
float min = 999999999.0f, max = -999999999.0f;
- short foundvert = FALSE;
+ bool foundvert = false;
if (fcu->totvert) {
if (fcu->bezt) {
@@ -596,19 +604,19 @@ bool calc_fcurve_range(FCurve *fcu, float *start, float *end,
min = min_ff(min, bezt_first->vec[1][0]);
max = max_ff(max, bezt_last->vec[1][0]);
- foundvert = TRUE;
+ foundvert = true;
}
}
else if (fcu->fpt) {
min = min_ff(min, fcu->fpt[0].vec[0]);
max = max_ff(max, fcu->fpt[fcu->totvert - 1].vec[0]);
- foundvert = TRUE;
+ foundvert = true;
}
}
- if (foundvert == FALSE) {
+ if (foundvert == false) {
min = max = 0.0f;
}
@@ -826,7 +834,7 @@ void calchandles_fcurve(FCurve *fcu)
if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0] = bezt->vec[1][0];
/* calculate auto-handles */
- BKE_nurb_handle_calc(bezt, prev, next, 1); /* (1 == special) autohandle */
+ BKE_nurb_handle_calc(bezt, prev, next, true);
/* for automatic ease in and out */
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
@@ -870,7 +878,7 @@ void testhandles_fcurve(FCurve *fcu, const bool use_handle)
*/
void sort_time_fcurve(FCurve *fcu)
{
- short ok = 1;
+ bool ok = true;
/* keep adjusting order of beztriples until nothing moves (bubble-sort) */
while (ok) {
@@ -1297,7 +1305,8 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
bPoseChannel *pchan;
float mat[4][4];
float oldEul[3] = {0.0f, 0.0f, 0.0f};
- short use_eulers = FALSE, rot_order = ROT_MODE_EUL;
+ bool use_eulers = false;
+ short rot_order = ROT_MODE_EUL;
/* check if this target has valid data */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
@@ -1325,7 +1334,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (pchan->rotmode > 0) {
copy_v3_v3(oldEul, pchan->eul);
rot_order = pchan->rotmode;
- use_eulers = TRUE;
+ use_eulers = true;
}
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
@@ -1352,7 +1361,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (ob->rotmode > 0) {
copy_v3_v3(oldEul, ob->rot);
rot_order = ob->rotmode;
- use_eulers = TRUE;
+ use_eulers = true;
}
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
@@ -1919,6 +1928,7 @@ static void berekenx(float *f, float *o, int b)
/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
{
+ const float eps = 1.e-8f;
BezTriple *bezt, *prevbezt, *lastbezt;
float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
unsigned int a;
@@ -2038,57 +2048,276 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
else {
/* evaltime occurs somewhere in the middle of the curve */
- for (a = 0; prevbezt && bezt && (a < fcu->totvert - 1); a++, prevbezt = bezt, bezt++) {
- /* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
- if (fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) {
- cvalue = bezt->vec[1][1];
+ bool exact = false;
+
+ /* - use binary search to find appropriate keyframes */
+ a = binarysearch_bezt_index_ex(bezts, evaltime, fcu->totvert, 0.001, &exact);
+ if (G.debug & G_DEBUG) printf("eval fcurve '%s' - %f => %d/%d, %d\n", fcu->rna_path, evaltime, a, fcu->totvert, exact);
+
+ if (exact) {
+ /* index returned must be interpreted differently when it sits on top of an existing keyframe
+ * - that keyframe is the start of the segment we need (see action_bug_2.blend in T39207)
+ */
+ prevbezt = bezts + a;
+ bezt = (a < fcu->totvert - 1) ? (prevbezt + 1) : prevbezt;
+ }
+ else {
+ /* index returned refers to the keyframe that the eval-time occurs *before*
+ * - hence, that keyframe marks the start of the segment we're dealing with
+ */
+ bezt = bezts + a;
+ prevbezt = (a > 0) ? (bezt - 1) : bezt;
+ }
+
+ /* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
+ /* XXX: consult T39207 for examples of files where failure of these checks can cause issues */
+ if (exact) {
+ cvalue = prevbezt->vec[1][1];
+ }
+ else if (fabsf(bezt->vec[1][0] - evaltime) < eps) {
+ cvalue = bezt->vec[1][1];
+ }
+ /* evaltime occurs within the interval defined by these two keyframes */
+ else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
+ const float begin = prevbezt->vec[1][1];
+ const float change = bezt->vec[1][1] - prevbezt->vec[1][1];
+ const float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
+ const float time = evaltime - prevbezt->vec[1][0];
+ const float amplitude = prevbezt->amplitude;
+ const float period = prevbezt->period;
+
+ /* value depends on interpolation mode */
+ if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES) || (duration == 0)) {
+ /* constant (evaltime not relevant, so no interpolation needed) */
+ cvalue = prevbezt->vec[1][1];
}
- /* evaltime occurs within the interval defined by these two keyframes */
- else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
- /* value depends on interpolation mode */
- if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES)) {
- /* constant (evaltime not relevant, so no interpolation needed) */
- cvalue = prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo == BEZT_IPO_LIN) {
- /* linear - interpolate between values of the two keyframes */
- fac = bezt->vec[1][0] - prevbezt->vec[1][0];
+ else {
+ switch (prevbezt->ipo) {
+ /* interpolation ...................................... */
+ case BEZT_IPO_BEZ:
+ /* bezier interpolation */
+ /* (v1, v2) are the first keyframe and its 2nd handle */
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ v2[0] = prevbezt->vec[2][0];
+ v2[1] = prevbezt->vec[2][1];
+ /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ /* adjust handles so that they don't overlap (forming a loop) */
+ correct_bezpart(v1, v2, v3, v4);
+
+ /* try to get a value for this position - if failure, try another set of points */
+ b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+ if (b) {
+ berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+ cvalue = opl[0];
+ /* break; */
+ }
+ else {
+ if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ }
+ break;
+
+ case BEZT_IPO_LIN:
+ /* linear - simply linearly interpolate between values of the two keyframes */
+ cvalue = BLI_easing_linear_ease(time, begin, change, duration);
+ break;
+
+ /* easing ............................................ */
+ case BEZT_IPO_BACK:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_back_ease_in(time, begin, change, duration, prevbezt->back);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_back_ease_in_out(time, begin, change, duration, prevbezt->back);
+ break;
+
+ default: /* default/auto: same as ease out */
+ cvalue = BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);
+ break;
+ }
+ break;
- /* prevent division by zero */
- if (fac) {
- fac = (evaltime - prevbezt->vec[1][0]) / fac;
- cvalue = prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
- }
- else {
- cvalue = prevbezt->vec[1][1];
- }
- }
- else {
- /* bezier interpolation */
- /* (v1, v2) are the first keyframe and its 2nd handle */
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- v2[0] = prevbezt->vec[2][0];
- v2[1] = prevbezt->vec[2][1];
- /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
+ case BEZT_IPO_BOUNCE:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_bounce_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_bounce_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_bounce_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease out */
+ cvalue = BLI_easing_bounce_ease_out(time, begin, change, duration);
+ break;
+ }
+ break;
- /* adjust handles so that they don't overlap (forming a loop) */
- correct_bezpart(v1, v2, v3, v4);
+ case BEZT_IPO_CIRC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_circ_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_circ_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_circ_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_circ_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_CUBIC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_cubic_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_cubic_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_cubic_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_cubic_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
- /* try to get a value for this position - if failure, try another set of points */
- b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
- if (b) {
- berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
- cvalue = opl[0];
+ case BEZT_IPO_ELASTIC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_elastic_ease_in(time, begin, change, duration, amplitude, period);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_elastic_ease_in_out(time, begin, change, duration, amplitude, period);
+ break;
+
+ default: /* default/auto: same as ease out */
+ cvalue = BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_EXPO:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_expo_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_expo_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_expo_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_expo_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUAD:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_quad_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_quad_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_quad_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_quad_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUART:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_quart_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_quart_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_quart_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_quart_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUINT:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_quint_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_quint_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_quint_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_quint_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_SINE:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BLI_easing_sine_ease_in(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BLI_easing_sine_ease_out(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BLI_easing_sine_ease_in_out(time, begin, change, duration);
+ break;
+
+ default: /* default/auto: same as ease in */
+ cvalue = BLI_easing_sine_ease_in(time, begin, change, duration);
+ break;
+ }
+ break;
+
+
+ default:
+ cvalue = prevbezt->vec[1][1];
break;
- }
}
}
}
+ else {
+ if (G.debug & G_DEBUG) printf(" ERROR: failed eval - p=%f b=%f, t=%f (%f)\n", prevbezt->vec[1][0], bezt->vec[1][0], evaltime, fabsf(bezt->vec[1][0] - evaltime));
+ }
}
/* return value */
@@ -2115,7 +2344,7 @@ static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
cvalue = lastfpt->vec[1];
}
else {
- float t = (float)abs(evaltime - (int)evaltime);
+ float t = fabsf(evaltime - floorf(evaltime));
/* find the one on the right frame (assume that these are spaced on 1-frame intervals) */
fpt = prevfpt + (int)(evaltime - prevfpt->vec[0]);
@@ -2193,7 +2422,7 @@ float evaluate_fcurve(FCurve *fcu, float evaltime)
cvalue = fcurve_eval_samples(fcu, fcu->fpt, devaltime);
/* evaluate modifiers */
- evaluate_value_fmodifiers(storage, &fcu->modifiers, fcu, &cvalue, evaltime);
+ evaluate_value_fmodifiers(storage, &fcu->modifiers, fcu, &cvalue, devaltime);
evaluate_fmodifiers_storage_free(storage);
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index efc9869c5ca..beb85b31847 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -44,7 +44,7 @@
#include "DNA_object_force.h" // for pointcache
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
-#include "DNA_scene_types.h" // N_T
+#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index bcbc5571077..56b087e7eb6 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -605,7 +605,8 @@ static float fcm_cycles_time(FModifierStackStorage *storage, FCurve *fcu, FModif
FMod_Cycles *data = (FMod_Cycles *)fcm->data;
float prevkey[2], lastkey[2], cycyofs = 0.0f;
short side = 0, mode = 0;
- int cycles = 0, ofs = 0;
+ int cycles = 0;
+ float ofs = 0;
/* check if modifier is first in stack, otherwise disable ourself... */
/* FIXME... */
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index c60c1ea2b5f..ef861e2844c 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -52,7 +52,6 @@
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"
#include "DNA_vfont_types.h"
-#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "BKE_packedFile.h"
@@ -62,7 +61,6 @@
#include "BKE_main.h"
#include "BKE_anim.h"
#include "BKE_curve.h"
-#include "BKE_displist.h"
static ThreadRWMutex vfont_rwlock = BLI_RWLOCK_INITIALIZER;
@@ -217,14 +215,14 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
BLI_strncpy(filename, name, sizeof(filename));
pf = get_builtin_packedfile();
- is_builtin = TRUE;
+ is_builtin = true;
}
else {
BLI_split_file_part(name, filename, sizeof(filename));
pf = newPackedFile(NULL, name, bmain->name);
temp_pf = newPackedFile(NULL, name, bmain->name);
- is_builtin = FALSE;
+ is_builtin = false;
}
if (pf) {
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 13dc13c49c9..2e194d21956 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -171,7 +171,7 @@ static FreestyleLineSet *alloc_lineset(void)
return (FreestyleLineSet *)MEM_callocN(sizeof(FreestyleLineSet), "Freestyle line set");
}
-FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config)
+FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config, const char *name)
{
int lineset_index = BLI_countlist(&config->linesets);
@@ -188,15 +188,36 @@ FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config)
lineset->edge_types = FREESTYLE_FE_SILHOUETTE | FREESTYLE_FE_BORDER | FREESTYLE_FE_CREASE;
lineset->exclude_edge_types = 0;
lineset->group = NULL;
- if (lineset_index > 0)
+ if (name) {
+ BLI_strncpy(lineset->name, name, sizeof(lineset->name));
+ }
+ else if (lineset_index > 0) {
sprintf(lineset->name, "LineSet %i", lineset_index + 1);
- else
+ }
+ else {
strcpy(lineset->name, "LineSet");
+ }
BKE_freestyle_lineset_unique_name(config, lineset);
return lineset;
}
+bool BKE_freestyle_lineset_delete(FreestyleConfig *config, FreestyleLineSet *lineset)
+{
+ if (BLI_findindex(&config->linesets, lineset) == -1)
+ return false;
+ if (lineset->group) {
+ lineset->group->id.us--;
+ }
+ if (lineset->linestyle) {
+ lineset->linestyle->id.us--;
+ }
+ BLI_remlink(&config->linesets, lineset);
+ MEM_freeN(lineset);
+ BKE_freestyle_lineset_set_active_index(config, 0);
+ return true;
+}
+
FreestyleLineSet *BKE_freestyle_lineset_get_active(FreestyleConfig *config)
{
FreestyleLineSet *lineset;
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 2eed25cde0e..c381084cfd2 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -48,8 +48,6 @@
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_library.h"
-#include "BKE_main.h"
-
/* ************************************************** */
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 01cecd2c38b..c6f58aecdf3 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -40,7 +40,6 @@
#include "DNA_group_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
-#include "DNA_nla_types.h"
#include "DNA_scene_types.h"
#include "DNA_particle_types.h"
@@ -155,17 +154,17 @@ Group *BKE_group_copy(Group *group)
}
/* external */
-static int group_object_add_internal(Group *group, Object *ob)
+static bool group_object_add_internal(Group *group, Object *ob)
{
GroupObject *go;
if (group == NULL || ob == NULL) {
- return FALSE;
+ return false;
}
/* check if the object has been added already */
if (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob))) {
- return FALSE;
+ return false;
}
go = MEM_callocN(sizeof(GroupObject), "groupobject");
@@ -173,7 +172,7 @@ static int group_object_add_internal(Group *group, Object *ob)
go->ob = ob;
- return TRUE;
+ return true;
}
bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base)
@@ -297,7 +296,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
{
static ListBase nlastrips = {NULL, NULL};
static bAction *action = NULL;
- static int done = FALSE;
+ static bool done = false;
bActionStrip *strip, *nstrip;
if (mode == 's') {
@@ -311,7 +310,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
action = target->action;
target->action = NULL;
target->nlaflag |= OB_NLA_OVERRIDE;
- done = TRUE;
+ done = true;
}
nstrip = MEM_dupallocN(strip);
BLI_addtail(&target->nlastrips, nstrip);
@@ -326,7 +325,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
BLI_listbase_clear(&nlastrips); /* not needed, but yah... :) */
action = NULL;
- done = FALSE;
+ done = false;
}
}
}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 0596c5109dd..f12a0720692 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
@@ -334,13 +335,12 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
prop->len = 1; /* NULL string, has len of 1 to account for null byte. */
}
else {
- int stlen = strlen(st);
+ /* include null terminator '\0' */
+ int stlen = strlen(st) + 1;
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
- stlen++; /* null terminator '\0' */
-
prop->data.pointer = MEM_mallocN(stlen, "id property string 2");
prop->len = prop->totallen = stlen;
BLI_strncpy(prop->data.pointer, st, stlen);
@@ -807,7 +807,7 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed)
}
/**
- * \param is_strict When FALSE treat missing items as a match */
+ * \param is_strict When false treat missing items as a match */
bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict)
{
if (prop1 == NULL && prop2 == NULL)
@@ -821,6 +821,19 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
case IDP_INT:
return (IDP_Int(prop1) == IDP_Int(prop2));
case IDP_FLOAT:
+#ifdef DEBUG
+ {
+ float p1 = IDP_Float(prop1);
+ float p2 = IDP_Float(prop2);
+ if ((p1 != p2) && ((fabsf(p1 - p2) / max_ff(p1, p2)) < 0.001f)) {
+ printf("WARNING: Comparing two float properties that have nearly the same value (%f vs. %f)\n", p1, p2);
+ printf(" p1: ");
+ IDP_spit(prop1);
+ printf(" p2: ");
+ IDP_spit(prop2);
+ }
+ }
+#endif
return (IDP_Float(prop1) == IDP_Float(prop2));
case IDP_DOUBLE:
return (IDP_Double(prop1) == IDP_Double(prop2));
@@ -872,7 +885,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
{
- return IDP_EqualsProperties_ex(prop1, prop2, TRUE);
+ return IDP_EqualsProperties_ex(prop1, prop2, true);
}
/**
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 55699bc0aae..440320e98fe 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -40,11 +40,6 @@
#include <time.h>
-#ifdef _WIN32
-# define open _open
-# define close _close
-#endif
-
#include "MEM_guardedalloc.h"
#include "IMB_colormanagement.h"
@@ -133,6 +128,15 @@ static int imagecache_hashcmp(const void *a_v, const void *b_v)
return a->index - b->index;
}
+static void imagecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
+{
+ ImageCacheKey *key = (ImageCacheKey *)userkey;
+
+ *framenr = IMA_INDEX_FRAME(key->index);
+ *proxy = IMB_PROXY_NONE;
+ *render_flags = 0;
+}
+
static void imagecache_put(Image *image, int index, ImBuf *ibuf)
{
ImageCacheKey key;
@@ -143,6 +147,7 @@ static void imagecache_put(Image *image, int index, ImBuf *ibuf)
image->cache = IMB_moviecache_create("Image Datablock Cache", sizeof(ImageCacheKey),
imagecache_hashhash, imagecache_hashcmp);
+ IMB_moviecache_set_getdata_callback(image->cache, imagecache_keydata);
}
key.index = index;
@@ -382,7 +387,7 @@ void BKE_image_make_local(struct Image *ima)
Tex *tex;
Brush *brush;
Mesh *me;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -403,14 +408,14 @@ void BKE_image_make_local(struct Image *ima)
for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->ima == ima) {
- if (tex->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (tex->id.lib) is_lib = true;
+ else is_local = true;
}
}
for (brush = bmain->brush.first; brush; brush = brush->id.next) {
if (brush->clone.image == ima) {
- if (brush->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (brush->id.lib) is_lib = true;
+ else is_local = true;
}
}
for (me = bmain->mesh.first; me; me = me->id.next) {
@@ -424,8 +429,8 @@ void BKE_image_make_local(struct Image *ima)
for (a = 0; a < me->totface; a++, tface++) {
if (tface->tpage == ima) {
- if (me->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (me->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -442,8 +447,8 @@ void BKE_image_make_local(struct Image *ima)
for (a = 0; a < me->totpoly; a++, mtpoly++) {
if (mtpoly->tpage == ima) {
- if (me->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (me->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -452,7 +457,7 @@ void BKE_image_make_local(struct Image *ima)
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &ima->id);
extern_local_image(ima);
}
@@ -625,7 +630,7 @@ Image *BKE_image_load(Main *bmain, const char *filepath)
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
- if (file < 0)
+ if (file == -1)
return NULL;
close(file);
@@ -739,7 +744,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
- TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ true, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
return ibuf;
@@ -1156,21 +1161,23 @@ int BKE_imtype_requires_linear_float(const char imtype)
case R_IMF_IMTYPE_RADHDR:
case R_IMF_IMTYPE_OPENEXR:
case R_IMF_IMTYPE_MULTILAYER:
- return TRUE;
+ return true;
}
return 0;
}
-char BKE_imtype_valid_channels(const char imtype)
+char BKE_imtype_valid_channels(const char imtype, bool write_file)
{
char chan_flag = IMA_CHAN_FLAG_RGB; /* assume all support rgb */
/* alpha */
switch (imtype) {
+ case R_IMF_IMTYPE_BMP:
+ if (write_file) break;
+ /* fall-through */
case R_IMF_IMTYPE_TARGA:
case R_IMF_IMTYPE_IRIS:
case R_IMF_IMTYPE_PNG:
- /* case R_IMF_IMTYPE_BMP: */ /* read but not write */
case R_IMF_IMTYPE_RADHDR:
case R_IMF_IMTYPE_TIFF:
case R_IMF_IMTYPE_OPENEXR:
@@ -1370,7 +1377,7 @@ static bool do_add_image_extension(char *string, const char imtype, const ImageF
}
else {
- return FALSE;
+ return false;
}
}
@@ -1568,7 +1575,7 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
}
if (scene->r.stamp & R_STAMP_MARKER) {
- char *name = BKE_scene_find_last_marker_name(scene, CFRA);
+ const char *name = BKE_scene_find_last_marker_name(scene, CFRA);
if (name) BLI_strncpy(text, name, sizeof(text));
else BLI_strncpy(text, "<none>", sizeof(text));
@@ -1890,10 +1897,10 @@ bool BKE_imbuf_alpha_test(ImBuf *ibuf)
{
int tot;
if (ibuf->rect_float) {
- float *buf = ibuf->rect_float;
+ const float *buf = ibuf->rect_float;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
if (buf[3] < 1.0f) {
- return TRUE;
+ return true;
}
}
}
@@ -1901,12 +1908,12 @@ bool BKE_imbuf_alpha_test(ImBuf *ibuf)
unsigned char *buf = (unsigned char *)ibuf->rect;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
if (buf[3] != 255) {
- return TRUE;
+ return true;
}
}
}
- return FALSE;
+ return false;
}
/* note: imf->planes is ignored here, its assumed the image channels
@@ -2053,7 +2060,7 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
/* same as BKE_imbuf_write() but crappy workaround not to perminantly modify
* _some_, values in the imbuf */
int BKE_imbuf_write_as(ImBuf *ibuf, const char *name, ImageFormatData *imf,
- const short save_copy)
+ const bool save_copy)
{
ImBuf ibuf_back = *ibuf;
int ok;
@@ -2096,12 +2103,14 @@ static void do_makepicstring(char *string, const char *base, const char *relbase
do_add_image_extension(string, imtype, im_format);
}
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const ImageFormatData *im_format, const short use_ext, const short use_frames)
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame,
+ const ImageFormatData *im_format, const bool use_ext, const bool use_frames)
{
do_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
}
-void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame,
+ const char imtype, const bool use_ext, const bool use_frames)
{
do_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
}
@@ -2439,7 +2448,7 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
{
const char *colorspace = ima->colorspace_settings.name;
- int predivide = ima->alpha_mode == IMA_ALPHA_PREMUL;
+ bool predivide = (ima->alpha_mode == IMA_ALPHA_PREMUL);
ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
@@ -2916,7 +2925,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
return ibuf;
}
-static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
+static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *r_frame, int *r_index)
{
int frame = 0, index = 0;
@@ -2934,8 +2943,8 @@ static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r
}
}
- *frame_r = frame;
- *index_r = index;
+ *r_frame = frame;
+ *r_index = index;
}
/* Get the ibuf from an image cache for a given image user.
@@ -2944,7 +2953,7 @@ static void image_get_frame_and_index(Image *ima, ImageUser *iuser, int *frame_r
* call IMB_freeImBuf to de-reference the image buffer after
* it's done handling it.
*/
-static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
+static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *r_frame, int *r_index)
{
ImBuf *ibuf = NULL;
int frame = 0, index = 0;
@@ -2990,11 +2999,11 @@ static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *frame_r,
* a big bottleneck */
}
- if (frame_r)
- *frame_r = frame;
+ if (r_frame)
+ *r_frame = frame;
- if (index_r)
- *index_r = index;
+ if (r_index)
+ *r_index = index;
return ibuf;
}
@@ -3002,16 +3011,16 @@ static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *frame_r,
BLI_INLINE bool image_quick_test(Image *ima, ImageUser *iuser)
{
if (ima == NULL)
- return FALSE;
+ return false;
if (iuser) {
if (iuser->ok == 0)
- return FALSE;
+ return false;
}
else if (ima->ok == 0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
/* Checks optional ImageUser and verifies/creates ImBuf.
@@ -3058,7 +3067,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
if (ima->type == IMA_TYPE_MULTILAYER)
/* keeps render result, stores ibufs in listbase, allows saving */
ibuf = image_get_ibuf_multilayer(ima, iuser);
-
}
else if (ima->source == IMA_SRC_GENERATED) {
/* generated is: ibuf is allocated dynamically */
@@ -3076,9 +3084,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* always verify entirely, and potentially
* returns pointer to release later */
ibuf = image_get_render_result(ima, iuser, lock_r);
- if (ibuf) {
- ibuf->userflags |= IB_PERSISTENT;
- }
}
else if (ima->type == IMA_TYPE_COMPOSITE) {
/* requires lock/unlock, otherwise don't return image */
@@ -3097,10 +3102,14 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
image_assign_ibuf(ima, ibuf, 0, frame);
}
- ibuf->userflags |= IB_PERSISTENT;
}
}
}
+
+ /* We only want movies and sequences to be memory limited. */
+ if (ibuf != NULL && !ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ ibuf->userflags |= IB_PERSISTENT;
+ }
}
BKE_image_tag_time(ima);
@@ -3155,7 +3164,7 @@ bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
/* quick reject tests */
if (!image_quick_test(ima, iuser))
- return FALSE;
+ return false;
BLI_spin_lock(&image_spin);
@@ -3213,15 +3222,15 @@ void BKE_image_pool_free(ImagePool *pool)
MEM_freeN(pool);
}
-BLI_INLINE ImBuf *image_pool_find_entry(ImagePool *pool, Image *image, int frame, int index, int *found)
+BLI_INLINE ImBuf *image_pool_find_entry(ImagePool *pool, Image *image, int frame, int index, bool *found)
{
ImagePoolEntry *entry;
- *found = FALSE;
+ *found = false;
for (entry = pool->image_buffers.first; entry; entry = entry->next) {
if (entry->image == image && entry->frame == frame && entry->index == index) {
- *found = TRUE;
+ *found = true;
return entry->ibuf;
}
}
@@ -3232,7 +3241,8 @@ BLI_INLINE ImBuf *image_pool_find_entry(ImagePool *pool, Image *image, int frame
ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool)
{
ImBuf *ibuf;
- int index, frame, found;
+ int index, frame;
+ bool found;
if (!image_quick_test(ima, iuser))
return NULL;
@@ -3289,7 +3299,7 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool
const int len = (iuser->fie_ima * iuser->frames) / 2;
if (r_is_in_range) {
- *r_is_in_range = FALSE;
+ *r_is_in_range = false;
}
if (len == 0) {
@@ -3306,7 +3316,7 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool
if (cfra == 0) cfra = len;
if (r_is_in_range) {
- *r_is_in_range = TRUE;
+ *r_is_in_range = true;
}
}
@@ -3318,7 +3328,7 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, bool
}
else {
if (r_is_in_range) {
- *r_is_in_range = TRUE;
+ *r_is_in_range = true;
}
}
@@ -3468,7 +3478,7 @@ unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame)
unsigned char *pixels = NULL;
iuser.framenr = frame;
- iuser.ok = TRUE;
+ iuser.ok = true;
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
@@ -3495,7 +3505,7 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame)
float *pixels = NULL;
iuser.framenr = frame;
- iuser.ok = TRUE;
+ iuser.ok = true;
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
@@ -3620,6 +3630,7 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
IMB_refImBuf(ibuf);
break;
}
+ IMB_moviecacheIter_step(iter);
}
IMB_moviecacheIter_free(iter);
}
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 71b4f9947a4..4f9ed5f258d 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -126,13 +126,13 @@ void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int widt
for (x = 0; x < width; x++) {
h = 0.125f * floorf(x / checkerwidth);
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4))
+ if ((abs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
+ (abs((y % checkerwidth) - (checkerwidth / 2)) < 4))
{
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1))
+ if ((abs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
+ (abs((y % checkerwidth) - (checkerwidth / 2)) < 1))
{
- hsv[0] = fmodf(fabs(h - hoffs), 1.0f);
+ hsv[0] = fmodf(fabsf(h - hoffs), 1.0f);
hsv_to_rgb_v(hsv, rgb);
if (rect) {
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 08959850fb9..e28fb59cfe6 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -37,7 +37,6 @@
#include "DNA_object_force.h"
#include "DNA_meshdata_types.h"
-#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
@@ -1271,16 +1270,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
k = scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
// TODO: verify, half verified (couldn't see error)
- if(s->type & CLOTH_SPRING_TYPE_SEWING) {
- // sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
- float force = k*(length-L);
- if(force > clmd->sim_parms->max_sewing) {
- force = clmd->sim_parms->max_sewing;
- }
- mul_fvector_S(stretch_force, dir, force);
- } else {
- mul_fvector_S(stretch_force, dir, k*(length-L));
- }
+ if (s->type & CLOTH_SPRING_TYPE_SEWING) {
+ // sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
+ float force = k*(length-L);
+ if (force > clmd->sim_parms->max_sewing) {
+ force = clmd->sim_parms->max_sewing;
+ }
+ mul_fvector_S(stretch_force, dir, force);
+ }
+ else {
+ mul_fvector_S(stretch_force, dir, k * (length - L));
+ }
VECADD(s->f, s->f, stretch_force);
@@ -1399,7 +1399,7 @@ static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
n[2] = n1[0]*n2[1]-n1[1]*n2[0];
}
-static float calculateVertexWindForce(float wind[3], float vertexnormal[3])
+static float calculateVertexWindForce(const float wind[3], const float vertexnormal[3])
{
return dot_v3v3(wind, vertexnormal);
}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index cf66d866c2c..7385322ddeb 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -60,7 +60,6 @@
#include "DNA_world_types.h"
#include "DNA_object_types.h"
-#include "BLI_math.h" /* windows needs for M_PI */
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
@@ -78,6 +77,10 @@
#include "MEM_guardedalloc.h"
+#ifdef WIN32
+# include "BLI_math_base.h" /* M_PI */
+#endif
+
/* *************************************************** */
/* Old-Data Freeing Tools */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 9dbaaa939ca..0f04c03688c 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -59,8 +59,6 @@
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_editmesh.h"
-#include "BKE_main.h"
-#include "BKE_object.h"
#include "BKE_scene.h"
@@ -546,10 +544,10 @@ static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **
/* currently only the first value of 'ofs' may be set. */
-static short key_pointer_size(const Key *key, const int mode, int *poinsize, int *ofs)
+static bool key_pointer_size(const Key *key, const int mode, int *poinsize, int *ofs)
{
if (key->from == NULL) {
- return FALSE;
+ return false;
}
switch (GS(key->from->name)) {
@@ -574,10 +572,10 @@ static short key_pointer_size(const Key *key, const int mode, int *poinsize, int
break;
default:
BLI_assert(!"invalid 'key->from' ID type");
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void cp_key(const int start, int end, const int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, const int mode)
@@ -1681,7 +1679,7 @@ void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb)
void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
{
BPoint *bp;
- float *fp;
+ const float *fp;
int a, tot;
bp = lt->def;
@@ -1752,7 +1750,7 @@ void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- float *fp;
+ const float *fp;
int a, tot;
nu = nurb->first;
@@ -1822,7 +1820,7 @@ void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb)
void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
{
MVert *mvert;
- float *fp;
+ const float *fp;
int a, tot;
mvert = me->mvert;
@@ -1839,7 +1837,7 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
{
float (*vertCos)[3], *co;
- float *fp = kb->data;
+ const float *fp = kb->data;
int tot = 0, a;
/* Count of vertex coords in array */
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 3cade886a04..749e915e5ca 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -161,7 +161,7 @@ void BKE_lamp_make_local(Lamp *la)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -177,13 +177,13 @@ void BKE_lamp_make_local(Lamp *la)
ob = bmain->object.first;
while (ob) {
if (ob->data == la) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
ob = ob->id.next;
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &la->id);
}
else if (is_local && is_lib) {
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index f7d394563ae..51fbb86b38e 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -59,11 +59,15 @@
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
+/* Workaround for cyclic depenndnecy with curves.
+ * In such case curve_cache might not be ready yet,
+ */
+#define CYCLIC_DEPENDENCY_WORKAROUND
+
int BKE_lattice_index_from_uvw(Lattice *lt,
const int u, const int v, const int w)
{
@@ -309,7 +313,7 @@ void BKE_lattice_make_local(Lattice *lt)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -322,14 +326,14 @@ void BKE_lattice_make_local(Lattice *lt)
return;
}
- for (ob = bmain->object.first; ob && ELEM(FALSE, is_lib, is_local); ob = ob->id.next) {
+ for (ob = bmain->object.first; ob && ELEM(false, is_lib, is_local); ob = ob->id.next) {
if (ob->data == lt) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &lt->id);
}
else if (is_local && is_lib) {
@@ -363,7 +367,7 @@ LatticeDeformData *init_latt_deform(Object *oblatt, Object *ob)
Lattice *lt = oblatt->data;
BPoint *bp;
DispList *dl = oblatt->curve_cache ? BKE_displist_find(&oblatt->curve_cache->disp, DL_VERTS) : NULL;
- float *co = dl ? dl->verts : NULL;
+ const float *co = dl ? dl->verts : NULL;
float *fp, imat[4][4];
float fu, fv, fw;
int u, v, w;
@@ -614,8 +618,8 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* co: local coord, result local too */
/* returns quaternion for rotation, using cd->no_rot_axis */
/* axis is using another define!!! */
-static bool calc_curve_deform(Object *par, float co[3],
- const short axis, CurveDeform *cd, float quat_r[4])
+static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
+ const short axis, CurveDeform *cd, float r_quat[4])
{
Curve *cu = par->data;
float fac, loc[4], dir[3], new_quat[4], radius;
@@ -624,7 +628,12 @@ static bool calc_curve_deform(Object *par, float co[3],
/* to be sure, mostly after file load */
if (ELEM(NULL, par->curve_cache, par->curve_cache->path)) {
- return 0; // happens on append and cyclic dependencies...
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ BKE_displist_make_curveTypes(scene, par, false);
+#endif
+ if (par->curve_cache->path == NULL) {
+ return 0; // happens on append and cyclic dependencies...
+ }
}
/* options */
@@ -637,10 +646,17 @@ static bool calc_curve_deform(Object *par, float co[3],
}
else {
index = axis;
- if (cu->flag & CU_STRETCH)
+ if (cu->flag & CU_STRETCH) {
fac = (co[index] - cd->dmin[index]) / (cd->dmax[index] - cd->dmin[index]);
- else
- fac = +(co[index] - cd->dmin[index]) / (par->curve_cache->path->totdist);
+ }
+ else {
+ if (LIKELY(par->curve_cache->path->totdist > FLT_EPSILON)) {
+ fac = +(co[index] - cd->dmin[index]) / (par->curve_cache->path->totdist);
+ }
+ else {
+ fac = 0.0f;
+ }
+ }
}
if (where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
@@ -696,15 +712,15 @@ static bool calc_curve_deform(Object *par, float co[3],
/* translation */
add_v3_v3v3(co, cent, loc);
- if (quat_r)
- copy_qt_qt(quat_r, quat);
+ if (r_quat)
+ copy_qt_qt(r_quat, quat);
return 1;
}
return 0;
}
-void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
+void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis)
{
Curve *cu;
@@ -721,7 +737,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
init_curve_deform(cuOb, target, &cd);
/* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */
- if (is_neg_axis == FALSE) {
+ if (is_neg_axis == false) {
cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = 0.0f;
cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 1.0f;
}
@@ -746,7 +762,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
}
}
else {
- use_vgroups = FALSE;
+ use_vgroups = false;
}
if (vgroup && vgroup[0] && use_vgroups) {
@@ -768,7 +784,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
if (weight > 0.0f) {
mul_m4_v3(cd.curvespace, vertexCos[a]);
copy_v3_v3(vec, vertexCos[a]);
- calc_curve_deform(cuOb, vec, defaxis, &cd, NULL);
+ calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
mul_m4_v3(cd.objectspace, vertexCos[a]);
}
@@ -796,7 +812,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
if (weight > 0.0f) {
/* already in 'cd.curvespace', prev for loop */
copy_v3_v3(vec, vertexCos[a]);
- calc_curve_deform(cuOb, vec, defaxis, &cd, NULL);
+ calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
mul_m4_v3(cd.objectspace, vertexCos[a]);
}
@@ -808,7 +824,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
if (cu->flag & CU_DEFORM_BOUNDS_OFF) {
for (a = 0; a < numVerts; a++) {
mul_m4_v3(cd.curvespace, vertexCos[a]);
- calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd, NULL);
+ calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
mul_m4_v3(cd.objectspace, vertexCos[a]);
}
}
@@ -823,7 +839,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
for (a = 0; a < numVerts; a++) {
/* already in 'cd.curvespace', prev for loop */
- calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd, NULL);
+ calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
mul_m4_v3(cd.objectspace, vertexCos[a]);
}
}
@@ -833,7 +849,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
/* input vec and orco = local coord in armature space */
/* orco is original not-animated or deformed reference point */
/* result written in vec and mat */
-void curve_deform_vector(Object *cuOb, Object *target,
+void curve_deform_vector(Scene *scene, Object *cuOb, Object *target,
float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
{
CurveDeform cd;
@@ -852,7 +868,7 @@ void curve_deform_vector(Object *cuOb, Object *target,
mul_m4_v3(cd.curvespace, vec);
- if (calc_curve_deform(cuOb, vec, target->trackflag, &cd, quat)) {
+ if (calc_curve_deform(scene, cuOb, vec, target->trackflag, &cd, quat)) {
float qmat[3][3];
quat_to_mat3(qmat, quat);
@@ -870,7 +886,7 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
{
LatticeDeformData *lattice_deform_data;
int a;
- int use_vgroups;
+ bool use_vgroups;
if (laOb->type != OB_LATTICE)
return;
@@ -884,7 +900,7 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
if (target && target->type == OB_MESH) {
/* if there's derived data without deformverts, don't use vgroups */
if (dm) {
- use_vgroups = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);
+ use_vgroups = (dm->getVertDataArray(dm, CD_MDEFORMVERT) != NULL);
}
else {
Mesh *me = target->data;
@@ -892,7 +908,7 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
}
}
else {
- use_vgroups = FALSE;
+ use_vgroups = false;
}
if (vgroup && vgroup[0] && use_vgroups) {
@@ -1014,14 +1030,14 @@ void outside_lattice(Lattice *lt)
}
}
-float (*BKE_lattice_vertexcos_get(struct Object *ob, int *numVerts_r))[3]
+float (*BKE_lattice_vertexcos_get(struct Object *ob, int *r_numVerts))[3]
{
Lattice *lt = ob->data;
int i, numVerts;
float (*vertexCos)[3];
if (lt->editlatt) lt = lt->editlatt->latt;
- numVerts = *numVerts_r = lt->pntsu * lt->pntsv * lt->pntsw;
+ numVerts = *r_numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
vertexCos = MEM_mallocN(sizeof(*vertexCos) * numVerts, "lt_vcos");
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 516bcf77ad6..fe2d1481581 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -52,12 +52,12 @@
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
-#include "DNA_nla_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -69,7 +69,6 @@
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -89,7 +88,6 @@
#include "BKE_group.h"
#include "BKE_gpencil.h"
#include "BKE_idprop.h"
-#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
@@ -134,7 +132,7 @@
* also note that the id _must_ have a library - campbell */
void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
{
- char *bpath_user_data[2] = {bmain->name, lib->filepath};
+ const char *bpath_user_data[2] = {bmain->name, lib->filepath};
BKE_bpath_traverse_id(bmain, id,
BKE_bpath_relocate_visitor,
@@ -283,7 +281,7 @@ bool id_make_local(ID *id, bool test)
case ID_GD:
return false; /* not implemented */
case ID_LS:
- return 0; /* not implemented */
+ return false; /* not implemented */
}
return false;
@@ -384,7 +382,7 @@ bool id_copy(ID *id, ID **newid, bool test)
return true;
case ID_LS:
if (!test) *newid = (ID *)BKE_copy_linestyle((FreestyleLineStyle *)id);
- return 1;
+ return true;
}
return false;
@@ -808,6 +806,32 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id)
return idn;
}
+void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
+{
+ ID *idn;
+ size_t idn_len;
+
+ idn = alloc_libblock_notest(GS(id->name));
+ assert(idn != NULL);
+
+ BLI_strncpy(idn->name, id->name, sizeof(idn->name));
+
+ idn_len = MEM_allocN_len(idn);
+ if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
+ const char *cp = (const char *)id;
+ char *cpn = (char *)idn;
+
+ memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
+ }
+
+ id->newid = idn;
+ idn->flag |= LIB_NEW;
+
+ BKE_libblock_copy_data(idn, id, do_action);
+
+ return idn;
+}
+
void *BKE_libblock_copy(ID *id)
{
return BKE_libblock_copy_ex(G.main, id);
@@ -1096,135 +1120,6 @@ ID *BKE_libblock_find_name(const short type, const char *name) /* type: "OB
return BLI_findstring(lb, name, offsetof(ID, name) + 2);
}
-#if 0 /* UNUSED */
-#define MAX_IDPUP 60 /* was 24 */
-
-static void get_flags_for_id(ID *id, char *buf)
-{
- int isfake = id->flag & LIB_FAKEUSER;
- int isnode = 0;
- /* Writeout the flags for the entry, note there
- * is a small hack that writes 5 spaces instead
- * of 4 if no flags are displayed... this makes
- * things usually line up ok - better would be
- * to have that explicit, oh well - zr
- */
-
- if (GS(id->name) == ID_MA)
- isnode = ((Material *)id)->use_nodes;
- if (GS(id->name) == ID_TE)
- isnode = ((Tex *)id)->use_nodes;
-
- if (id->us < 0)
- strcpy(buf, "-1W ");
- else if (!id->lib && !isfake && id->us && !isnode)
- strcpy(buf, " ");
- else if (isnode)
- sprintf(buf, "%c%cN%c ", id->lib ? 'L' : ' ', isfake ? 'F' : ' ', (id->us == 0) ? 'O' : ' ');
- else
- sprintf(buf, "%c%c%c ", id->lib ? 'L' : ' ', isfake ? 'F' : ' ', (id->us == 0) ? 'O' : ' ');
-}
-
-#define IDPUP_NO_VIEWER 1
-
-static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag)
-{
- int i, nids = BLI_countlist(lb);
-
- if (nr) *nr = -1;
-
- if (nr && nids > MAX_IDPUP) {
- BLI_dynstr_append(pupds, "DataBrowse %x-2");
- *nr = -2;
- }
- else {
- ID *id;
-
- for (i = 0, id = lb->first; id; id = id->next, i++) {
- char numstr[32];
-
- if (nr && id == link) *nr = i + 1;
-
- if (U.uiflag & USER_HIDE_DOT && id->name[2] == '.')
- continue;
- if (hideflag & IDPUP_NO_VIEWER)
- if (GS(id->name) == ID_IM)
- if ( ((Image *)id)->source == IMA_SRC_VIEWER)
- continue;
-
- get_flags_for_id(id, numstr);
-
- BLI_dynstr_append(pupds, numstr);
- BLI_dynstr_append(pupds, id->name + 2);
- BLI_snprintf(numstr, sizeof(numstr), "%%x%d", i + 1);
- BLI_dynstr_append(pupds, numstr);
-
- /* icon */
- switch (GS(id->name)) {
- case ID_MA: /* fall through */
- case ID_TE: /* fall through */
- case ID_IM: /* fall through */
- case ID_WO: /* fall through */
- case ID_LA: /* fall through */
- BLI_snprintf(numstr, sizeof(numstr), "%%i%d", BKE_icon_getid(id));
- BLI_dynstr_append(pupds, numstr);
- break;
- default:
- break;
- }
-
- if (id->next)
- BLI_dynstr_append(pupds, "|");
- }
- }
-}
-
-/* used by headerbuttons.c buttons.c editobject.c editseq.c */
-/* if (nr == NULL) no MAX_IDPUP, this for non-header browsing */
-void IDnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
-{
- DynStr *pupds = BLI_dynstr_new();
-
- if (title) {
- BLI_dynstr_append(pupds, title);
- BLI_dynstr_append(pupds, "%t|");
- }
-
- if (extraops) {
- BLI_dynstr_append(pupds, extraops);
- if (BLI_dynstr_get_len(pupds))
- BLI_dynstr_append(pupds, "|");
- }
-
- IDnames_to_dyn_pupstring(pupds, lb, link, nr, 0);
-
- *str = BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-}
-
-/* skips viewer images */
-void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
-{
- DynStr *pupds = BLI_dynstr_new();
-
- if (title) {
- BLI_dynstr_append(pupds, title);
- BLI_dynstr_append(pupds, "%t|");
- }
-
- if (extraops) {
- BLI_dynstr_append(pupds, extraops);
- if (BLI_dynstr_get_len(pupds))
- BLI_dynstr_append(pupds, "|");
- }
-
- IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER);
-
- *str = BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-}
-#endif
-
void id_sort_by_name(ListBase *lb, ID *id)
{
ID *idtest;
@@ -1452,6 +1347,11 @@ void id_clear_lib_data(Main *bmain, ID *id)
BKE_id_lib_local_paths(bmain, id->lib, id);
+ if (id->flag & LIB_FAKEUSER) {
+ id->us--;
+ id->flag &= ~LIB_FAKEUSER;
+ }
+
id->lib = NULL;
id->flag = LIB_LOCAL;
new_id(which_libbase(bmain, GS(id->name)), id, NULL);
@@ -1465,6 +1365,7 @@ void id_clear_lib_data(Main *bmain, ID *id)
case ID_LA: ntree = ((Lamp *)id)->nodetree; break;
case ID_WO: ntree = ((World *)id)->nodetree; break;
case ID_TE: ntree = ((Tex *)id)->nodetree; break;
+ case ID_LS: ntree = ((FreestyleLineStyle *)id)->nodetree; break;
}
if (ntree)
ntree->id.lib = NULL;
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
new file mode 100644
index 00000000000..e9bdc3679c1
--- /dev/null
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -0,0 +1,474 @@
+/*
+ * ***** 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 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/library_query.c
+ * \ingroup bke
+ */
+
+#include <stdlib.h>
+
+
+#include "DNA_anim_types.h"
+#include "DNA_brush_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_linestyle_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_force.h"
+#include "DNA_sequence_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_vfont_types.h"
+#include "DNA_world_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_animsys.h"
+#include "BKE_constraint.h"
+#include "BKE_fcurve.h"
+#include "BKE_library_query.h"
+#include "BKE_modifier.h"
+#include "BKE_particle.h"
+#include "BKE_sequencer.h"
+#include "BKE_tracking.h"
+
+#define FOREACH_CALLBACK_INVOKE_ID_PP(self_id, id_pp, flag, callback, user_data, cb_flag) \
+ { \
+ ID *old_id = *id_pp; \
+ bool keep_working = callback(user_data, id_pp, cb_flag); \
+ if (flag & IDWALK_READONLY) { \
+ BLI_assert(*id_pp == old_id); \
+ (void)old_id; /* quiet warning */ \
+ } \
+ if (keep_working == false) { \
+ /* REAL DANGER! Beware of this return! */ \
+ /* TODO(sergey): Make it less creepy without too much duplicated code.. */ \
+ return; \
+ } \
+ } (void) 0
+
+#define FOREACH_CALLBACK_INVOKE_ID(self_id, id, flag, callback, user_data, cb_flag) \
+ FOREACH_CALLBACK_INVOKE_ID_PP(self_id, &(id), flag, callback, user_data, cb_flag) \
+
+#define FOREACH_CALLBACK_INVOKE(self_id, id_super, flag, callback, user_data, cb_flag) \
+ { \
+ CHECK_TYPE(&((id_super)->id), ID *); \
+ FOREACH_CALLBACK_INVOKE_ID_PP(self_id, (ID **)&id_super, flag, callback, user_data, cb_flag); \
+ } (void) 0
+
+typedef struct LibraryForeachIDData {
+ ID *self_id;
+ int flag;
+ LibraryIDLinkCallback callback;
+ void *user_data;
+} LibraryForeachIDData;
+
+static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object),
+ ID **id_pointer)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
+ FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, IDWALK_NOP);
+}
+
+static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer,
+ bool UNUSED(is_reference), void *user_data)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
+ FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, IDWALK_NOP);
+}
+
+static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
+{
+ FCurve *fcu;
+
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ /* only used targets */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ FOREACH_CALLBACK_INVOKE_ID(data->self_id, dtar->id, data->flag, data->callback, data->user_data, IDWALK_NOP);
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
+}
+
+
+static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex)
+{
+ FOREACH_CALLBACK_INVOKE(data->self_id, mtex->object, data->flag, data->callback, data->user_data, IDWALK_NOP);
+ FOREACH_CALLBACK_INVOKE(data->self_id, mtex->tex, data->flag, data->callback, data->user_data, IDWALK_NOP);
+}
+
+
+/**
+ * Loop over all of the ID's this datablock links to.
+ *
+ * \note: May be extended to be recursive in the future.
+ */
+void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
+{
+ AnimData *adt;
+ LibraryForeachIDData data;
+ int i;
+
+ data.self_id = id;
+ data.flag = flag;
+ data.callback = callback;
+ data.user_data = user_data;
+
+ adt = BKE_animdata_from_id(id);
+ if (adt) {
+ library_foreach_animationData(&data, adt);
+ }
+
+#define CALLBACK_INVOKE_ID(check_id, cb_flag) \
+ FOREACH_CALLBACK_INVOKE_ID(id, check_id, flag, callback, user_data, cb_flag)
+
+#define CALLBACK_INVOKE(check_id_super, cb_flag) \
+ FOREACH_CALLBACK_INVOKE(id, check_id_super, flag, callback, user_data, cb_flag)
+
+ switch (GS(id->name)) {
+ case ID_SCE:
+ {
+ Scene *scene = (Scene *) id;
+ Base *base;
+
+ CALLBACK_INVOKE(scene->camera, IDWALK_NOP);
+ CALLBACK_INVOKE(scene->world, IDWALK_NOP);
+ CALLBACK_INVOKE(scene->set, IDWALK_NOP);
+ if (scene->basact) {
+ CALLBACK_INVOKE(scene->basact->object, IDWALK_NOP);
+ }
+ CALLBACK_INVOKE(scene->obedit, IDWALK_NOP);
+
+ if (scene->ed) {
+ Sequence *seq;
+ SEQP_BEGIN(scene->ed, seq)
+ {
+ CALLBACK_INVOKE(seq->scene, IDWALK_NOP);
+ CALLBACK_INVOKE(seq->scene_camera, IDWALK_NOP);
+ CALLBACK_INVOKE(seq->clip, IDWALK_NOP);
+ CALLBACK_INVOKE(seq->mask, IDWALK_NOP);
+ }
+ SEQ_END
+ }
+
+ CALLBACK_INVOKE(scene->gpd, IDWALK_NOP);
+
+ for (base = scene->base.first; base; base = base->next) {
+ CALLBACK_INVOKE(base->object, IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_OB:
+ {
+ Object *object = (Object *) id;
+ CALLBACK_INVOKE(object->parent, IDWALK_NOP);
+ CALLBACK_INVOKE(object->track, IDWALK_NOP);
+ CALLBACK_INVOKE(object->proxy, IDWALK_NOP);
+ CALLBACK_INVOKE(object->proxy_group, IDWALK_NOP);
+ CALLBACK_INVOKE(object->proxy_from, IDWALK_NOP);
+ CALLBACK_INVOKE(object->poselib, IDWALK_NOP);
+ for (i = 0; i < object->totcol; i++) {
+ CALLBACK_INVOKE(object->mat[i], IDWALK_NOP);
+ }
+ CALLBACK_INVOKE(object->gpd, IDWALK_NOP);
+ CALLBACK_INVOKE(object->dup_group, IDWALK_NOP);
+ if (object->particlesystem.first) {
+ ParticleSystem *particle_system;
+ for (particle_system = object->particlesystem.first;
+ particle_system;
+ particle_system = particle_system->next)
+ {
+ CALLBACK_INVOKE(particle_system->target_ob, IDWALK_NOP);
+ CALLBACK_INVOKE(particle_system->parent, IDWALK_NOP);
+ }
+ }
+
+ if (object->pose) {
+ bPoseChannel *pose_channel;
+ for (pose_channel = object->pose->chanbase.first;
+ pose_channel;
+ pose_channel = pose_channel->next)
+ {
+ CALLBACK_INVOKE(pose_channel->custom, IDWALK_NOP);
+ BKE_constraints_id_loop(&pose_channel->constraints,
+ library_foreach_constraintObjectLooper,
+ &data);
+ }
+ }
+
+ modifiers_foreachIDLink(object,
+ library_foreach_modifiersForeachIDLink,
+ &data);
+ BKE_constraints_id_loop(&object->constraints,
+ library_foreach_constraintObjectLooper,
+ &data);
+ break;
+ }
+
+ case ID_ME:
+ {
+ Mesh *mesh = (Mesh *) id;
+ CALLBACK_INVOKE(mesh->texcomesh, IDWALK_NOP);
+ CALLBACK_INVOKE(mesh->key, IDWALK_NOP);
+ for (i = 0; i < mesh->totcol; i++) {
+ CALLBACK_INVOKE(mesh->mat[i], IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_CU:
+ {
+ Curve *curve = (Curve *) id;
+ CALLBACK_INVOKE(curve->bevobj, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->taperobj, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->textoncurve, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->key, IDWALK_NOP);
+ for (i = 0; i < curve->totcol; i++) {
+ CALLBACK_INVOKE(curve->mat[i], IDWALK_NOP);
+ }
+ CALLBACK_INVOKE(curve->vfont, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->vfontb, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->vfonti, IDWALK_NOP);
+ CALLBACK_INVOKE(curve->vfontbi, IDWALK_NOP);
+ break;
+ }
+
+ case ID_MB:
+ {
+ MetaBall *metaball = (MetaBall *) id;
+ for (i = 0; i < metaball->totcol; i++) {
+ CALLBACK_INVOKE(metaball->mat[i], IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_MA:
+ {
+ Material *material = (Material *) id;
+ for (i = 0; i < MAX_MTEX; i++) {
+ if (material->mtex[i]) {
+ library_foreach_mtex(&data, material->mtex[i]);
+ }
+ }
+ CALLBACK_INVOKE(material->nodetree, IDWALK_NOP);
+ CALLBACK_INVOKE(material->group, IDWALK_NOP);
+ break;
+ }
+
+ case ID_TE:
+ {
+ Tex *texture = (Tex *) id;
+ CALLBACK_INVOKE(texture->nodetree, IDWALK_NOP);
+ CALLBACK_INVOKE(texture->ima, IDWALK_NOP);
+ break;
+ }
+
+ case ID_LT:
+ {
+ Lattice *lattice = (Lattice *) id;
+ CALLBACK_INVOKE(lattice->key, IDWALK_NOP);
+ break;
+ }
+
+ case ID_LA:
+ {
+ Lamp *lamp = (Lamp *) id;
+ for (i = 0; i < MAX_MTEX; i++) {
+ if (lamp->mtex[i]) {
+ library_foreach_mtex(&data, lamp->mtex[i]);
+ }
+ }
+ CALLBACK_INVOKE(lamp->nodetree, IDWALK_NOP);
+ break;
+ }
+
+ case ID_CA:
+ {
+ Camera *camera = (Camera *) id;
+ CALLBACK_INVOKE(camera->dof_ob, IDWALK_NOP);
+ break;
+ }
+
+ case ID_KE:
+ {
+ Key *key = (Key *) id;
+ CALLBACK_INVOKE_ID(key->from, IDWALK_NOP);
+ break;
+ }
+
+ case ID_SCR:
+ {
+ bScreen *screen = (bScreen *) id;
+ CALLBACK_INVOKE(screen->scene, IDWALK_NOP);
+ break;
+ }
+
+ case ID_WO:
+ {
+ World *world = (World *) id;
+ for (i = 0; i < MAX_MTEX; i++) {
+ if (world->mtex[i]) {
+ library_foreach_mtex(&data, world->mtex[i]);
+ }
+ }
+ CALLBACK_INVOKE(world->nodetree, IDWALK_NOP);
+ break;
+ }
+
+ case ID_SPK:
+ {
+ Speaker *speaker = (Speaker *) id;
+ CALLBACK_INVOKE(speaker->sound, IDWALK_NOP);
+ break;
+ }
+
+ case ID_GR:
+ {
+ Group *group = (Group *) id;
+ GroupObject *group_object;
+ for (group_object = group->gobject.first;
+ group_object;
+ group_object = group_object->next)
+ {
+ CALLBACK_INVOKE(group_object->ob, IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_NT:
+ {
+ bNodeTree *ntree = (bNodeTree *) id;
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ CALLBACK_INVOKE_ID(node->id, IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_BR:
+ {
+ Brush *brush = (Brush *) id;
+ CALLBACK_INVOKE(brush->toggle_brush, IDWALK_NOP);
+ library_foreach_mtex(&data, &brush->mtex);
+ library_foreach_mtex(&data, &brush->mask_mtex);
+ break;
+ }
+
+ case ID_PA:
+ {
+ ParticleSettings *particle_settings = (ParticleSettings *) id;
+ CALLBACK_INVOKE(particle_settings->dup_group, IDWALK_NOP);
+ CALLBACK_INVOKE(particle_settings->dup_ob, IDWALK_NOP);
+ CALLBACK_INVOKE(particle_settings->bb_ob, IDWALK_NOP);
+ if (particle_settings->effector_weights) {
+ CALLBACK_INVOKE(particle_settings->effector_weights->group, IDWALK_NOP);
+ }
+ break;
+ }
+
+ case ID_MC:
+ {
+ MovieClip *clip = (MovieClip *) id;
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *object;
+ CALLBACK_INVOKE(clip->gpd, IDWALK_NOP);
+ for (object = tracking->objects.first;
+ object;
+ object = object->next)
+ {
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+ MovieTrackingTrack *track;
+ for (track = tracksbase->first;
+ track;
+ track = track->next)
+ {
+ CALLBACK_INVOKE(track->gpd, IDWALK_NOP);
+ }
+ }
+ break;
+ }
+
+ case ID_MSK:
+ {
+ Mask *mask = (Mask *) id;
+ MaskLayer *mask_layer;
+ for (mask_layer = mask->masklayers.first;
+ mask_layer;
+ mask_layer = mask_layer->next)
+ {
+ MaskSpline *mask_spline;
+
+ for (mask_spline = mask_layer->splines.first;
+ mask_spline;
+ mask_spline = mask_spline->next)
+ {
+ int i;
+ for (i = 0; i < mask_spline->tot_point; i++) {
+ MaskSplinePoint *point = &mask_spline->points[i];
+ CALLBACK_INVOKE_ID(point->parent.id, IDWALK_NOP);
+ }
+ }
+ }
+ break;
+ }
+
+ case ID_LS:
+ {
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *) id;
+ for (i = 0; i < MAX_MTEX; i++) {
+ if (linestyle->mtex[i]) {
+ library_foreach_mtex(&data, linestyle->mtex[i]);
+ }
+ }
+ CALLBACK_INVOKE(linestyle->nodetree, IDWALK_NOP);
+ break;
+ }
+
+ }
+
+#undef CALLBACK_INVOKE_ID
+#undef CALLBACK_INVOKE
+}
+
+#undef FOREACH_CALLBACK_INVOKE_ID
+#undef FOREACH_CALLBACK_INVOKE
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index fcd23b2831e..5f133a2f5e9 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -47,7 +47,7 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
-#include "BKE_main.h"
+#include "BKE_node.h"
#include "BKE_texture.h"
#include "BKE_colortools.h"
#include "BKE_animsys.h"
@@ -82,7 +82,7 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->thickness = 3.0f;
linestyle->thickness_position = LS_THICKNESS_CENTER;
linestyle->thickness_ratio = 0.5f;
- linestyle->flag = LS_SAME_OBJECT;
+ linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
linestyle->chaining = LS_CHAINING_PLAIN;
linestyle->rounds = 3;
linestyle->min_angle = DEG2RADF(0.0f);
@@ -90,6 +90,10 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->min_length = 0.0f;
linestyle->max_length = 10000.0f;
linestyle->split_length = 100;
+ linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
+ linestyle->integration_type = LS_INTEGRATION_MEAN;
+ linestyle->texstep = 1.0f;
+ linestyle->pr_texture = TEX_PR_TEXTURE;
BLI_listbase_clear(&linestyle->color_modifiers);
BLI_listbase_clear(&linestyle->alpha_modifiers);
@@ -119,6 +123,19 @@ void BKE_free_linestyle(FreestyleLineStyle *linestyle)
{
LineStyleModifier *m;
+ MTex *mtex;
+ int a;
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ mtex = linestyle->mtex[a];
+ if (mtex && mtex->tex) mtex->tex->id.us--;
+ if (mtex) MEM_freeN(mtex);
+ }
+ if (linestyle->nodetree) {
+ ntreeFreeTree(linestyle->nodetree);
+ MEM_freeN(linestyle->nodetree);
+ }
+
BKE_free_animdata(&linestyle->id);
while ((m = (LineStyleModifier *)linestyle->color_modifiers.first))
BKE_remove_linestyle_color_modifier(linestyle, m);
@@ -134,10 +151,22 @@ FreestyleLineStyle *BKE_copy_linestyle(FreestyleLineStyle *linestyle)
{
FreestyleLineStyle *new_linestyle;
LineStyleModifier *m;
+ int a;
new_linestyle = BKE_new_linestyle(linestyle->id.name + 2, NULL);
BKE_free_linestyle(new_linestyle);
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) {
+ new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_copy_linestyle");
+ memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex));
+ id_us_plus((ID *)new_linestyle->mtex[a]->tex);
+ }
+ }
+ if (linestyle->nodetree) {
+ linestyle->nodetree = ntreeCopyTree(linestyle->nodetree);
+ }
+
new_linestyle->r = linestyle->r;
new_linestyle->g = linestyle->g;
new_linestyle->b = linestyle->b;
@@ -167,6 +196,8 @@ FreestyleLineStyle *BKE_copy_linestyle(FreestyleLineStyle *linestyle)
new_linestyle->dash3 = linestyle->dash3;
new_linestyle->gap3 = linestyle->gap3;
new_linestyle->panel = linestyle->panel;
+ new_linestyle->texstep = linestyle->texstep;
+ new_linestyle->pr_texture = linestyle->pr_texture;
for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
BKE_copy_linestyle_color_modifier(new_linestyle, m);
for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
@@ -1025,7 +1056,7 @@ void BKE_list_modifier_color_ramps(FreestyleLineStyle *linestyle, ListBase *list
default:
continue;
}
- link = (LinkData *) MEM_callocN( sizeof(LinkData), "link to color ramp");
+ link = (LinkData *) MEM_callocN(sizeof(LinkData), "link to color ramp");
link->data = color_ramp;
BLI_addtail(listbase, link);
}
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index fab7ebf2060..8c1cc4b0279 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -50,7 +50,6 @@
#include "DNA_sequence_types.h"
#include "BKE_curve.h"
-#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mask.h"
@@ -150,7 +149,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
masklay->blend = MASK_BLEND_MERGE_ADD;
masklay->alpha = 1.0f;
- masklay->flag = MASK_LAYERFLAG_FILL_DISCRETE;
+ masklay->flag = MASK_LAYERFLAG_FILL_DISCRETE | MASK_LAYERFLAG_FILL_OVERLAP;
return masklay;
}
@@ -263,7 +262,7 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay)
bool BKE_mask_spline_remove(MaskLayer *mask_layer, MaskSpline *spline)
{
- if (BLI_remlink_safe(&mask_layer->splines, spline) == FALSE) {
+ if (BLI_remlink_safe(&mask_layer->splines, spline) == false) {
return false;
}
@@ -435,58 +434,87 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point,
/* point */
-bool BKE_mask_point_has_handle(MaskSplinePoint *point)
+eMaskhandleMode BKE_mask_point_handles_mode_get(MaskSplinePoint *point)
{
BezTriple *bezt = &point->bezt;
- return bezt->h1 == HD_ALIGN;
+ if (bezt->h1 == bezt->h2 && bezt->h1 == HD_ALIGN) {
+ return MASK_HANDLE_MODE_STICK;
+ }
+
+ return MASK_HANDLE_MODE_INDIVIDUAL_HANDLES;
}
-void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2])
+void BKE_mask_point_handle(MaskSplinePoint *point, eMaskWhichHandle which_handle, float handle[2])
{
- float vec[2];
+ BezTriple *bezt = &point->bezt;
+
+ if (which_handle == MASK_WHICH_HANDLE_STICK) {
+ float vec[2];
- sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]);
+ sub_v2_v2v2(vec, bezt->vec[0], bezt->vec[1]);
- handle[0] = (point->bezt.vec[1][0] + vec[1]);
- handle[1] = (point->bezt.vec[1][1] - vec[0]);
+ handle[0] = (bezt->vec[1][0] + vec[1]);
+ handle[1] = (bezt->vec[1][1] - vec[0]);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ copy_v2_v2(handle, bezt->vec[0]);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ copy_v2_v2(handle, bezt->vec[2]);
+ }
+ else {
+ BLI_assert(!"Unknown handle passed to BKE_mask_point_handle");
+ }
}
-void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], bool keep_direction,
+void BKE_mask_point_set_handle(MaskSplinePoint *point, eMaskWhichHandle which_handle,
+ float loc[2], bool keep_direction,
float orig_handle[2], float orig_vec[3][3])
{
BezTriple *bezt = &point->bezt;
- float v1[2], v2[2], vec[2];
- if (keep_direction) {
- sub_v2_v2v2(v1, loc, orig_vec[1]);
- sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
+ if (which_handle == MASK_WHICH_HANDLE_STICK) {
+ float v1[2], v2[2], vec[2];
+ if (keep_direction) {
+ sub_v2_v2v2(v1, loc, orig_vec[1]);
+ sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
- project_v2_v2v2(vec, v1, v2);
+ project_v2_v2v2(vec, v1, v2);
- if (dot_v2v2(v2, vec) > 0) {
- float len = len_v2(vec);
+ if (dot_v2v2(v2, vec) > 0) {
+ float len = len_v2(vec);
- sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
+ sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
- mul_v2_fl(v1, len / len_v2(v1));
+ mul_v2_fl(v1, len / len_v2(v1));
- add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
- sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
+ add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
+ sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
+ }
+ else {
+ copy_v3_v3(bezt->vec[0], bezt->vec[1]);
+ copy_v3_v3(bezt->vec[2], bezt->vec[1]);
+ }
}
else {
- copy_v3_v3(bezt->vec[0], bezt->vec[1]);
- copy_v3_v3(bezt->vec[2], bezt->vec[1]);
+ sub_v2_v2v2(v1, loc, bezt->vec[1]);
+
+ v2[0] = -v1[1];
+ v2[1] = v1[0];
+
+ add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
+ sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
}
}
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ copy_v2_v2(bezt->vec[0], loc);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ copy_v2_v2(bezt->vec[2], loc);
+ }
else {
- sub_v2_v2v2(v1, loc, bezt->vec[1]);
-
- v2[0] = -v1[1];
- v2[1] = v1[0];
-
- add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
- sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
+ BLI_assert(!"unknown handle passed to BKE_mask_point_set_handle");
}
}
@@ -514,36 +542,68 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
interp_v2_v2v2(co, r0, r1, u);
}
+BLI_INLINE void orthogonal_direction_get(float vec[2], float result[2])
+{
+ result[0] = -vec[1];
+ result[1] = vec[0];
+ normalize_v2(result);
+}
+
+/* TODO(sergey): This function will re-calculate loads of stuff again and again
+ * when differentiating feather points. This might be easily cached
+ * in the callee function for this case.
+ */
void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2])
{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
- BezTriple *bezt = &point->bezt, *bezt_next;
- float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2];
+ MaskSplinePoint *point_prev, *point_next;
- bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
+ /* TODO(sergey): This actually depends on a resolution. */
+ const float du = 0.05f;
- if (!bezt_next) {
- BKE_mask_point_handle(point, vec);
+ BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
- sub_v2_v2v2(n, vec, bezt->vec[1]);
- normalize_v2(n);
- return;
+ if (u - du < 0.0f && point_prev == NULL) {
+ float co[2], dir[2];
+ BKE_mask_point_segment_co(spline, point, u + du, co);
+ sub_v2_v2v2(dir, co, point->bezt.vec[1]);
+ orthogonal_direction_get(dir, n);
+ }
+ else if (u + du > 1.0f && point_next == NULL) {
+ float co[2], dir[2];
+ BKE_mask_point_segment_co(spline, point, u - du, co);
+ sub_v2_v2v2(dir, point->bezt.vec[1], co);
+ orthogonal_direction_get(dir, n);
}
+ else {
+ float prev_co[2], next_co[2], co[2];
+ float dir1[2], dir2[2], dir[2];
- interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u);
- interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u);
- interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u);
+ if (u - du < 0.0f) {
+ BKE_mask_point_segment_co(spline, point_prev, 1.0f + (u - du), prev_co);
+ }
+ else {
+ BKE_mask_point_segment_co(spline, point, u - du, prev_co);
+ }
- interp_v2_v2v2(r0, q0, q1, u);
- interp_v2_v2v2(r1, q1, q2, u);
+ BKE_mask_point_segment_co(spline, point, u, co);
+
+ if (u + du > 1.0f) {
+ BKE_mask_point_segment_co(spline, point_next, u + du - 1.0f, next_co);
+ }
+ else {
+ BKE_mask_point_segment_co(spline, point, u + du, next_co);
+ }
- sub_v2_v2v2(vec, r1, r0);
+ sub_v2_v2v2(dir1, co, prev_co);
+ sub_v2_v2v2(dir2, next_co, co);
- n[0] = -vec[1];
- n[1] = vec[0];
+ normalize_v2(dir1);
+ normalize_v2(dir2);
+ add_v2_v2v2(dir, dir1, dir2);
- normalize_v2(n);
+ orthogonal_direction_get(dir, n);
+ }
}
static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u)
@@ -693,13 +753,37 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, const bool do_select)
}
}
-void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const bool do_select)
+void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const eMaskWhichHandle which_handle, const bool do_select)
{
if (do_select) {
- MASKPOINT_SEL_HANDLE(point);
+ if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_BOTH)) {
+ point->bezt.f1 |= SELECT;
+ point->bezt.f3 |= SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ point->bezt.f1 |= SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ point->bezt.f3 |= SELECT;
+ }
+ else {
+ BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
+ }
}
else {
- MASKPOINT_DESEL_HANDLE(point);
+ if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_BOTH)) {
+ point->bezt.f1 &= ~SELECT;
+ point->bezt.f3 &= ~SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ point->bezt.f1 &= ~SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ point->bezt.f3 &= ~SELECT;
+ }
+ else {
+ BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
+ }
}
}
@@ -734,6 +818,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
return mask;
}
+/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */
Mask *BKE_mask_copy_nolib(Mask *mask)
{
Mask *mask_new;
@@ -1169,7 +1254,7 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *poin
else if (handle_type == HD_AUTO) {
BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0);
}
- else if (handle_type == HD_ALIGN) {
+ else if (handle_type == HD_ALIGN || handle_type == HD_ALIGN_DOUBLESIDE) {
float v1[3], v2[3];
float vec[3], h[3];
@@ -1316,7 +1401,7 @@ void BKE_mask_calc_handle_point_auto(MaskSpline *spline, MaskSplinePoint *point,
point->bezt.h2 = h_back[1];
/* preserve length by applying it back */
- if (do_recalc_length == FALSE) {
+ if (do_recalc_length == false) {
dist_ensure_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
dist_ensure_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
}
@@ -1403,7 +1488,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
for (spline = masklay->splines.first; spline; spline = spline->next) {
int i;
- int need_handle_recalc = FALSE;
+ bool need_handle_recalc = false;
BKE_mask_spline_ensure_deform(spline);
@@ -1419,7 +1504,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
mask_evaluate_apply_point_parent(point_deform, ctime);
if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) {
- need_handle_recalc = TRUE;
+ need_handle_recalc = true;
}
}
@@ -1601,8 +1686,8 @@ void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay,
{
int tot = BKE_mask_layer_shape_totvert(masklay);
if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) {
- float *fp_a = masklay_shape_a->data;
- float *fp_b = masklay_shape_b->data;
+ const float *fp_a = masklay_shape_a->data;
+ const float *fp_b = masklay_shape_b->data;
const float ifac = 1.0f - fac;
MaskSpline *spline;
@@ -2019,7 +2104,7 @@ void BKE_mask_clipboard_paste_to_layer(Main *bmain, MaskLayer *mask_layer)
for (i = 0; i < spline_new->tot_point; i++) {
MaskSplinePoint *point = &spline_new->points[i];
if (point->parent.id) {
- char *id_name = BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id);
+ const char *id_name = BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id);
ListBase *listbase;
BLI_assert(id_name != NULL);
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index c6cc4a412b8..3ed6148054c 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -37,30 +37,14 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "DNA_mask_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_tracking_types.h"
-#include "DNA_sequence_types.h"
#include "BKE_curve.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
#include "BKE_mask.h"
-#include "BKE_node.h"
-#include "BKE_sequencer.h"
-#include "BKE_tracking.h"
-#include "BKE_movieclip.h"
unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
@@ -252,20 +236,21 @@ static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int e
bucket->tot_segment++;
}
-static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
- int cur_a, int cur_b)
+static void feather_bucket_check_intersect(
+ float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
+ int cur_a, int cur_b)
{
int i;
- float *v1 = (float *) feather_points[cur_a];
- float *v2 = (float *) feather_points[cur_b];
+ const float *v1 = (float *) feather_points[cur_a];
+ const float *v2 = (float *) feather_points[cur_b];
for (i = 0; i < bucket->tot_segment; i++) {
int check_a = bucket->segments[i][0];
int check_b = bucket->segments[i][1];
- float *v3 = (float *) feather_points[check_a];
- float *v4 = (float *) feather_points[check_b];
+ const float *v3 = (float *) feather_points[check_a];
+ const float *v4 = (float *) feather_points[check_b];
if (check_a >= cur_a - 1 || cur_b == check_a)
continue;
@@ -313,8 +298,9 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f
}
}
-static int feather_bucket_index_from_coord(const float co[2], const float min[2], const float bucket_scale[2],
- const int buckets_per_side)
+static int feather_bucket_index_from_coord(
+ const float co[2], const float min[2], const float bucket_scale[2],
+ const int buckets_per_side)
{
int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
@@ -328,9 +314,9 @@ static int feather_bucket_index_from_coord(const float co[2], const float min[2]
return y * buckets_per_side + x;
}
-static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index,
- int buckets_per_side, FeatherEdgesBucket **diagonal_bucket_a_r,
- FeatherEdgesBucket **diagonal_bucket_b_r)
+static void feather_bucket_get_diagonal(
+ FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index, int buckets_per_side,
+ FeatherEdgesBucket **r_diagonal_bucket_a, FeatherEdgesBucket **r_diagonal_bucket_b)
{
int start_bucket_x = start_bucket_index % buckets_per_side;
int start_bucket_y = start_bucket_index / buckets_per_side;
@@ -341,11 +327,12 @@ static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_b
int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
- *diagonal_bucket_a_r = &buckets[diagonal_bucket_a_index];
- *diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
+ *r_diagonal_bucket_a = &buckets[diagonal_bucket_a_index];
+ *r_diagonal_bucket_b = &buckets[diagonal_bucket_b_index];
}
-void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], const unsigned int tot_feather_point)
+void BKE_mask_spline_feather_collapse_inner_loops(
+ MaskSpline *spline, float (*feather_points)[2], const unsigned int tot_feather_point)
{
#define BUCKET_INDEX(co) \
feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
@@ -502,11 +489,9 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe
}
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
-static float (*mask_spline_feather_differentiated_points_with_resolution__even(MaskSpline *spline,
- unsigned int *tot_feather_point,
- const unsigned int resol,
- const bool do_feather_isect
- ))[2]
+static float (*mask_spline_feather_differentiated_points_with_resolution__even(
+ MaskSpline *spline, unsigned int *tot_feather_point,
+ const unsigned int resol, const bool do_feather_isect))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
MaskSplinePoint *point_curr, *point_prev;
@@ -575,11 +560,9 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__even(M
}
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
-static float (*mask_spline_feather_differentiated_points_with_resolution__double(MaskSpline *spline,
- unsigned int *tot_feather_point,
- const unsigned int resol,
- const bool do_feather_isect
- ))[2]
+static float (*mask_spline_feather_differentiated_points_with_resolution__double(
+ MaskSpline *spline, unsigned int *tot_feather_point,
+ const unsigned int resol, const bool do_feather_isect))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -712,20 +695,16 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__double
* values align with #BKE_mask_spline_differentiate_with_resolution
* when \a resol arguments match.
*/
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline,
- unsigned int *tot_feather_point,
- const unsigned int resol,
- const bool do_feather_isect
- ))[2]
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
+ MaskSpline *spline, unsigned int *tot_feather_point,
+ const unsigned int resol, const bool do_feather_isect))[2]
{
switch (spline->offset_mode) {
case MASK_SPLINE_OFFSET_EVEN:
return mask_spline_feather_differentiated_points_with_resolution__even(spline, tot_feather_point, resol, do_feather_isect);
- break;
case MASK_SPLINE_OFFSET_SMOOTH:
default:
return mask_spline_feather_differentiated_points_with_resolution__double(spline, tot_feather_point, resol, do_feather_isect);
- break;
}
}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 2c60f52578d..35207595103 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -82,10 +82,11 @@
#include "BLI_rect.h"
#include "BLI_listbase.h"
#include "BLI_linklist.h"
-#include "BLI_strict_flags.h"
#include "BKE_mask.h"
+#include "BLI_strict_flags.h"
+
/* this is rather and annoying hack, use define to isolate it.
* problem is caused by scanfill removing edges on us. */
#define USE_SCANFILL_EDGE_WORKAROUND
@@ -294,7 +295,7 @@ static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather
/* normalize_v2(d_prev); */ /* precalc */
normalize_v2(d_next);
- if ((do_test == FALSE) ||
+ if ((do_test == false) ||
(len_squared_v2v2(diff_feather_points[k], diff_points[k]) < ofs_squared))
{
@@ -317,7 +318,7 @@ static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather
/* this function is not exact, sometimes it returns false positives,
* the main point of it is to clear out _almost_ all bucket/face non-intersections,
- * returning TRUE in corner cases is ok but missing an intersection is NOT.
+ * returning true in corner cases is ok but missing an intersection is NOT.
*
* method used
* - check if the center of the buckets bounding box is intersecting the face
@@ -347,18 +348,18 @@ static bool layer_bucket_isect_test(
const float *v3 = cos[face[2]];
if (isect_point_tri_v2(cent, v1, v2, v3)) {
- return TRUE;
+ return true;
}
else {
if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
(dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) ||
(dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared))
{
- return TRUE;
+ return true;
}
else {
// printf("skip tri\n");
- return FALSE;
+ return false;
}
}
@@ -370,10 +371,10 @@ static bool layer_bucket_isect_test(
const float *v4 = cos[face[3]];
if (isect_point_tri_v2(cent, v1, v2, v3)) {
- return TRUE;
+ return true;
}
else if (isect_point_tri_v2(cent, v1, v3, v4)) {
- return TRUE;
+ return true;
}
else {
if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
@@ -381,11 +382,11 @@ static bool layer_bucket_isect_test(
(dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) ||
(dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared))
{
- return TRUE;
+ return true;
}
else {
// printf("skip quad\n");
- return FALSE;
+ return false;
}
}
}
@@ -632,7 +633,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
if (do_feather) {
diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(
- spline, &tot_diff_feather_points, resol, FALSE);
+ spline, &tot_diff_feather_points, resol, false);
BLI_assert(diff_feather_points);
}
else {
@@ -680,20 +681,20 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
/* fake aa, using small feather */
- if (do_mask_aa == TRUE) {
- if (do_feather == FALSE) {
+ if (do_mask_aa == true) {
+ if (do_feather == false) {
tot_diff_feather_points = tot_diff_point;
diff_feather_points = MEM_mallocN(sizeof(*diff_feather_points) *
(size_t)tot_diff_feather_points,
__func__);
/* add single pixel feather */
maskrasterize_spline_differentiate_point_outset(diff_feather_points, diff_points,
- tot_diff_point, pixel_size, FALSE);
+ tot_diff_point, pixel_size, false);
}
else {
/* ensure single pixel feather, on any zero feather areas */
maskrasterize_spline_differentiate_point_outset(diff_feather_points, diff_points,
- tot_diff_point, pixel_size, TRUE);
+ tot_diff_point, pixel_size, true);
}
}
@@ -840,8 +841,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
open_spline_ranges[open_spline_index].vertex_total_cap_tail = 0;
if (!is_cyclic) {
- float *fp_cent;
- float *fp_turn;
+ const float *fp_cent;
+ const float *fp_turn;
unsigned int k;
@@ -1433,8 +1434,16 @@ void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
const unsigned int width, const unsigned int height,
float *buffer)
{
+ const float x_inv = 1.0f / (float)width;
+ const float y_inv = 1.0f / (float)height;
+ const float x_px_ofs = x_inv * 0.5f;
+ const float y_px_ofs = y_inv * 0.5f;
#ifdef _MSC_VER
int y; /* msvc requires signed for some reason */
+
+ /* ignore sign mismatch */
+# pragma warning(push)
+# pragma warning(disable:4018)
#else
unsigned int y;
#endif
@@ -1444,11 +1453,16 @@ void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
unsigned int i = y * width;
unsigned int x;
float xy[2];
- xy[1] = (float)y / (float)height;
+ xy[1] = ((float)y * y_inv) + y_px_ofs;
for (x = 0; x < width; x++, i++) {
- xy[0] = (float)x / (float)width;
+ xy[0] = ((float)x * x_inv) + x_px_ofs;
buffer[i] = BKE_maskrasterize_handle_sample(mr_handle, xy);
}
}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 5f6331315f8..de3aea9267f 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -80,7 +80,7 @@ void init_def_material(void)
/* not material itself */
void BKE_material_free(Material *ma)
{
- BKE_material_free_ex(ma, TRUE);
+ BKE_material_free_ex(ma, true);
}
/* not material itself */
@@ -203,6 +203,7 @@ void init_material(Material *ma)
ma->game.face_orientation = 0;
ma->mode = MA_TRACEBLE | MA_SHADBUF | MA_SHADOW | MA_RAYBIAS | MA_TANGENT_STR | MA_ZTRANSP;
+ ma->mode2 = MA_CASTSHADOW;
ma->shade_flag = MA_APPROX_OCCLUSION;
ma->preview = NULL;
}
@@ -256,8 +257,7 @@ Material *localize_material(Material *ma)
Material *man;
int a;
- man = BKE_libblock_copy(&ma->id);
- BLI_remlink(&G.main->mat, man);
+ man = BKE_libblock_copy_nolib(&ma->id, false);
/* no increment for texture ID users, in previewrender.c it prevents decrement */
for (a = 0; a < MAX_MTEX; a++) {
@@ -295,7 +295,8 @@ void BKE_material_make_local(Material *ma)
Mesh *me;
Curve *cu;
MetaBall *mb;
- int a, is_local = FALSE, is_lib = FALSE;
+ int a;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -319,8 +320,8 @@ void BKE_material_make_local(Material *ma)
if (ob->mat) {
for (a = 0; a < ob->totcol; a++) {
if (ob->mat[a] == ma) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -332,8 +333,8 @@ void BKE_material_make_local(Material *ma)
if (me->mat) {
for (a = 0; a < me->totcol; a++) {
if (me->mat[a] == ma) {
- if (me->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (me->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -345,8 +346,8 @@ void BKE_material_make_local(Material *ma)
if (cu->mat) {
for (a = 0; a < cu->totcol; a++) {
if (cu->mat[a] == ma) {
- if (cu->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (cu->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -358,8 +359,8 @@ void BKE_material_make_local(Material *ma)
if (mb->mat) {
for (a = 0; a < mb->totcol; a++) {
if (mb->mat[a] == ma) {
- if (mb->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (mb->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
@@ -367,7 +368,7 @@ void BKE_material_make_local(Material *ma)
}
/* Only local users. */
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &ma->id);
extern_local_material(ma);
}
@@ -507,13 +508,10 @@ Material ***give_matarar_id(ID *id)
switch (GS(id->name)) {
case ID_ME:
return &(((Mesh *)id)->mat);
- break;
case ID_CU:
return &(((Curve *)id)->mat);
- break;
case ID_MB:
return &(((MetaBall *)id)->mat);
- break;
}
return NULL;
}
@@ -526,13 +524,10 @@ short *give_totcolp_id(ID *id)
switch (GS(id->name)) {
case ID_ME:
return &(((Mesh *)id)->totcol);
- break;
case ID_CU:
return &(((Curve *)id)->totcol);
- break;
case ID_MB:
return &(((MetaBall *)id)->totcol);
- break;
}
return NULL;
}
@@ -674,7 +669,7 @@ void BKE_material_clear_id(struct ID *id, bool update_data)
Material *give_current_material(Object *ob, short act)
{
Material ***matarar, *ma;
- short *totcolp;
+ const short *totcolp;
if (ob == NULL) return NULL;
@@ -779,7 +774,7 @@ void test_object_materials(Main *bmain, ID *id)
{
/* make the ob mat-array same size as 'ob->data' mat-array */
Object *ob;
- short *totcol;
+ const short *totcol;
if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
return;
@@ -951,14 +946,14 @@ short find_material_index(Object *ob, Material *ma)
return 0;
}
-int object_add_material_slot(Object *ob)
+bool object_add_material_slot(Object *ob)
{
- if (ob == NULL) return FALSE;
- if (ob->totcol >= MAXMAT) return FALSE;
+ if (ob == NULL) return false;
+ if (ob->totcol >= MAXMAT) return false;
assign_material(ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
ob->actcol = ob->totcol;
- return TRUE;
+ return true;
}
static void do_init_render_material(Material *ma, int r_mode, float *amb)
@@ -1015,16 +1010,6 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
ma->ambg = ma->amb * amb[1];
ma->ambb = ma->amb * amb[2];
}
- /* will become or-ed result of all node modes */
- ma->mode_l = ma->mode;
- ma->mode_l &= ~MA_SHLESS;
-
- if (ma->strand_surfnor > 0.0f)
- ma->mode_l |= MA_STR_SURFDIFF;
-
- /* parses the geom+tex nodes */
- if (ma->nodetree && ma->use_nodes)
- ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l);
/* local group override */
if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) {
@@ -1049,8 +1034,16 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode
if (ma != basemat) {
do_init_render_material(ma, r_mode, amb);
basemat->texco |= ma->texco;
- basemat->mode_l |= ma->mode_l & ~(MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP);
}
+
+ basemat->mode_l |= ma->mode & ~(MA_MODE_PIPELINE | MA_SHLESS);
+ basemat->mode2_l |= ma->mode2 & ~MA_MODE2_PIPELINE;
+ /* basemat only considered shadeless if all node materials are too */
+ if (!(ma->mode & MA_SHLESS))
+ basemat->mode_l &= ~MA_SHLESS;
+
+ if (ma->strand_surfnor > 0.0f)
+ basemat->mode_l |= MA_STR_SURFDIFF;
}
else if (node->type == NODE_GROUP)
init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb);
@@ -1064,11 +1057,27 @@ void init_render_material(Material *mat, int r_mode, float *amb)
do_init_render_material(mat, r_mode, amb);
if (mat->nodetree && mat->use_nodes) {
+ /* mode_l will take the pipeline options from the main material, and the or-ed
+ * result of non-pipeline options from the nodes. shadeless is an exception,
+ * mode_l will have it set when all node materials are shadeless. */
+ mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS;
+ mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE;
+
+ /* parses the geom+tex nodes */
+ ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l);
+
init_render_nodetree(mat->nodetree, mat, r_mode, amb);
if (!mat->nodetree->execdata)
mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
}
+ else {
+ mat->mode_l = mat->mode;
+ mat->mode2_l = mat->mode2;
+
+ if (mat->strand_surfnor > 0.0f)
+ mat->mode_l |= MA_STR_SURFDIFF;
+ }
}
void init_render_materials(Main *bmain, int r_mode, float *amb)
@@ -1093,7 +1102,7 @@ void init_render_materials(Main *bmain, int r_mode, float *amb)
init_render_material(ma, r_mode, amb);
}
- do_init_render_material(&defmaterial, r_mode, amb);
+ init_render_material(&defmaterial, r_mode, amb);
}
/* only needed for nodes now */
@@ -1135,7 +1144,7 @@ static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
return 0;
}
-int material_in_material(Material *parmat, Material *mat)
+bool material_in_material(Material *parmat, Material *mat)
{
if (parmat == mat)
return 1;
@@ -1203,7 +1212,7 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime)
ma->id.flag &= ~LIB_DOIT;
}
-int object_remove_material_slot(Object *ob)
+bool object_remove_material_slot(Object *ob)
{
Material *mao, ***matarar;
Object *obt;
@@ -1211,14 +1220,14 @@ int object_remove_material_slot(Object *ob)
short a, actcol;
if (ob == NULL || ob->totcol == 0) {
- return FALSE;
+ return false;
}
/* this should never happen and used to crash */
if (ob->actcol <= 0) {
printf("%s: invalid material index %d, report a bug!\n", __func__, ob->actcol);
BLI_assert(0);
- return FALSE;
+ return false;
}
/* take a mesh/curve/mball as starting point, remove 1 index,
@@ -1287,7 +1296,7 @@ int object_remove_material_slot(Object *ob)
}
}
- return TRUE;
+ return true;
}
@@ -1350,12 +1359,9 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
break;
case MA_RAMP_DARK:
- tmp = col[0] + ((1 - col[0]) * facm);
- if (tmp < r_col[0]) r_col[0] = tmp;
- tmp = col[1] + ((1 - col[1]) * facm);
- if (tmp < r_col[1]) r_col[1] = tmp;
- tmp = col[2] + ((1 - col[2]) * facm);
- if (tmp < r_col[2]) r_col[2] = tmp;
+ r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
+ r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
+ r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
break;
case MA_RAMP_LIGHT:
tmp = fac * col[0];
@@ -1539,7 +1545,7 @@ void free_matcopybuf(void)
matcopybuf.ramp_spec = NULL;
if (matcopybuf.nodetree) {
- ntreeFreeTree_ex(matcopybuf.nodetree, FALSE);
+ ntreeFreeTree_ex(matcopybuf.nodetree, false);
MEM_freeN(matcopybuf.nodetree);
matcopybuf.nodetree = NULL;
}
@@ -1565,7 +1571,7 @@ void copy_matcopybuf(Material *ma)
matcopybuf.mtex[a] = MEM_dupallocN(mtex);
}
}
- matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, FALSE);
+ matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, false);
matcopybuf.preview = NULL;
BLI_listbase_clear(&matcopybuf.gpumaterial);
matcopied = 1;
@@ -1618,7 +1624,7 @@ void paste_matcopybuf(Material *ma)
}
}
- ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, FALSE);
+ ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, false);
}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index c43ef048909..57ac3b0b6bc 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -252,7 +252,7 @@ void BKE_mball_make_local(MetaBall *mb)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -269,12 +269,12 @@ void BKE_mball_make_local(MetaBall *mb)
for (ob = G.main->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
if (ob->data == mb) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &mb->id);
extern_local_mball(mb);
}
@@ -356,7 +356,8 @@ void BKE_mball_texspace_calc(Object *ob)
DispList *dl;
BoundBox *bb;
float *data, min[3], max[3] /*, loc[3], size[3] */;
- int tot, do_it = FALSE;
+ int tot;
+ bool do_it = false;
if (ob->bb == NULL) ob->bb = MEM_callocN(sizeof(BoundBox), "mb boundbox");
bb = ob->bb;
@@ -369,7 +370,7 @@ void BKE_mball_texspace_calc(Object *ob)
dl = ob->curve_cache->disp.first;
while (dl) {
tot = dl->nr;
- if (tot) do_it = TRUE;
+ if (tot) do_it = true;
data = dl->verts;
while (tot--) {
/* Also weird... but longer. From utildefines. */
@@ -751,7 +752,8 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
}
}
- return node;
+ /* all cases accounted for */
+ BLI_assert(0);
}
static float metaball(PROCESS *process, float x, float y, float z)
@@ -1110,11 +1112,11 @@ static int otherface(int edge, int face)
static void makecubetable(void)
{
- static int is_done = FALSE;
+ static bool is_done = false;
int i, e, c, done[12], pos[8];
if (is_done) return;
- is_done = TRUE;
+ is_done = true;
for (i = 0; i < 256; i++) {
for (e = 0; e < 12; e++) done[e] = 0;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index b3484707d44..21f6730da78 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -40,7 +40,6 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_edgehash.h"
-#include "BLI_string_utf8.h"
#include "BLI_string.h"
#include "BKE_animsys.h"
@@ -54,6 +53,8 @@
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_key.h"
+#include "BKE_mball.h"
+#include "BKE_depsgraph.h"
/* these 2 are only used by conversion functions */
#include "BKE_curve.h"
/* -- */
@@ -337,6 +338,43 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
}
}
+void BKE_mesh_ensure_skin_customdata(Mesh *me)
+{
+ BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+ MVertSkin *vs;
+
+ if (bm) {
+ if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
+ BMVert *v;
+ BMIter iter;
+
+ BM_data_layer_add(bm, &bm->vdata, CD_MVERT_SKIN);
+
+ /* Mark an arbitrary vertex as root */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
+ CD_MVERT_SKIN);
+ vs->flag |= MVERT_SKIN_ROOT;
+ break;
+ }
+ }
+ }
+ else {
+ if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
+ vs = CustomData_add_layer(&me->vdata,
+ CD_MVERT_SKIN,
+ CD_DEFAULT,
+ NULL,
+ me->totvert);
+
+ /* Mark an arbitrary vertex as root */
+ if (vs) {
+ vs->flag |= MVERT_SKIN_ROOT;
+ }
+ }
+ }
+}
+
/* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
* mloopcol and mcol) have the same relative active/render/clone/mask indices.
*
@@ -386,11 +424,12 @@ void BKE_mesh_unlink(Mesh *me)
int a;
if (me == NULL) return;
-
- if (me->mat)
- for (a = 0; a < me->totcol; a++) {
- if (me->mat[a]) me->mat[a]->id.us--;
- me->mat[a] = NULL;
+
+ if (me->mat) {
+ for (a = 0; a < me->totcol; a++) {
+ if (me->mat[a]) me->mat[a]->id.us--;
+ me->mat[a] = NULL;
+ }
}
if (me->key) {
@@ -489,7 +528,7 @@ Mesh *BKE_mesh_copy_ex(Main *bmain, Mesh *me)
CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
}
else {
- mesh_tessface_clear_intern(men, FALSE);
+ mesh_tessface_clear_intern(men, false);
}
BKE_mesh_update_customdata_pointers(men, do_tessface);
@@ -586,7 +625,7 @@ void BKE_mesh_make_local(Mesh *me)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -602,12 +641,12 @@ void BKE_mesh_make_local(Mesh *me)
for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
if (me == ob->data) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &me->id);
expand_local_mesh(me);
}
@@ -986,7 +1025,7 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
MVert *mvert;
MLoop *mloop, *allloop;
MPoly *mpoly;
- float *nors, *verts;
+ const float *nors, *verts;
int a;
unsigned int *index;
@@ -1090,7 +1129,7 @@ static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge,
/* --- */
for (ehi = BLI_edgehashIterator_new(eh);
- BLI_edgehashIterator_isDone(ehi) == FALSE;
+ BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), ++medge, e_index++)
{
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
@@ -1158,7 +1197,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MLoop *mloop;
MLoopUV *mloopuv = NULL;
MEdge *medge;
- float *data;
+ const float *data;
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
int p1, p2, p3, p4;
unsigned int *index;
@@ -1561,19 +1600,19 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
/* each iteration find a polyline and add this as a nurbs poly spline */
ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */
- int closed = FALSE;
+ bool closed = false;
int totpoly = 0;
MEdge *med_current = ((EdgeLink *)edges.last)->edge;
unsigned int startVert = med_current->v1;
unsigned int endVert = med_current->v2;
- int ok = TRUE;
+ bool ok = true;
appendPolyLineVert(&polyline, startVert); totpoly++;
appendPolyLineVert(&polyline, endVert); totpoly++;
BLI_freelinkN(&edges, edges.last); totedges--;
while (ok) { /* while connected edges are found... */
- ok = FALSE;
+ ok = false;
i = totedges;
while (i) {
EdgeLink *edl;
@@ -1586,25 +1625,25 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
endVert = med->v2;
appendPolyLineVert(&polyline, med->v2); totpoly++;
BLI_freelinkN(&edges, edl); totedges--;
- ok = TRUE;
+ ok = true;
}
else if (med->v2 == endVert) {
endVert = med->v1;
appendPolyLineVert(&polyline, endVert); totpoly++;
BLI_freelinkN(&edges, edl); totedges--;
- ok = TRUE;
+ ok = true;
}
else if (med->v1 == startVert) {
startVert = med->v2;
prependPolyLineVert(&polyline, startVert); totpoly++;
BLI_freelinkN(&edges, edl); totedges--;
- ok = TRUE;
+ ok = true;
}
else if (med->v2 == startVert) {
startVert = med->v1;
prependPolyLineVert(&polyline, startVert); totpoly++;
BLI_freelinkN(&edges, edl); totedges--;
- ok = TRUE;
+ ok = true;
}
}
}
@@ -1613,7 +1652,7 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
if (startVert == endVert) {
BLI_freelinkN(&polyline, polyline.last);
totpoly--;
- closed = TRUE;
+ closed = true;
}
/* --- nurbs --- */
@@ -1752,7 +1791,7 @@ void BKE_mesh_smooth_flag_set(Object *meshOb, int enableSmooth)
/**
* Return a newly MEM_malloc'd array of all the mesh vertex locations
- * \note \a numVerts_r may be NULL
+ * \note \a r_numVerts may be NULL
*/
float (*BKE_mesh_vertexCos_get(Mesh *me, int *r_numVerts))[3]
{
@@ -1783,11 +1822,11 @@ int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart,
}
/**
- * Fill \a adj_r with the loop indices in \a poly adjacent to the
+ * Fill \a r_adj with the loop indices in \a poly adjacent to the
* vertex. Returns the index of the loop matching vertex, or -1 if the
* vertex is not in \a poly
*/
-int poly_get_adj_loops_from_vert(unsigned adj_r[3], const MPoly *poly,
+int poly_get_adj_loops_from_vert(unsigned r_adj[3], const MPoly *poly,
const MLoop *mloop, unsigned vert)
{
int corner = poly_find_loop_from_vert(poly,
@@ -1798,9 +1837,9 @@ int poly_get_adj_loops_from_vert(unsigned adj_r[3], const MPoly *poly,
const MLoop *ml = &mloop[poly->loopstart + corner];
/* vertex was found */
- adj_r[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v;
- adj_r[1] = ml->v;
- adj_r[2] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v;
+ r_adj[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v;
+ r_adj[1] = ml->v;
+ r_adj[2] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v;
}
return corner;
@@ -1885,7 +1924,7 @@ void BKE_mesh_tessface_ensure(Mesh *mesh)
void BKE_mesh_tessface_clear(Mesh *mesh)
{
- mesh_tessface_clear_intern(mesh, TRUE);
+ mesh_tessface_clear_intern(mesh, true);
}
void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
@@ -2051,3 +2090,220 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
BLI_assert((me->mselect[me->totselect - 1].index == index) &&
(me->mselect[me->totselect - 1].type == type));
}
+
+/* settings: 1 - preview, 2 - render */
+Mesh *BKE_mesh_new_from_object(
+ Main *bmain, Scene *sce, Object *ob,
+ int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
+{
+ Mesh *tmpmesh;
+ Curve *tmpcu = NULL, *copycu;
+ Object *tmpobj = NULL;
+ int render = settings == eModifierMode_Render, i;
+ int cage = !apply_modifiers;
+
+ /* perform the mesh extraction based on type */
+ switch (ob->type) {
+ case OB_FONT:
+ case OB_CURVE:
+ case OB_SURF:
+ {
+ ListBase dispbase = {NULL, NULL};
+ DerivedMesh *derivedFinal = NULL;
+ int uv_from_orco;
+
+ /* copies object and modifiers (but not the data) */
+ tmpobj = BKE_object_copy_ex(bmain, ob, true);
+ tmpcu = (Curve *)tmpobj->data;
+ tmpcu->id.us--;
+
+ /* if getting the original caged mesh, delete object modifiers */
+ if (cage)
+ BKE_object_free_modifiers(tmpobj);
+
+ /* copies the data */
+ copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
+
+ /* temporarily set edit so we get updates from edit mode, but
+ * also because for text datablocks copying it while in edit
+ * mode gives invalid data structures */
+ copycu->editfont = tmpcu->editfont;
+ copycu->editnurb = tmpcu->editnurb;
+
+ /* get updated display list, and convert to a mesh */
+ BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, false, render);
+
+ copycu->editfont = NULL;
+ copycu->editnurb = NULL;
+
+ tmpobj->derivedFinal = derivedFinal;
+
+ /* convert object type to mesh */
+ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+ BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
+
+ tmpmesh = tmpobj->data;
+
+ BKE_displist_free(&dispbase);
+
+ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked.
+ * if it didn't the curve did not have any segments or otherwise
+ * would have generated an empty mesh */
+ if (tmpobj->type != OB_MESH) {
+ BKE_libblock_free_us(G.main, tmpobj);
+ return NULL;
+ }
+
+ BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
+
+ BKE_libblock_free_us(bmain, tmpobj);
+ break;
+ }
+
+ case OB_MBALL:
+ {
+ /* metaballs don't have modifiers, so just convert to mesh */
+ Object *basis_ob = BKE_mball_basis_find(sce, ob);
+ /* todo, re-generatre for render-res */
+ /* metaball_polygonize(scene, ob) */
+
+ if (ob != basis_ob)
+ return NULL; /* only do basis metaball */
+
+ tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ /* BKE_mesh_add gives us a user count we don't need */
+ tmpmesh->id.us--;
+
+ if (render) {
+ ListBase disp = {NULL, NULL};
+ /* TODO(sergey): This is gonna to work for until EvaluationContext
+ * only contains for_render flag. As soon as CoW is
+ * implemented, this is to be rethinked.
+ */
+ EvaluationContext eval_ctx = {0};
+ eval_ctx.for_render = render;
+ BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp);
+ BKE_mesh_from_metaball(&disp, tmpmesh);
+ BKE_displist_free(&disp);
+ }
+ else {
+ ListBase disp = {NULL, NULL};
+ if (ob->curve_cache) {
+ disp = ob->curve_cache->disp;
+ }
+ BKE_mesh_from_metaball(&disp, tmpmesh);
+ }
+
+ BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
+
+ break;
+
+ }
+ case OB_MESH:
+ /* copies object and modifiers (but not the data) */
+ if (cage) {
+ /* copies the data */
+ tmpmesh = BKE_mesh_copy_ex(bmain, ob->data);
+ /* if not getting the original caged mesh, get final derived mesh */
+ }
+ else {
+ /* Make a dummy mesh, saves copying */
+ DerivedMesh *dm;
+ /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
+ CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+ * for example, needs CD_MASK_MDEFORMVERT */
+
+ if (calc_undeformed)
+ mask |= CD_MASK_ORCO;
+
+ /* Write the display mesh into the dummy mesh */
+ if (render)
+ dm = mesh_create_derived_render(sce, ob, mask);
+ else
+ dm = mesh_create_derived_view(sce, ob, mask);
+
+ tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ DM_to_mesh(dm, tmpmesh, ob, mask);
+ dm->release(dm);
+ }
+
+ /* BKE_mesh_add/copy gives us a user count we don't need */
+ tmpmesh->id.us--;
+
+ break;
+ default:
+ /* "Object does not have geometry data") */
+ return NULL;
+ }
+
+ /* Copy materials to new mesh */
+ switch (ob->type) {
+ case OB_SURF:
+ case OB_FONT:
+ case OB_CURVE:
+ tmpmesh->totcol = tmpcu->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if (tmpcu->mat) {
+ for (i = tmpcu->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+
+ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
+
+ if (tmpmesh->mat[i]) {
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+
+#if 0
+ /* Crashes when assigning the new material, not sure why */
+ case OB_MBALL:
+ tmpmb = (MetaBall *)ob->data;
+ tmpmesh->totcol = tmpmb->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if (tmpmb->mat) {
+ for (i = tmpmb->totcol; i-- > 0; ) {
+ tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
+ if (tmpmesh->mat[i]) {
+ tmpmb->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+#endif
+
+ case OB_MESH:
+ if (!cage) {
+ Mesh *origmesh = ob->data;
+ tmpmesh->flag = origmesh->flag;
+ tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+ tmpmesh->totcol = origmesh->totcol;
+ tmpmesh->smoothresh = origmesh->smoothresh;
+ if (origmesh->mat) {
+ for (i = origmesh->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
+
+ if (tmpmesh->mat[i]) {
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ }
+ }
+ break;
+ } /* end copy materials */
+
+ if (calc_tessface) {
+ /* cycles and exporters rely on this still */
+ BKE_mesh_tessface_ensure(tmpmesh);
+ }
+
+ /* make sure materials get updated in objects */
+ test_object_materials(bmain, &tmpmesh->id);
+
+ return tmpmesh;
+}
+
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index be24fa8fc46..74e380c7d50 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -83,39 +83,39 @@ static void mesh_calc_normals_vert_fallback(MVert *mverts, int numVerts)
}
}
-/* Calculate vertex and face normals, face normals are returned in *faceNors_r if non-NULL
+/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL
* and vertex normals are stored in actual mverts.
*/
void BKE_mesh_calc_normals_mapping(MVert *mverts, int numVerts,
- MLoop *mloop, MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3],
- MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3])
+ MLoop *mloop, MPoly *mpolys, int numLoops, int numPolys, float (*r_polyNors)[3],
+ MFace *mfaces, int numFaces, const int *origIndexFace, float (*r_faceNors)[3])
{
BKE_mesh_calc_normals_mapping_ex(mverts, numVerts, mloop, mpolys,
- numLoops, numPolys, polyNors_r, mfaces, numFaces,
- origIndexFace, faceNors_r, FALSE);
+ numLoops, numPolys, r_polyNors, mfaces, numFaces,
+ origIndexFace, r_faceNors, false);
}
/* extended version of 'BKE_mesh_calc_normals_poly' with option not to calc vertex normals */
void BKE_mesh_calc_normals_mapping_ex(
MVert *mverts, int numVerts,
MLoop *mloop, MPoly *mpolys,
- int numLoops, int numPolys, float (*polyNors_r)[3],
- MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3],
+ int numLoops, int numPolys, float (*r_polyNors)[3],
+ MFace *mfaces, int numFaces, const int *origIndexFace, float (*r_faceNors)[3],
const bool only_face_normals)
{
- float (*pnors)[3] = polyNors_r, (*fnors)[3] = faceNors_r;
+ float (*pnors)[3] = r_polyNors, (*fnors)[3] = r_faceNors;
int i;
MFace *mf;
MPoly *mp;
if (numPolys == 0) {
- if (only_face_normals == FALSE) {
+ if (only_face_normals == false) {
mesh_calc_normals_vert_fallback(mverts, numVerts);
}
return;
}
/* if we are not calculating verts and no verts were passes then we have nothing to do */
- if ((only_face_normals == TRUE) && (polyNors_r == NULL) && (faceNors_r == NULL)) {
+ if ((only_face_normals == true) && (r_polyNors == NULL) && (r_faceNors == NULL)) {
printf("%s: called with nothing to do\n", __func__);
return;
}
@@ -124,7 +124,7 @@ void BKE_mesh_calc_normals_mapping_ex(
/* if (!fnors) fnors = MEM_callocN(sizeof(float[3]) * numFaces, "face nors mesh.c"); */ /* NO NEED TO ALLOC YET */
- if (only_face_normals == FALSE) {
+ if (only_face_normals == false) {
/* vertex normals are optional, they require some extra calculations,
* so make them optional */
BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false);
@@ -138,7 +138,7 @@ void BKE_mesh_calc_normals_mapping_ex(
}
if (origIndexFace &&
- /* fnors == faceNors_r */ /* NO NEED TO ALLOC YET */
+ /* fnors == r_faceNors */ /* NO NEED TO ALLOC YET */
fnors != NULL &&
numFaces)
{
@@ -154,8 +154,8 @@ void BKE_mesh_calc_normals_mapping_ex(
}
}
- if (pnors != polyNors_r) MEM_freeN(pnors);
- /* if (fnors != faceNors_r) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */
+ if (pnors != r_polyNors) MEM_freeN(pnors);
+ /* if (fnors != r_faceNors) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */
fnors = pnors = NULL;
@@ -172,8 +172,8 @@ static void mesh_calc_normals_poly_accum(MPoly *mp, MLoop *ml,
/* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */
{
int i_prev = nverts - 1;
- float const *v_prev = mvert[ml[i_prev].v].co;
- float const *v_curr;
+ const float *v_prev = mvert[ml[i_prev].v].co;
+ const float *v_curr;
zero_v3(polyno);
/* Newell's Method */
@@ -277,17 +277,17 @@ void BKE_mesh_calc_normals(Mesh *mesh)
#endif
}
-void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3])
+void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*r_faceNors)[3])
{
float (*tnorms)[3] = MEM_callocN(sizeof(*tnorms) * (size_t)numVerts, "tnorms");
- float (*fnors)[3] = (faceNors_r) ? faceNors_r : MEM_callocN(sizeof(*fnors) * (size_t)numFaces, "meshnormals");
+ float (*fnors)[3] = (r_faceNors) ? r_faceNors : MEM_callocN(sizeof(*fnors) * (size_t)numFaces, "meshnormals");
int i;
for (i = 0; i < numFaces; i++) {
MFace *mf = &mfaces[i];
float *f_no = fnors[i];
float *n4 = (mf->v4) ? tnorms[mf->v4] : NULL;
- float *c4 = (mf->v4) ? mverts[mf->v4].co : NULL;
+ const float *c4 = (mf->v4) ? mverts[mf->v4].co : NULL;
if (mf->v4)
normal_quad_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
@@ -312,7 +312,7 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces,
MEM_freeN(tnorms);
- if (fnors != faceNors_r)
+ if (fnors != r_faceNors)
MEM_freeN(fnors);
}
@@ -574,6 +574,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdg
#undef IS_EDGE_SHARP
}
+
/** \} */
@@ -737,8 +738,8 @@ static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart,
MVert *mvert, float normal[3])
{
const int nverts = mpoly->totloop;
- float const *v_prev = mvert[loopstart[nverts - 1].v].co;
- float const *v_curr;
+ const float *v_prev = mvert[loopstart[nverts - 1].v].co;
+ const float *v_curr;
int i;
zero_v3(normal);
@@ -787,8 +788,8 @@ static void mesh_calc_ngon_normal_coords(MPoly *mpoly, MLoop *loopstart,
const float (*vertex_coords)[3], float normal[3])
{
const int nverts = mpoly->totloop;
- float const *v_prev = vertex_coords[loopstart[nverts - 1].v];
- float const *v_curr;
+ const float *v_prev = vertex_coords[loopstart[nverts - 1].v];
+ const float *v_curr;
int i;
zero_v3(normal);
@@ -871,7 +872,7 @@ void BKE_mesh_calc_poly_center(MPoly *mpoly, MLoop *loopstart,
/* note, passing polynormal is only a speedup so we can skip calculating it */
float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
- MVert *mvarray, const float polynormal[3])
+ MVert *mvarray)
{
if (mpoly->totloop == 3) {
return area_tri_v3(mvarray[loopstart[0].v].co,
@@ -889,22 +890,16 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
else {
int i;
MLoop *l_iter = loopstart;
- float area, polynorm_local[3];
+ float area;
float (*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
- const float *no = polynormal ? polynormal : polynorm_local;
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co);
}
- /* need normal for area_poly_v3 as well */
- if (polynormal == NULL) {
- BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, polynorm_local);
- }
-
/* finally calculate the area */
- area = area_poly_v3(mpoly->totloop, vertexcos, no);
+ area = area_poly_v3((const float (*)[3])vertexcos, (unsigned int)mpoly->totloop);
return area;
}
@@ -1103,7 +1098,8 @@ void BKE_mesh_loops_to_mface_corners(
const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */
const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */
const bool hasPCol, /* CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL) */
- const bool hasOrigSpace /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
+ const bool hasOrigSpace, /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
+ const bool hasLNor /* CustomData_has_layer(ldata, CD_NORMAL) */
)
{
MTFace *texface;
@@ -1152,6 +1148,14 @@ void BKE_mesh_loops_to_mface_corners(
copy_v2_v2(of->uv[j], lof->uv);
}
}
+
+ if (hasLNor) {
+ short (*tlnors)[3] = CustomData_get(fdata, findex, CD_TESSLOOPNORMAL);
+
+ for (j = 0; j < mf_len; j++) {
+ normal_float_to_short_v3(tlnors[j], CustomData_get(ldata, (int)lindex[j], CD_NORMAL));
+ }
+ }
}
/**
@@ -1172,8 +1176,9 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
+ const bool hasLoopNormal = CustomData_has_layer(ldata, CD_NORMAL);
int findex, i, j;
- int *pidx;
+ const int *pidx;
unsigned int (*lidx)[4];
for (i = 0; i < numTex; i++) {
@@ -1225,6 +1230,17 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData
}
}
}
+
+ if (hasLoopNormal) {
+ short (*fnors)[4][3] = CustomData_get_layer(fdata, CD_TESSLOOPNORMAL);
+ float (*lnors)[3] = CustomData_get_layer(ldata, CD_NORMAL);
+
+ for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, fnors++) {
+ for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
+ normal_float_to_short_v3((*fnors)[j], lnors[(*lidx)[j]]);
+ }
+ }
+ }
}
/**
@@ -1516,6 +1532,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
+ const bool hasLNor = CustomData_has_layer(ldata, CD_NORMAL);
/* over-alloc, ngons will be skipped */
mface = MEM_mallocN(sizeof(*mface) * (size_t)totpoly, __func__);
@@ -1575,7 +1592,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
lindex, k, i, 3,
- numTex, numCol, hasPCol, hasOrigSpace);
+ numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
test_index_face(mf, fdata, k, 3);
}
else {
@@ -1595,7 +1612,7 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
lindex, k, i, 4,
- numTex, numCol, hasPCol, hasOrigSpace);
+ numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
test_index_face(mf, fdata, k, 4);
}
@@ -1651,6 +1668,16 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata,
}
}
+ if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) {
+ float (*lnors)[3] = CustomData_get(ldata, loopstart, CD_NORMAL);
+ short (*tlnors)[3] = CustomData_get(fdata, findex, CD_TESSLOOPNORMAL);
+ const int max = mf->v4 ? 4 : 3;
+
+ for (i = 0; i < max; i++, lnors++, tlnors++) {
+ normal_short_to_float_v3(*lnors, *tlnors);
+ }
+ }
+
if (CustomData_has_layer(fdata, CD_MDISPS)) {
MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS);
MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS);
@@ -1733,8 +1760,8 @@ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
int totedge_i, int totface_i, int totloop_i, int totpoly_i,
MEdge *medge, MFace *mface,
- int *totloop_r, int *totpoly_r,
- MLoop **mloop_r, MPoly **mpoly_r)
+ int *r_totloop, int *r_totpoly,
+ MLoop **r_mloop, MPoly **r_mpoly)
{
MFace *mf;
MLoop *ml, *mloop;
@@ -1744,6 +1771,9 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData
int numTex, numCol;
int i, j, totloop, totpoly, *polyindex;
+ /* old flag, clear to allow for reuse */
+#define ME_FGON (1 << 3)
+
/* just in case some of these layers are filled in (can happen with python created meshes) */
CustomData_free(ldata, totloop_i);
CustomData_free(pdata, totpoly_i);
@@ -1828,10 +1858,13 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData
BLI_edgehash_free(eh, NULL);
- *totpoly_r = totpoly;
- *totloop_r = totloop;
- *mpoly_r = mpoly;
- *mloop_r = mloop;
+ *r_totpoly = totpoly;
+ *r_totloop = totloop;
+ *r_mpoly = mpoly;
+ *r_mloop = mloop;
+
+#undef ME_FGON
+
}
/** \} */
@@ -1990,13 +2023,13 @@ void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(to
i = totpoly;
for (mp = mpoly; i--; mp++) {
if ((mp->flag & ME_HIDE) == 0) {
- int ok = TRUE;
+ bool ok = true;
const MLoop *ml;
int j;
j = mp->totloop;
for (ml = &mloop[mp->loopstart]; j--; ml++) {
if ((mvert[ml->v].flag & SELECT) == 0) {
- ok = FALSE;
+ ok = false;
break;
}
}
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 94f29b5b1a4..65c576dd6a0 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -29,7 +29,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
@@ -426,7 +425,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) {
/* loop over poly users */
const MeshElemMap *map_ele = &edge_poly_map[ml->e];
- int *p = map_ele->indices;
+ const int *p = map_ele->indices;
int i = map_ele->count;
if (!(medge[ml->e].flag & ME_SHARP)) {
for (; i--; p++) {
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 7b56784b1dd..858fe83b43f 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -73,7 +73,7 @@ typedef struct SortPoly {
int numverts;
int loopstart;
unsigned int index;
- int invalid; /* Poly index. */
+ bool invalid; /* Poly index. */
} SortPoly;
static void edge_store_assign(uint32_t verts[2], const uint32_t v1, const uint32_t v2)
@@ -256,7 +256,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
for (i = 1; i < totvert; i++, mv++) {
- int fix_normal = TRUE;
+ bool fix_normal = true;
for (j = 0; j < 3; j++) {
if (!finite(mv->co[j])) {
@@ -265,25 +265,25 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (do_fixes) {
zero_v3(mv->co);
- verts_fixed = TRUE;
+ verts_fixed = true;
}
}
if (mv->no[j] != 0)
- fix_normal = FALSE;
+ fix_normal = false;
}
if (fix_normal) {
PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal\n", i);
if (do_fixes) {
mv->no[2] = SHRT_MAX;
- verts_fixed = TRUE;
+ verts_fixed = true;
}
}
}
for (i = 0, me = medges; i < totedge; i++, me++) {
- int remove = FALSE;
+ bool remove = false;
if (me->v1 == me->v2) {
PRINT_ERR("\tEdge %u: has matching verts, both %u\n", i, me->v1);
remove = do_fixes;
@@ -303,7 +303,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
remove = do_fixes;
}
- if (remove == FALSE) {
+ if (remove == false) {
BLI_edgehash_insert(edge_hash, me->v1, me->v2, SET_INT_IN_POINTER(i));
}
else {
@@ -312,7 +312,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
if (mfaces && !mpolys) {
-# define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; do_face_free = TRUE; } (void)0
+# define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; do_face_free = true; } (void)0
# define CHECK_FACE_VERT_INDEX(a, b) \
if (mf->a == mf->b) { \
PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \
@@ -322,7 +322,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
" (%u,%u) is missing edge data\n", i, mf->a, mf->b); \
- do_edge_recalc = TRUE; \
+ do_edge_recalc = true; \
} (void)0
MFace *mf;
@@ -336,7 +336,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("No Polys, only tesselated Faces\n");
for (i = 0, mf = mfaces, sf = sort_faces; i < totface; i++, mf++) {
- int remove = FALSE;
+ bool remove = false;
int fidx;
unsigned int fv[4];
@@ -349,7 +349,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
} while (fidx--);
- if (remove == FALSE) {
+ if (remove == false) {
if (mf->v4) {
CHECK_FACE_VERT_INDEX(v1, v2);
CHECK_FACE_VERT_INDEX(v1, v3);
@@ -367,7 +367,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
CHECK_FACE_VERT_INDEX(v2, v3);
}
- if (remove == FALSE) {
+ if (remove == false) {
if (totedge) {
if (mf->v4) {
CHECK_FACE_EDGE(v1, v2);
@@ -411,7 +411,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
sf++;
for (i = 1; i < totsortface; i++, sf++) {
- int remove = FALSE;
+ bool remove = false;
/* on a valid mesh, code below will never run */
if (memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) {
@@ -475,18 +475,18 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Invalid loop data. */
PRINT_ERR("\tPoly %u is invalid (loopstart: %u, totloop: %u)\n",
sp->index, mp->loopstart, mp->totloop);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
else if (mp->loopstart + mp->totloop > totloop) {
/* Invalid loop data. */
PRINT_ERR("\tPoly %u uses loops out of range (loopstart: %u, loopend: %u, max nbr of loops: %u)\n",
sp->index, mp->loopstart, mp->loopstart + mp->totloop - 1, totloop - 1);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
else {
/* Poly itself is valid, for now. */
int v1, v2; /* v1 is prev loop vert idx, v2 is current loop one. */
- sp->invalid = FALSE;
+ sp->invalid = false;
sp->verts = v = MEM_mallocN(sizeof(int) * mp->totloop, "Vert idx of SortPoly");
sp->numverts = mp->totloop;
sp->loopstart = mp->loopstart;
@@ -496,7 +496,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (ml->v >= totvert) {
/* Invalid vert idx. */
PRINT_ERR("\tLoop %u has invalid vert reference (%u)\n", sp->loopstart + j, ml->v);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
mverts[ml->v].flag |= ME_VERT_TMP_TAG;
@@ -509,7 +509,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
for (j = 0; j < mp->totloop; j++, v++) {
if ((mverts[*v].flag & ME_VERT_TMP_TAG) == 0) {
PRINT_ERR("\tPoly %u has duplicate vert reference at corner (%u)\n", i, j);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
mverts[*v].flag &= ~ME_VERT_TMP_TAG;
}
@@ -526,9 +526,9 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Edge not existing. */
PRINT_ERR("\tPoly %u needs missing edge (%u, %u)\n", sp->index, v1, v2);
if (do_fixes)
- do_edge_recalc = TRUE;
+ do_edge_recalc = true;
else
- sp->invalid = TRUE;
+ sp->invalid = true;
}
else if (ml->e >= totedge) {
/* Invalid edge idx.
@@ -541,7 +541,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
else {
PRINT_ERR("\tLoop %u has invalid edge reference (%u)\n", sp->loopstart + j, ml->e);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
}
else {
@@ -557,7 +557,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
else {
PRINT_ERR("\tPoly %u has invalid edge reference (%u)\n", sp->index, ml->e);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
}
}
@@ -565,7 +565,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Now check that that poly does not use a same vertex more than once! */
if (!sp->invalid) {
- int *prev_v = v = sp->verts;
+ const int *prev_v = v = sp->verts;
j = sp->numverts;
qsort(sp->verts, j, sizeof(int), int_cmp);
@@ -576,7 +576,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (dlt > 1) {
PRINT_ERR("\tPoly %u is invalid, it multi-uses vertex %u (%u times)\n",
sp->index, *prev_v, dlt);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
prev_v = v;
}
@@ -584,7 +584,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (v - prev_v > 1) { /* Don't forget final verts! */
PRINT_ERR("\tPoly %u is invalid, it multi-uses vertex %u (%u times)\n",
sp->index, *prev_v, (int)(v - prev_v));
- sp->invalid = TRUE;
+ sp->invalid = true;
}
}
@@ -598,8 +598,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
for (i = 1; i < totpoly; i++, sp++) {
int p1_nv = sp->numverts, p2_nv = prev_sp->numverts;
- int *p1_v = sp->verts, *p2_v = prev_sp->verts;
- short p1_sub = TRUE, p2_sub = TRUE;
+ const int *p1_v = sp->verts, *p2_v = prev_sp->verts;
+ short p1_sub = true, p2_sub = true;
if (sp->invalid)
break;
/* Test same polys. */
@@ -616,13 +616,13 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
while ((p1_nv && p2_nv) && (p1_sub || p2_sub)) {
if (*p1_v < *p2_v) {
if (p1_sub)
- p1_sub = FALSE;
+ p1_sub = false;
p1_nv--;
p1_v++;
}
else if (*p2_v < *p1_v) {
if (p2_sub)
- p2_sub = FALSE;
+ p2_sub = false;
p2_nv--;
p2_v++;
}
@@ -635,23 +635,23 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
}
if (p1_nv && p1_sub)
- p1_sub = FALSE;
+ p1_sub = false;
else if (p2_nv && p2_sub)
- p2_sub = FALSE;
+ p2_sub = false;
if (p1_sub && p2_sub) {
PRINT("\tPolys %u and %u use same vertices, considering poly %u as invalid.\n",
prev_sp->index, sp->index, sp->index);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
/* XXX In fact, these might be valid? :/ */
else if (p1_sub) {
PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", sp->index, prev_sp->index);
- sp->invalid = TRUE;
+ sp->invalid = true;
}
else if (p2_sub) {
PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", prev_sp->index, sp->index);
- prev_sp->invalid = TRUE;
+ prev_sp->invalid = true;
prev_sp = sp; /* sp is new reference poly. */
}
#else
@@ -670,7 +670,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
else {
is_valid = false;
}
- sp->invalid = TRUE;
+ sp->invalid = true;
}
#endif
else {
@@ -755,14 +755,14 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
dw->weight = 0.0f;
- vert_weights_fixed = TRUE;
+ vert_weights_fixed = true;
}
}
else if (dw->weight < 0.0f || dw->weight > 1.0f) {
PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
CLAMP(dw->weight, 0.0f, 1.0f);
- vert_weights_fixed = TRUE;
+ vert_weights_fixed = true;
}
}
@@ -776,7 +776,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
j--;
dw = dv->dw + j;
- vert_weights_fixed = TRUE;
+ vert_weights_fixed = true;
}
else { /* all freed */
break;
@@ -812,7 +812,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (mesh && mesh->mselect) {
MSelect *msel;
- int free_msel = FALSE;
+ bool free_msel = false;
for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) {
int tot_elem = 0;
@@ -820,7 +820,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (msel->index < 0) {
PRINT_ERR("\tMesh select element %d type %d index is negative, "
"resetting selection stack.\n", i, msel->type);
- free_msel = TRUE;
+ free_msel = true;
break;
}
@@ -840,7 +840,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("\tMesh select element %d type %d index %d is larger than data array size %d, "
"resetting selection stack.\n", i, msel->type, msel->index, tot_elem);
- free_msel = TRUE;
+ free_msel = true;
break;
}
}
@@ -1095,12 +1095,12 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
int *new_idx = MEM_mallocN(sizeof(int) * me->totloop, __func__);
for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
- int invalid = FALSE;
+ bool invalid = false;
int i = p->loopstart;
int stop = i + p->totloop;
if (stop > me->totloop || stop < i) {
- invalid = TRUE;
+ invalid = true;
}
else {
l = &me->mloop[i];
@@ -1108,7 +1108,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
/* If one of the poly's loops is invalid, the whole poly is invalid! */
for (; i--; l++) {
if (l->e == INVALID_LOOP_EDGE_MARKER) {
- invalid = TRUE;
+ invalid = true;
break;
}
}
@@ -1431,7 +1431,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
med = CustomData_get_layer(&edata, CD_MEDGE);
for (ehi = BLI_edgehashIterator_new(eh), i = 0;
- BLI_edgehashIterator_isDone(ehi) == FALSE;
+ BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), ++i, ++med)
{
if (update && (med_orig = BLI_edgehashIterator_getValue(ehi))) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index f9a0d462ac0..563831616de 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -57,7 +57,6 @@
#include "BLF_translation.h"
-#include "BKE_cloth.h"
#include "BKE_key.h"
#include "BKE_multires.h"
#include "BKE_DerivedMesh.h"
@@ -173,12 +172,12 @@ bool modifier_isPreview(ModifierData *md)
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (!(mti->flags & eModifierTypeFlag_UsesPreview))
- return FALSE;
+ return false;
if (md->mode & eModifierMode_Realtime)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
ModifierData *modifiers_findByType(Object *ob, ModifierType type)
@@ -337,15 +336,15 @@ void modifier_setError(ModifierData *md, const char *_format, ...)
* then is NULL)
* also used for some mesh tools to give warnings
*/
-int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCageIndex_r, int virtual_)
+int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
{
VirtualModifierData virtualModifierData;
- ModifierData *md = (virtual_) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
+ ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
int i, cageIndex = -1;
- if (lastPossibleCageIndex_r) {
+ if (r_lastPossibleCageIndex) {
/* ensure the value is initialized */
- *lastPossibleCageIndex_r = -1;
+ *r_lastPossibleCageIndex = -1;
}
/* Find the last modifier acting on the cage. */
@@ -354,8 +353,6 @@ int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCag
md->scene = scene;
- if (!(md->mode & eModifierMode_Realtime)) continue;
- if (!(md->mode & eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
if (md->mode & eModifierMode_DisableTemporary) continue;
@@ -363,7 +360,13 @@ int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCag
if (!modifier_supportsMapping(md))
break;
- if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i;
+ if (r_lastPossibleCageIndex) {
+ *r_lastPossibleCageIndex = i;
+ }
+
+ if (!(md->mode & eModifierMode_Realtime)) continue;
+ if (!(md->mode & eModifierMode_Editmode)) continue;
+
if (md->mode & eModifierMode_OnCage)
cageIndex = i;
}
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index a9ff569e70a..c1726da32ae 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -33,9 +33,6 @@
#include "BLI_math.h"
#include "BLI_alloca.h"
-#include "DNA_object_types.h"
-
-
#include "BKE_DerivedMesh.h"
#include "BKE_editmesh.h"
@@ -79,7 +76,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
int cd_edge_bweight_offset;
int cd_edge_crease_offset;
- if (is_init == FALSE) {
+ if (is_init == false) {
/* check if we have an origflag */
has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0;
has_orig_hflag |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0;
@@ -104,8 +101,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
totedge = dm->getNumEdges(dm);
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
- vtable = MEM_callocN(sizeof(void **) * totvert, __func__);
- etable = MEM_callocN(sizeof(void **) * totedge, __func__);
+ vtable = MEM_mallocN(sizeof(*vtable) * totvert, __func__);
+ etable = MEM_mallocN(sizeof(*etable) * totedge, __func__);
/*do verts*/
mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm);
@@ -176,7 +173,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
/* Save index of correspsonding MLoop */
- CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, j++, &l_iter->head.data, true);
+ CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, j, &l_iter->head.data, true);
+ BM_elem_index_set(l_iter, j++); /* set_inline */
} while ((l_iter = l_iter->next) != l_first);
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
@@ -195,7 +193,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
*orig_index = ORIGINDEX_NONE;
}
}
- if (is_init) bm->elem_index_dirty &= ~BM_FACE;
+ if (is_init) bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
MEM_freeN(vtable);
MEM_freeN(etable);
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 39c3b96f66e..35bf453c328 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -41,11 +41,6 @@
#include <time.h>
-#ifdef _WIN32
-# define open _open
-# define close _close
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_constraint_types.h"
@@ -65,7 +60,6 @@
#include "BLI_threads.h"
#include "BKE_animsys.h"
-#include "BKE_constraint.h"
#include "BKE_colortools.h"
#include "BKE_library.h"
#include "BKE_global.h"
@@ -74,7 +68,6 @@
#include "BKE_node.h"
#include "BKE_image.h" /* openanim */
#include "BKE_tracking.h"
-#include "BKE_sequencer.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
@@ -206,7 +199,8 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
{
struct ImBuf *ibuf;
char name[FILE_MAX];
- int loadflag, use_proxy = FALSE;
+ int loadflag;
+ bool use_proxy = false;
char *colorspace;
use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
@@ -214,8 +208,17 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
get_proxy_fname(clip, user->render_size, undistort, framenr, name);
- /* proxies were built using default color space settings */
- colorspace = NULL;
+ /* Well, this is a bit weird, but proxies for movie sources
+ * are built in the same exact color space as the input,
+ *
+ * But image sequences are built in the display space.
+ */
+ if (clip->source == MCLIP_SRC_MOVIE) {
+ colorspace = clip->colorspace_settings.name;
+ }
+ else {
+ colorspace = NULL;
+ }
}
else {
get_sequence_fname(clip, framenr, name);
@@ -270,17 +273,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in
movieclip_open_anim_file(clip);
if (clip->anim) {
- int dur;
- int fra;
-
- dur = IMB_anim_get_duration(clip->anim, tc);
- fra = framenr - clip->start_frame + clip->frame_offset;
-
- if (fra < 0)
- fra = 0;
-
- if (fra > (dur - 1))
- fra = dur - 1;
+ int fra = framenr - clip->start_frame + clip->frame_offset;
ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
}
@@ -335,8 +328,10 @@ typedef struct MovieClipCache {
/* cache for undistorted shot */
float principal[2];
- float k1, k2, k3;
- short undistortion_used;
+ float polynomial_k1, polynomial_k2, polynomial_k3;
+ float division_k1, division_k2;
+ short distortion_model;
+ bool undistortion_used;
int proxy;
short render_flag;
@@ -501,7 +496,7 @@ static bool has_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
return IMB_moviecache_has_frame(clip->cache->moviecache, &key);
}
- return FALSE;
+ return false;
}
static bool put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag, bool destructive)
@@ -624,7 +619,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
- if (file < 0)
+ if (file == -1)
return NULL;
close(file);
@@ -726,19 +721,29 @@ static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag)
return result;
}
-static int check_undistortion_cache_flags(MovieClip *clip)
+static bool check_undistortion_cache_flags(MovieClip *clip)
{
MovieClipCache *cache = clip->cache;
MovieTrackingCamera *camera = &clip->tracking.camera;
/* check for distortion model changes */
- if (!equals_v2v2(camera->principal, cache->postprocessed.principal))
- return FALSE;
+ if (!equals_v2v2(camera->principal, cache->postprocessed.principal)) {
+ return false;
+ }
- if (!equals_v3v3(&camera->k1, &cache->postprocessed.k1))
- return FALSE;
+ if (camera->distortion_model != cache->postprocessed.distortion_model) {
+ return false;
+ }
- return TRUE;
+ if (!equals_v3v3(&camera->k1, &cache->postprocessed.polynomial_k1)) {
+ return false;
+ }
+
+ if (!equals_v2v2(&camera->division_k1, &cache->postprocessed.division_k1)) {
+ return false;
+ }
+
+ return true;
}
static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag)
@@ -823,12 +828,14 @@ static void put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *use
}
if (need_undistortion_postprocess(user)) {
+ cache->postprocessed.distortion_model = camera->distortion_model;
copy_v2_v2(cache->postprocessed.principal, camera->principal);
- copy_v3_v3(&cache->postprocessed.k1, &camera->k1);
- cache->postprocessed.undistortion_used = TRUE;
+ copy_v3_v3(&cache->postprocessed.polynomial_k1, &camera->k1);
+ copy_v2_v2(&cache->postprocessed.division_k1, &camera->division_k1);
+ cache->postprocessed.undistortion_used = true;
}
else {
- cache->postprocessed.undistortion_used = FALSE;
+ cache->postprocessed.undistortion_used = false;
}
IMB_refImBuf(ibuf);
@@ -843,7 +850,8 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
int postprocess_flag, int cache_flag)
{
ImBuf *ibuf = NULL;
- int framenr = user->framenr, need_postprocess = FALSE;
+ int framenr = user->framenr;
+ bool need_postprocess = false;
/* cache isn't threadsafe itself and also loading of movies
* can't happen from concurent threads that's why we use lock here */
@@ -854,14 +862,14 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag);
if (!ibuf)
- need_postprocess = TRUE;
+ need_postprocess = true;
}
if (!ibuf)
ibuf = get_imbuf_cache(clip, user, flag);
if (!ibuf) {
- int use_sequence = FALSE;
+ bool use_sequence = false;
/* undistorted proxies for movies should be read as image sequence */
use_sequence = (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) &&
@@ -1064,10 +1072,10 @@ bool BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
if (ibuf) {
IMB_freeImBuf(ibuf);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
@@ -1180,7 +1188,7 @@ void BKE_movieclip_reload(MovieClip *clip)
/* clear cache */
free_buffers(clip);
- clip->tracking.stabilization.ok = FALSE;
+ clip->tracking.stabilization.ok = false;
/* update clip source */
detect_clip_source(clip);
@@ -1220,7 +1228,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->marker = NULL;
scopes->track = NULL;
- scopes->track_locked = TRUE;
+ scopes->track_locked = true;
if (clip) {
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
@@ -1234,15 +1242,14 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->track = track;
if (marker->flag & MARKER_DISABLED) {
- scopes->track_disabled = TRUE;
+ scopes->track_disabled = true;
}
else {
ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
- scopes->track_disabled = FALSE;
+ scopes->track_disabled = false;
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
- ImBuf *search_ibuf;
MovieTrackingMarker undist_marker = *marker;
if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
@@ -1260,16 +1267,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
undist_marker.pos[1] /= height * aspy;
}
- search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE);
-
- if (search_ibuf) {
- if (!search_ibuf->rect_float) {
- /* sampling happens in float buffer */
- IMB_float_from_rect(search_ibuf);
- }
-
- scopes->track_search = search_ibuf;
- }
+ scopes->track_search = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, true, true);
scopes->undist_marker = undist_marker;
@@ -1285,7 +1283,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
if ((track->flag & TRACK_LOCKED) == 0) {
float pat_min[2], pat_max[2];
- scopes->track_locked = FALSE;
+ scopes->track_locked = false;
/* XXX: would work fine with non-transformed patterns, but would likely fail
* with transformed patterns, but that would be easier to debug when
@@ -1299,7 +1297,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
}
scopes->framenr = user->framenr;
- scopes->ok = TRUE;
+ scopes->ok = true;
}
static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, bool undistorted, bool threaded)
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index cba905ad487..3d8e35699a9 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -439,7 +439,7 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm
/* Create DerivedMesh for deformation modifier */
dm = get_multires_dm(scene, mmd, ob);
numVerts = dm->getNumVerts(dm);
- deformedVerts = MEM_callocN(sizeof(float) * numVerts * 3, "multiresReshape_deformVerts");
+ deformedVerts = MEM_mallocN(sizeof(float[3]) * numVerts, "multiresReshape_deformVerts");
dm->getVertCos(dm, deformedVerts);
mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0);
@@ -699,7 +699,7 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
multires_set_tot_level(ob, mmd, lvl);
}
-static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, int alloc_paint_mask)
+static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask)
{
MultiresModifierData mmd = {{NULL}};
MultiresFlags flags = MULTIRES_USE_LOCAL_MMD;
@@ -1302,7 +1302,7 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
}
totlvl = mmd->totlvl;
- ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, FALSE);
+ ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false);
subsurf = subsurf_dm_create_local(ob, dm, totlvl,
mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c
index 3c499908bf7..64d59b165e1 100644
--- a/source/blender/blenkernel/intern/navmesh_conversion.c
+++ b/source/blender/blenkernel/intern/navmesh_conversion.c
@@ -123,7 +123,7 @@ int buildRawVertIndicesData(DerivedMesh *dm, int *nverts_r, float **verts_r,
printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff);
return 0;
}
- verts = MEM_callocN(sizeof(float) * 3 * nverts, "buildRawVertIndicesData verts");
+ verts = MEM_mallocN(sizeof(float[3]) * nverts, "buildRawVertIndicesData verts");
dm->getVertCos(dm, (float(*)[3])verts);
/* flip coordinates */
@@ -400,7 +400,7 @@ int buildNavMeshData(const int nverts, const float *verts,
if (curpolyidx != prevpolyidx) {
if (curpolyidx != prevpolyidx + 1) {
printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n");
- return 0;
+ goto fail;
}
dmesh = dmesh == NULL ? dmeshes : dmesh + 4;
dmesh[2] = (unsigned short)i; /* tbase */
@@ -427,6 +427,12 @@ int buildNavMeshData(const int nverts, const float *verts,
*dtrisToTrisMap_r = dtrisToTrisMap;
return 1;
+
+fail:
+ MEM_freeN(dmeshes);
+ MEM_freeN(dtrisToPolysMap);
+ MEM_freeN(dtrisToTrisMap);
+ return 0;
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 06a12bdade1..0c244e8a40b 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -157,8 +157,10 @@ void free_nladata(ListBase *tracks)
/* Copying ------------------------------------------- */
-/* Copy NLA strip */
-NlaStrip *copy_nlastrip(NlaStrip *strip)
+/* Copy NLA strip
+ * < use_same_action: if true, the existing action is used (instead of being duplicated)
+ */
+NlaStrip *copy_nlastrip(NlaStrip *strip, const bool use_same_action)
{
NlaStrip *strip_d;
NlaStrip *cs, *cs_d;
@@ -171,9 +173,17 @@ NlaStrip *copy_nlastrip(NlaStrip *strip)
strip_d = MEM_dupallocN(strip);
strip_d->next = strip_d->prev = NULL;
- /* increase user-count of action */
- if (strip_d->act)
- id_us_plus(&strip_d->act->id);
+ /* handle action */
+ if (strip_d->act) {
+ if (use_same_action) {
+ /* increase user-count of action */
+ id_us_plus(&strip_d->act->id);
+ }
+ else {
+ /* use a copy of the action instead (user count shouldn't have changed yet) */
+ strip_d->act = BKE_action_copy(strip_d->act);
+ }
+ }
/* copy F-Curves and modifiers */
copy_fcurves(&strip_d->fcurves, &strip->fcurves);
@@ -183,7 +193,7 @@ NlaStrip *copy_nlastrip(NlaStrip *strip)
BLI_listbase_clear(&strip_d->strips);
for (cs = strip->strips.first; cs; cs = cs->next) {
- cs_d = copy_nlastrip(cs);
+ cs_d = copy_nlastrip(cs, use_same_action);
BLI_addtail(&strip_d->strips, cs_d);
}
@@ -192,7 +202,7 @@ NlaStrip *copy_nlastrip(NlaStrip *strip)
}
/* Copy NLA Track */
-NlaTrack *copy_nlatrack(NlaTrack *nlt)
+NlaTrack *copy_nlatrack(NlaTrack *nlt, const bool use_same_actions)
{
NlaStrip *strip, *strip_d;
NlaTrack *nlt_d;
@@ -209,7 +219,7 @@ NlaTrack *copy_nlatrack(NlaTrack *nlt)
BLI_listbase_clear(&nlt_d->strips);
for (strip = nlt->strips.first; strip; strip = strip->next) {
- strip_d = copy_nlastrip(strip);
+ strip_d = copy_nlastrip(strip, use_same_actions);
BLI_addtail(&nlt_d->strips, strip_d);
}
@@ -232,7 +242,8 @@ void copy_nladata(ListBase *dst, ListBase *src)
/* copy each NLA-track, one at a time */
for (nlt = src->first; nlt; nlt = nlt->next) {
/* make a copy, and add the copy to the destination list */
- nlt_d = copy_nlatrack(nlt);
+ // XXX: we need to fix this sometime
+ nlt_d = copy_nlatrack(nlt, true);
BLI_addtail(dst, nlt_d);
}
}
@@ -626,10 +637,10 @@ void BKE_nlastrips_sort_strips(ListBase *strips)
/* Add the given NLA-Strip to the given list of strips, assuming that it
* isn't currently a member of another list
*/
-short BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
+bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
{
NlaStrip *ns;
- short not_added = 1;
+ bool not_added = true;
/* sanity checks */
if (ELEM(NULL, strips, strip))
@@ -664,7 +675,7 @@ short BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
* contained within 'Meta-Strips' which act as strips which contain strips.
* temp: are the meta-strips to be created 'temporary' ones used for transforms?
*/
-void BKE_nlastrips_make_metas(ListBase *strips, short temp)
+void BKE_nlastrips_make_metas(ListBase *strips, bool is_temp)
{
NlaStrip *mstrip = NULL;
NlaStrip *strip, *stripn;
@@ -689,7 +700,7 @@ void BKE_nlastrips_make_metas(ListBase *strips, short temp)
mstrip->flag = NLASTRIP_FLAG_SELECT;
/* set temp flag if appropriate (i.e. for transform-type editing) */
- if (temp)
+ if (is_temp)
mstrip->flag |= NLASTRIP_FLAG_TEMP_META;
/* set default repeat/scale values to prevent warnings */
@@ -741,7 +752,7 @@ void BKE_nlastrips_clear_metastrip(ListBase *strips, NlaStrip *strip)
* sel: only consider selected meta-strips, otherwise all meta-strips are removed
* onlyTemp: only remove the 'temporary' meta-strips used for transforms
*/
-void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp)
+void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp)
{
NlaStrip *strip, *stripn;
@@ -756,8 +767,8 @@ void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp)
/* check if strip is a meta-strip */
if (strip->type == NLASTRIP_TYPE_META) {
/* if check if selection and 'temporary-only' considerations are met */
- if ((onlySel == 0) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
- if ((!onlyTemp) || (strip->flag & NLASTRIP_FLAG_TEMP_META)) {
+ if ((!only_sel) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
+ if ((!only_temp) || (strip->flag & NLASTRIP_FLAG_TEMP_META)) {
BKE_nlastrips_clear_metastrip(strips, strip);
}
}
@@ -768,7 +779,7 @@ void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp)
/* Add the given NLA-Strip to the given Meta-Strip, assuming that the
* strip isn't attached to any list of strips
*/
-short BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
+bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, mstrip, strip))
@@ -1002,7 +1013,7 @@ void BKE_nlatrack_sort_strips(NlaTrack *nlt)
/* Add the given NLA-Strip to the given NLA-Track, assuming that it
* isn't currently attached to another one
*/
-short BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
+bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, nlt, strip))
@@ -1015,7 +1026,7 @@ short BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
/* Get the extents of the given NLA-Track including gaps between strips,
* returning whether this succeeded or not
*/
-short BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
+bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
{
NlaStrip *strip;
@@ -1085,7 +1096,7 @@ void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
/* Does the given NLA-strip fall within the given bounds (times)? */
-short BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
+bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
{
const float stripLen = (strip) ? strip->end - strip->start : 0.0f;
const float boundsLen = fabsf(max - min);
@@ -1220,7 +1231,7 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
/* Animated Strips ------------------------------------------- */
/* Check if the given NLA-Track has any strips with own F-Curves */
-short BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
+bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
{
NlaStrip *strip;
@@ -1239,7 +1250,7 @@ short BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
}
/* Check if given NLA-Tracks have any strips with own F-Curves */
-short BKE_nlatracks_have_animated_strips(ListBase *tracks)
+bool BKE_nlatracks_have_animated_strips(ListBase *tracks)
{
NlaTrack *nlt;
@@ -1567,7 +1578,7 @@ void BKE_nla_action_pushdown(AnimData *adt)
/* Find the active strip + track combo, and set them up as the tweaking track,
* and return if successful or not.
*/
-short BKE_nla_tweakmode_enter(AnimData *adt)
+bool BKE_nla_tweakmode_enter(AnimData *adt)
{
NlaTrack *nlt, *activeTrack = NULL;
NlaStrip *strip, *activeStrip = NULL;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index d6225560e32..ce1e34de0b0 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -44,6 +44,7 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_string.h"
#include "BLI_math.h"
@@ -54,11 +55,8 @@
#include "BLF_translation.h"
#include "BKE_animsys.h"
-#include "BKE_action.h"
-#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
-#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -174,6 +172,12 @@ static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode *node, bNodeType *typeinfo)
{
+ /* for nodes saved in older versions storage can get lost, make undefined then */
+ if (node->flag & NODE_INIT) {
+ if (typeinfo->storagename[0] && !node->storage)
+ typeinfo = NULL;
+ }
+
if (typeinfo) {
node->typeinfo = typeinfo;
@@ -1027,16 +1031,16 @@ void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
}
}
-int nodeAttachNodeCheck(bNode *node, bNode *parent)
+bool nodeAttachNodeCheck(bNode *node, bNode *parent)
{
bNode *parent_recurse;
for (parent_recurse = node; parent_recurse; parent_recurse = parent_recurse->parent) {
if (parent_recurse == parent) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
void nodeAttachNode(bNode *node, bNode *parent)
@@ -1044,7 +1048,7 @@ void nodeAttachNode(bNode *node, bNode *parent)
float locx, locy;
BLI_assert(parent->type == NODE_FRAME);
- BLI_assert(nodeAttachNodeCheck(parent, node) == FALSE);
+ BLI_assert(nodeAttachNodeCheck(parent, node) == false);
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
@@ -1114,20 +1118,13 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
if (ntree == NULL) return NULL;
- if (bmain) {
- /* is ntree part of library? */
- if (BLI_findindex(&bmain->nodetree, ntree) != -1)
- newtree = BKE_libblock_copy(&ntree->id);
- else
- newtree = NULL;
+ /* is ntree part of library? */
+ if (bmain && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
+ newtree = BKE_libblock_copy(&ntree->id);
}
- else
- newtree = NULL;
-
- if (newtree == NULL) {
- newtree = MEM_dupallocN(ntree);
+ else {
+ newtree = BKE_libblock_copy_nolib(&ntree->id, true);
newtree->id.lib = NULL; /* same as owning datablock id.lib */
- BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
}
id_us_plus((ID *)newtree->gpd);
@@ -1210,11 +1207,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const bool do_id_user)
{
- return ntreeCopyTree_internal(ntree, G.main, do_id_user, TRUE, TRUE);
+ return ntreeCopyTree_internal(ntree, G.main, do_id_user, true, true);
}
bNodeTree *ntreeCopyTree(bNodeTree *ntree)
{
- return ntreeCopyTree_ex(ntree, TRUE);
+ return ntreeCopyTree_ex(ntree, true);
}
/* use when duplicating scenes */
@@ -1241,7 +1238,7 @@ void ntreeSwitchID_ex(bNodeTree *ntree, ID *id_from, ID *id_to, const bool do_id
}
void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
{
- ntreeSwitchID_ex(ntree, id_from, id_to, TRUE);
+ ntreeSwitchID_ex(ntree, id_from, id_to, true);
}
void ntreeUserIncrefID(bNodeTree *ntree)
@@ -1272,7 +1269,7 @@ int BKE_node_preview_used(bNode *node)
return (node->typeinfo->flag & NODE_PREVIEW) != 0;
}
-bNodePreview *BKE_node_preview_verify(bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, int create)
+bNodePreview *BKE_node_preview_verify(bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create)
{
bNodePreview *preview;
@@ -1786,7 +1783,7 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
/* same as ntreeFreeTree_ex but always manage users */
void ntreeFreeTree(bNodeTree *ntree)
{
- ntreeFreeTree_ex(ntree, TRUE);
+ ntreeFreeTree_ex(ntree, true);
}
void ntreeFreeCache(bNodeTree *ntree)
@@ -1876,6 +1873,7 @@ bNodeTree *ntreeFromID(ID *id)
case ID_WO: return ((World *)id)->nodetree;
case ID_TE: return ((Tex *)id)->nodetree;
case ID_SCE: return ((Scene *)id)->nodetree;
+ case ID_LS: return ((FreestyleLineStyle *)id)->nodetree;
default: return NULL;
}
}
@@ -1883,7 +1881,7 @@ bNodeTree *ntreeFromID(ID *id)
void ntreeMakeLocal(bNodeTree *ntree)
{
Main *bmain = G.main;
- int lib = FALSE, local = FALSE;
+ bool lib = false, local = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -1903,9 +1901,9 @@ void ntreeMakeLocal(bNodeTree *ntree)
for (node = tntree->nodes.first; node; node = node->next) {
if (node->id == (ID *)ntree) {
if (owner_id->lib)
- lib = TRUE;
+ lib = true;
else
- local = TRUE;
+ local = true;
}
}
} FOREACH_NODETREE_END
@@ -1978,7 +1976,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
/* Make full copy.
* Note: previews are not copied here.
*/
- ltree = ntreeCopyTree_internal(ntree, NULL, FALSE, FALSE, FALSE);
+ ltree = ntreeCopyTree_internal(ntree, NULL, false, false, false);
ltree->flag |= NTREE_IS_LOCALIZED;
for (node = ltree->nodes.first; node; node = node->next) {
@@ -2035,7 +2033,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
if (ntree->typeinfo->local_merge)
ntree->typeinfo->local_merge(localtree, ntree);
- ntreeFreeTree_ex(localtree, FALSE);
+ ntreeFreeTree_ex(localtree, false);
MEM_freeN(localtree);
}
}
@@ -2177,7 +2175,7 @@ static void ntree_interface_identifier_base(bNodeTree *ntree, char *base)
{
/* generate a valid RNA identifier */
sprintf(base, "NodeTreeInterface_%s", ntree->id.name + 2);
- RNA_identifier_sanitize(base, FALSE);
+ RNA_identifier_sanitize(base, false);
}
/* check if the identifier is already in use */
@@ -2397,9 +2395,9 @@ bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
for (node = ntree->nodes.first; node; node = node->next) {
if (node->id && GS(node->id->name) == idtype) {
- if (id && ok == FALSE && node->id == id) {
+ if (id && ok == false && node->id == id) {
node->flag |= NODE_ACTIVE_ID;
- ok = TRUE;
+ ok = true;
}
else {
node->flag &= ~NODE_ACTIVE_ID;
@@ -2432,7 +2430,7 @@ void nodeClearActiveID(bNodeTree *ntree, short idtype)
node->flag &= ~NODE_ACTIVE_ID;
}
-void nodeSetSelected(bNode *node, int select)
+void nodeSetSelected(bNode *node, bool select)
{
if (select) {
node->flag |= NODE_SELECT;
@@ -2550,7 +2548,7 @@ void BKE_node_clipboard_clear(void)
#endif
}
-/* return FALSE when one or more ID's are lost */
+/* return false when one or more ID's are lost */
bool BKE_node_clipboard_validate(void)
{
bool ok = true;
@@ -2764,16 +2762,16 @@ void BKE_node_instance_hash_tag(bNodeInstanceHash *UNUSED(hash), void *value)
entry->tag = 1;
}
-int BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key)
+bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key)
{
bNodeInstanceHashEntry *entry = BKE_node_instance_hash_lookup(hash, key);
if (entry) {
entry->tag = 1;
- return TRUE;
+ return true;
}
else
- return FALSE;
+ return false;
}
void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
@@ -2810,7 +2808,7 @@ static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort
bNodeLink *link;
int level = 0xFFF;
- node->done = TRUE;
+ node->done = true;
/* check linked nodes */
for (link = ntree->links.first; link; link = link->next) {
@@ -2847,7 +2845,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in
/* first clear data */
for (node = ntree->nodes.first; node; node = node->next) {
- node->done = FALSE;
+ node->done = false;
(*totnodes)++;
}
if (*totnodes == 0) {
@@ -2872,7 +2870,7 @@ static void ntree_update_node_level(bNodeTree *ntree)
/* first clear tag */
for (node = ntree->nodes.first; node; node = node->next) {
- node->done = FALSE;
+ node->done = false;
}
/* recursive check */
@@ -2944,7 +2942,7 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
/* avoid reentrant updates, can be caused by RNA update callbacks */
if (ntree->is_updating)
return;
- ntree->is_updating = TRUE;
+ ntree->is_updating = true;
if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
/* set the bNodeSocket->link pointers */
@@ -2992,7 +2990,7 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
}
ntree->update = 0;
- ntree->is_updating = FALSE;
+ ntree->is_updating = false;
}
void nodeUpdate(bNodeTree *ntree, bNode *node)
@@ -3000,7 +2998,7 @@ void nodeUpdate(bNodeTree *ntree, bNode *node)
/* avoid reentrant updates, can be caused by RNA update callbacks */
if (ntree->is_updating)
return;
- ntree->is_updating = TRUE;
+ ntree->is_updating = true;
if (node->typeinfo->updatefunc)
node->typeinfo->updatefunc(ntree, node);
@@ -3010,7 +3008,7 @@ void nodeUpdate(bNodeTree *ntree, bNode *node)
/* clear update flag */
node->update = 0;
- ntree->is_updating = FALSE;
+ ntree->is_updating = false;
}
bool nodeUpdateID(bNodeTree *ntree, ID *id)
@@ -3041,7 +3039,7 @@ bool nodeUpdateID(bNodeTree *ntree, ID *id)
nodeUpdateInternalLinks(ntree, node);
}
- ntree->is_updating = FALSE;
+ ntree->is_updating = false;
return changed;
}
@@ -3145,7 +3143,7 @@ static void node_type_base_defaults(bNodeType *ntype)
/* allow this node for any tree type */
static int node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(ntree))
{
- return TRUE;
+ return true;
}
/* use the basic poll function */
@@ -3460,6 +3458,7 @@ static void registerCompositNodes(void)
register_node_type_cmp_mask();
register_node_type_cmp_trackpos();
register_node_type_cmp_planetrackdeform();
+ register_node_type_cmp_cornerpin();
}
static void registerShaderNodes(void)
@@ -3526,6 +3525,7 @@ static void registerShaderNodes(void)
register_node_type_sh_subsurface_scattering();
register_node_type_sh_mix_shader();
register_node_type_sh_add_shader();
+ register_node_type_sh_uvmap();
register_node_type_sh_output_lamp();
register_node_type_sh_output_material();
@@ -3596,9 +3596,9 @@ static void registerTextureNodes(void)
void init_nodesystem(void)
{
- nodetreetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetreetypes_hash gh");
- nodetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetypes_hash gh");
- nodesockettypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodesockettypes_hash gh");
+ nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
+ nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
+ nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh");
register_undefined_types();
@@ -3669,6 +3669,7 @@ void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *b
ntreeiter->tex = bmain->tex.first;
ntreeiter->lamp = bmain->lamp.first;
ntreeiter->world = bmain->world.first;
+ ntreeiter->linestyle = bmain->linestyle.first;
}
bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
bNodeTree **r_nodetree, struct ID **r_id)
@@ -3703,6 +3704,11 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
*r_id = (ID *)ntreeiter->world;
ntreeiter->world = ntreeiter->world->id.next;
}
+ else if (ntreeiter->linestyle) {
+ *r_nodetree = ntreeiter->linestyle->nodetree;
+ *r_id = (ID *)ntreeiter->linestyle;
+ ntreeiter->linestyle = ntreeiter->linestyle->id.next;
+ }
else {
return false;
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index c0336bf9bc7..d99086a626a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -52,7 +52,6 @@
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_smoke_types.h"
-#include "DNA_sound_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
@@ -76,7 +75,6 @@
#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_bullet.h"
-#include "BKE_colortools.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
@@ -88,7 +86,6 @@
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
-#include "BKE_icons.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
@@ -98,7 +95,6 @@
#include "BKE_editmesh.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -273,7 +269,7 @@ void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
if (md->type == eModifierType_Skin) {
/* ensure skin-node customdata exists */
- modifier_skin_customdata_ensure(ob_dst);
+ BKE_mesh_ensure_skin_customdata(ob_dst->data);
}
nmd = modifier_new(md->type);
@@ -331,6 +327,10 @@ void BKE_object_free_derived_caches(Object *ob)
free_path(ob->curve_cache->path);
ob->curve_cache->path = NULL;
}
+
+ /* Signal for viewport to run DAG workarounds. */
+ MEM_freeN(ob->curve_cache);
+ ob->curve_cache = NULL;
}
}
@@ -390,7 +390,7 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
free_controllers(&ob->controllers);
free_actuators(&ob->actuators);
- BKE_free_constraints(&ob->constraints);
+ BKE_constraints_free(&ob->constraints);
free_partdeflect(ob->pd);
BKE_rigidbody_free_object(ob);
@@ -400,7 +400,7 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
if (ob->bsoft) bsbFree(ob->bsoft);
if (ob->gpulamp.first) GPU_lamp_free(ob);
- free_sculptsession(ob);
+ BKE_free_sculptsession(ob);
if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
@@ -496,7 +496,7 @@ void BKE_object_unlink(Object *ob)
bPoseChannel *pchan;
for (pchan = obt->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -527,7 +527,7 @@ void BKE_object_unlink(Object *ob)
sca_remove_ob_poin(obt, ob);
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1002,8 +1002,6 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
ob->margin = 0.04f;
ob->init_state = 1;
ob->state = 1;
- /* ob->pad3 == Contact Processing Threshold */
- ob->m_contactProcessingThreshold = 1.0f;
ob->obstacleRad = 1.0f;
ob->step_height = 0.15f;
ob->jump_speed = 10.0f;
@@ -1045,6 +1043,9 @@ Object *BKE_object_add(Main *bmain, Scene *scene, int type)
return ob;
}
+
+#ifdef WITH_GAMEENGINE
+
void BKE_object_lod_add(Object *ob)
{
LodLevel *lod = MEM_callocN(sizeof(LodLevel), "LoD Level");
@@ -1106,21 +1107,19 @@ bool BKE_object_lod_remove(Object *ob, int level)
return true;
}
-static LodLevel *lod_level_select(Object *ob, const float cam_loc[3])
+static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
{
LodLevel *current = ob->currentlod;
- float ob_loc[3], delta[3];
- float dist_sq;
+ float dist_sq, dist_sq_curr;
if (!current) return NULL;
- copy_v3_v3(ob_loc, ob->obmat[3]);
- sub_v3_v3v3(delta, ob_loc, cam_loc);
- dist_sq = len_squared_v3(delta);
+ dist_sq = len_squared_v3v3(ob->obmat[3], camera_position);
+ dist_sq_curr = current->distance * current->distance;
- if (dist_sq < current->distance * current->distance) {
+ if (dist_sq < dist_sq_curr) {
/* check for higher LoD */
- while (current->prev && dist_sq < (current->distance * current->distance)) {
+ while (current->prev && dist_sq < dist_sq_curr) {
current = current->prev;
}
}
@@ -1140,17 +1139,14 @@ bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
return (ob->mode == OB_MODE_OBJECT || !active);
}
-bool BKE_object_lod_update(Object *ob, float camera_position[3])
+void BKE_object_lod_update(Object *ob, const float camera_position[3])
{
LodLevel *cur_level = ob->currentlod;
LodLevel *new_level = lod_level_select(ob, camera_position);
if (new_level != cur_level) {
ob->currentlod = new_level;
- return true;
}
-
- return false;
}
static Object *lod_ob_get(Object *ob, Scene *scene, int flag)
@@ -1177,7 +1173,10 @@ struct Object *BKE_object_lod_matob_get(Object *ob, Scene *scene)
return lod_ob_get(ob, scene, OB_LOD_USE_MAT);
}
-SoftBody *copy_softbody(SoftBody *sb, int copy_caches)
+#endif /* WITH_GAMEENGINE */
+
+
+SoftBody *copy_softbody(SoftBody *sb, bool copy_caches)
{
SoftBody *sbn;
@@ -1185,7 +1184,7 @@ SoftBody *copy_softbody(SoftBody *sb, int copy_caches)
sbn = MEM_dupallocN(sb);
- if (copy_caches == FALSE) {
+ if (copy_caches == false) {
sbn->totspring = sbn->totpoint = 0;
sbn->bpoint = NULL;
sbn->bspring = NULL;
@@ -1279,16 +1278,16 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->pathcache = NULL;
psysn->childcache = NULL;
psysn->edit = NULL;
- psysn->frand = NULL;
psysn->pdd = NULL;
psysn->effectors = NULL;
psysn->tree = NULL;
+ psysn->bvhtree = NULL;
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
psysn->renderdata = NULL;
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, FALSE);
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, false);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -1349,7 +1348,7 @@ void BKE_object_copy_particlesystems(Object *obn, Object *ob)
void BKE_object_copy_softbody(Object *obn, Object *ob)
{
if (ob->soft)
- obn->soft = copy_softbody(ob->soft, FALSE);
+ obn->soft = copy_softbody(ob->soft, false);
}
static void copy_object_pose(Object *obn, Object *ob)
@@ -1365,12 +1364,8 @@ static void copy_object_pose(Object *obn, Object *ob)
chan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
- if (chan->custom) {
- id_us_plus(&chan->custom->id);
- }
-
for (con = chan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1440,7 +1435,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
+Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
{
Object *obn;
ModifierData *md;
@@ -1482,16 +1477,11 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
BKE_pose_rebuild(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
- BKE_copy_constraints(&obn->constraints, &ob->constraints, TRUE);
+ BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
obn->mode = 0;
obn->sculpt = NULL;
- /* Proxies are not to be copied. */
- obn->proxy_from = NULL;
- obn->proxy_group = NULL;
- obn->proxy = NULL;
-
/* increase user numbers */
id_us_plus((ID *)obn->data);
id_us_plus((ID *)obn->gpd);
@@ -1533,7 +1523,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
/* copy objects, will re-initialize cached simulation data */
Object *BKE_object_copy(Object *ob)
{
- return BKE_object_copy_ex(G.main, ob, FALSE);
+ return BKE_object_copy_ex(G.main, ob, false);
}
static void extern_local_object(Object *ob)
@@ -1556,7 +1546,7 @@ void BKE_object_make_local(Object *ob)
Main *bmain = G.main;
Scene *sce;
Base *base;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -1574,12 +1564,12 @@ void BKE_object_make_local(Object *ob)
else {
for (sce = bmain->scene.first; sce && ELEM(0, is_lib, is_local); sce = sce->id.next) {
if (BKE_scene_base_find(sce, ob)) {
- if (sce->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (sce->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &ob->id);
extern_local_object(ob);
}
@@ -1722,7 +1712,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
mul_mat3_m4_v3(ob->obmat, tvec);
sub_v3_v3(ob->obmat[3], tvec);
}
- BKE_object_apply_mat4(ob, ob->obmat, FALSE, TRUE);
+ BKE_object_apply_mat4(ob, ob->obmat, false, true);
}
else {
BKE_object_transform_copy(ob, target);
@@ -1950,7 +1940,7 @@ void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
BKE_object_scale_to_mat3(ob, smat);
/* rot */
- BKE_object_rot_to_mat3(ob, rmat, TRUE);
+ BKE_object_rot_to_mat3(ob, rmat, true);
mul_m3_m3m3(mat, rmat, smat);
}
@@ -2217,7 +2207,7 @@ static void ob_get_parent_matrix(Scene *scene, Object *ob, Object *par, float pa
{
float tmat[4][4];
float vec[3];
- int ok;
+ bool ok;
switch (ob->partype & PARTYPE) {
case PAROBJECT:
@@ -2323,7 +2313,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
if (ob->parent) {
Object *par = ob->parent;
- float slowmat[4][4] = MAT4_UNITY;
+ float slowmat[4][4];
/* calculate parent matrix */
solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, true);
@@ -2349,7 +2339,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- BKE_solve_constraints(&ob->constraints, cob, ctime);
+ BKE_constraints_solve(&ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
@@ -2369,9 +2359,10 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
* used for bundles orientation in 3d space relative to parented blender camera */
void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
{
- float slowmat[4][4] = MAT4_UNITY;
if (ob->parent) {
+ float slowmat[4][4];
+
Object *par = ob->parent;
solve_parenting(scene, ob, par, obmat, slowmat, NULL, false);
@@ -2432,7 +2423,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, c
mul_m4_m4m4(diff_mat, parent_mat, ob->parentinv);
invert_m4_m4(imat, diff_mat);
mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
- BKE_object_apply_mat4(ob, rmat, use_compat, FALSE);
+ BKE_object_apply_mat4(ob, rmat, use_compat, false);
/* same as below, use rmat rather than mat */
mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat);
@@ -2520,7 +2511,7 @@ void BKE_object_dimensions_get(Object *ob, float vec[3])
}
}
-void BKE_object_dimensions_set(Object *ob, const float *value)
+void BKE_object_dimensions_set(Object *ob, const float value[3])
{
BoundBox *bb = NULL;
@@ -2587,7 +2578,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment
* (editarmature.c:2592)... Skip in this case too! */
- if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) {
+ if (pchan->bone && !((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false))) {
mul_v3_m4v3(vec, ob->obmat, pchan->pose_head);
minmax_v3v3_v3(min_r, max_r, vec);
mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
@@ -2724,7 +2715,7 @@ void BKE_object_foreach_display_point(
DispList *dl;
for (dl = ob->curve_cache->disp.first; dl; dl = dl->next) {
- float *v3 = dl->verts;
+ const float *v3 = dl->verts;
int totvert = dl->nr;
int i;
@@ -2844,7 +2835,8 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
Scene *scene, Object *ob,
- RigidBodyWorld *rbw)
+ RigidBodyWorld *rbw,
+ const bool do_proxy_update)
{
if (ob->recalc & OB_RECALC_ALL) {
/* speed optimization for animation lookups */
@@ -3037,8 +3029,10 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
/* the no-group proxy case, we call update */
if (ob->proxy_group == NULL) {
- // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
- BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+ if (do_proxy_update) {
+ // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
+ BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+ }
}
}
}
@@ -3049,7 +3043,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
*/
void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL);
+ BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true);
}
void BKE_object_sculpt_modifiers_changed(Object *ob)
@@ -3066,7 +3060,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
ss->pbvh = NULL;
}
- free_sculptsession_deformMats(ob->sculpt);
+ BKE_free_sculptsession_deformMats(ob->sculpt);
}
else {
PBVHNode **nodes;
@@ -3230,9 +3224,9 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons
newkey = 1;
}
- if (newkey || from_mix == FALSE) {
+ if (newkey || from_mix == false) {
/* create from mesh */
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, false);
BKE_key_convert_from_mesh(me, kb);
}
else {
@@ -3241,7 +3235,7 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons
float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, false);
kb->data = data;
kb->totelem = totelem;
}
@@ -3262,8 +3256,8 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons
newkey = 1;
}
- if (newkey || from_mix == FALSE) {
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ if (newkey || from_mix == false) {
+ kb = BKE_keyblock_add_ctime(key, name, false);
if (!newkey) {
KeyBlock *basekb = (KeyBlock *)key->block.first;
kb->data = MEM_dupallocN(basekb->data);
@@ -3279,7 +3273,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons
float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, false);
kb->totelem = totelem;
kb->data = data;
}
@@ -3301,9 +3295,9 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con
newkey = 1;
}
- if (newkey || from_mix == FALSE) {
+ if (newkey || from_mix == false) {
/* create from curve */
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, false);
if (!newkey) {
KeyBlock *basekb = (KeyBlock *)key->block.first;
kb->data = MEM_dupallocN(basekb->data);
@@ -3319,7 +3313,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con
float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
- kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, false);
kb->totelem = totelem;
kb->data = data;
}
@@ -3436,11 +3430,11 @@ void BKE_object_relink(Object *ob)
if (ob->id.lib)
return;
- BKE_relink_constraints(&ob->constraints);
+ BKE_constraints_relink(&ob->constraints);
if (ob->pose) {
bPoseChannel *chan;
for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
- BKE_relink_constraints(&chan->constraints);
+ BKE_constraints_relink(&chan->constraints);
}
}
modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
@@ -3653,7 +3647,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
unsigned int i;
DerivedMesh *dm = ob->derivedDeform ? ob->derivedDeform : ob->derivedFinal;
- int *index;
+ const int *index;
if (dm && (index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))) {
MVert *mvert = dm->getVertArray(dm);
@@ -3668,7 +3662,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
if (index[i] != ORIGINDEX_NONE) {
float co[3];
mul_v3_m4v3(co, ob->obmat, mvert[i].co);
- BLI_kdtree_insert(tree, index[i], co, NULL);
+ BLI_kdtree_insert(tree, index[i], co);
tot++;
}
}
@@ -3682,7 +3676,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
for (i = 0; i < tot; i++) {
float co[3];
mul_v3_m4v3(co, ob->obmat, mvert[i].co);
- BLI_kdtree_insert(tree, i, co, NULL);
+ BLI_kdtree_insert(tree, i, co);
}
}
@@ -3712,7 +3706,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
while (a--) {
float co[3];
mul_v3_m4v3(co, ob->obmat, bezt->vec[1]);
- BLI_kdtree_insert(tree, i++, co, NULL);
+ BLI_kdtree_insert(tree, i++, co);
bezt++;
}
}
@@ -3724,7 +3718,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
while (a--) {
float co[3];
mul_v3_m4v3(co, ob->obmat, bp->vec);
- BLI_kdtree_insert(tree, i++, co, NULL);
+ BLI_kdtree_insert(tree, i++, co);
bp++;
}
}
@@ -3748,7 +3742,7 @@ KDTree *BKE_object_as_kdtree(Object *ob, int *r_tot)
for (bp = lt->def; i < tot; bp++) {
float co[3];
mul_v3_m4v3(co, ob->obmat, bp->vec);
- BLI_kdtree_insert(tree, i++, co, NULL);
+ BLI_kdtree_insert(tree, i++, co);
}
BLI_kdtree_balance(tree);
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index f313c098f4b..e53bd26b9a2 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -144,16 +144,16 @@ bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_t
for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
- dg_selection[i] = TRUE;
+ dg_selection[i] = true;
(*r_dg_flags_sel_tot) += 1;
}
else {
- dg_selection[i] = FALSE;
+ dg_selection[i] = false;
}
}
}
else {
- memset(dg_selection, FALSE, sizeof(*dg_selection) * defbase_tot);
+ memset(dg_selection, false, sizeof(*dg_selection) * defbase_tot);
}
return dg_selection;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 74426df58c7..84e626a3104 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -301,6 +301,18 @@ static void make_duplis_group(const DupliContext *ctx)
if (go->ob != ob) {
float mat[4][4];
+ /* Special case for instancing dupli-groups, see: T40051
+ * this object may be instanced via dupli-verts/faces, in this case we don't want to render
+ * (blender convention), but _do_ show in the viewport.
+ *
+ * Regular objects work fine but not if we're instancing dupli-groups,
+ * because the rules for rendering aren't applied to objects they instance.
+ * We could recursively pass down the 'hide' flag instead, but that seems unnecessary.
+ */
+ if (for_render && go->ob->parent && go->ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES)) {
+ continue;
+ }
+
/* group dupli offset, should apply after everything else */
mul_m4_m4m4(mat, group_mat, go->ob->obmat);
@@ -684,7 +696,7 @@ static void get_dupliface_transform(MPoly *mpoly, MLoop *mloop, MVert *mvert,
BKE_mesh_calc_poly_center(mpoly, mloop, mvert, loc);
/* rotation */
{
- float *v1, *v2, *v3;
+ const float *v1, *v2, *v3;
BKE_mesh_calc_poly_normal(mpoly, mloop, mvert, f_no);
v1 = mvert[mloop[0].v].co;
v2 = mvert[mloop[1].v].co;
@@ -693,7 +705,7 @@ static void get_dupliface_transform(MPoly *mpoly, MLoop *mloop, MVert *mvert,
}
/* scale */
if (use_scale) {
- float area = BKE_mesh_calc_poly_area(mpoly, mloop, mvert, f_no);
+ float area = BKE_mesh_calc_poly_area(mpoly, mloop, mvert);
scale = sqrtf(area) * scale_fac;
}
else
@@ -780,7 +792,7 @@ static void make_duplis_faces(const DupliContext *ctx)
bool for_render = ctx->eval_ctx->for_render;
FaceDupliData fdd;
- fdd.use_scale = parent->transflag & OB_DUPLIFACES_SCALE;
+ fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0);
/* gather mesh info */
{
@@ -1245,3 +1257,42 @@ int count_duplilist(Object *ob)
}
return 1;
}
+
+DupliApplyData *duplilist_apply_matrix(ListBase *duplilist)
+{
+ DupliApplyData *apply_data = NULL;
+ int num_objects = BLI_countlist(duplilist);
+ if (num_objects > 0) {
+ DupliObject *dob;
+ int i;
+ apply_data = MEM_mallocN(sizeof(DupliApplyData), "DupliObject apply data");
+ apply_data->num_objects = num_objects;
+ apply_data->extra = MEM_mallocN(sizeof(DupliExtraData) * (size_t) num_objects,
+ "DupliObject apply extra data");
+
+ for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) {
+ copy_m4_m4(apply_data->extra[i].obmat, dob->ob->obmat);
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ }
+ }
+ return apply_data;
+}
+
+void duplilist_restore_matrix(ListBase *duplilist, DupliApplyData *apply_data)
+{
+ DupliObject *dob;
+ int i;
+ /* Restore object matrices.
+ * NOTE: this has to happen in reverse order, since nested
+ * dupli objects can repeatedly override the obmat.
+ */
+ for (dob = duplilist->last, i = apply_data->num_objects - 1; dob; dob = dob->prev, --i) {
+ copy_m4_m4(dob->ob->obmat, apply_data->extra[i].obmat);
+ }
+}
+
+void duplilist_free_apply_data(DupliApplyData *apply_data)
+{
+ MEM_freeN(apply_data->extra);
+ MEM_freeN(apply_data);
+}
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index c1e43365a84..373ad34e7bd 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -41,7 +41,6 @@
#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_rand.h"
-#include "BLI_string.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -846,6 +845,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
+ BLI_lock_thread(LOCK_FFTW);
+
if (o->_do_disp_y) {
o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
@@ -890,6 +891,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
}
+ BLI_unlock_thread(LOCK_FFTW);
+
BLI_rw_mutex_unlock(&o->oceanmutex);
set_height_normalize_factor(o);
@@ -903,6 +906,8 @@ void BKE_free_ocean_data(struct Ocean *oc)
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
+ BLI_lock_thread(LOCK_FFTW);
+
if (oc->_do_disp_y) {
fftw_destroy_plan(oc->_disp_y_plan);
MEM_freeN(oc->_disp_y);
@@ -939,6 +944,8 @@ void BKE_free_ocean_data(struct Ocean *oc)
MEM_freeN(oc->_Jxz);
}
+ BLI_unlock_thread(LOCK_FFTW);
+
if (oc->_fft_in)
MEM_freeN(oc->_fft_in);
@@ -995,7 +1002,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
- BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
+ BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true);
}
/* silly functions but useful to inline when the args do a lot of indirections */
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index b120ec0d1f1..dafe5ca55ff 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -59,14 +59,6 @@
#include "BKE_report.h"
#include "BKE_sound.h"
-#ifdef _WIN32
-#define open _open
-#define close _close
-#define read _read
-#define write _write
-#endif
-
-
int seekPackedFile(PackedFile *pf, int offset, int whence)
{
int oldseek = -1, seek = 0;
@@ -202,7 +194,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
* and create a PackedFile structure */
file = BLI_open(name, O_BINARY | O_RDONLY, 0);
- if (file < 0) {
+ if (file == -1) {
BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path '%s' not found", name);
}
else {
@@ -253,7 +245,7 @@ void packAll(Main *bmain, ReportList *reports)
}
for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
- if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == FALSE) {
+ if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == false) {
vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name);
tot ++;
}
@@ -303,8 +295,9 @@ static char *find_new_name(char *name)
int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, int guimode)
{
- int file, number, remove_tmp = FALSE;
+ int file, number;
int ret_value = RET_OK;
+ bool remove_tmp = false;
char name[FILE_MAX];
char tempname[FILE_MAX];
/* void *data; */
@@ -319,7 +312,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
BLI_snprintf(tempname, sizeof(tempname), "%s.%03d_", name, number);
if (!BLI_exists(tempname)) {
if (BLI_copy(name, tempname) == RET_OK) {
- remove_tmp = TRUE;
+ remove_tmp = true;
}
break;
}
@@ -330,7 +323,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
BLI_make_existing_file(name);
file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
- if (file < 0) {
+ if (file == -1) {
BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name);
ret_value = RET_ERROR;
}
@@ -393,7 +386,7 @@ int checkPackedFile(const char *filename, PackedFile *pf)
/* we'll have to compare the two... */
file = BLI_open(name, O_BINARY | O_RDONLY, 0);
- if (file < 0) {
+ if (file == -1) {
ret_val = PF_NOFILE;
}
else {
@@ -626,21 +619,27 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
/* ID should be not NULL, return 1 if there's a packed file */
bool BKE_pack_check(ID *id)
{
- if (GS(id->name) == ID_IM) {
- Image *ima = (Image *)id;
- return ima->packedfile != NULL;
- }
- if (GS(id->name) == ID_VF) {
- VFont *vf = (VFont *)id;
- return vf->packedfile != NULL;
- }
- if (GS(id->name) == ID_SO) {
- bSound *snd = (bSound *)id;
- return snd->packedfile != NULL;
- }
- if (GS(id->name) == ID_LI) {
- Library *li = (Library *)id;
- return li->packedfile != NULL;
+ switch (GS(id->name)) {
+ case ID_IM:
+ {
+ Image *ima = (Image *)id;
+ return ima->packedfile != NULL;
+ }
+ case ID_VF:
+ {
+ VFont *vf = (VFont *)id;
+ return vf->packedfile != NULL;
+ }
+ case ID_SO:
+ {
+ bSound *snd = (bSound *)id;
+ return snd->packedfile != NULL;
+ }
+ case ID_LI:
+ {
+ Library *li = (Library *)id;
+ return li->packedfile != NULL;
+ }
}
return false;
}
@@ -648,23 +647,36 @@ bool BKE_pack_check(ID *id)
/* ID should be not NULL */
void BKE_unpack_id(Main *bmain, ID *id, ReportList *reports, int how)
{
- if (GS(id->name) == ID_IM) {
- Image *ima = (Image *)id;
- if (ima->packedfile)
- unpackImage(reports, ima, how);
- }
- if (GS(id->name) == ID_VF) {
- VFont *vf = (VFont *)id;
- if (vf->packedfile)
- unpackVFont(reports, vf, how);
- }
- if (GS(id->name) == ID_SO) {
- bSound *snd = (bSound *)id;
- if (snd->packedfile)
- unpackSound(bmain, reports, snd, how);
- }
- if (GS(id->name) == ID_LI) {
- Library *li = (Library *)id;
- BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name);
+ switch (GS(id->name)) {
+ case ID_IM:
+ {
+ Image *ima = (Image *)id;
+ if (ima->packedfile) {
+ unpackImage(reports, ima, how);
+ }
+ break;
+ }
+ case ID_VF:
+ {
+ VFont *vf = (VFont *)id;
+ if (vf->packedfile) {
+ unpackVFont(reports, vf, how);
+ }
+ break;
+ }
+ case ID_SO:
+ {
+ bSound *snd = (bSound *)id;
+ if (snd->packedfile) {
+ unpackSound(bmain, reports, snd, how);
+ }
+ break;
+ }
+ case ID_LI:
+ {
+ Library *li = (Library *)id;
+ BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name);
+ break;
+ }
}
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 690217a0779..1b8c4e084cf 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -37,6 +37,7 @@
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
#include "DNA_space_types.h"
@@ -47,10 +48,14 @@
#include "BKE_brush.h"
#include "BKE_context.h"
+#include "BKE_crazyspace.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_key.h"
#include "BKE_library.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -265,7 +270,7 @@ void BKE_paint_brush_set(Paint *p, Brush *br)
}
/* are we in vertex paint or weight pain face select mode? */
-bool paint_facesel_test(Object *ob)
+bool BKE_paint_select_face_test(Object *ob)
{
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
@@ -276,7 +281,7 @@ bool paint_facesel_test(Object *ob)
}
/* are we in weight paint vertex select mode? */
-bool paint_vertsel_test(Object *ob)
+bool BKE_paint_select_vert_test(Object *ob)
{
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
@@ -286,6 +291,16 @@ bool paint_vertsel_test(Object *ob)
);
}
+/**
+ * used to check if selection is possible
+ * (when we don't care if its face or vert)
+ */
+bool BKE_paint_select_elem_test(Object *ob)
+{
+ return (BKE_paint_select_vert_test(ob) ||
+ BKE_paint_select_face_test(ob));
+}
+
void BKE_paint_init(Paint *p, const char col[3])
{
Brush *brush;
@@ -298,8 +313,6 @@ void BKE_paint_init(Paint *p, const char col[3])
memcpy(p->paint_cursor_col, col, 3);
p->paint_cursor_col[3] = 128;
-
- p->flags |= PAINT_SHOW_BRUSH;
}
void BKE_paint_free(Paint *paint)
@@ -340,7 +353,7 @@ bool paint_is_grid_face_hidden(const unsigned int *grid_hidden,
BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x));
}
-/* Return TRUE if all vertices in the face are visible, FALSE otherwise */
+/* Return true if all vertices in the face are visible, false otherwise */
bool paint_is_bmesh_face_hidden(BMFace *f)
{
BMLoop *l_iter;
@@ -384,7 +397,7 @@ void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_
}
}
-void free_sculptsession_deformMats(SculptSession *ss)
+void BKE_free_sculptsession_deformMats(SculptSession *ss)
{
if (ss->orig_cos) MEM_freeN(ss->orig_cos);
if (ss->deform_cos) MEM_freeN(ss->deform_cos);
@@ -405,17 +418,16 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
BMIter iter;
BMFace *efa;
BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
- BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
- ss->bm_smooth_shading);
+ BM_elem_flag_set(efa, BM_ELEM_SMOOTH, ss->bm_smooth_shading);
}
if (reorder)
BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
- BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
+ BM_mesh_bm_to_me(ss->bm, ob->data, false);
}
}
}
-void sculptsession_bm_to_me(Object *ob, int reorder)
+void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
{
if (ob && ob->sculpt) {
sculptsession_bm_to_me_update_data_only(ob, reorder);
@@ -425,7 +437,7 @@ void sculptsession_bm_to_me(Object *ob, int reorder)
}
}
-void sculptsession_bm_to_me_for_render(Object *object)
+void BKE_sculptsession_bm_to_me_for_render(Object *object)
{
if (object && object->sculpt) {
if (object->sculpt->bm) {
@@ -452,14 +464,14 @@ void sculptsession_bm_to_me_for_render(Object *object)
}
}
-void free_sculptsession(Object *ob)
+void BKE_free_sculptsession(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
DerivedMesh *dm = ob->derivedFinal;
if (ss->bm) {
- sculptsession_bm_to_me(ob, TRUE);
+ BKE_sculptsession_bm_to_me(ob, true);
BM_mesh_free(ss->bm);
}
@@ -492,3 +504,239 @@ void free_sculptsession(Object *ob)
ob->sculpt = NULL;
}
}
+
+/* Sculpt mode handles multires differently from regular meshes, but only if
+ * it's the last modifier on the stack and it is not on the first level */
+MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
+{
+ Mesh *me = (Mesh *)ob->data;
+ ModifierData *md;
+ VirtualModifierData virtualModifierData;
+
+ if (ob->sculpt && ob->sculpt->bm) {
+ /* can't combine multires and dynamic topology */
+ return NULL;
+ }
+
+ if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
+ /* multires can't work without displacement layer */
+ return NULL;
+ }
+
+ for (md = modifiers_getVirtualModifierList(ob, &virtualModifierData); md; md = md->next) {
+ if (md->type == eModifierType_Multires) {
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+
+ if (!modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ continue;
+
+ if (mmd->sculptlvl > 0) return mmd;
+ else return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Checks if there are any supported deformation modifiers active */
+static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
+{
+ ModifierData *md;
+ Mesh *me = (Mesh *)ob->data;
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+ VirtualModifierData virtualModifierData;
+
+ if (mmd || ob->sculpt->bm)
+ return 0;
+
+ /* non-locked shape keys could be handled in the same way as deformed mesh */
+ if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
+ return 1;
+
+ md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+
+ /* exception for shape keys because we can edit those */
+ for (; md; md = md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
+ if (ELEM(md->type, eModifierType_ShapeKey, eModifierType_Multires)) continue;
+
+ if (mti->type == eModifierTypeType_OnlyDeform) return 1;
+ else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * \param need_mask So the DerivedMesh thats returned has mask data
+ */
+void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
+ bool need_pmap, bool need_mask)
+{
+ DerivedMesh *dm;
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+
+ ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
+ ss->show_diffuse_color = (sd->flags & SCULPT_SHOW_DIFFUSE) != 0;
+
+ if (need_mask) {
+ if (mmd == NULL) {
+ if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) {
+ BKE_sculpt_mask_layers_ensure(ob, NULL);
+ }
+ }
+ else {
+ if (!CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
+#if 1
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
+#else /* if we wanted to support adding mask data while multi-res painting, we would need to do this */
+ if ((ED_sculpt_mask_layers_ensure(ob, mmd) & ED_SCULPT_MASK_LAYER_CALC_LOOP)) {
+ /* remake the derived mesh */
+ ob->recalc |= OB_RECALC_DATA;
+ BKE_object_handle_update(scene, ob);
+ }
+#endif
+ }
+ }
+ }
+
+ /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
+ BKE_mesh_tessface_ensure(me);
+
+ if (!mmd) ss->kb = BKE_keyblock_from_object(ob);
+ else ss->kb = NULL;
+
+ /* needs to be called after we ensure tessface */
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+
+ if (mmd) {
+ ss->multires = mmd;
+ ss->totvert = dm->getNumVerts(dm);
+ ss->totpoly = dm->getNumPolys(dm);
+ ss->mvert = NULL;
+ ss->mpoly = NULL;
+ ss->mloop = NULL;
+ ss->face_normals = NULL;
+ }
+ else {
+ ss->totvert = me->totvert;
+ ss->totpoly = me->totpoly;
+ ss->mvert = me->mvert;
+ ss->mpoly = me->mpoly;
+ ss->mloop = me->mloop;
+ ss->face_normals = NULL;
+ ss->multires = NULL;
+ ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+ }
+
+ ss->pbvh = dm->getPBVH(ob, dm);
+ ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
+
+ pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
+
+ if (ss->modifiers_active) {
+ if (!ss->orig_cos) {
+ int a;
+
+ BKE_free_sculptsession_deformMats(ss);
+
+ ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
+
+ BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
+
+ for (a = 0; a < me->totvert; ++a) {
+ invert_m3(ss->deform_imats[a]);
+ }
+ }
+ }
+ else {
+ BKE_free_sculptsession_deformMats(ss);
+ }
+
+ /* if pbvh is deformed, key block is already applied to it */
+ if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
+ float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
+
+ if (vertCos) {
+ /* apply shape keys coordinates to PBVH */
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ MEM_freeN(vertCos);
+ }
+ }
+}
+
+int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
+{
+ const float *paint_mask;
+ Mesh *me = ob->data;
+ int ret = 0;
+
+ paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+
+ /* if multires is active, create a grid paint mask layer if there
+ * isn't one already */
+ if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
+ GridPaintMask *gmask;
+ int level = max_ii(1, mmd->sculptlvl);
+ int gridsize = BKE_ccg_gridsize(level);
+ int gridarea = gridsize * gridsize;
+ int i, j;
+
+ gmask = CustomData_add_layer(&me->ldata, CD_GRID_PAINT_MASK,
+ CD_CALLOC, NULL, me->totloop);
+
+ for (i = 0; i < me->totloop; i++) {
+ GridPaintMask *gpm = &gmask[i];
+
+ gpm->level = level;
+ gpm->data = MEM_callocN(sizeof(float) * gridarea,
+ "GridPaintMask.data");
+ }
+
+ /* if vertices already have mask, copy into multires data */
+ if (paint_mask) {
+ for (i = 0; i < me->totpoly; i++) {
+ const MPoly *p = &me->mpoly[i];
+ float avg = 0;
+
+ /* mask center */
+ for (j = 0; j < p->totloop; j++) {
+ const MLoop *l = &me->mloop[p->loopstart + j];
+ avg += paint_mask[l->v];
+ }
+ avg /= (float)p->totloop;
+
+ /* fill in multires mask corner */
+ for (j = 0; j < p->totloop; j++) {
+ GridPaintMask *gpm = &gmask[p->loopstart + j];
+ const MLoop *l = &me->mloop[p->loopstart + j];
+ const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j);
+ const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j);
+
+ gpm->data[0] = avg;
+ gpm->data[1] = (paint_mask[l->v] +
+ paint_mask[next->v]) * 0.5f;
+ gpm->data[2] = (paint_mask[l->v] +
+ paint_mask[prev->v]) * 0.5f;
+ gpm->data[3] = paint_mask[l->v];
+ }
+ }
+ }
+
+ ret |= SCULPT_MASK_LAYER_CALC_LOOP;
+ }
+
+ /* create vertex paint mask layer if there isn't one already */
+ if (!paint_mask) {
+ CustomData_add_layer(&me->vdata, CD_PAINT_MASK,
+ CD_CALLOC, NULL, me->totvert);
+ ret |= SCULPT_MASK_LAYER_CALC_VERT;
+ }
+
+ return ret;
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index edf902e0eb5..eb657bac312 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -71,7 +71,6 @@
#include "BKE_displist.h"
#include "BKE_particle.h"
-#include "BKE_object.h"
#include "BKE_material.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -85,6 +84,21 @@
#include "RE_render_ext.h"
+unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
+
+void psys_init_rng(void)
+{
+ int i;
+ BLI_srandom(5831); /* arbitrary */
+ for (i = 0; i < PSYS_FRAND_COUNT; ++i) {
+ PSYS_FRAND_BASE[i] = BLI_frand();
+ PSYS_FRAND_SEED_OFFSET[i] = (unsigned int)BLI_rand();
+ PSYS_FRAND_SEED_MULTIPLIER[i] = (unsigned int)BLI_rand();
+ }
+}
+
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
static void do_child_modifiers(ParticleSimulationData *sim,
@@ -260,16 +274,6 @@ int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
{
return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys == psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit) && !psys->renderdata);
}
-static void psys_create_frand(ParticleSystem *psys)
-{
- int i;
- float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
-
- BLI_srandom(psys->seed);
-
- for (i = 0; i < 1024; i++, rand++)
- *rand = BLI_frand();
-}
int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd;
@@ -285,14 +289,6 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
else if (!(psmd->modifier.mode & eModifierMode_Realtime))
return 0;
- /* perhaps not the perfect place, but we have to be sure the rands are there before usage */
- if (!psys->frand)
- psys_create_frand(psys);
- else if (psys->recalc & PSYS_RECALC_RESET) {
- MEM_freeN(psys->frand);
- psys_create_frand(psys);
- }
-
return 1;
}
@@ -579,9 +575,6 @@ void psys_free(Object *ob, ParticleSystem *psys)
pdEndEffectors(&psys->effectors);
- if (psys->frand)
- MEM_freeN(psys->frand);
-
if (psys->pdd) {
psys_free_pdd(psys);
MEM_freeN(psys->pdd);
@@ -787,7 +780,7 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
PARTICLE_P;
LOOP_PARTICLES {
- if (PSYS_FRAND(p) > disp)
+ if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -849,7 +842,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
if (data->elems)
MEM_freeN(data->elems);
- data->do_simplify = TRUE;
+ data->do_simplify = true;
data->elems = elems;
data->index_mf_to_mpoly = index_mf_to_mpoly;
data->index_mp_to_orig = index_mp_to_orig;
@@ -980,7 +973,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
return newtot;
}
-int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params)
+bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params)
{
ParticleRenderData *data;
ParticleRenderElem *elem;
@@ -2403,18 +2396,23 @@ void psys_find_parents(ParticleSimulationData *sim)
if ((sim->psys->renderdata || G.is_rendering) && part->child_nbr && part->ren_child_nbr)
totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
+ /* hard limit, workaround for it being ignored above */
+ if (sim->psys->totpart < totparent) {
+ totparent = sim->psys->totpart;
+ }
+
tree = BLI_kdtree_new(totparent);
for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) {
psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco, 0);
- BLI_kdtree_insert(tree, p, orco, NULL);
+ BLI_kdtree_insert(tree, p, orco);
}
BLI_kdtree_balance(tree);
for (; p < totchild; p++, cpa++) {
psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco, 0);
- cpa->parent = BLI_kdtree_find_nearest(tree, orco, NULL, NULL);
+ cpa->parent = BLI_kdtree_find_nearest(tree, orco, NULL);
}
BLI_kdtree_free(tree);
@@ -2680,7 +2678,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
/* get different child parameters from textures & vgroups */
get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
- if (ptex.exist < PSYS_FRAND(i + 24)) {
+ if (ptex.exist < psys_frand(psys, i + 24)) {
child_keys->steps = -1;
return;
}
@@ -2996,7 +2994,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
LOOP_SHOWN_PARTICLES {
if (!psys->totchild) {
psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
- pa_length = ptex.length * (1.0f - part->randlength * PSYS_FRAND(psys->seed + p));
+ pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
if (vg_length)
pa_length *= psys_particle_value_from_verts(psmd->dm, part->from, pa, vg_length);
}
@@ -3711,7 +3709,7 @@ void BKE_particlesettings_make_local(ParticleSettings *part)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -3726,17 +3724,17 @@ void BKE_particlesettings_make_local(ParticleSettings *part)
}
/* test objects */
- for (ob = bmain->object.first; ob && ELEM(FALSE, is_lib, is_local); ob = ob->id.next) {
+ for (ob = bmain->object.first; ob && ELEM(false, is_lib, is_local); ob = ob->id.next) {
ParticleSystem *psys = ob->particlesystem.first;
for (; psys; psys = psys->next) {
if (psys->part == part) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &part->id);
expand_local_particlesettings(part);
}
@@ -3780,7 +3778,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
return 0;
if (pa) {
- i = (pa->num_dmcache == DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache;
+ i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
if (i >= dm->getNumTessFaces(dm))
i = -1;
}
@@ -3832,8 +3830,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
- ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
- ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
+ ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
+ ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
for (m = 0; m < MAX_MTEX; m++, mtexp++) {
mtex = *mtexp;
@@ -3995,7 +3993,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra,
w++;
}
- life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25));
+ life = part->lifetime * (1.0f - part->randlife * psys_frand(psys, cpa - psys->child + 25));
}
else {
ParticleData *pa = psys->particles + cpa->parent;
@@ -4024,7 +4022,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED
size *= part->childsize;
if (part->childrandsize != 0.0f)
- size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
+ size *= 1.0f - part->childrandsize * psys_frand(psys, cpa - psys->child + 26);
return size;
}
@@ -4036,7 +4034,7 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
- if (ptex->exist < PSYS_FRAND(i + 24))
+ if (ptex->exist < psys_frand(psys, i + 24))
return;
if (ctx->vg_length)
@@ -4091,14 +4089,20 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte
if (rough1 > 0.f)
do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
- if (rough2 > 0.f)
- do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+ if (rough2 > 0.f) {
+ float vec[3];
+ psys_frand_vec(sim->psys, i + 27, vec);
+ do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+ }
- if (rough_end > 0.f)
- do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough_end, part->rough_end_shape, state);
+ if (rough_end > 0.f) {
+ float vec[3];
+ psys_frand_vec(sim->psys, i + 27, vec);
+ do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
+ }
}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
-void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel)
+void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
{
PARTICLE_PSMD;
ParticleSystem *psys = sim->psys;
@@ -4358,7 +4362,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
}
}
- state->time = (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24));
+ state->time = (cfra - (part->sta + (part->end - part->sta) * psys_frand(psys, p + 23))) / (part->lifetime * psys_frand(psys, p + 24));
psys_get_particle_on_path(sim, p, state, 1);
return 1;
@@ -4567,7 +4571,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
float q_phase[4];
float phasefac = psys->part->phasefac;
if (psys->part->randphasefac != 0.0f)
- phasefac += psys->part->randphasefac * PSYS_FRAND((pa - psys->particles) + 20);
+ phasefac += psys->part->randphasefac * psys_frand(psys, (pa - psys->particles) + 20);
axis_angle_to_quat(q_phase, vec, phasefac * (float)M_PI);
mul_qt_v3(q_phase, side);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4eaa2618e26..d213a88f8b1 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -54,12 +54,9 @@
#include "DNA_modifier_types.h"
#include "DNA_object_force.h"
#include "DNA_object_types.h"
-#include "DNA_material_types.h"
#include "DNA_curve_types.h"
-#include "DNA_group_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "DNA_ipo_types.h" // XXX old animation system stuff... to be removed!
#include "DNA_listBase.h"
#include "BLI_utildefines.h"
@@ -74,12 +71,10 @@
#include "BLI_threads.h"
#include "BLI_linklist.h"
-#include "BKE_main.h"
#include "BKE_animsys.h"
#include "BKE_boids.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_collision.h"
-#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_particle.h"
#include "BKE_global.h"
@@ -88,7 +83,6 @@
#include "BKE_object.h"
#include "BKE_material.h"
#include "BKE_cloth.h"
-#include "BKE_depsgraph.h"
#include "BKE_lattice.h"
#include "BKE_pointcache.h"
#include "BKE_mesh.h"
@@ -109,6 +103,8 @@
#endif // WITH_MOD_FLUID
+static ThreadRWMutex psys_bvhtree_rwlock = BLI_RWLOCK_INITIALIZER;
+
/************************************************/
/* Reacting to system events */
/************************************************/
@@ -493,15 +489,19 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
int totvert=dm->getNumVerts(dm), from=psys->part->from;
int i, j, k, p, res=psys->part->grid_res, size[3], axis;
- mv=mvert;
-
/* find bounding box of dm */
- copy_v3_v3(min, mv->co);
- copy_v3_v3(max, mv->co);
- mv++;
-
- for (i=1; i<totvert; i++, mv++) {
- minmax_v3v3_v3(min, max, mv->co);
+ if (totvert > 0) {
+ mv=mvert;
+ copy_v3_v3(min, mv->co);
+ copy_v3_v3(max, mv->co);
+ mv++;
+ for (i = 1; i < totvert; i++, mv++) {
+ minmax_v3v3_v3(min, max, mv->co);
+ }
+ }
+ else {
+ zero_v3(min);
+ zero_v3(max);
}
sub_v3_v3v3(delta, max, min);
@@ -660,9 +660,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
if (pa->flag & PARS_UNEXIST)
continue;
- pa->fuv[0] += rfac * (PSYS_FRAND(p + 31) - 0.5f);
- pa->fuv[1] += rfac * (PSYS_FRAND(p + 32) - 0.5f);
- pa->fuv[2] += rfac * (PSYS_FRAND(p + 33) - 0.5f);
+ pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
+ pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
+ pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f);
}
}
}
@@ -690,7 +690,7 @@ static void hammersley_create(float *out, int n, int seed, float amount)
}
}
-/* modified copy from effect.c */
+/* almost exact copy of BLI_jitter_init */
static void init_mv_jit(float *jit, int num, int seed2, float amount)
{
RNG *rng;
@@ -721,9 +721,9 @@ static void init_mv_jit(float *jit, int num, int seed2, float amount)
jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
for (i=0 ; i<4 ; i++) {
- BLI_jitterate1(jit, jit2, num, rad1);
- BLI_jitterate1(jit, jit2, num, rad1);
- BLI_jitterate2(jit, jit2, num, rad2);
+ BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
+ BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
+ BLI_jitterate2((float (*)[2])jit, (float (*)[2])jit2, num, rad2);
}
MEM_freeN(jit2);
BLI_rng_free(rng);
@@ -815,7 +815,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch
psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
- maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,NULL,ptn,3);
+ maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
for (w=0; w<maxw; w++) {
pa->verts[w]=ptn->num;
@@ -940,7 +940,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch
psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL);
BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
- maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,NULL,ptn,3);
+ maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
maxd=ptn[maxw-1].dist;
/* mind=ptn[0].dist; */ /* UNUSED */
@@ -1077,7 +1077,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
int totelem=0, totpart, *particle_element=0, children=0, totseam=0;
int jitlevel= 1, distr;
float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL;
- float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3], ornor[3];
+ float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3];
if (ELEM3(NULL, ob, psys, psys->part))
return 0;
@@ -1128,9 +1128,9 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
tree=BLI_kdtree_new(totpart);
for (p=0,pa=psys->particles; p<totpart; p++,pa++) {
- psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
+ psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,NULL);
BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1);
- BLI_kdtree_insert(tree, p, orco, ornor);
+ BLI_kdtree_insert(tree, p, orco);
}
BLI_kdtree_balance(tree);
@@ -1170,7 +1170,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
}
else
copy_v3_v3(co,mv[p].co);
- BLI_kdtree_insert(tree,p,co,NULL);
+ BLI_kdtree_insert(tree, p, co);
}
BLI_kdtree_balance(tree);
@@ -1549,7 +1549,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
if (part->type != PART_FLUID) {
psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
- if (ptex.exist < PSYS_FRAND(p+125))
+ if (ptex.exist < psys_frand(psys, p+125))
pa->flag |= PARS_UNEXIST;
pa->time = (part->type == PART_HAIR) ? 0.f : part->sta + (part->end - part->sta)*ptex.time;
@@ -1714,9 +1714,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
/* -velocity (boids need this even if there's no random velocity) */
if (part->randfac != 0.0f || (part->phystype==PART_PHYS_BOIDS && pa->boid)) {
- r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
- r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
- r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
+ r_vel[0] = 2.0f * (psys_frand(psys, p + 10) - 0.5f);
+ r_vel[1] = 2.0f * (psys_frand(psys, p + 11) - 0.5f);
+ r_vel[2] = 2.0f * (psys_frand(psys, p + 12) - 0.5f);
mul_mat3_m4_v3(ob->obmat, r_vel);
normalize_v3(r_vel);
@@ -1724,9 +1724,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
/* -angular velocity */
if (part->avemode==PART_AVE_RAND) {
- r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
- r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
- r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
+ r_ave[0] = 2.0f * (psys_frand(psys, p + 13) - 0.5f);
+ r_ave[1] = 2.0f * (psys_frand(psys, p + 14) - 0.5f);
+ r_ave[2] = 2.0f * (psys_frand(psys, p + 15) - 0.5f);
mul_mat3_m4_v3(ob->obmat,r_ave);
normalize_v3(r_ave);
@@ -1734,10 +1734,10 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
/* -rotation */
if (part->randrotfac != 0.0f) {
- r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
- r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
- r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
- r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
+ r_rot[0] = 2.0f * (psys_frand(psys, p + 16) - 0.5f);
+ r_rot[1] = 2.0f * (psys_frand(psys, p + 17) - 0.5f);
+ r_rot[2] = 2.0f * (psys_frand(psys, p + 18) - 0.5f);
+ r_rot[3] = 2.0f * (psys_frand(psys, p + 19) - 0.5f);
normalize_qt(r_rot);
mat4_to_quat(rot,ob->obmat);
@@ -1940,7 +1940,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
/* rotation phase */
phasefac = part->phasefac;
if (part->randphasefac != 0.0f)
- phasefac += part->randphasefac * PSYS_FRAND(p + 20);
+ phasefac += part->randphasefac * psys_frand(psys, p + 20);
axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
/* combine base rotation & phase */
@@ -1962,10 +1962,21 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
}
}
}
+
+/* recursively evaluate emitter parent anim at cfra */
+static void evaluate_emitter_anim(Scene *scene, Object *ob, float cfra)
+{
+ if (ob->parent)
+ evaluate_emitter_anim(scene, ob->parent, cfra);
+
+ /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM);
+ BKE_object_where_is_calc_time(scene, ob, cfra);
+}
+
/* sets particle to the emitter surface with initial velocity & rotation */
void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
{
- Object *ob = sim->ob;
ParticleSystem *psys = sim->psys;
ParticleSettings *part;
ParticleTexture ptex;
@@ -1974,13 +1985,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* get precise emitter matrix if particle is born */
if (part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
- /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
- while (ob) {
- BKE_animsys_evaluate_animdata(sim->scene, &ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
- BKE_object_where_is_calc_time(sim->scene, ob, pa->time);
- ob = ob->parent;
- }
- ob = sim->ob;
+ evaluate_emitter_anim(sim->scene, sim->ob, pa->time);
psys->flag |= PSYS_OB_ANIM_RESTORE;
}
@@ -2019,7 +2024,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* initialize the lifetime, in case the texture coordinates
* are from Particles/Strands, which would cause undefined values
*/
- pa->lifetime = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(p + 21));
+ pa->lifetime = part->lifetime * (1.0f - part->randlife * psys_frand(psys, p + 21));
pa->dietime = pa->time + pa->lifetime;
/* get possible textural influence */
@@ -2028,7 +2033,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
pa->lifetime = part->lifetime * ptex.life;
if (part->randlife != 0.0f)
- pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21);
+ pa->lifetime *= 1.0f - part->randlife * psys_frand(psys, p + 21);
}
pa->dietime = pa->time + pa->lifetime;
@@ -2209,15 +2214,22 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
if (psys) {
PARTICLE_P;
int totpart = 0;
+ bool need_rebuild;
- if (!psys->bvhtree || psys->bvhtree_frame != cfra) {
+ BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
+ need_rebuild = !psys->bvhtree || psys->bvhtree_frame != cfra;
+ BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
+
+ if (need_rebuild) {
LOOP_SHOWN_PARTICLES {
totpart++;
}
+ BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_WRITE);
+
BLI_bvhtree_free(psys->bvhtree);
psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6);
-
+
LOOP_SHOWN_PARTICLES {
if (pa->alive == PARS_ALIVE) {
if (pa->state.time == cfra)
@@ -2227,8 +2239,10 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
}
}
BLI_bvhtree_balance(psys->bvhtree);
-
+
psys->bvhtree_frame = cfra;
+
+ BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
}
}
}
@@ -2249,9 +2263,9 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra)
LOOP_SHOWN_PARTICLES {
if (pa->alive == PARS_ALIVE) {
if (pa->state.time == cfra)
- BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
+ BLI_kdtree_insert(psys->tree, p, pa->prev_state.co);
else
- BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
+ BLI_kdtree_insert(psys->tree, p, pa->state.co);
}
}
BLI_kdtree_balance(psys->tree);
@@ -2546,7 +2560,11 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3],
break;
}
else {
+ BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
+
BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+
+ BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
}
}
}
@@ -4071,7 +4089,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
psys->clmd->point_cache = psys->pointcache;
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
- deformedVerts = MEM_callocN(sizeof(*deformedVerts)*dm->getNumVerts(dm), "do_hair_dynamics vertexCos");
+ deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * dm->getNumVerts(dm), "do_hair_dynamics vertexCos");
psys->hair_out_dm = CDDM_copy(dm);
psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts);
@@ -4093,9 +4111,9 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
LOOP_PARTICLES {
pa->size = part->size;
if (part->randsize > 0.0f)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
- if (PSYS_FRAND(p) > disp)
+ if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -4254,7 +4272,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
pa->size = part->size*ptex.size;
if (part->randsize > 0.0f)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
reset_particle(sim, pa, dtime, cfra);
}
@@ -4312,7 +4330,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
pa->size = part->size*ptex.size;
if (part->randsize > 0.0f)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
birthtime = pa->time;
dietime = pa->dietime;
@@ -4498,7 +4516,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
pa->size = part->size*ptex.size;
if (part->randsize > 0.0f)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
@@ -4520,7 +4538,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
psys->lattice_deform_data = NULL;
}
- if (PSYS_FRAND(p) > disp)
+ if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -4744,7 +4762,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
disp= psys_get_current_display_percentage(psys);
LOOP_PARTICLES {
- if (PSYS_FRAND(p) > disp)
+ if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -5055,11 +5073,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
LOOP_EXISTING_PARTICLES {
pa->size = part->size;
if (part->randsize > 0.0f)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
reset_particle(&sim, pa, 0.0, cfra);
- if (PSYS_FRAND(p) > disp)
+ if (psys_frand(psys, p) > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -5085,13 +5103,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
/* make sure emitter is left at correct time (particle emission can change this) */
if (psys->flag & PSYS_OB_ANIM_RESTORE) {
- while (ob) {
- BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM);
- BKE_object_where_is_calc_time(scene, ob, cfra);
- ob = ob->parent;
- }
- ob = sim.ob;
-
+ evaluate_emitter_anim(scene, ob, cfra);
psys->flag &= ~PSYS_OB_ANIM_RESTORE;
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index b0ea11f2a92..369646371d7 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -34,10 +34,9 @@
#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
-#include "BKE_global.h" /* for BKE_mesh_calc_normals */
#include "BKE_paint.h"
-#include "BKE_subsurf.h"
#include "GPU_buffers.h"
@@ -280,6 +279,7 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
GHashIterator *iter;
GHash *map;
int i, j, totface;
+ bool has_visible = false;
node->uniq_verts = node->face_verts = 0;
totface = node->totprim;
@@ -299,6 +299,9 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
map_insert_vert(bvh, map, &node->face_verts,
&node->uniq_verts, (&f->v1)[j]);
}
+
+ if (!paint_is_face_hidden(f, bvh->verts))
+ has_visible = true;
}
node->vert_indices = MEM_callocN(sizeof(int) *
@@ -336,6 +339,8 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !has_visible);
+
BLI_ghash_free(map, NULL, NULL);
}
@@ -351,6 +356,45 @@ static void update_vb(PBVH *bvh, PBVHNode *node, BBC *prim_bbc,
node->orig_vb = node->vb;
}
+/* Returns the number of visible quads in the nodes' grids. */
+int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
+ int *grid_indices, int totgrid,
+ int gridsize)
+{
+ int gridarea = (gridsize - 1) * (gridsize - 1);
+ int i, x, y, totquad;
+
+ /* grid hidden layer is present, so have to check each grid for
+ * visibility */
+
+ for (i = 0, totquad = 0; i < totgrid; i++) {
+ const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
+
+ if (gh) {
+ /* grid hidden are present, have to check each element */
+ for (y = 0; y < gridsize - 1; y++) {
+ for (x = 0; x < gridsize - 1; x++) {
+ if (!paint_is_grid_face_hidden(gh, gridsize, x, y))
+ totquad++;
+ }
+ }
+ }
+ else
+ totquad += gridarea;
+ }
+
+ return totquad;
+}
+
+static void build_grid_leaf_node(PBVH *bvh, PBVHNode *node)
+{
+ int totquads = BKE_pbvh_count_grid_quads(bvh->grid_hidden, node->prim_indices,
+ node->totprim, bvh->gridkey.grid_size);
+ BKE_pbvh_node_fully_hidden_set(node, (totquads == 0));
+ BKE_pbvh_node_mark_rebuild_draw(node);
+}
+
+
static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
int offset, int count)
{
@@ -364,8 +408,9 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
if (bvh->faces)
build_mesh_leaf_node(bvh, bvh->nodes + node_index);
- else
- BKE_pbvh_node_mark_rebuild_draw(bvh->nodes + node_index);
+ else {
+ build_grid_leaf_node(bvh, bvh->nodes + node_index);
+ }
}
/* Return zero if all primitives in the node can be drawn with the
@@ -598,7 +643,7 @@ void BKE_pbvh_free(PBVH *bvh)
BKE_pbvh_node_layer_disp_free(node);
if (node->bm_faces)
- BLI_ghash_free(node->bm_faces, NULL, NULL);
+ BLI_gset_free(node->bm_faces, NULL);
if (node->bm_unique_verts)
BLI_gset_free(node->bm_unique_verts, NULL);
if (node->bm_other_verts)
@@ -622,14 +667,16 @@ void BKE_pbvh_free(PBVH *bvh)
if (bvh->prim_indices)
MEM_freeN(bvh->prim_indices);
- if (bvh->bm_vert_to_node)
- BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
- if (bvh->bm_face_to_node)
- BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
-
MEM_freeN(bvh);
}
+void BKE_pbvh_free_layer_disp(PBVH *bvh)
+{
+ int i;
+ for (i = 0; i < bvh->totnode; ++i)
+ BKE_pbvh_node_layer_disp_free(&bvh->nodes[i]);
+}
+
static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback scb, void *search_data)
{
iter->bvh = bvh;
@@ -1040,7 +1087,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
break;
case PBVH_FACES:
node->draw_buffers =
- GPU_build_pbvh_mesh_buffers(node->face_vert_indices,
+ GPU_build_mesh_pbvh_buffers(node->face_vert_indices,
bvh->faces, bvh->verts,
node->prim_indices,
node->totprim);
@@ -1082,7 +1129,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
bvh->bm,
node->bm_faces,
node->bm_unique_verts,
- node->bm_other_verts);
+ node->bm_other_verts,
+ bvh->show_diffuse_color);
break;
}
@@ -1091,6 +1139,22 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
}
}
+static void pbvh_draw_BB(PBVH *bvh)
+{
+ PBVHNode *node;
+ int a;
+
+ GPU_init_draw_pbvh_BB();
+
+ for (a = 0; a < bvh->totnode; a++) {
+ node = &bvh->nodes[a];
+
+ GPU_draw_pbvh_BB(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
+ }
+
+ GPU_end_draw_pbvh_BB();
+}
+
static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
{
int update = 0;
@@ -1165,17 +1229,17 @@ void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
copy_v3_v3(bb_max, bb.bmax);
}
-void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r_totface)
{
PBVHIter iter;
PBVHNode *node;
- GHashIterator *hiter;
- GHash *map;
+ GSetIterator gs_iter;
+ GSet *face_set;
void *face, **faces;
unsigned i;
int tot;
- map = BLI_ghash_ptr_new("pbvh_get_grid_updates gh");
+ face_set = BLI_gset_ptr_new(__func__);
pbvh_iter_begin(&iter, bvh, NULL, NULL);
@@ -1183,8 +1247,8 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
if (node->flag & PBVH_UpdateNormals) {
for (i = 0; i < node->totprim; ++i) {
face = bvh->gridfaces[node->prim_indices[i]];
- if (!BLI_ghash_lookup(map, face))
- BLI_ghash_insert(map, face, face);
+ if (!BLI_gset_haskey(face_set, face))
+ BLI_gset_insert(face_set, face);
}
if (clear)
@@ -1194,29 +1258,24 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
pbvh_iter_end(&iter);
- tot = BLI_ghash_size(map);
+ tot = BLI_gset_size(face_set);
if (tot == 0) {
- *totface = 0;
- *gridfaces = NULL;
- BLI_ghash_free(map, NULL, NULL);
+ *r_totface = 0;
+ *r_gridfaces = NULL;
+ BLI_gset_free(face_set, NULL);
return;
}
- faces = MEM_callocN(sizeof(void *) * tot, "PBVH Grid Faces");
+ faces = MEM_mallocN(sizeof(*faces) * tot, "PBVH Grid Faces");
- for (hiter = BLI_ghashIterator_new(map), i = 0;
- BLI_ghashIterator_done(hiter) == false;
- BLI_ghashIterator_step(hiter), ++i)
- {
- faces[i] = BLI_ghashIterator_getKey(hiter);
+ GSET_ITER_INDEX (gs_iter, face_set, i) {
+ faces[i] = BLI_gsetIterator_getKey(&gs_iter);
}
- BLI_ghashIterator_free(hiter);
-
- BLI_ghash_free(map, NULL, NULL);
+ BLI_gset_free(face_set, NULL);
- *totface = tot;
- *gridfaces = faces;
+ *r_totface = tot;
+ *r_gridfaces = faces;
}
/***************************** PBVH Access ***********************************/
@@ -1450,14 +1509,16 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
return hit;
}
-static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
- float (*origco)[3],
- const float ray_start[3],
- const float ray_normal[3], float *dist)
+static bool pbvh_grids_node_raycast(
+ PBVH *bvh, PBVHNode *node,
+ float (*origco)[3],
+ const float ray_start[3], const float ray_normal[3],
+ float *dist)
{
int totgrid = node->totprim;
int gridsize = bvh->gridkey.grid_size;
- int i, x, y, hit = 0;
+ int i, x, y;
+ bool hit = false;
for (i = 0; i < totgrid; ++i) {
CCGElem *grid = bvh->grids[node->prim_indices[i]];
@@ -1502,9 +1563,10 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
return hit;
}
-int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
- const float ray_start[3], const float ray_normal[3],
- float *dist)
+bool BKE_pbvh_node_raycast(
+ PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
+ const float ray_start[3], const float ray_normal[3],
+ float *dist)
{
bool hit = false;
@@ -1666,7 +1728,7 @@ static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node)
if (!node->draw_buffers)
return;
- if (GPU_pbvh_buffers_diffuse_changed(node->draw_buffers, bvh->show_diffuse_color))
+ if (GPU_pbvh_buffers_diffuse_changed(node->draw_buffers, node->bm_faces, bvh->show_diffuse_color))
node->flag |= PBVH_UpdateDrawBuffers;
}
@@ -1695,6 +1757,9 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
else {
BKE_pbvh_search_callback(bvh, NULL, NULL, BKE_pbvh_node_draw, &draw_data);
}
+
+ if (G.debug_value == 14)
+ pbvh_draw_BB(bvh);
}
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
@@ -1917,5 +1982,20 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
void pbvh_show_diffuse_color_set(PBVH *bvh, bool show_diffuse_color)
{
- bvh->show_diffuse_color = show_diffuse_color;
+ bool has_mask = false;
+
+ switch (bvh->type) {
+ case PBVH_GRIDS:
+ has_mask = (bvh->gridkey.has_mask != 0);
+ break;
+ case PBVH_FACES:
+ has_mask = (bvh->vdata && CustomData_get_layer(bvh->vdata,
+ CD_PAINT_MASK));
+ break;
+ case PBVH_BMESH:
+ has_mask = (bvh->bm && (CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK) != -1));
+ break;
+ }
+
+ bvh->show_diffuse_color = !has_mask || show_diffuse_color;
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 0176d2055cd..83e0d1a4740 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -32,8 +32,6 @@
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
-#include "BKE_paint.h"
#include "BKE_pbvh.h"
#include "GPU_buffers.h"
@@ -46,10 +44,11 @@
/****************************** Building ******************************/
/* Update node data after splitting */
-static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
+static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index, const int cd_vert_node_offset, const int cd_face_node_offset)
{
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
PBVHNode *n = &bvh->nodes[node_index];
+ bool has_visible = false;
/* Create vert hash sets */
n->bm_unique_verts = BLI_gset_ptr_new("bm_unique_verts");
@@ -57,32 +56,34 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
BB_reset(&n->vb);
- GHASH_ITER (gh_iter, n->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, n->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
BMLoop *l_iter;
BMLoop *l_first;
BMVert *v;
- void *node_val = SET_INT_IN_POINTER(node_index);
/* Update ownership of faces */
- BLI_ghash_insert(bvh->bm_face_to_node, f, node_val);
+ BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
- /* Update vertices */
+ /* Update vertices */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
v = l_iter->v;
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
- if (BLI_ghash_haskey(bvh->bm_vert_to_node, v)) {
+ if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
BLI_gset_reinsert(n->bm_other_verts, v, NULL);
}
else {
BLI_gset_insert(n->bm_unique_verts, v);
- BLI_ghash_insert(bvh->bm_vert_to_node, v, node_val);
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
}
}
/* Update node bounding box */
BB_expand(&n->vb, v->co);
} while ((l_iter = l_iter->next) != l_first);
+
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
+ has_visible = true;
}
BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
@@ -93,32 +94,34 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
/* Build GPU buffers for new node and update vertex normals */
BKE_pbvh_node_mark_rebuild_draw(n);
+
+ BKE_pbvh_node_fully_hidden_set(n, !has_visible);
n->flag |= PBVH_UpdateNormals;
}
/* Recursively split the node if it exceeds the leaf_limit */
static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
{
- GHash *empty, *other;
- GHashIterator gh_iter;
+ GSet *empty, *other;
GSetIterator gs_iter;
PBVHNode *n, *c1, *c2;
BB cb;
float mid;
int axis, children;
-
+ const int cd_vert_node_offset = bvh->cd_vert_node_offset;
+ const int cd_face_node_offset = bvh->cd_face_node_offset;
n = &bvh->nodes[node_index];
- if (BLI_ghash_size(n->bm_faces) <= bvh->leaf_limit) {
+ if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) {
/* Node limit not exceeded */
- pbvh_bmesh_node_finalize(bvh, node_index);
+ pbvh_bmesh_node_finalize(bvh, node_index, cd_vert_node_offset, cd_face_node_offset);
return;
}
/* Calculate bounding box around primitive centroids */
BB_reset(&cb);
- GHASH_ITER (gh_iter, n->bm_faces) {
- const BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, n->bm_faces) {
+ const BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
BB_expand(&cb, bbc->bcentroid);
@@ -141,35 +144,35 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
c2 = &bvh->nodes[children + 1];
c1->flag |= PBVH_Leaf;
c2->flag |= PBVH_Leaf;
- c1->bm_faces = BLI_ghash_ptr_new_ex("bm_faces", BLI_ghash_size(n->bm_faces) / 2);
- c2->bm_faces = BLI_ghash_ptr_new_ex("bm_faces", BLI_ghash_size(n->bm_faces) / 2);
+ c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
+ c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
/* Partition the parent node's faces between the two children */
- GHASH_ITER (gh_iter, n->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, n->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
if (bbc->bcentroid[axis] < mid)
- BLI_ghash_insert(c1->bm_faces, f, NULL);
+ BLI_gset_insert(c1->bm_faces, f);
else
- BLI_ghash_insert(c2->bm_faces, f, NULL);
+ BLI_gset_insert(c2->bm_faces, f);
}
/* Enforce at least one primitive in each node */
empty = NULL;
- if (BLI_ghash_size(c1->bm_faces) == 0) {
+ if (BLI_gset_size(c1->bm_faces) == 0) {
empty = c1->bm_faces;
other = c2->bm_faces;
}
- else if (BLI_ghash_size(c2->bm_faces) == 0) {
+ else if (BLI_gset_size(c2->bm_faces) == 0) {
empty = c2->bm_faces;
other = c1->bm_faces;
}
if (empty) {
- GHASH_ITER (gh_iter, other) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BLI_ghash_insert(empty, key, NULL);
- BLI_ghash_remove(other, key, NULL, NULL);
+ GSET_ITER (gs_iter, other) {
+ void *key = BLI_gsetIterator_getKey(&gs_iter);
+ BLI_gset_insert(empty, key);
+ BLI_gset_remove(other, key, NULL);
break;
}
}
@@ -180,17 +183,17 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
if (n->bm_unique_verts) {
GSET_ITER (gs_iter, n->bm_unique_verts) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
}
BLI_gset_free(n->bm_unique_verts, NULL);
}
/* Unclaim faces */
- GHASH_ITER (gh_iter, n->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
- BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+ GSET_ITER (gs_iter, n->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
+ BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
}
- BLI_ghash_free(n->bm_faces, NULL, NULL);
+ BLI_gset_free(n->bm_faces, NULL);
if (n->bm_other_verts)
BLI_gset_free(n->bm_other_verts, NULL);
@@ -225,28 +228,28 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
}
/* Recursively split the node if it exceeds the leaf_limit */
-static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
+static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
{
GHash *prim_bbc;
- GHash *bm_faces;
+ GSet *bm_faces;
int bm_faces_size;
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
BBC *bbc_array;
unsigned int i;
bm_faces = bvh->nodes[node_index].bm_faces;
- bm_faces_size = BLI_ghash_size(bm_faces);
+ bm_faces_size = BLI_gset_size(bm_faces);
if (bm_faces_size <= bvh->leaf_limit) {
/* Node limit not exceeded */
- return FALSE;
+ return false;
}
/* For each BMFace, store the AABB and AABB centroid */
prim_bbc = BLI_ghash_ptr_new_ex("prim_bbc", bm_faces_size);
bbc_array = MEM_callocN(sizeof(BBC) * bm_faces_size, "BBC");
- GHASH_ITER_INDEX (gh_iter, bm_faces, i) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER_INDEX (gs_iter, bm_faces, i) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
BBC *bbc = &bbc_array[i];
BMLoop *l_iter;
BMLoop *l_first;
@@ -266,18 +269,17 @@ static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
BLI_ghash_free(prim_bbc, NULL, NULL);
MEM_freeN(bbc_array);
- return TRUE;
+ return true;
}
/**********************************************************************/
-static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
+static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, void *key, const int cd_node_offset)
{
- int node_index;
+ int node_index = BM_ELEM_CD_GET_INT((BMElem *)key, cd_node_offset);
- BLI_assert(BLI_ghash_haskey(map, key));
+ BLI_assert(node_index != DYNTOPO_NODE_NONE);
- node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
BLI_assert(node_index < bvh->totnode);
return &bvh->nodes[node_index];
@@ -285,48 +287,54 @@ static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
const float co[3],
- const BMVert *example)
+ const BMVert *example,
+ const int cd_vert_mask_offset,
+ const int cd_vert_node_offset)
{
BMVert *v = BM_vert_create(bvh->bm, co, example, BM_CREATE_NOP);
- void *val = SET_INT_IN_POINTER(node_index);
+ PBVHNode *node = &bvh->nodes[node_index];
BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
- BLI_gset_insert(bvh->nodes[node_index].bm_unique_verts, v);
- BLI_ghash_insert(bvh->bm_vert_to_node, v, val);
+ BLI_gset_insert(node->bm_unique_verts, v);
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
+
+ node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
/* Log the new vertex */
- BM_log_vert_added(bvh->bm, bvh->bm_log, v);
+ BM_log_vert_added(bvh->bm_log, v, cd_vert_mask_offset);
return v;
}
static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index,
BMVert *v_tri[3], BMEdge *e_tri[3],
- const BMFace *f_example)
+ const BMFace *f_example, const int cd_face_node_offset)
{
BMFace *f;
- void *val = SET_INT_IN_POINTER(node_index);
+ PBVHNode *node = &bvh->nodes[node_index];
/* ensure we never add existing face */
BLI_assert(BM_face_exists(v_tri, 3, NULL) == false);
f = BM_face_create(bvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
+ f->head.hflag = f_example->head.hflag;
- if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) {
+ BLI_gset_insert(node->bm_faces, f);
+ BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
- BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL);
- BLI_ghash_insert(bvh->bm_face_to_node, f, val);
+ /* mark node for update */
+ node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
+ node->flag &= ~PBVH_FullyHidden;
- /* Log the new face */
- BM_log_face_added(bvh->bm_log, f);
- }
+ /* Log the new face */
+ BM_log_face_added(bvh->bm_log, f);
return f;
}
/* Return the number of faces in 'node' that use vertex 'v' */
-static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
+static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v, const int cd_face_node_offset)
{
BMIter bm_iter;
BMFace *f;
@@ -335,7 +343,7 @@ static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
PBVHNode *f_node;
- f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ f_node = pbvh_bmesh_node_lookup(bvh, f, cd_face_node_offset);
if (f_node == node)
count++;
@@ -345,18 +353,20 @@ static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
}
/* Return a node that uses vertex 'v' other than its current owner */
-static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
+static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v,
+ const int cd_vert_node_offset,
+ const int cd_face_node_offset)
{
BMIter bm_iter;
BMFace *f;
PBVHNode *current_node;
- current_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ current_node = pbvh_bmesh_node_lookup(bvh, v, cd_vert_node_offset);
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
PBVHNode *f_node;
- f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ f_node = pbvh_bmesh_node_lookup(bvh, f, cd_face_node_offset);
if (f_node != current_node)
return f_node;
@@ -366,42 +376,47 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
}
static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
- BMVert *v)
+ BMVert *v, const int cd_vert_node_offset)
{
PBVHNode *current_owner;
- current_owner = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ current_owner = pbvh_bmesh_node_lookup(bvh, v, cd_vert_node_offset);
+ /* mark node for update */
+ current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
+
+
BLI_assert(current_owner != new_owner);
/* Remove current ownership */
BLI_gset_remove(current_owner->bm_unique_verts, v, NULL);
/* Set new ownership */
- BLI_ghash_reinsert(bvh->bm_vert_to_node, v,
- SET_INT_IN_POINTER(new_owner - bvh->nodes), NULL, NULL);
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, new_owner - bvh->nodes);
BLI_gset_insert(new_owner->bm_unique_verts, v);
BLI_gset_remove(new_owner->bm_other_verts, v, NULL);
BLI_assert(!BLI_gset_haskey(new_owner->bm_other_verts, v));
+
+ /* mark node for update */
+ new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
}
-static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
+static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v, const int cd_vert_node_offset, const int cd_face_node_offset)
{
PBVHNode *v_node;
BMIter bm_iter;
BMFace *f;
- BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
- v_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ v_node = pbvh_bmesh_node_lookup(bvh, v, cd_vert_node_offset);
BLI_gset_remove(v_node->bm_unique_verts, v, NULL);
- BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
/* Have to check each neighboring face's node */
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
- PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, f, cd_face_node_offset);
+
+ f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
/* Remove current ownership */
- /* Should be handled above by vert_to_node removal, leaving just in case - psy-fi */
- //BLI_ghash_remove(f_node->bm_unique_verts, v, NULL, NULL);
BLI_gset_remove(f_node->bm_other_verts, v, NULL);
BLI_assert(!BLI_gset_haskey(f_node->bm_unique_verts, v));
@@ -409,7 +424,7 @@ static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
}
}
-static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
+static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f, const int cd_vert_node_offset, const int cd_face_node_offset)
{
PBVHNode *f_node;
BMVert *v;
@@ -417,23 +432,23 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
BMLoop *l_iter;
BMLoop *l_first;
- f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ f_node = pbvh_bmesh_node_lookup(bvh, f, cd_face_node_offset);
/* Check if any of this face's vertices need to be removed
* from the node */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
v = l_iter->v;
- if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v) == 1) {
+ if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v, cd_face_node_offset) == 1) {
if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
/* Find a different node that uses 'v' */
PBVHNode *new_node;
- new_node = pbvh_bmesh_vert_other_node_find(bvh, v);
+ new_node = pbvh_bmesh_vert_other_node_find(bvh, v, cd_vert_node_offset, cd_face_node_offset);
BLI_assert(new_node || BM_vert_face_count(v) == 1);
if (new_node) {
- pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v);
+ pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v, cd_vert_node_offset);
}
}
else {
@@ -444,11 +459,14 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
} while ((l_iter = l_iter->next) != l_first);
/* Remove face from node and top level */
- BLI_ghash_remove(f_node->bm_faces, f, NULL, NULL);
- BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+ BLI_gset_remove(f_node->bm_faces, f, NULL);
+ BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
/* Log removed face */
BM_log_face_removed(bvh->bm_log, f);
+
+ /* mark node for update */
+ f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
}
static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
@@ -492,6 +510,8 @@ typedef struct {
BLI_mempool *pool;
BMesh *bm;
int cd_vert_mask_offset;
+ int cd_vert_node_offset;
+ int cd_face_node_offset;
} EdgeQueueContext;
static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
@@ -526,7 +546,10 @@ static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e,
* should already make the brush move the vertices only 50%, which means
* that topology updates will also happen less frequent, that should be
* enough. */
- if (check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2)) {
+ if ((check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2)) &&
+ !(BM_elem_flag_test_bool(e->v1, BM_ELEM_HIDDEN) ||
+ BM_elem_flag_test_bool(e->v2, BM_ELEM_HIDDEN)))
+ {
pair = BLI_mempool_alloc(eq_ctx->pool);
pair[0] = e->v1;
pair[1] = e->v2;
@@ -539,7 +562,7 @@ static void long_edge_queue_edge_add(EdgeQueueContext *eq_ctx,
{
const float len_sq = BM_edge_calc_length_squared(e);
if (len_sq > eq_ctx->q->limit_len_squared)
- edge_queue_insert(eq_ctx, e, 1.0f / len_sq);
+ edge_queue_insert(eq_ctx, e, -len_sq);
}
static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx,
@@ -605,13 +628,14 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
/* Check leaf nodes marked for topology update */
if ((node->flag & PBVH_Leaf) &&
- (node->flag & PBVH_UpdateTopology))
+ (node->flag & PBVH_UpdateTopology) &&
+ !(node->flag & PBVH_FullyHidden))
{
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
/* Check each face */
- GHASH_ITER (gh_iter, node->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
long_edge_queue_face_add(eq_ctx, f);
}
@@ -644,13 +668,14 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
/* Check leaf nodes marked for topology update */
if ((node->flag & PBVH_Leaf) &&
- (node->flag & PBVH_UpdateTopology))
+ (node->flag & PBVH_UpdateTopology) &&
+ !(node->flag & PBVH_FullyHidden))
{
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
/* Check each face */
- GHASH_ITER (gh_iter, node->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
short_edge_queue_face_add(eq_ctx, f);
}
@@ -673,7 +698,6 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
BMVert *v_new;
float mid[3];
int i, node_index;
- const int cd_vert_mask_offset = CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK);
/* Get all faces adjacent to the edge */
pbvh_bmesh_edge_loops(edge_loops, e);
@@ -681,17 +705,16 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
/* Create a new vertex in current node at the edge's midpoint */
mid_v3_v3v3(mid, e->v1->co, e->v2->co);
- node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(bvh->bm_vert_to_node,
- e->v1));
- v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
+ node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
+ v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1, eq_ctx->cd_vert_mask_offset, eq_ctx->cd_vert_node_offset);
/* update paint mask */
- if (cd_vert_mask_offset != -1) {
- float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, cd_vert_mask_offset);
- float mask_v2 = BM_ELEM_CD_GET_FLOAT(e->v2, cd_vert_mask_offset);
+ if (eq_ctx->cd_vert_mask_offset != -1) {
+ float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, eq_ctx->cd_vert_mask_offset);
+ float mask_v2 = BM_ELEM_CD_GET_FLOAT(e->v2, eq_ctx->cd_vert_mask_offset);
float mask_v_new = 0.5f * (mask_v1 + mask_v2);
- BM_ELEM_CD_SET_FLOAT(v_new, cd_vert_mask_offset, mask_v_new);
+ BM_ELEM_CD_SET_FLOAT(v_new, eq_ctx->cd_vert_mask_offset, mask_v_new);
}
/* For each face, add two new triangles and delete the original */
@@ -702,15 +725,10 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
BMVert *v_opp, *v1, *v2;
BMVert *v_tri[3];
BMEdge *e_tri[3];
- void *nip;
int ni;
BLI_assert(f_adj->len == 3);
- nip = BLI_ghash_lookup(bvh->bm_face_to_node, f_adj);
- ni = GET_INT_FROM_POINTER(nip);
-
- /* Ensure node gets redrawn */
- bvh->nodes[ni].flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals;
+ ni = BM_ELEM_CD_GET_INT(f_adj, eq_ctx->cd_face_node_offset);
/* Find the vertex not in the edge */
v_opp = l_adj->prev->v;
@@ -722,14 +740,14 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
v2 = l_adj->next->v;
if (ni != node_index && i == 0)
- pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new);
+ pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new, eq_ctx->cd_vert_node_offset);
/* Create two new faces */
v_tri[0] = v1;
v_tri[1] = v_new;
v_tri[2] = v_opp;
bm_edges_from_tri(bvh->bm, v_tri, e_tri);
- f_new = pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f_adj);
+ f_new = pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f_adj, eq_ctx->cd_face_node_offset);
long_edge_queue_face_add(eq_ctx, f_new);
v_tri[0] = v_new;
@@ -738,11 +756,11 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
e_tri[0] = BM_edge_create(bvh->bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
e_tri[2] = e_tri[1]; /* switched */
e_tri[1] = BM_edge_create(bvh->bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
- f_new = pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f_adj);
+ f_new = pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f_adj, eq_ctx->cd_face_node_offset);
long_edge_queue_face_add(eq_ctx, f_new);
/* Delete original */
- pbvh_bmesh_face_remove(bvh, f_adj);
+ pbvh_bmesh_face_remove(bvh, f_adj, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
BM_face_kill(bvh->bm, f_adj);
/* Ensure new vertex is in the node */
@@ -765,38 +783,38 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
BM_edge_kill(bvh->bm, e);
}
-static int pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *bvh,
- BLI_Buffer *edge_loops)
+static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *bvh,
+ BLI_Buffer *edge_loops)
{
- int any_subdivided = FALSE;
+ bool any_subdivided = false;
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap);
+ BMVert *v1 = pair[0], *v2 = pair[1];
BMEdge *e;
+ BLI_mempool_free(eq_ctx->pool, pair);
+ pair = NULL;
+
+ if (len_squared_v3v3(v1->co, v2->co) <= eq_ctx->q->limit_len_squared)
+ continue;
+
/* Check that the edge still exists */
- if (!(e = BM_edge_exists(pair[0], pair[1]))) {
- BLI_mempool_free(eq_ctx->pool, pair);
+ if (!(e = BM_edge_exists(v1, v2))) {
continue;
}
- BLI_mempool_free(eq_ctx->pool, pair);
- pair = NULL;
-
/* Check that the edge's vertices are still in the PBVH. It's
* possible that an edge collapse has deleted adjacent faces
* and the node has been split, thus leaving wire edges and
* associated vertices. */
- if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
- !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
+ (BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE))
{
continue;
}
- if (BM_edge_calc_length_squared(e) <= eq_ctx->q->limit_len_squared)
- continue;
-
- any_subdivided = TRUE;
+ any_subdivided = true;
pbvh_bmesh_split_edge(eq_ctx, bvh, e, edge_loops);
}
@@ -804,52 +822,66 @@ static int 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, GHash *deleted_verts,
+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)
+ BLI_Buffer *deleted_faces,
+ EdgeQueueContext *eq_ctx)
{
BMIter bm_iter;
BMFace *f;
+ BMVert *v_del, *v_conn;
int i;
+ float mask_v1 = BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset);
+
+ /* one of the two vertices may be masked, select the correct one for deletion */
+ if (mask_v1 < 1.0f) {
+ v_del = v1;
+ v_conn = v2;
+ }
+ else {
+ v_del = v2;
+ 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, v2);
+ 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);
BMFace *f_adj = l_adj->f;
- pbvh_bmesh_face_remove(bvh, f_adj);
+ pbvh_bmesh_face_remove(bvh, f_adj, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
BM_face_kill(bvh->bm, f_adj);
}
/* Kill the edge */
- BLI_assert(BM_edge_face_count(e) == 0);
+ BLI_assert(BM_edge_is_wire(e));
BM_edge_kill(bvh->bm, e);
- /* For all remaining faces of v2, create a new face that is the
- * same except it uses v1 instead of v2 */
+ /* For all remaining faces of v_del, create a new face that is the
+ * same except it uses v_conn instead of v_del */
/* Note: this could be done with BM_vert_splice(), but that
* requires handling other issues like duplicate edges, so doesn't
* really buy anything. */
deleted_faces->count = 0;
- BM_ITER_ELEM (f, &bm_iter, v2, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM (f, &bm_iter, v_del, BM_FACES_OF_VERT) {
BMVert *v_tri[3];
BMFace *existing_face;
PBVHNode *n;
int ni;
- /* Get vertices, replace use of v2 with v1 */
+ /* Get vertices, replace use of v_del with v_conn */
// BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
BM_face_as_array_vert_tri(f, v_tri);
for (i = 0; i < 3; i++) {
- if (v_tri[i] == v2) {
- v_tri[i] = v1;
+ if (v_tri[i] == v_del) {
+ v_tri[i] = v_conn;
}
}
@@ -863,16 +895,16 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
}
else {
BMEdge *e_tri[3];
- n = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ n = pbvh_bmesh_node_lookup(bvh, f, eq_ctx->cd_face_node_offset);
ni = n - bvh->nodes;
bm_edges_from_tri(bvh->bm, v_tri, e_tri);
- pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f);
+ pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f, eq_ctx->cd_face_node_offset);
- /* Ensure that v1 is in the new face's node */
- if (!BLI_gset_haskey(n->bm_unique_verts, v1) &&
- !BLI_gset_haskey(n->bm_other_verts, v1))
+ /* Ensure that v_conn is in the new face's node */
+ if (!BLI_gset_haskey(n->bm_unique_verts, v_conn) &&
+ !BLI_gset_haskey(n->bm_other_verts, v_conn))
{
- BLI_gset_insert(n->bm_other_verts, v1);
+ BLI_gset_insert(n->bm_other_verts, v_conn);
}
}
@@ -897,9 +929,9 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
/* Check if any of the face's vertices are now unused, if so
* remove them from the PBVH */
for (j = 0; j < 3; j++) {
- if (v_tri[j] != v2 && BM_vert_face_count(v_tri[j]) == 1) {
- BLI_ghash_insert(deleted_verts, v_tri[j], NULL);
- pbvh_bmesh_vert_remove(bvh, v_tri[j]);
+ if (v_tri[j] != v_del && BM_vert_face_count(v_tri[j]) == 1) {
+ BLI_gset_insert(deleted_verts, v_tri[j]);
+ pbvh_bmesh_vert_remove(bvh, v_tri[j], eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
}
else {
v_tri[j] = NULL;
@@ -907,101 +939,102 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
}
/* Remove the face */
- pbvh_bmesh_face_remove(bvh, f_del);
+ pbvh_bmesh_face_remove(bvh, f_del, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
BM_face_kill(bvh->bm, f_del);
/* Check if any of the face's edges are now unused by any
* face, if so delete them */
for (j = 0; j < 3; j++) {
- if (BM_edge_face_count(e_tri[j]) == 0)
+ if (BM_edge_is_wire(e_tri[j]))
BM_edge_kill(bvh->bm, e_tri[j]);
}
/* Delete unused vertices */
for (j = 0; j < 3; j++) {
if (v_tri[j]) {
- BM_log_vert_removed(bvh->bm, bvh->bm_log, v_tri[j]);
+ BM_log_vert_removed(bvh->bm_log, v_tri[j], eq_ctx->cd_vert_mask_offset);
BM_vert_kill(bvh->bm, v_tri[j]);
}
}
}
- /* Move v1 to the midpoint of v1 and v2 (if v1 still exists, it
+ /* Move v_conn to the midpoint of v_conn and v_del (if v_conn still exists, it
* may have been deleted above) */
- if (!BLI_ghash_haskey(deleted_verts, v1)) {
- BM_log_vert_before_modified(bvh->bm, bvh->bm_log, v1);
- mid_v3_v3v3(v1->co, v1->co, v2->co);
+ if (!BLI_gset_haskey(deleted_verts, v_conn)) {
+ BM_log_vert_before_modified(bvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset);
+ mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
}
- /* Delete v2 */
- BLI_assert(BM_vert_face_count(v2) == 0);
- BLI_ghash_insert(deleted_verts, v2, NULL);
- BM_log_vert_removed(bvh->bm, bvh->bm_log, v2);
- BM_vert_kill(bvh->bm, v2);
+ /* Delete v_del */
+ BLI_assert(BM_vert_face_count(v_del) == 0);
+ BLI_gset_insert(deleted_verts, v_del);
+ BM_log_vert_removed(bvh->bm_log, v_del, eq_ctx->cd_vert_mask_offset);
+ BM_vert_kill(bvh->bm, v_del);
}
-static int 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 *edge_loops,
+ BLI_Buffer *deleted_faces)
{
float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
- GHash *deleted_verts;
- int any_collapsed = FALSE;
+ GSet *deleted_verts;
+ bool any_collapsed = false;
- deleted_verts = BLI_ghash_ptr_new("deleted_verts");
+ deleted_verts = BLI_gset_ptr_new("deleted_verts");
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap);
+ BMVert *v1 = pair[0], *v2 = pair[1];
BMEdge *e;
- BMVert *v1, *v2;
- v1 = pair[0];
- v2 = pair[1];
BLI_mempool_free(eq_ctx->pool, pair);
pair = NULL;
- /* Check that the vertices/edge still exist */
- if (BLI_ghash_haskey(deleted_verts, v1) ||
- BLI_ghash_haskey(deleted_verts, v2) ||
- !(e = BM_edge_exists(v1, v2)))
+ /* Check the verts still exist */
+ if (BLI_gset_haskey(deleted_verts, v1) ||
+ BLI_gset_haskey(deleted_verts, v2))
{
continue;
}
+ if (len_squared_v3v3(v1->co, v2->co) >= min_len_squared)
+ continue;
+
+ /* Check that the edge still exists */
+ if (!(e = BM_edge_exists(v1, v2))) {
+ continue;
+ }
+
/* Check that the edge's vertices are still in the PBVH. It's
* possible that an edge collapse has deleted adjacent faces
* and the node has been split, thus leaving wire edges and
* associated vertices. */
- if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
- !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
+ (BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE))
{
continue;
}
- if (BM_edge_calc_length_squared(e) >= min_len_squared)
- continue;
-
- any_collapsed = TRUE;
+ any_collapsed = true;
pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
deleted_verts, edge_loops,
- deleted_faces);
+ deleted_faces, eq_ctx);
}
- BLI_ghash_free(deleted_verts, NULL, NULL);
+ BLI_gset_free(deleted_verts, NULL);
return any_collapsed;
}
/************************* Called from pbvh.c *************************/
-int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+bool pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
const float ray_normal[3], float *dist,
- int use_original)
+ bool use_original)
{
- GHashIterator gh_iter;
- int hit = 0;
+ bool hit = false;
if (use_original && node->bm_tot_ortri) {
int i;
@@ -1015,11 +1048,13 @@ int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
}
}
else {
- GHASH_ITER (gh_iter, node->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSetIterator gs_iter;
+
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
BLI_assert(f->len == 3);
- if (f->len == 3 && !paint_is_bmesh_face_hidden(f)) {
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMVert *v_tri[3];
BM_face_as_array_vert_tri(f, v_tri);
@@ -1035,6 +1070,55 @@ int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
return hit;
}
+bool BKE_pbvh_bmesh_node_raycast_detail(
+ PBVHNode *node,
+ const float ray_start[3], const float ray_normal[3],
+ float *detail, float *dist)
+{
+ GSetIterator gs_iter;
+ bool hit = false;
+ BMFace *f_hit = NULL;
+
+ if (node->flag & PBVH_FullyHidden)
+ return 0;
+
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
+
+ BLI_assert(f->len == 3);
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ BMVert *v_tri[3];
+ bool hit_local;
+ BM_face_as_array_vert_tri(f, v_tri);
+ hit_local = ray_face_intersection(
+ ray_start, ray_normal,
+ v_tri[0]->co,
+ v_tri[1]->co,
+ v_tri[2]->co,
+ NULL, dist);
+
+ if (hit_local) {
+ f_hit = f;
+ hit = true;
+ }
+ }
+ }
+
+ if (hit) {
+ float len1, len2, len3;
+ BMVert *v_tri[3];
+ BM_face_as_array_vert_tri(f_hit, v_tri);
+ len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
+ len2 = len_squared_v3v3(v_tri[1]->co, v_tri[2]->co);
+ len3 = len_squared_v3v3(v_tri[2]->co, v_tri[0]->co);
+
+ /* detail returned will be set to the maximum allowed size, so take max here */
+ *detail = sqrtf(max_fff(len1, len2, len3));
+ }
+
+ return hit;
+}
+
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
{
@@ -1044,11 +1128,10 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
PBVHNode *node = nodes[n];
if (node->flag & PBVH_UpdateNormals) {
- GHashIterator gh_iter;
GSetIterator gs_iter;
- GHASH_ITER (gh_iter, node->bm_faces) {
- BM_face_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BM_face_normal_update(BLI_gsetIterator_getKey(&gs_iter));
}
GSET_ITER (gs_iter, node->bm_unique_verts) {
BM_vert_normal_update(BLI_gsetIterator_getKey(&gs_iter));
@@ -1064,22 +1147,42 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
/***************************** Public API *****************************/
+static void pbvh_bmesh_node_layers_reset(PBVH *bvh)
+{
+ BMFace *f;
+ BMVert *v;
+ BMIter iter;
+ BMesh *bm = bvh->bm;
+ int cd_vert_node_offset = bvh->cd_vert_node_offset;
+ int cd_face_node_offset = bvh->cd_face_node_offset;
+
+ /* clear the elements of the node information */
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
+ }
+
+ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
+ }
+}
+
+
/* Build a PBVH from a BMesh */
-void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
- BMLog *log)
+void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log,
+ const int cd_vert_node_offset, const int cd_face_node_offset)
{
BMIter iter;
BMFace *f;
PBVHNode *n;
int node_index = 0;
+ bvh->cd_vert_node_offset = cd_vert_node_offset;
+ bvh->cd_face_node_offset = cd_face_node_offset;
bvh->bm = bm;
BKE_pbvh_bmesh_detail_size_set(bvh, 0.75);
bvh->type = PBVH_BMESH;
- bvh->bm_face_to_node = BLI_ghash_ptr_new("bm_face_to_node");
- bvh->bm_vert_to_node = BLI_ghash_ptr_new("bm_vert_to_node");
bvh->bm_log = log;
/* TODO: choose leaf limit better */
@@ -1088,40 +1191,44 @@ void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
if (smooth_shading)
bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
+ pbvh_bmesh_node_layers_reset(bvh);
+
/* Start with all faces in the root node */
n = bvh->nodes = MEM_callocN(sizeof(PBVHNode), "PBVHNode");
bvh->totnode = 1;
n->flag = PBVH_Leaf;
- n->bm_faces = BLI_ghash_ptr_new_ex("bm_faces", bvh->bm->totface);
+ n->bm_faces = BLI_gset_ptr_new_ex("bm_faces", bvh->bm->totface);
BM_ITER_MESH (f, &iter, bvh->bm, BM_FACES_OF_MESH) {
- BLI_ghash_insert(n->bm_faces, f, NULL);
+ BLI_gset_insert(n->bm_faces, f);
}
/* Recursively split the node until it is under the limit; if no
* splitting occurs then finalize the existing leaf node */
if (!pbvh_bmesh_node_limit_ensure(bvh, node_index))
- pbvh_bmesh_node_finalize(bvh, 0);
+ pbvh_bmesh_node_finalize(bvh, 0, cd_vert_node_offset, cd_face_node_offset);
}
/* Collapse short edges, subdivide long edges */
-int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+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(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;
+ const int cd_face_node_offset = bvh->cd_face_node_offset;
- int modified = FALSE;
+ bool modified = false;
int n;
if (mode & PBVH_Collapse) {
EdgeQueue q;
- BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]),
- 128, 128, 0);
- EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset};
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]), 0, 128, BLI_MEMPOOL_NOP);
+ EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset};
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,
&deleted_faces);
BLI_heap_free(q.heap, NULL);
@@ -1130,11 +1237,11 @@ int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
if (mode & PBVH_Subdivide) {
EdgeQueue q;
- BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]),
- 128, 128, 0);
- EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset};
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]), 0, 128, BLI_MEMPOOL_NOP);
+ EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset};
long_edge_queue_create(&eq_ctx, bvh, center, radius);
+ modified |= !BLI_heap_is_empty(q.heap);
pbvh_bmesh_subdivide_long_edges(&eq_ctx, bvh, &edge_loops);
BLI_heap_free(q.heap, NULL);
BLI_mempool_destroy(queue_pool);
@@ -1173,7 +1280,6 @@ BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
* Skips triangles that are hidden. */
void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
{
- GHashIterator gh_iter;
GSetIterator gs_iter;
int i, totvert, tottri;
@@ -1184,10 +1290,10 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
totvert = (BLI_gset_size(node->bm_unique_verts) +
BLI_gset_size(node->bm_other_verts));
- tottri = BLI_ghash_size(node->bm_faces);
+ tottri = BLI_gset_size(node->bm_faces);
- node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, AT);
- node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, AT);
+ node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
+ node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
/* Copy out the vertices and assign a temporary index */
i = 0;
@@ -1206,10 +1312,10 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
/* Copy the triangles */
i = 0;
- GHASH_ITER (gh_iter, node->bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, node->bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
- if (paint_is_bmesh_face_hidden(f))
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN))
continue;
#if 0
@@ -1231,6 +1337,7 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
{
int i;
+
for (i = 0; i < bvh->totnode; i++) {
PBVHNode *n = &bvh->nodes[i];
if (n->flag & PBVH_Leaf) {
@@ -1265,29 +1372,14 @@ GSet *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
return node->bm_other_verts;
}
-/****************************** Debugging *****************************/
-
-#if 0
-void bli_ghash_duplicate_key_check(GHash *gh)
+struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node)
{
- GHashIterator gh_iter1, gh_iter2;
-
- GHASH_ITER (gh_iter1, gh) {
- void *key1 = BLI_ghashIterator_getKey(&gh_iter1);
- int dup = -1;
+ return node->bm_faces;
+}
- GHASH_ITER (gh_iter2, gh) {
- void *key2 = BLI_ghashIterator_getKey(&gh_iter2);
+/****************************** Debugging *****************************/
- if (key1 == key2) {
- dup++;
- if (dup > 0) {
- BLI_assert(!"duplicate in hash");
- }
- }
- }
- }
-}
+#if 0
void bli_gset_duplicate_key_check(GSet *gs)
{
@@ -1442,7 +1534,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
BLI_assert(n->flag & PBVH_Leaf);
/* Check that the face's node knows it owns the face */
- BLI_assert(BLI_ghash_haskey(n->bm_faces, f));
+ BLI_assert(BLI_gset_haskey(n->bm_faces, f));
/* Check the face's vertices... */
BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
@@ -1472,7 +1564,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
void *nip = BLI_ghashIterator_getValue(&gh_iter);
int ni = GET_INT_FROM_POINTER(nip);
PBVHNode *n = &bvh->nodes[ni];
- int found;
+ bool found;
/* Check that the vert's node is a leaf */
BLI_assert(n->flag & PBVH_Leaf);
@@ -1487,7 +1579,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
* adjacent faces */
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
if (BLI_ghash_lookup(bvh->bm_face_to_node, f) == nip) {
- found = TRUE;
+ found = true;
break;
}
}
@@ -1530,7 +1622,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
/* Check for duplicate entries */
/* Slow */
#if 0
- bli_ghash_duplicate_key_check(n->bm_faces);
+ bli_gset_duplicate_key_check(n->bm_faces);
bli_gset_duplicate_key_check(n->bm_unique_verts);
bli_gset_duplicate_key_check(n->bm_other_verts);
#endif
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index d4cd6bcf9d8..6b3ef8eb5da 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -104,7 +104,7 @@ struct PBVHNode {
PBVHProxyNode *proxies;
/* Dyntopo */
- GHash *bm_faces;
+ GSet *bm_faces;
GSet *bm_unique_verts;
GSet *bm_other_verts;
float (*bm_orco)[3];
@@ -160,10 +160,10 @@ struct PBVH {
/* Dynamic topology */
BMesh *bm;
- GHash *bm_face_to_node;
- GHash *bm_vert_to_node;
float bm_max_edge_len;
float bm_min_edge_len;
+ int cd_vert_node_offset;
+ int cd_face_node_offset;
struct BMLog *bm_log;
};
@@ -181,9 +181,10 @@ bool ray_face_intersection(const float ray_start[3], const float ray_normal[3],
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
/* pbvh_bmesh.c */
-int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
- const float ray_normal[3], float *dist,
- int use_original);
+bool pbvh_bmesh_node_raycast(
+ PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ bool use_original);
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index df6534946fd..c8042171a94 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
-#include "DNA_cloth_types.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -51,6 +50,8 @@
#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
#include "BLF_translation.h"
@@ -61,10 +62,8 @@
#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_cloth.h"
-#include "BKE_depsgraph.h"
#include "BKE_dynamicpaint.h"
#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -100,9 +99,7 @@
/* untitled blend's need getpid for a unique name */
#ifndef WIN32
# include <dirent.h>
-# include <unistd.h>
#else
-# include <process.h>
# include "BLI_winstuff.h"
#endif
@@ -1059,7 +1056,7 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
if (rbo->type == RBO_TYPE_ACTIVE) {
copy_v3_v3(keys[1].co, rbo->pos);
- copy_v3_v3(keys[1].rot, rbo->orn);
+ copy_qt_qt(keys[1].rot, rbo->orn);
if (old_data) {
memcpy(keys[2].co, data, 3 * sizeof(float));
@@ -1075,7 +1072,7 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
interp_qt_qtqt(keys->rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
copy_v3_v3(rbo->pos, keys->co);
- copy_v3_v3(rbo->orn, keys->rot);
+ copy_qt_qt(rbo->orn, keys->rot);
}
}
}
@@ -1409,7 +1406,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
if (scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
ListBase *lb_dupli_ob;
/* don't update the dupli groups, we only want their pid's */
- if ((lb_dupli_ob = object_duplilist_ex(G.main->eval_ctx, scene, ob, FALSE))) {
+ if ((lb_dupli_ob = object_duplilist_ex(G.main->eval_ctx, scene, ob, false))) {
DupliObject *dob;
for (dob= lb_dupli_ob->first; dob; dob= dob->next) {
if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */
@@ -1493,7 +1490,7 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
idname = (pid->ob->id.name + 2);
/* convert chars to hex so they are always a valid filename */
while ('\0' != *idname) {
- BLI_snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
+ BLI_snprintf(newname, MAX_PTCACHE_FILE, "%02X", (unsigned int)(*idname++));
newname+=2;
len += 2;
}
@@ -3000,7 +2997,7 @@ PointCache *BKE_ptcache_add(ListBase *ptcaches)
cache= MEM_callocN(sizeof(PointCache), "PointCache");
cache->startframe= 1;
cache->endframe= 250;
- cache->step= 10;
+ cache->step = 1;
cache->index = -1;
BLI_addtail(ptcaches, cache);
@@ -3039,7 +3036,7 @@ void BKE_ptcache_free_list(ListBase *ptcaches)
}
}
-static PointCache *ptcache_copy(PointCache *cache, int copy_data)
+static PointCache *ptcache_copy(PointCache *cache, bool copy_data)
{
PointCache *ncache;
@@ -3047,7 +3044,7 @@ static PointCache *ptcache_copy(PointCache *cache, int copy_data)
BLI_listbase_clear(&ncache->mem_cache);
- if (copy_data == FALSE) {
+ if (copy_data == false) {
ncache->cached_frames = NULL;
/* flag is a mix of user settings and simulator/baking state */
@@ -3082,7 +3079,7 @@ static PointCache *ptcache_copy(PointCache *cache, int copy_data)
}
/* returns first point cache */
-PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old, int copy_data)
+PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old, bool copy_data)
{
PointCache *cache = ptcaches_old->first;
@@ -3144,7 +3141,8 @@ static void ptcache_dt_to_str(char *str, double dtime)
static void *ptcache_bake_thread(void *ptr)
{
- int use_timer = FALSE, sfra, efra;
+ bool use_timer = false;
+ int sfra, efra;
double stime, ptime, ctime, fetd;
char run[32], cur[32], etd[32];
@@ -3165,7 +3163,7 @@ static void *ptcache_bake_thread(void *ptr)
fetd = (ctime-ptime)*(efra-*data->cfra_ptr)/data->step;
if (use_timer || fetd > 60.0) {
- use_timer = TRUE;
+ use_timer = true;
ptcache_dt_to_str(cur, ctime-ptime);
ptcache_dt_to_str(run, ctime-stime);
@@ -3183,7 +3181,7 @@ static void *ptcache_bake_thread(void *ptr)
printf("\nBake %s %s (%i frames simulated).\n", (data->break_operation ? "canceled after" : "finished in"), run, *data->cfra_ptr-sfra);
}
- data->thread_ended = TRUE;
+ data->thread_ended = true;
return NULL;
}
@@ -3212,7 +3210,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
thread_data.scene = baker->scene;
thread_data.main = baker->main;
- G.is_break = FALSE;
+ G.is_break = false;
/* set caches to baking mode and figure out start frame */
if (pid) {
@@ -3304,8 +3302,8 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
CFRA = startframe;
scene->r.framelen = 1.0;
- thread_data.break_operation = FALSE;
- thread_data.thread_ended = FALSE;
+ thread_data.break_operation = false;
+ thread_data.thread_ended = false;
old_progress = -1;
WM_cursor_wait(1);
@@ -3317,7 +3315,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
BLI_init_threads(&threads, ptcache_bake_thread, 1);
BLI_insert_thread(&threads, (void*)&thread_data);
- while (thread_data.thread_ended == FALSE) {
+ while (thread_data.thread_ended == false) {
if (bake)
progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe));
@@ -3335,7 +3333,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
/* NOTE: breaking baking should leave calculated frames in cache, not clear it */
if (blender_test_break() && !thread_data.break_operation) {
- thread_data.break_operation = TRUE;
+ thread_data.break_operation = true;
if (baker->progressend)
baker->progressend(baker->progresscontext);
WM_cursor_wait(1);
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 3d0713f9514..90b5d8cf1a1 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -291,15 +291,15 @@ Report *BKE_reports_last_displayable(ReportList *reports)
return NULL;
}
-int BKE_reports_contain(ReportList *reports, ReportType level)
+bool BKE_reports_contain(ReportList *reports, ReportType level)
{
Report *report;
if (reports != NULL) {
for (report = reports->list.first; report; report = report->next)
if (report->type >= level)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 4b4cb054337..8e5b67404ac 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -46,26 +46,20 @@
# include "RBI_api.h"
#endif
-#include "DNA_anim_types.h"
#include "DNA_group_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "BKE_animsys.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_group.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -762,7 +756,7 @@ RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
if (rbwn->constraints)
id_us_plus(&rbwn->constraints->id);
- rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, FALSE);
+ rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, false);
rbwn->objects = NULL;
rbwn->physics_world = NULL;
@@ -941,10 +935,7 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
Object *obt = go->ob;
if (obt && obt->rigidbody_constraint) {
rbc = obt->rigidbody_constraint;
- if (rbc->ob1 == ob) {
- BKE_rigidbody_remove_constraint(scene, obt);
- }
- if (rbc->ob2 == ob) {
+ if (ELEM(ob, rbc->ob1, rbc->ob2)) {
BKE_rigidbody_remove_constraint(scene, obt);
}
}
@@ -1049,7 +1040,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
/* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
- RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+ RB_body_set_kinematic_state(rbo->physics_object, true);
RB_body_set_mass(rbo->physics_object, 0.0f);
}
@@ -1275,7 +1266,7 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
if (rbo->physics_object) {
/* allow passive objects to return to original transform */
if (rbo->type == RBO_TYPE_PASSIVE)
- RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+ RB_body_set_kinematic_state(rbo->physics_object, true);
RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
}
// RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 09bfdbb2d95..0e95cf1d418 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -34,12 +34,6 @@
#include <stdio.h>
#include <string.h>
-#ifndef WIN32
-# include <unistd.h>
-#else
-# include <io.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -80,7 +74,6 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
@@ -476,6 +469,23 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
sce->r.bake_samples = 256;
sce->r.bake_biasdist = 0.001;
+
+ sce->r.bake.flag = R_BAKE_CLEAR;
+ sce->r.bake.width = 512;
+ sce->r.bake.height = 512;
+ sce->r.bake.margin = 16;
+ sce->r.bake.normal_space = R_BAKE_SPACE_TANGENT;
+ sce->r.bake.normal_swizzle[0] = R_BAKE_POSX;
+ sce->r.bake.normal_swizzle[1] = R_BAKE_POSY;
+ sce->r.bake.normal_swizzle[2] = R_BAKE_POSZ;
+ BLI_strncpy(sce->r.bake.filepath, U.renderdir, sizeof(sce->r.bake.filepath));
+
+ sce->r.bake.im_format.planes = R_IMF_PLANES_RGBA;
+ sce->r.bake.im_format.imtype = R_IMF_IMTYPE_PNG;
+ sce->r.bake.im_format.depth = R_IMF_CHAN_DEPTH_8;
+ sce->r.bake.im_format.quality = 90;
+ sce->r.bake.im_format.compress = 15;
+
sce->r.scemode = R_DOCOMP | R_DOSEQ | R_EXTENSION;
sce->r.stamp = R_STAMP_TIME | R_STAMP_FRAME | R_STAMP_DATE | R_STAMP_CAMERA | R_STAMP_SCENE | R_STAMP_FILENAME | R_STAMP_RENDERTIME;
sce->r.stamp_font_id = 12;
@@ -542,6 +552,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->toolsettings->proportional_size = 1.0f;
+ sce->toolsettings->imapaint.paint.flags |= PAINT_SHOW_BRUSH;
+
sce->physics_settings.gravity[0] = 0.0f;
sce->physics_settings.gravity[1] = 0.0f;
sce->physics_settings.gravity[2] = -9.81f;
@@ -738,6 +750,13 @@ static void scene_unlink_space_node(SpaceNode *snode, Scene *sce)
}
}
+static void scene_unlink_space_buts(SpaceButs *sbuts, Scene *sce)
+{
+ if (sbuts->pinid == &sce->id) {
+ sbuts->pinid = NULL;
+ }
+}
+
void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
{
Scene *sce1;
@@ -770,8 +789,14 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
for (area = screen->areabase.first; area; area = area->next) {
SpaceLink *space_link;
for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
- if (space_link->spacetype == SPACE_NODE)
- scene_unlink_space_node((SpaceNode *)space_link, sce);
+ switch (space_link->spacetype) {
+ case SPACE_NODE:
+ scene_unlink_space_node((SpaceNode *)space_link, sce);
+ break;
+ case SPACE_BUTS:
+ scene_unlink_space_buts((SpaceButs *)space_link, sce);
+ break;
+ }
}
}
}
@@ -1268,7 +1293,7 @@ static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Sc
for (base = scene->base.first; base; base = base->next) {
Object *object = base->object;
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+ BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true);
if (object->dup_group && (object->transflag & OB_DUPLIGROUP))
BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group);
@@ -1302,9 +1327,11 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
double start_time = 0.0;
bool add_to_stats = false;
- PRINT("Thread %d: update object %s\n", threadid, object->id.name);
-
if (G.debug & G_DEBUG_DEPSGRAPH) {
+ if (object->recalc & OB_RECALC_ALL) {
+ printf("Thread %d: update object %s\n", threadid, object->id.name);
+ }
+
start_time = PIL_check_seconds_timer();
if (object->recalc & OB_RECALC_ALL) {
@@ -1317,7 +1344,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
* separately from main thread because of we've got no idea about
* dependencies inside the group.
*/
- BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+ BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false);
/* Calculate statistics. */
if (add_to_stats) {
@@ -1333,7 +1360,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
}
else {
PRINT("Threda %d: update node %s\n", threadid,
- DAG_get_node_name(node));
+ DAG_get_node_name(scene, node));
}
/* Update will decrease child's valency and schedule child with zero valency. */
@@ -1442,34 +1469,6 @@ static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene
* BKE_object_handle_update() then we do nothing here.
*/
if (!scene_need_update_objects(bmain)) {
- /* For debug builds we check whether early return didn't give
- * us any regressions in terms of missing updates.
- *
- * TODO(sergey): Remove once we're sure the check above is correct.
- */
-#ifndef NDEBUG
- Base *base;
-
- for (base = scene->base.first; base; base = base->next) {
- Object *object = base->object;
-
- BLI_assert((object->recalc & OB_RECALC_ALL) == 0);
-
- if (object->proxy) {
- BLI_assert((object->proxy->recalc & OB_RECALC_ALL) == 0);
- }
-
- if (object->dup_group && (object->transflag & OB_DUPLIGROUP)) {
- GroupObject *go;
- for (go = object->dup_group->gobject.first; go; go = go->next) {
- if (go->ob) {
- BLI_assert((go->ob->recalc & OB_RECALC_ALL) == 0);
- }
- }
- }
- }
-#endif
-
return;
}
@@ -1537,9 +1536,6 @@ static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bma
/* scene drivers... */
scene_update_drivers(bmain, scene);
- /* update sound system animation */
- sound_update_scene(scene);
-
/* update masking curves */
BKE_mask_update_scene(bmain, scene);
@@ -1573,6 +1569,8 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
* in the future this should handle updates for all datablocks, not
* only objects and scenes. - brecht */
scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
+ /* update sound system animation (TODO, move to depsgraph) */
+ sound_update_scene(bmain, scene);
/* extra call here to recalc scene animation (for sequencer) */
{
@@ -1583,10 +1581,10 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
}
- /* Extra call here to recalc aterial animation.
+ /* Extra call here to recalc material animation.
*
* Need to do this so changing material settings from the graph/dopesheet
- * will update suff in the viewport.
+ * will update stuff in the viewport.
*/
if (DAG_id_type_tagged(bmain, ID_MA)) {
Material *material;
@@ -1604,7 +1602,7 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
- DAG_ids_check_recalc(bmain, scene, FALSE);
+ DAG_ids_check_recalc(bmain, scene, false);
/* clear recalc flags */
DAG_ids_clear_recalc(bmain);
@@ -1613,6 +1611,11 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
/* applies changes right away, does all sets too */
void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay)
{
+ BKE_scene_update_for_newframe_ex(eval_ctx, bmain, sce, lay, false);
+}
+
+void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay, bool do_invisible_flush)
+{
float ctime = BKE_scene_frame_get(sce);
Scene *sce_iter;
#ifdef DETAILED_ANALYSIS_OUTPUT
@@ -1648,7 +1651,7 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
/* Following 2 functions are recursive
* so don't call within 'scene_update_tagged_recursive' */
- DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still
+ DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush); // only stuff that moves or needs display still
BKE_mask_evaluate_all_masks(bmain, ctime, true);
@@ -1673,6 +1676,8 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
/* BKE_object_handle_update() on all objects, groups and sets */
scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
+ /* update sound system animation (TODO, move to depsgraph) */
+ sound_update_scene(bmain, sce);
scene_depsgraph_hack(eval_ctx, sce, sce);
@@ -1680,7 +1685,7 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
- DAG_ids_check_recalc(bmain, sce, TRUE);
+ DAG_ids_check_recalc(bmain, sce, true);
/* clear recalc flags */
DAG_ids_clear_recalc(bmain);
@@ -1885,4 +1890,3 @@ int BKE_scene_num_threads(const Scene *scene)
{
return BKE_render_num_threads(&scene->r);
}
-
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index ab725ae04a9..9d40ee6e667 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -193,7 +193,10 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
BLI_listbase_clear(&newar->panels);
BLI_duplicatelist(&newar->panels, &ar->panels);
-
+
+ BLI_listbase_clear(&newar->ui_previews);
+ BLI_duplicatelist(&newar->ui_previews, &ar->ui_previews);
+
/* copy panel pointers */
for (newpa = newar->panels.first; newpa; newpa = newpa->next) {
patab = newar->panels.first;
@@ -261,7 +264,7 @@ void BKE_spacedata_draw_locks(int set)
if (set)
art->do_lock = art->lock;
else
- art->do_lock = FALSE;
+ art->do_lock = false;
}
}
}
@@ -308,6 +311,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
}
}
BLI_freelistN(&ar->ui_lists);
+ BLI_freelistN(&ar->ui_previews);
BLI_freelistN(&ar->panels_category);
BLI_freelistN(&ar->panels_category_active);
}
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 9755d4b22e7..7ed9af8b87f 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -35,20 +35,16 @@
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "BLI_dynlib.h"
#include "BLI_math.h" /* windows needs for M_PI */
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_anim_types.h"
#include "BKE_fcurve.h"
-#include "BKE_main.h"
#include "BKE_sequencer.h"
-#include "BKE_texture.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -121,13 +117,13 @@ static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, ImBuf *ibuf1,
}
if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
- BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, TRUE);
+ BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, true);
}
if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
- BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, TRUE);
+ BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, true);
}
if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
- BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, TRUE);
+ BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, true);
}
if (ibuf1 && !ibuf1->rect && !out->rect_float) {
@@ -582,7 +578,7 @@ static void do_cross_effect(const SeqRenderData *context, Sequence *UNUSED(seq),
/* copied code from initrender.c */
static unsigned short gamtab[65536];
static unsigned short igamtab1[256];
-static int gamma_tabs_init = FALSE;
+static bool gamma_tabs_init = false;
#define RE_GAMMA_TABLE_SIZE 400
@@ -635,33 +631,35 @@ static void makeGammaTables(float gamma)
static float gammaCorrect(float c)
{
int i;
- float res = 0.0;
+ float res;
- i = floor(c * inv_color_step);
+ i = floorf(c * inv_color_step);
/* Clip to range [0, 1]: outside, just do the complete calculation.
* We may have some performance problems here. Stretching up the LUT
* may help solve that, by exchanging LUT size for the interpolation.
* Negative colors are explicitly handled.
*/
- if (i < 0) res = -pow(abs(c), valid_gamma);
- else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(c, valid_gamma);
- else res = gamma_range_table[i] + ( (c - color_domain_table[i]) * gamfactor_table[i]);
+ if (UNLIKELY(i < 0)) res = -powf(-c, valid_gamma);
+ else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_gamma);
+ else res = gamma_range_table[i] +
+ ((c - color_domain_table[i]) * gamfactor_table[i]);
return res;
}
/* ------------------------------------------------------------------------- */
-static float invGammaCorrect(float col)
+static float invGammaCorrect(float c)
{
int i;
float res = 0.0;
- i = floor(col * inv_color_step);
+ i = floorf(c * inv_color_step);
/* Negative colors are explicitly handled */
- if (i < 0) res = -pow(abs(col), valid_inv_gamma);
- else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
- else res = inv_gamma_range_table[i] + ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
+ if (UNLIKELY(i < 0)) res = -powf(-c, valid_inv_gamma);
+ else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_inv_gamma);
+ else res = inv_gamma_range_table[i] +
+ ((c - color_domain_table[i]) * inv_gamfactor_table[i]);
return res;
}
@@ -676,8 +674,10 @@ static void gamtabs(float gamma)
val = a;
val /= 65535.0f;
- if (gamma == 2.0f) val = sqrt(val);
- else if (gamma != 1.0f) val = pow(val, igamma);
+ if (gamma == 2.0f)
+ val = sqrtf(val);
+ else if (gamma != 1.0f)
+ val = powf(val, igamma);
gamtab[a] = (65535.99f * val);
}
@@ -694,10 +694,10 @@ static void gamtabs(float gamma)
static void build_gammatabs(void)
{
- if (gamma_tabs_init == FALSE) {
+ if (gamma_tabs_init == false) {
gamtabs(2.0f);
makeGammaTables(2.0f);
- gamma_tabs_init = TRUE;
+ gamma_tabs_init = true;
}
}
@@ -1350,8 +1350,8 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
b3 = yo - posy * 0.5f;
b2 = y;
- hyp = abs(y - posy * 0.5f);
- hyp2 = abs(y - (yo - posy * 0.5f));
+ hyp = fabsf(y - posy * 0.5f);
+ hyp2 = fabsf(y - (yo - posy * 0.5f));
}
else {
b1 = posy * 0.5f - (-angle) * posx * 0.5f;
@@ -1441,7 +1441,7 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
temp1 = xo * (1 - facf0 / 2) - xo * facf0 / 2;
temp2 = yo * (1 - facf0 / 2) - yo * facf0 / 2;
- pointdist = sqrt(temp1 * temp1 + temp2 * temp2);
+ pointdist = sqrtf(temp1 * temp1 + temp2 * temp2);
if (b2 < b1 && b2 < b3) {
if (hwidth < pointdist)
@@ -1498,11 +1498,11 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
hwidth = width * 0.5f;
temp1 = (halfx - (halfx) * facf0);
- pointdist = sqrt(temp1 * temp1 + temp1 * temp1);
+ pointdist = sqrtf(temp1 * temp1 + temp1 * temp1);
- temp2 = sqrt((halfx - x) * (halfx - x) + (halfy - y) * (halfy - y));
- if (temp2 > pointdist) output = in_band(hwidth, fabs(temp2 - pointdist), 0, 1);
- else output = in_band(hwidth, fabs(temp2 - pointdist), 1, 1);
+ temp2 = sqrtf((halfx - x) * (halfx - x) + (halfy - y) * (halfy - y));
+ if (temp2 > pointdist) output = in_band(hwidth, fabsf(temp2 - pointdist), 0, 1);
+ else output = in_band(hwidth, fabsf(temp2 - pointdist), 1, 1);
if (!wipe->forward) output = 1 - output;
@@ -2064,7 +2064,7 @@ static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, flo
inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input");
outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output");
- IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+ IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
IMB_buffer_float_premultiply(inbuf, x, y);
RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
@@ -2073,7 +2073,7 @@ static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, flo
RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
IMB_buffer_float_unpremultiply(outbuf, x, y);
- IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+ IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, x, y, x, x);
MEM_freeN(inbuf);
MEM_freeN(outbuf);
@@ -2428,7 +2428,7 @@ static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *
}
}
-void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, int force)
+void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
{
int cfra;
float fallback_fac = 1.0f;
@@ -2439,7 +2439,7 @@ void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, int forc
/* if not already done, load / initialize data */
BKE_sequence_get_effect(seq);
- if ((force == FALSE) &&
+ if ((force == false) &&
(seq->len == v->length) &&
(v->frameMap != NULL))
{
@@ -2655,8 +2655,8 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
struct SeqEffectHandle rval;
int sequence_type = seq_type;
- rval.multithreaded = FALSE;
- rval.supports_mask = FALSE;
+ rval.multithreaded = false;
+ rval.supports_mask = false;
rval.init = init_noop;
rval.num_inputs = num_inputs_default;
rval.load = load_noop;
@@ -2671,13 +2671,13 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
switch (sequence_type) {
case SEQ_TYPE_CROSS:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.execute_slice = do_cross_effect;
rval.early_out = early_out_fade;
rval.get_default_fac = get_default_fac_fade;
break;
case SEQ_TYPE_GAMCROSS:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.init = init_gammacross;
rval.load = load_gammacross;
rval.free = free_gammacross;
@@ -2687,31 +2687,31 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.execute_slice = do_gammacross_effect;
break;
case SEQ_TYPE_ADD:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.execute_slice = do_add_effect;
rval.early_out = early_out_mul_input2;
break;
case SEQ_TYPE_SUB:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.execute_slice = do_sub_effect;
rval.early_out = early_out_mul_input2;
break;
case SEQ_TYPE_MUL:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.execute_slice = do_mul_effect;
rval.early_out = early_out_mul_input2;
break;
case SEQ_TYPE_ALPHAOVER:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.init = init_alpha_over_or_under;
rval.execute_slice = do_alphaover_effect;
break;
case SEQ_TYPE_OVERDROP:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.execute_slice = do_overdrop_effect;
break;
case SEQ_TYPE_ALPHAUNDER:
- rval.multithreaded = TRUE;
+ rval.multithreaded = true;
rval.init = init_alpha_over_or_under;
rval.execute_slice = do_alphaunder_effect;
break;
@@ -2762,7 +2762,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.execute = do_multicam;
break;
case SEQ_TYPE_ADJUSTMENT:
- rval.supports_mask = TRUE;
+ rval.supports_mask = true;
rval.num_inputs = num_inputs_adjustment;
rval.early_out = early_out_adjustment;
rval.execute = do_adjustment;
@@ -2774,7 +2774,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq)
{
- struct SeqEffectHandle rval = {FALSE, FALSE, NULL};
+ struct SeqEffectHandle rval = {false, false, NULL};
if (seq->type & SEQ_TYPE_EFFECT) {
rval = get_sequence_effect_impl(seq->type);
@@ -2789,7 +2789,7 @@ struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq)
struct SeqEffectHandle BKE_sequence_get_blend(Sequence *seq)
{
- struct SeqEffectHandle rval = {FALSE, FALSE, NULL};
+ struct SeqEffectHandle rval = {false, false, NULL};
if (seq->blend_mode != 0) {
rval = get_sequence_effect_impl(seq->blend_mode);
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 27d09eeaf8f..b78529f51b4 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -50,7 +50,7 @@
#include "IMB_imbuf_types.h"
static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
-static int modifierTypesInit = FALSE;
+static bool modifierTypesInit = false;
/*********************** Modifiers *************************/
@@ -77,7 +77,7 @@ typedef struct ModifierThread {
} ModifierThread;
-static ImBuf *modifier_mask_get(SequenceModifierData *smd, const SeqRenderData *context, int cfra, int make_float)
+static ImBuf *modifier_mask_get(SequenceModifierData *smd, const SeqRenderData *context, int cfra, bool make_float)
{
return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, make_float);
}
@@ -160,7 +160,7 @@ static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *ma
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
- BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, FALSE, mask);
+ BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
}
static SequenceModifierTypeInfo seqModifier_ColorBalance = {
@@ -214,7 +214,7 @@ static void curves_apply_threaded(int width, int height, unsigned char *rect, fl
curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
if (mask_rect_float) {
- float *m = mask_rect_float + pixel_index;
+ const float *m = mask_rect_float + pixel_index;
pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
@@ -454,7 +454,7 @@ static void brightcontrast_apply_threaded(int width, int height, unsigned char *
v = a * i + b;
if (mask_rect_float) {
- float *m = mask_rect_float + pixel_index;
+ const float *m = mask_rect_float + pixel_index;
pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
}
@@ -518,7 +518,7 @@ static void maskmodifier_apply_threaded(int width, int height, unsigned char *re
else if (rect_float) {
int c;
float *pixel = rect_float + pixel_index;
- float *mask_pixel = mask_rect_float + pixel_index;
+ const float *mask_pixel = mask_rect_float + pixel_index;
float mask = min_fff(mask_pixel[0], mask_pixel[1], mask_pixel[2]);
/* float buffers are premultiplied, so need to premul color
@@ -571,7 +571,7 @@ SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
{
if (!modifierTypesInit) {
sequence_modifier_type_info_init();
- modifierTypesInit = TRUE;
+ modifierTypesInit = true;
}
return modifiersTypes[type];
@@ -602,15 +602,15 @@ SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name,
return smd;
}
-int BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd)
+bool BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd)
{
if (BLI_findindex(&seq->modifiers, smd) == -1)
- return FALSE;
+ return false;
BLI_remlink(&seq->modifiers, smd);
BKE_sequence_modifier_free(smd);
- return TRUE;
+ return true;
}
void BKE_sequence_modifier_clear(Sequence *seq)
@@ -684,7 +684,7 @@ ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context, Sequence
}
if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, FALSE);
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
}
return processed_ibuf;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index c25b3da15eb..cf15b235b45 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -35,7 +35,6 @@
#include <math.h>
#include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
#include "DNA_sequence_types.h"
#include "DNA_movieclip_types.h"
@@ -88,7 +87,7 @@
static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown);
static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, float cfra);
static void seq_free_animdata(Scene *scene, Sequence *seq);
-static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, short make_float);
+static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float);
/* **** XXX ******** */
#define SELECT 1
@@ -232,7 +231,7 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach
void BKE_sequence_free(Scene *scene, Sequence *seq)
{
- BKE_sequence_free_ex(scene, seq, TRUE);
+ BKE_sequence_free_ex(scene, seq, true);
}
/* cache must be freed before calling this function
@@ -246,7 +245,7 @@ static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
seq_free_sequence_recurse(scene, iseq);
}
- BKE_sequence_free_ex(scene, seq, FALSE);
+ BKE_sequence_free_ex(scene, seq, false);
}
@@ -268,7 +267,7 @@ static void seq_free_clipboard_recursive(Sequence *seq_parent)
}
BKE_sequence_clipboard_pointers_free(seq_parent);
- BKE_sequence_free_ex(NULL, seq_parent, FALSE);
+ BKE_sequence_free_ex(NULL, seq_parent, false);
}
void BKE_sequencer_free_clipboard(void)
@@ -403,7 +402,7 @@ void BKE_sequencer_editing_free(Scene *scene)
SEQ_BEGIN (ed, seq)
{
/* handle cache freeing above */
- BKE_sequence_free_ex(scene, seq, FALSE);
+ BKE_sequence_free_ex(scene, seq, false);
}
SEQ_END
@@ -423,7 +422,7 @@ static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf)
}
}
-void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_float)
+void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
{
const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
const char *to_colorspace = scene->sequencer_colorspace_settings.name;
@@ -515,6 +514,7 @@ SeqRenderData BKE_sequencer_new_render_data(EvaluationContext *eval_ctx,
rval.motion_blur_shutter = 0;
rval.eval_ctx = eval_ctx;
rval.skip_cache = false;
+ rval.is_proxy_render = false;
return rval;
}
@@ -554,7 +554,7 @@ static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
}
}
-static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
+static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, bool use_pointer)
{
Sequence **array;
@@ -579,7 +579,7 @@ static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_point
seq_build_array(&ed->seqbase, &array, 0);
}
-void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer)
+void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, bool use_pointer)
{
memset(iter, 0, sizeof(*iter));
seq_array(ed, &iter->array, &iter->tot, use_pointer);
@@ -873,7 +873,7 @@ void BKE_sequencer_sort(Scene *scene)
{
/* all strips together per kind, and in order of y location ("machine") */
ListBase seqbase, effbase;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seqt;
@@ -947,8 +947,9 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
Sequence *seq;
for (seq = seqbasep->first; seq; seq = seq->next) {
if ((sui->seq != seq) && STREQ(sui->name_dest, seq->name + 2)) {
- /* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */
- BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d", sui->name_src, sui->count++);
+ /* SEQ_NAME_MAXSTR -4 for the number, -1 for \0, - 2 for prefix */
+ BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.*s.%03d", SEQ_NAME_MAXSTR - 4 - 1 - 2,
+ sui->name_src, sui->count++);
sui->match = 1; /* be sure to re-scan */
}
}
@@ -1155,34 +1156,71 @@ StripElem *BKE_sequencer_give_stripelem(Sequence *seq, int cfra)
return se;
}
-static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra)
+static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra, int chanshown)
{
Sequence *seq;
- int totseq = 0;
+ Sequence *effect_inputs[MAXSEQ + 1];
+ int i, totseq = 0, num_effect_inputs = 0;
memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1));
seq = seqbase->first;
while (seq) {
if (seq->startdisp <= cfra && seq->enddisp > cfra) {
+ if ((seq->type & SEQ_TYPE_EFFECT)) {
+ if (seq->seq1) {
+ effect_inputs[num_effect_inputs++] = seq->seq1;
+ }
+
+ if (seq->seq2) {
+ effect_inputs[num_effect_inputs++] = seq->seq2;
+ }
+
+ if (seq->seq3) {
+ effect_inputs[num_effect_inputs++] = seq->seq3;
+ }
+ }
+
seq_arr[seq->machine] = seq;
totseq++;
}
seq = seq->next;
}
+ /* Drop strips which are used for effect inputs, we don't want
+ * them to blend into render stack in any other way than effect
+ * string rendering.
+ */
+ for (i = 0; i < num_effect_inputs; i++) {
+ seq = effect_inputs[i];
+ /* It's possible that effetc strip would be placed to the same
+ * 'machine' as it's inputs. We don't want to clear such strips
+ * from the stack.
+ */
+ if (seq_arr[seq->machine] && seq_arr[seq->machine]->type & SEQ_TYPE_EFFECT) {
+ continue;
+ }
+ /* If we're shown a specified channel, then we want to see the stirps
+ * which belongs to this machine.
+ */
+ if (chanshown != 0 && chanshown <= seq->machine) {
+ continue;
+ }
+ seq_arr[seq->machine] = NULL;
+ }
+
return totseq;
}
int BKE_sequencer_evaluate_frame(Scene *scene, int cfra)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq_arr[MAXSEQ + 1];
if (ed == NULL)
return 0;
- return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
+ return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra, 0);
}
static bool video_seq_is_rendered(Sequence *seq)
@@ -1200,7 +1238,7 @@ static int get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequ
return 0;
}
- if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
+ if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra, chanshown)) {
if (b == 0) {
b = MAXSEQ;
}
@@ -1313,13 +1351,13 @@ static void seq_open_anim_file(Sequence *seq)
}
-static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *name)
+static bool seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *name)
{
int frameno;
char dir[PROXY_MAXFILE];
if (!seq->strip->proxy) {
- return FALSE;
+ return false;
}
/* MOVIE tracks (only exception: custom files) are now handled
@@ -1337,7 +1375,7 @@ static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *n
BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
}
else {
- return FALSE;
+ return false;
}
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
@@ -1345,7 +1383,7 @@ static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *n
dir, seq->strip->proxy->file);
BLI_path_abs(name, G.main->name);
- return TRUE;
+ return true;
}
/* generate a separate proxy directory for each preview size */
@@ -1365,7 +1403,7 @@ static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *n
strcat(name, ".jpg");
- return TRUE;
+ return true;
}
static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra)
@@ -1443,8 +1481,8 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
ibuf = seq_render_strip(context, seq, cfra);
- rectx = (proxy_render_size * context->scene->r.xsch) / 100;
- recty = (proxy_render_size * context->scene->r.ysch) / 100;
+ rectx = (proxy_render_size * ibuf->x) / 100;
+ recty = (proxy_render_size * ibuf->y) / 100;
if (ibuf->x != rectx || ibuf->y != recty) {
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
@@ -1538,6 +1576,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
(scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
(scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100);
render_context.skip_cache = true;
+ render_context.is_proxy_render = true;
for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
if (context->size_flags & IMB_PROXY_25) {
@@ -1554,14 +1593,14 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
}
*progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
- *do_update = TRUE;
+ *do_update = true;
if (*stop || G.is_break)
break;
}
}
-void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, short stop)
+void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop)
{
if (context->index_context) {
IMB_close_anim_proxies(context->seq->anim);
@@ -1727,8 +1766,8 @@ static void color_balance_byte_float(StripColorBalance *cb_, unsigned char *rect
static void color_balance_float_float(StripColorBalance *cb_, float *rect_float, float *mask_rect_float, int width, int height, float mul)
{
float *p = rect_float;
- float *e = rect_float + width * 4 * height;
- float *m = mask_rect_float;
+ const float *e = rect_float + width * 4 * height;
+ const float *m = mask_rect_float;
StripColorBalance cb = calc_cb(cb_);
while (p < e) {
@@ -1753,7 +1792,7 @@ typedef struct ColorBalanceInitData {
ImBuf *ibuf;
float mul;
ImBuf *mask;
- short make_float;
+ bool make_float;
} ColorBalanceInitData;
typedef struct ColorBalanceThread {
@@ -1765,7 +1804,7 @@ typedef struct ColorBalanceThread {
unsigned char *rect, *mask_rect;
float *rect_float, *mask_rect_float;
- short make_float;
+ bool make_float;
} ColorBalanceThread;
static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1828,7 +1867,7 @@ static void *color_balance_do_thread(void *thread_data_v)
return NULL;
}
-ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, int make_float)
+ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, bool make_float)
{
ImBuf *mask_input = NULL;
@@ -1853,7 +1892,7 @@ ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_in
return mask_input;
}
-void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, short make_float, ImBuf *mask_input)
+void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input)
{
ColorBalanceInitData init_data;
@@ -1895,12 +1934,16 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float
* - Premultiply
*/
-int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *UNUSED(context), Sequence *seq, float UNUSED(cfra))
+bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, Sequence *seq, float UNUSED(cfra))
{
float mul;
+ if (context->is_proxy_render) {
+ return false;
+ }
+
if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
- return TRUE;
+ return true;
}
mul = seq->mul;
@@ -1910,18 +1953,18 @@ int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *UNUSED(context),
}
if (mul != 1.0f) {
- return TRUE;
+ return true;
}
if (seq->sat != 1.0f) {
- return TRUE;
+ return true;
}
if (seq->modifiers.first) {
- return TRUE;
+ return true;
}
-
- return FALSE;
+
+ return false;
}
static ImBuf *input_preprocess(const SeqRenderData *context, Sequence *seq, float cfra, ImBuf *ibuf,
@@ -2029,7 +2072,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context, Sequence *seq, floa
if (seq->flag & SEQ_MAKE_FLOAT) {
if (!ibuf->rect_float) {
- BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf, TRUE);
+ BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf, true);
}
if (ibuf->rect) {
@@ -2336,7 +2379,7 @@ static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context, Sequence
}
-static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, short make_float)
+static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float)
{
/* TODO - add option to rasterize to alpha imbuf? */
ImBuf *ibuf = NULL;
@@ -2358,7 +2401,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
mr_handle = BKE_maskrasterize_handle_new();
- BKE_maskrasterize_handle_init(mr_handle, mask_temp, context->rectx, context->recty, TRUE, TRUE, TRUE);
+ BKE_maskrasterize_handle_init(mr_handle, mask_temp, context->rectx, context->recty, true, true, true);
BKE_mask_free_nolib(mask_temp);
MEM_freeN(mask_temp);
@@ -2371,7 +2414,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
if (make_float) {
/* pixels */
- float *fp_src;
+ const float *fp_src;
float *fp_dst;
ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rectfloat);
@@ -2389,7 +2432,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
}
else {
/* pixels */
- float *fp_src;
+ const float *fp_src;
unsigned char *ub_dst;
ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
@@ -2413,7 +2456,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
static ImBuf *seq_render_mask_strip(const SeqRenderData *context, Sequence *seq, float nr)
{
- short make_float = seq->flag & SEQ_MAKE_FLOAT;
+ bool make_float = (seq->flag & SEQ_MAKE_FLOAT) != 0;
return seq_render_mask(context, seq->mask, nr, make_float);
}
@@ -2458,13 +2501,13 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
*/
const bool is_rendering = G.is_rendering;
- const bool is_background = G.background;
+ const bool is_background = G.background;
const bool do_seq_gl = is_rendering ?
0 /* (context->scene->r.seq_flag & R_SEQ_GL_REND) */ :
(context->scene->r.seq_flag & R_SEQ_GL_PREV) != 0;
int do_seq;
- // int have_seq = FALSE; /* UNUSED */
- int have_comp = FALSE;
+ // bool have_seq = false; /* UNUSED */
+ bool have_comp = false;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2476,7 +2519,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
scene = seq->scene;
frame = scene->r.sfra + nr + seq->anim_startofs;
- // have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; /* UNUSED */
+ // have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first); /* UNUSED */
have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
oldcfra = scene->r.cfra;
@@ -2490,7 +2533,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
camera = scene->camera;
}
- if (have_comp == FALSE && camera == NULL) {
+ if (have_comp == false && camera == NULL) {
scene->r.cfra = oldcfra;
return NULL;
}
@@ -2509,6 +2552,9 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) {
char err_out[256] = "unknown";
+ int width = (scene->r.xsch * scene->r.size) / 100;
+ int height = (scene->r.ysch * scene->r.size) / 100;
+
/* for old scened this can be uninitialized,
* should probably be added to do_versions at some point if the functionality stays */
if (context->scene->r.seq_prev_type == 0)
@@ -2516,9 +2562,10 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
/* opengl offscreen render */
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
- ibuf = sequencer_view3d_cb(scene, camera, context->rectx, context->recty, IB_rect,
- context->scene->r.seq_prev_type, context->scene->r.seq_flag & R_SEQ_SOLID_TEX,
- TRUE, scene->r.alphamode, err_out);
+ ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect,
+ context->scene->r.seq_prev_type,
+ (context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
+ true, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -2535,12 +2582,12 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
* When rendering from command line renderer is called from main thread, in this
* case it's always safe to render scene here
*/
- if (!is_thread_main || is_rendering == FALSE || is_background) {
+ if (!is_thread_main || is_rendering == false || is_background) {
if (re == NULL)
re = RE_NewRender(scene->id.name);
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
- RE_BlenderFrame(re, context->bmain, scene, NULL, camera, scene->lay, frame, FALSE);
+ RE_BlenderFrame(re, context->bmain, scene, NULL, camera, scene->lay, frame, false);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
G.is_rendering = is_rendering;
@@ -2557,7 +2604,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
}
/* float buffers in the sequencer are not linear */
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, FALSE);
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
}
else if (rres.rect32) {
ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
@@ -2591,7 +2638,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
ImBuf *ibuf = NULL;
float nr = give_stripelem_index(seq, cfra);
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
- int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ bool use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
char name[FILE_MAX];
switch (type) {
@@ -2623,7 +2670,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
float f_cfra;
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
- BKE_sequence_effect_speed_rebuild_map(context->scene, seq, 0);
+ BKE_sequence_effect_speed_rebuild_map(context->scene, seq, false);
/* weeek! */
f_cfra = seq->start + s->frameMap[(int)nr];
@@ -2669,7 +2716,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
imb_freerectImBuf(ibuf);
/* all sequencer color is done in SRGB space, linear gives odd crossfades */
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, FALSE);
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
copy_to_ibuf_still(context, seq, nr, ibuf);
@@ -2691,7 +2738,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
seq_rendersize_to_proxysize(context->preview_render_size));
if (ibuf) {
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, FALSE);
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect) {
@@ -2729,7 +2776,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
ibuf = i;
if (ibuf->rect_float)
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, FALSE);
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
copy_to_ibuf_still(context, seq, nr, ibuf);
}
@@ -2782,8 +2829,12 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
if (ibuf == NULL)
ibuf = do_render_strip_uncached(context, seq, cfra);
- if (ibuf)
+ if (ibuf) {
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
+ is_proxy_image = (context->preview_render_size != 100);
+ }
BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
}
}
@@ -2802,8 +2853,11 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
sequencer_imbuf_assign_spaces(context->scene, ibuf);
}
- if (ibuf->x != context->rectx || ibuf->y != context->recty)
- use_preprocess = TRUE;
+ if (context->is_proxy_render == false &&
+ (ibuf->x != context->rectx || ibuf->y != context->recty))
+ {
+ use_preprocess = true;
+ }
if (use_preprocess)
ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
@@ -2817,13 +2871,13 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
static bool seq_must_swap_input_in_blend_mode(Sequence *seq)
{
- bool swap_input = FALSE;
+ bool swap_input = false;
/* bad hack, to fix crazy input ordering of
* those two effects */
if (ELEM3(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) {
- swap_input = TRUE;
+ swap_input = true;
}
return swap_input;
@@ -3014,7 +3068,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq
ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown)
{
- Editing *ed = BKE_sequencer_editing_get(context->scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(context->scene, false);
int count;
ListBase *seqbasep;
@@ -3059,7 +3113,7 @@ static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
-static volatile int seq_thread_shutdown = TRUE;
+static volatile bool seq_thread_shutdown = true;
static volatile int seq_last_given_monoton_cfra = 0;
static int monoton_cfra = 0;
@@ -3114,14 +3168,14 @@ void BKE_sequencer_give_ibuf_prefetch_request(const SeqRenderData *context, floa
ImBuf *BKE_sequencer_give_ibuf_threaded(const SeqRenderData *context, float cfra, int chanshown)
{
PrefetchQueueElem *e = NULL;
- int found_something = FALSE;
+ bool found_something = false;
if (seq_thread_shutdown) {
return BKE_sequencer_give_ibuf(context, cfra, chanshown);
}
while (!e) {
- int success = FALSE;
+ bool success = false;
pthread_mutex_lock(&queue_lock);
for (e = prefetch_done.first; e; e = e->next) {
@@ -3131,8 +3185,8 @@ ImBuf *BKE_sequencer_give_ibuf_threaded(const SeqRenderData *context, float cfra
context->recty == e->recty &&
context->preview_render_size == e->preview_render_size)
{
- success = TRUE;
- found_something = TRUE;
+ success = true;
+ found_something = true;
break;
}
}
@@ -3145,7 +3199,7 @@ ImBuf *BKE_sequencer_give_ibuf_threaded(const SeqRenderData *context, float cfra
context->recty == e->recty &&
context->preview_render_size == e->preview_render_size)
{
- found_something = TRUE;
+ found_something = true;
break;
}
}
@@ -3165,7 +3219,7 @@ ImBuf *BKE_sequencer_give_ibuf_threaded(const SeqRenderData *context, float cfra
context->recty == tslot->current->recty &&
context->preview_render_size == tslot->current->preview_render_size)
{
- found_something = TRUE;
+ found_something = true;
break;
}
}
@@ -3250,7 +3304,7 @@ static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
}
}
-static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess)
+static void sequence_invalidate_cache(Scene *scene, Sequence *seq, bool invalidate_self, bool invalidate_preprocess)
{
Editing *ed = scene->ed;
@@ -3270,7 +3324,7 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat
/* if invalidation is invoked from sequence free routine, effectdata would be NULL here */
if (seq->effectdata && seq->type == SEQ_TYPE_SPEED)
- BKE_sequence_effect_speed_rebuild_map(scene, seq, TRUE);
+ BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
if (invalidate_preprocess)
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
@@ -3285,20 +3339,20 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
{
- sequence_invalidate_cache(scene, seq, TRUE, TRUE);
+ sequence_invalidate_cache(scene, seq, true, true);
}
void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq)
{
- sequence_invalidate_cache(scene, seq, FALSE, TRUE);
+ sequence_invalidate_cache(scene, seq, false, true);
}
void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq)
{
- sequence_invalidate_cache(scene, seq, TRUE, FALSE);
+ sequence_invalidate_cache(scene, seq, true, false);
}
-void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render)
+void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
{
Sequence *seq;
@@ -3314,7 +3368,7 @@ void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render)
free_anim_seq(seq);
}
if (seq->type == SEQ_TYPE_SPEED) {
- BKE_sequence_effect_speed_rebuild_map(scene, seq, 1);
+ BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
}
}
if (seq->type == SEQ_TYPE_META) {
@@ -3328,10 +3382,10 @@ void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render)
}
-static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
+static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
{
Sequence *subseq;
- int free_imbuf = 0;
+ bool free_imbuf = false;
/* recurs downwards to see if this seq depends on the changed seq */
@@ -3339,28 +3393,28 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan
return 0;
if (seq == changed_seq)
- free_imbuf = 1;
+ free_imbuf = true;
for (subseq = seq->seqbase.first; subseq; subseq = subseq->next)
if (update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
+ free_imbuf = true;
if (seq->seq1)
if (update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
+ free_imbuf = true;
if (seq->seq2 && (seq->seq2 != seq->seq1))
if (update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
+ free_imbuf = true;
if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
if (update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
+ free_imbuf = true;
if (free_imbuf) {
if (ibuf_change) {
if (seq->type == SEQ_TYPE_MOVIE)
free_anim_seq(seq);
if (seq->type == SEQ_TYPE_SPEED) {
- BKE_sequence_effect_speed_rebuild_map(scene, seq, 1);
+ BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
}
}
@@ -3373,7 +3427,7 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan
void BKE_sequencer_update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
if (ed == NULL) return;
@@ -3397,22 +3451,22 @@ static int seq_tx_get_end(Sequence *seq)
return seq->start + seq->len;
}
-int BKE_sequence_tx_get_final_left(Sequence *seq, int metaclip)
+int BKE_sequence_tx_get_final_left(Sequence *seq, bool metaclip)
{
if (metaclip && seq->tmp) {
/* return the range clipped by the parents range */
- return max_ii(BKE_sequence_tx_get_final_left(seq, 0), BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, TRUE));
+ return max_ii(BKE_sequence_tx_get_final_left(seq, false), BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, true));
}
else {
return (seq->start - seq->startstill) + seq->startofs;
}
}
-int BKE_sequence_tx_get_final_right(Sequence *seq, int metaclip)
+int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip)
{
if (metaclip && seq->tmp) {
/* return the range clipped by the parents range */
- return min_ii(BKE_sequence_tx_get_final_right(seq, 0), BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, TRUE));
+ return min_ii(BKE_sequence_tx_get_final_right(seq, false), BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, true));
}
else {
return ((seq->start + seq->len) + seq->endstill) - seq->endofs;
@@ -3501,12 +3555,12 @@ bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
void BKE_sequence_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
{
if (leftflag) {
- if (BKE_sequence_tx_get_final_left(seq, 0) >= BKE_sequence_tx_get_final_right(seq, 0)) {
- BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_right(seq, 0) - 1);
+ if (BKE_sequence_tx_get_final_left(seq, false) >= BKE_sequence_tx_get_final_right(seq, false)) {
+ BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_right(seq, false) - 1);
}
if (BKE_sequence_single_check(seq) == 0) {
- if (BKE_sequence_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
+ if (BKE_sequence_tx_get_final_left(seq, false) >= seq_tx_get_end(seq)) {
BKE_sequence_tx_set_final_left(seq, seq_tx_get_end(seq) - 1);
}
@@ -3523,12 +3577,12 @@ void BKE_sequence_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
}
if (rightflag) {
- if (BKE_sequence_tx_get_final_right(seq, 0) <= BKE_sequence_tx_get_final_left(seq, 0)) {
- BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_left(seq, 0) + 1);
+ if (BKE_sequence_tx_get_final_right(seq, false) <= BKE_sequence_tx_get_final_left(seq, false)) {
+ BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_left(seq, false) + 1);
}
if (BKE_sequence_single_check(seq) == 0) {
- if (BKE_sequence_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
+ if (BKE_sequence_tx_get_final_right(seq, false) <= seq_tx_get_start(seq)) {
BKE_sequence_tx_set_final_right(seq, seq_tx_get_start(seq) + 1);
}
}
@@ -3549,12 +3603,12 @@ void BKE_sequence_single_fix(Sequence *seq)
/* make sure the image is always at the start since there is only one,
* adjusting its start should be ok */
- left = BKE_sequence_tx_get_final_left(seq, 0);
+ left = BKE_sequence_tx_get_final_left(seq, false);
start = seq->start;
if (start != left) {
offset = left - start;
- BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_left(seq, 0) - offset);
- BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_right(seq, 0) - offset);
+ BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_left(seq, false) - offset);
+ BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_right(seq, false) - offset);
seq->start += offset;
}
}
@@ -3613,14 +3667,14 @@ void BKE_sequence_sound_init(Scene *scene, Sequence *seq)
seq->scene_sound = sound_add_scene_sound_defaults(scene, seq);
}
if (seq->scene) {
- sound_scene_add_scene_sound_defaults(scene, seq);
+ seq->scene_sound = sound_scene_add_scene_sound_defaults(scene, seq);
}
}
}
Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *best_seq = NULL;
int best_machine = -1;
@@ -3813,7 +3867,17 @@ void BKE_sequencer_update_sound_bounds_all(Scene *scene)
void BKE_sequencer_update_sound_bounds(Scene *scene, Sequence *seq)
{
- sound_move_scene_sound_defaults(scene, seq);
+ if (seq->type == SEQ_TYPE_SCENE) {
+ if (seq->scene_sound) {
+ /* We have to take into account start frame of the sequence's scene! */
+ int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
+
+ sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs);
+ }
+ }
+ else {
+ sound_move_scene_sound_defaults(scene, seq);
+ }
/* mute is set in seq_update_muting_recursive */
}
@@ -3987,11 +4051,19 @@ void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs)
for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) {
if (strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
unsigned int i;
- for (i = 0; i < fcu->totvert; i++) {
- BezTriple *bezt = &fcu->bezt[i];
- bezt->vec[0][0] += ofs;
- bezt->vec[1][0] += ofs;
- bezt->vec[2][0] += ofs;
+ if (fcu->bezt) {
+ for (i = 0; i < fcu->totvert; i++) {
+ BezTriple *bezt = &fcu->bezt[i];
+ bezt->vec[0][0] += ofs;
+ bezt->vec[1][0] += ofs;
+ bezt->vec[2][0] += ofs;
+ }
+ }
+ if (fcu->fpt) {
+ for (i = 0; i < fcu->totvert; i++) {
+ FPoint *fpt = &fcu->fpt[i];
+ fpt->vec[0] += ofs;
+ }
}
}
}
@@ -4054,7 +4126,7 @@ static void seq_free_animdata(Scene *scene, Sequence *seq)
}
}
-Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, int recursive)
+Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, bool recursive)
{
Sequence *iseq = NULL;
Sequence *rseq = NULL;
@@ -4096,7 +4168,7 @@ Sequence *BKE_sequencer_from_elem(ListBase *seqbase, StripElem *se)
Sequence *BKE_sequencer_active_get(Scene *scene)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL)
return NULL;
@@ -4106,7 +4178,7 @@ Sequence *BKE_sequencer_active_get(Scene *scene)
void BKE_sequencer_active_set(Scene *scene, Sequence *seq)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL)
return;
@@ -4116,7 +4188,7 @@ void BKE_sequencer_active_set(Scene *scene, Sequence *seq)
int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **seq_other)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
*seq_act = BKE_sequencer_active_get(scene);
@@ -4272,7 +4344,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C); /* only for sound */
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
bSound *sound;
Sequence *seq; /* generic strip vars */
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index dce82f9cbc4..e2cc7b84f95 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -41,7 +41,6 @@
#include "DNA_modifier_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -197,16 +196,17 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
/*
* This function raycast a single vertex and updates the hit if the "hit" is considered valid.
- * Returns TRUE if "hit" was updated.
+ * Returns true if "hit" was updated.
* Opts control whether an hit is valid or not
* Supported options are:
* MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored)
* MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored)
*/
-int BKE_shrinkwrap_project_normal(char options, const float vert[3],
- const float dir[3], const SpaceTransform *transf,
- BVHTree *tree, BVHTreeRayHit *hit,
- BVHTree_RayCastCallback callback, void *userdata)
+bool BKE_shrinkwrap_project_normal(
+ char options, const float vert[3],
+ const float dir[3], const SpaceTransform *transf,
+ BVHTree *tree, BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback, void *userdata)
{
/* don't use this because this dist value could be incompatible
* this value used by the callback for comparing prev/new dist values.
@@ -255,7 +255,7 @@ int BKE_shrinkwrap_project_normal(char options, const float vert[3],
if (((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f) ||
((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f))
{
- return FALSE; /* Ignore hit */
+ return false; /* Ignore hit */
}
}
@@ -270,13 +270,13 @@ int BKE_shrinkwrap_project_normal(char options, const float vert[3],
BLI_assert(hit_tmp.dist <= hit->dist);
memcpy(hit, &hit_tmp, sizeof(hit_tmp));
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool forRender)
+static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for_render)
{
int i;
@@ -323,7 +323,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
}
if (calc->smd->auxTarget) {
- auxMesh = object_get_derived_final(calc->smd->auxTarget, forRender);
+ auxMesh = object_get_derived_final(calc->smd->auxTarget, for_render);
if (!auxMesh)
return;
SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget);
@@ -504,7 +504,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
/* Main shrinkwrap function */
void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, bool forRender)
+ float (*vertexCos)[3], int numVerts, bool for_render)
{
DerivedMesh *ss_mesh = NULL;
@@ -532,7 +532,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
if (smd->target) {
- calc.target = object_get_derived_final(smd->target, forRender);
+ calc.target = object_get_derived_final(smd->target, for_render);
/* TODO there might be several "bugs" on non-uniform scales matrixs
* because it will no longer be nearest surface, not sphere projection
@@ -583,7 +583,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
break;
case MOD_SHRINKWRAP_PROJECT:
- TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc, forRender), deform_project);
+ TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc, for_render), deform_project);
break;
case MOD_SHRINKWRAP_NEAREST_VERTEX:
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 71fab27ad2c..57d8ffda641 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -40,12 +40,8 @@
#include <stdio.h>
#include <string.h> /* memset */
-#include "BLI_linklist.h"
-#include "BLI_rand.h"
-#include "BLI_jitter.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
#include "BLI_threads.h"
@@ -56,9 +52,7 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_customdata_types.h"
-#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -207,7 +201,14 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
sds->wt = NULL;
return;
}
+
+ /* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
+ BLI_lock_thread(LOCK_FFTW);
+
sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temporary_dir(), use_fire, use_colors);
+
+ BLI_unlock_thread(LOCK_FFTW);
+
sds->res_wt[0] = res[0] * (sds->amplify + 1);
sds->res_wt[1] = res[1] * (sds->amplify + 1);
sds->res_wt[2] = res[2] * (sds->amplify + 1);
@@ -226,7 +227,7 @@ static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3])
}
/* set domain transformations and base resolution from object derivedmesh */
-static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm, int init_resolution)
+static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm, bool init_resolution)
{
size_t i;
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
@@ -311,7 +312,7 @@ static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene,
SmokeDomainSettings *sds = smd->domain;
int res[3];
/* set domain dimensions from derivedmesh */
- smoke_set_domain_from_derivedmesh(sds, ob, dm, TRUE);
+ smoke_set_domain_from_derivedmesh(sds, ob, dm, true);
/* reset domain values */
zero_v3_int(sds->shift);
zero_v3(sds->shift_f);
@@ -927,7 +928,7 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
**********************************************************/
/* set "ignore cache" flag for all caches on this object */
-static void object_cacheIgnoreClear(Object *ob, int state)
+static void object_cacheIgnoreClear(Object *ob, bool state)
{
ListBase pidlist;
PTCacheID *pid;
@@ -945,7 +946,7 @@ static void object_cacheIgnoreClear(Object *ob, int state)
BLI_freelistN(&pidlist);
}
-static int subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int parent_recursion, float frame, bool for_render)
+static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int parent_recursion, float frame, bool for_render)
{
SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke);
bConstraint *con;
@@ -957,9 +958,9 @@ static int subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* if object has parents, update them too */
if (parent_recursion) {
int recursion = parent_recursion - 1;
- int is_domain = 0;
- if (ob->parent) is_domain += subframe_updateObject(scene, ob->parent, 0, recursion, frame, for_render);
- if (ob->track) is_domain += subframe_updateObject(scene, ob->track, 0, recursion, frame, for_render);
+ bool is_domain = false;
+ if (ob->parent) is_domain |= subframe_updateObject(scene, ob->parent, 0, recursion, frame, for_render);
+ if (ob->track) is_domain |= subframe_updateObject(scene, ob->track, 0, recursion, frame, for_render);
/* skip subframe if object is parented
* to vertex of a dynamic paint canvas */
@@ -968,7 +969,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
@@ -1067,7 +1068,7 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3]
}
}
-static void em_allocateData(EmissionMap *em, int use_velocity, int hires_mul)
+static void em_allocateData(EmissionMap *em, bool use_velocity, int hires_mul)
{
int i, res[3];
@@ -1290,7 +1291,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]);
if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE) {
- BLI_kdtree_insert(tree, valid_particles, pos, NULL);
+ BLI_kdtree_insert(tree, valid_particles, pos);
}
/* calculate emission map bounds */
@@ -1372,7 +1373,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
/* find particle distance from the kdtree */
KDTreeNearest nearest;
float range = solid + smooth;
- BLI_kdtree_find_nearest(tree, ray_start, NULL, &nearest);
+ BLI_kdtree_find_nearest(tree, ray_start, &nearest);
if (nearest.dist < range) {
em->influence[index] = (nearest.dist < solid) ? 1.0f : (1.0f - (nearest.dist-solid) / smooth);
@@ -1397,7 +1398,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
/* find particle distance from the kdtree */
KDTreeNearest nearest;
float range = solid + hr_smooth;
- BLI_kdtree_find_nearest(tree, ray_start, NULL, &nearest);
+ BLI_kdtree_find_nearest(tree, ray_start, &nearest);
if (nearest.dist < range) {
em->influence_high[index] = (nearest.dist < solid) ? 1.0f : (1.0f - (nearest.dist-solid) / smooth);
@@ -1421,8 +1422,11 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
}
}
-static void sample_derivedmesh(SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface, float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3], BVHTreeFromMesh *treeData, float ray_start[3],
- float *vert_vel, int has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z)
+static void sample_derivedmesh(
+ SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface,
+ float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3],
+ BVHTreeFromMesh *treeData, const float ray_start[3], const float *vert_vel,
+ bool has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z)
{
float ray_dir[3] = {1.0f, 0.0f, 0.0f};
BVHTreeRayHit hit = {0};
@@ -1550,7 +1554,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
{
if (!sfs->dm) return;
{
- DerivedMesh *dm = sfs->dm;
+ DerivedMesh *dm;
int defgrp_index = sfs->vgroup_density - 1;
MDeformVert *dvert = NULL;
MVert *mvert = NULL;
@@ -1566,6 +1570,11 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
int min[3], max[3], res[3];
int hires_multiplier = 1;
+ /* copy derivedmesh for thread safety because we modify it,
+ * main issue is its VertArray being modified, then replaced and freed
+ */
+ dm = CDDM_copy(sfs->dm);
+
CDDM_calc_normals(dm);
mvert = dm->getVertArray(dm);
mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */
@@ -2457,7 +2466,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *
/* update object state */
invert_m4_m4(sds->imat, ob->obmat);
copy_m4_m4(sds->obmat, ob->obmat);
- smoke_set_domain_from_derivedmesh(sds, ob, domain_dm, (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN));
+ smoke_set_domain_from_derivedmesh(sds, ob, domain_dm, (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) != 0);
/* use global gravity if enabled */
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index fb5fc97fd46..9c411142566 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -75,7 +75,6 @@ variables on the UI for now
#include "BKE_global.h"
#include "BKE_modifier.h"
#include "BKE_softbody.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_pointcache.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
@@ -1688,7 +1687,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
else
sb_threads[i].ifirst = 0;
sb_threads[i].do_effector = do_effector;
- sb_threads[i].do_deflector = FALSE;// not used here
+ sb_threads[i].do_deflector = false;// not used here
sb_threads[i].fieldfactor = 0.0f;// not used here
sb_threads[i].windfactor = 0.0f;// not used here
sb_threads[i].nr= i;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 3a8754e8dd2..6ba843c8a8f 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -53,15 +53,13 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
-#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_packedFile.h"
-#include "BKE_animsys.h"
#include "BKE_sequencer.h"
#include "BKE_scene.h"
#ifdef WITH_AUDASPACE
-// evil global ;-)
+/* evil global ;-) */
static int sound_cfra;
#endif
@@ -70,7 +68,7 @@ bSound *sound_new_file(struct Main *bmain, const char *filename)
bSound *sound = NULL;
char str[FILE_MAX];
- char *path;
+ const char *path;
size_t len;
@@ -86,7 +84,7 @@ bSound *sound_new_file(struct Main *bmain, const char *filename)
sound = BKE_libblock_alloc(bmain, ID_SO, filename + len);
BLI_strncpy(sound->name, filename, FILE_MAX);
-// XXX unused currently sound->type = SOUND_TYPE_FILE;
+ /* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
sound_load(bmain, sound);
@@ -118,7 +116,7 @@ void BKE_sound_free(bSound *sound)
}
sound_free_waveform(sound);
-#endif // WITH_AUDASPACE
+#endif /* WITH_AUDASPACE */
}
#ifdef WITH_AUDASPACE
@@ -223,7 +221,7 @@ void sound_exit_once(void)
AUD_exitOnce();
}
-// XXX unused currently
+/* XXX unused currently */
#if 0
bSound *sound_new_buffer(struct Main *bmain, bSound *source)
{
@@ -330,7 +328,7 @@ void sound_load(struct Main *bmain, bSound *sound)
sound_free_waveform(sound);
-// XXX unused currently
+/* XXX unused currently */
#if 0
switch (sound->type)
{
@@ -353,7 +351,7 @@ void sound_load(struct Main *bmain, bSound *sound)
else
sound->handle = AUD_load(fullpath);
}
-// XXX unused currently
+/* XXX unused currently */
#if 0
break;
}
@@ -437,10 +435,14 @@ void sound_update_scene_listener(struct Scene *scene)
scene->audio.doppler_factor, scene->audio.distance_model);
}
-void *sound_scene_add_scene_sound(struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip)
+void *sound_scene_add_scene_sound(struct Scene *scene, struct Sequence *sequence,
+ int startframe, int endframe, int frameskip)
{
- if (scene != sequence->scene)
- return AUD_addSequence(scene->sound_scene, sequence->scene->sound_scene, startframe / FPS, endframe / FPS, frameskip / FPS);
+ if (scene != sequence->scene) {
+ const double fps = FPS;
+ return AUD_addSequence(scene->sound_scene, sequence->scene->sound_scene,
+ startframe / fps, endframe / fps, frameskip / fps);
+ }
return NULL;
}
@@ -453,7 +455,9 @@ void *sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence
void *sound_add_scene_sound(struct Scene *scene, struct Sequence *sequence, int startframe, int endframe, int frameskip)
{
- void *handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS);
+ const double fps = FPS;
+ void *handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle,
+ startframe / fps, endframe / fps, frameskip / fps);
AUD_muteSequence(handle, (sequence->flag & SEQ_MUTE) != 0);
AUD_setSequenceAnimData(handle, AUD_AP_VOLUME, CFRA, &sequence->volume, 0);
AUD_setSequenceAnimData(handle, AUD_AP_PITCH, CFRA, &sequence->pitch, 0);
@@ -480,7 +484,8 @@ void sound_mute_scene_sound(void *handle, char mute)
void sound_move_scene_sound(struct Scene *scene, void *handle, int startframe, int endframe, int frameskip)
{
- AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS);
+ const double fps = FPS;
+ AUD_moveSequence(handle, startframe / fps, endframe / fps, frameskip / fps);
}
void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence)
@@ -504,7 +509,8 @@ void sound_set_cfra(int cfra)
void sound_set_scene_volume(struct Scene *scene, float volume)
{
- AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_VOLUME, CFRA, &volume, (scene->audio.flag & AUDIO_VOLUME_ANIMATED) != 0);
+ AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_VOLUME, CFRA, &volume,
+ (scene->audio.flag & AUDIO_VOLUME_ANIMATED) != 0);
}
void sound_set_scene_sound_volume(void *handle, float volume, char animated)
@@ -545,20 +551,23 @@ static void sound_start_play_scene(struct Scene *scene)
void sound_play_scene(struct Scene *scene)
{
AUD_Status status;
+ const float cur_time = (float)((double)CFRA / FPS);
+
AUD_lock();
status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
- if (status == AUD_STATUS_INVALID)
+ if (status == AUD_STATUS_INVALID) {
sound_start_play_scene(scene);
- if (!scene->sound_scene_handle) {
- AUD_unlock();
- return;
+ if (!scene->sound_scene_handle) {
+ AUD_unlock();
+ return;
+ }
}
if (status != AUD_STATUS_PLAYING) {
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ AUD_seek(scene->sound_scene_handle, cur_time);
AUD_resume(scene->sound_scene_handle);
}
@@ -584,6 +593,9 @@ void sound_seek_scene(struct Main *bmain, struct Scene *scene)
bScreen *screen;
int animation_playing;
+ const float one_frame = (float)(1.0 / FPS);
+ const float cur_time = (float)((double)CFRA / FPS);
+
AUD_lock();
status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
@@ -608,26 +620,31 @@ void sound_seek_scene(struct Main *bmain, struct Scene *scene)
if (scene->audio.flag & AUDIO_SCRUB && !animation_playing) {
if (scene->audio.flag & AUDIO_SYNC) {
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
- AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
+ AUD_seek(scene->sound_scene_handle, cur_time);
+ AUD_seekSequencer(scene->sound_scene_handle, cur_time);
+ }
+ else {
+ AUD_seek(scene->sound_scene_handle, cur_time);
}
- else
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_resume(scene->sound_scene_handle);
- if (scene->sound_scrub_handle && AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
+ if (scene->sound_scrub_handle && AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID) {
AUD_seek(scene->sound_scrub_handle, 0);
+ }
else {
- if (scene->sound_scrub_handle)
+ if (scene->sound_scrub_handle) {
AUD_stop(scene->sound_scrub_handle);
- scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
+ }
+ scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, one_frame);
}
}
else {
- if (scene->audio.flag & AUDIO_SYNC)
- AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
+ if (scene->audio.flag & AUDIO_SYNC) {
+ AUD_seekSequencer(scene->sound_scene_handle, cur_time);
+ }
else {
- if (status == AUD_STATUS_PLAYING)
- AUD_seek(scene->sound_scene_handle, CFRA / FPS);
+ if (status == AUD_STATUS_PLAYING) {
+ AUD_seek(scene->sound_scene_handle, cur_time);
+ }
}
}
@@ -681,7 +698,7 @@ void sound_read_waveform(bSound *sound)
}
}
-void sound_update_scene(struct Scene *scene)
+void sound_update_scene(Main *bmain, struct Scene *scene)
{
Object *ob;
Base *base;
@@ -694,50 +711,55 @@ void sound_update_scene(struct Scene *scene)
void *handle;
float quat[4];
- for (SETLOOPER(scene, sce_it, base)) {
- ob = base->object;
- if (ob->type == OB_SPEAKER) {
- if (ob->adt) {
- for (track = ob->adt->nla_tracks.first; track; track = track->next) {
- for (strip = track->strips.first; strip; strip = strip->next) {
- if (strip->type == NLASTRIP_TYPE_SOUND) {
- speaker = (Speaker *)ob->data;
-
- if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) {
- if (speaker->sound)
- AUD_moveSequence(strip->speaker_handle, (double)strip->start / FPS, -1, 0);
- else {
- AUD_removeSequence(scene->sound_scene, strip->speaker_handle);
- strip->speaker_handle = NULL;
- }
- }
- else {
- if (speaker->sound) {
- strip->speaker_handle = AUD_addSequence(scene->sound_scene,
- speaker->sound->playback_handle,
- (double)strip->start / FPS, -1, 0);
- AUD_setRelativeSequence(strip->speaker_handle, 0);
- }
- }
-
- if (strip->speaker_handle) {
- AUD_addSet(new_set, strip->speaker_handle);
- AUD_updateSequenceData(strip->speaker_handle, speaker->volume_max,
- speaker->volume_min, speaker->distance_max,
- speaker->distance_reference, speaker->attenuation,
- speaker->cone_angle_outer, speaker->cone_angle_inner,
- speaker->cone_volume_outer);
-
- mat4_to_quat(quat, ob->obmat);
- AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1);
- AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1);
- AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1);
- AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1);
- AUD_updateSequenceSound(strip->speaker_handle, speaker->sound->playback_handle);
- AUD_muteSequence(strip->speaker_handle, ((strip->flag & NLASTRIP_FLAG_MUTED) != 0) || ((speaker->flag & SPK_MUTED) != 0));
- }
+ /* cheap test to skip looping over all objects (no speakers is a common case) */
+ if (!BLI_listbase_is_empty(&bmain->speaker)) {
+ for (SETLOOPER(scene, sce_it, base)) {
+ ob = base->object;
+ if ((ob->type != OB_SPEAKER) || !ob->adt) {
+ continue;
+ }
+ for (track = ob->adt->nla_tracks.first; track; track = track->next) {
+ for (strip = track->strips.first; strip; strip = strip->next) {
+ if (strip->type != NLASTRIP_TYPE_SOUND) {
+ continue;
+ }
+ speaker = (Speaker *)ob->data;
+
+ if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) {
+ if (speaker->sound) {
+ AUD_moveSequence(strip->speaker_handle, (double)strip->start / FPS, -1, 0);
+ }
+ else {
+ AUD_removeSequence(scene->sound_scene, strip->speaker_handle);
+ strip->speaker_handle = NULL;
+ }
+ }
+ else {
+ if (speaker->sound) {
+ strip->speaker_handle = AUD_addSequence(scene->sound_scene,
+ speaker->sound->playback_handle,
+ (double)strip->start / FPS, -1, 0);
+ AUD_setRelativeSequence(strip->speaker_handle, 0);
}
}
+
+ if (strip->speaker_handle) {
+ const bool mute = ((strip->flag & NLASTRIP_FLAG_MUTED) || (speaker->flag & SPK_MUTED));
+ AUD_addSet(new_set, strip->speaker_handle);
+ AUD_updateSequenceData(strip->speaker_handle, speaker->volume_max,
+ speaker->volume_min, speaker->distance_max,
+ speaker->distance_reference, speaker->attenuation,
+ speaker->cone_angle_outer, speaker->cone_angle_inner,
+ speaker->cone_volume_outer);
+
+ mat4_to_quat(quat, ob->obmat);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1);
+ AUD_updateSequenceSound(strip->speaker_handle, speaker->sound->playback_handle);
+ AUD_muteSequence(strip->speaker_handle, mute);
+ }
}
}
}
@@ -759,7 +781,7 @@ void sound_update_scene(struct Scene *scene)
void *sound_get_factory(void *sound)
{
- return ((bSound *) sound)->playback_handle;
+ return ((bSound *)sound)->playback_handle;
}
/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */
@@ -770,52 +792,56 @@ float sound_get_length(bSound *sound)
return info.length;
}
-int sound_is_jack_supported(void)
+bool sound_is_jack_supported(void)
{
- return AUD_isJackSupported();
+ return (bool)AUD_isJackSupported();
}
-#else // WITH_AUDASPACE
+#else /* WITH_AUDASPACE */
#include "BLI_utildefines.h"
-int sound_define_from_str(const char *UNUSED(str)) { return -1;}
+int sound_define_from_str(const char *UNUSED(str)) { return -1; }
void sound_force_device(int UNUSED(device)) {}
void sound_init_once(void) {}
void sound_init(struct Main *UNUSED(bmain)) {}
void sound_exit(void) {}
void sound_exit_once(void) {}
-void sound_cache(struct bSound *UNUSED(sound)) { }
+void sound_cache(struct bSound *UNUSED(sound)) {}
void sound_delete_cache(struct bSound *UNUSED(sound)) {}
void sound_load(struct Main *UNUSED(bmain), struct bSound *UNUSED(sound)) {}
void sound_create_scene(struct Scene *UNUSED(scene)) {}
void sound_destroy_scene(struct Scene *UNUSED(scene)) {}
void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
-void *sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
-void *sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; }
-void *sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void *sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence),
+ int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void *sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene),
+ struct Sequence *UNUSED(sequence)) { return NULL; }
+void *sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe),
+ int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
void *sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; }
void sound_remove_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle)) {}
void sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute)) {}
-void sound_move_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
+void sound_move_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe),
+ int UNUSED(endframe), int UNUSED(frameskip)) {}
void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {}
void sound_play_scene(struct Scene *UNUSED(scene)) {}
void sound_stop_scene(struct Scene *UNUSED(scene)) {}
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
-void sound_read_waveform(struct bSound *sound) { (void)sound; }
-void sound_init_main(struct Main *bmain) { (void)bmain; }
-void sound_set_cfra(int cfra) { (void)cfra; }
-void sound_update_sequencer(struct Main *main, struct bSound *sound) { (void)main; (void)sound; }
-void sound_update_scene(struct Scene *scene) { (void)scene; }
-void sound_update_scene_sound(void *handle, struct bSound *sound) { (void)handle; (void)sound; }
-void sound_update_scene_listener(struct Scene *scene) { (void)scene; }
-void sound_update_fps(struct Scene *scene) { (void)scene; }
-void sound_set_scene_sound_volume(void *handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; }
-void sound_set_scene_sound_pan(void *handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; }
-void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; }
-void sound_set_scene_sound_pitch(void *handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
-float sound_get_length(struct bSound *sound) { (void)sound; return 0; }
-int sound_is_jack_supported(void) { return 0; }
-#endif // WITH_AUDASPACE
+void sound_read_waveform(struct bSound *UNUSED(sound)) {}
+void sound_init_main(struct Main *UNUSED(bmain)) {}
+void sound_set_cfra(int UNUSED(cfra)) {}
+void sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {}
+void sound_update_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
+void sound_update_scene_sound(void *UNUSED(handle), struct bSound *UNUSED(sound)) {}
+void sound_update_scene_listener(struct Scene *UNUSED(scene)) {}
+void sound_update_fps(struct Scene *UNUSED(scene)) {}
+void sound_set_scene_sound_volume(void *UNUSED(handle), float UNUSED(volume), char UNUSED(animated)) {}
+void sound_set_scene_sound_pan(void *UNUSED(handle), float UNUSED(pan), char UNUSED(animated)) {}
+void sound_set_scene_volume(struct Scene *UNUSED(scene), float UNUSED(volume)) {}
+void sound_set_scene_sound_pitch(void *UNUSED(handle), float UNUSED(pitch), char UNUSED(animated)) {}
+float sound_get_length(struct bSound *UNUSED(sound)) { return 0; }
+bool sound_is_jack_supported(void) { return false; }
+#endif /* WITH_AUDASPACE */
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 332eef17ae7..08daa09cc85 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -74,7 +74,7 @@ void BKE_speaker_make_local(Speaker *spk)
{
Main *bmain = G.main;
Object *ob;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -90,13 +90,13 @@ void BKE_speaker_make_local(Speaker *spk)
ob = bmain->object.first;
while (ob) {
if (ob->data == spk) {
- if (ob->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ob->id.lib) is_lib = true;
+ else is_local = true;
}
ob = ob->id.next;
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &spk->id);
}
else if (is_local && is_lib) {
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index ddc647674ab..9b95f24a2c2 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -63,8 +63,18 @@
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "BLI_threads.h"
+#include "BKE_pbvh.h"
+#include "BKE_ccg.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_global.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_multires.h"
+#include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_subsurf.h"
+
#include "PIL_time.h"
#ifndef USE_DYNSIZE
@@ -90,6 +100,9 @@
#include <float.h>
+static ThreadRWMutex loops_cache_rwlock = BLI_RWLOCK_INITIALIZER;
+static ThreadRWMutex origindex_cache_rwlock = BLI_RWLOCK_INITIALIZER;
+
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
@@ -701,7 +714,7 @@ static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
if (max[2] < vec[2]) max[2] = vec[2];
}
-static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
+static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -715,13 +728,13 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
CCG_key_top_level(&key, ss);
if (!ccgSubSurf_getNumVerts(ss))
- min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
+ r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
float *co = ccgSubSurf_getVertData(ss, v);
- minmax_v3_v3v3(co, min_r, max_r);
+ minmax_v3_v3v3(co, r_min, r_max);
}
ccgVertIterator_free(vi);
@@ -730,7 +743,7 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
for (i = 0; i < edgeSize; i++)
- minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), min_r, max_r);
+ minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
}
ccgEdgeIterator_free(ei);
@@ -743,7 +756,7 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
for (y = 0; y < gridSize; y++)
for (x = 0; x < gridSize; x++)
- minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), min_r, max_r);
+ minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
}
}
ccgFaceIterator_free(fi);
@@ -870,20 +883,20 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
}
}
-static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
+static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
{
MVert mvert;
ccgDM_getFinalVert(dm, vertNum, &mvert);
- copy_v3_v3(co_r, mvert.co);
+ copy_v3_v3(r_co, mvert.co);
}
-static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
+static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
{
MVert mvert;
ccgDM_getFinalVert(dm, vertNum, &mvert);
- normal_short_to_float_v3(no_r, mvert.no);
+ normal_short_to_float_v3(r_no, mvert.no);
}
static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
@@ -1336,16 +1349,21 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
/* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
if (!ccgdm->ehash) {
- MEdge *medge;
+ BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
+ if (!ccgdm->ehash) {
+ MEdge *medge;
- ccgdm->ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
- medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
+ ccgdm->ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
+ medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
- for (i = 0; i < ccgdm->dm.numEdgeData; i++) {
- BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
+ for (i = 0; i < ccgdm->dm.numEdgeData; i++) {
+ BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
+ }
}
+ BLI_rw_mutex_unlock(&loops_cache_rwlock);
}
+ BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_READ);
totface = ccgSubSurf_getNumFaces(ss);
mv = mloop;
for (index = 0; index < totface; index++) {
@@ -1388,6 +1406,7 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
}
}
}
+ BLI_rw_mutex_unlock(&loops_cache_rwlock);
}
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
@@ -1561,6 +1580,35 @@ static void ccgDM_foreachMappedEdge(
ccgEdgeIterator_free(ei);
}
+static void ccgDM_foreachMappedLoop(
+ DerivedMesh *dm,
+ void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
+{
+ /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
+ * return loop data from bmesh itself. */
+ const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
+
+ MVert *mv = dm->getVertArray(dm);
+ MLoop *ml = dm->getLoopArray(dm);
+ MPoly *mp = dm->getPolyArray(dm);
+ const int *v_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ const int *f_index = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ int p_idx, i;
+
+ for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
+ for (i = 0; i < mp->totloop; ++i, ++ml) {
+ const int v_idx = v_index ? v_index[ml->v] : ml->v;
+ const int f_idx = f_index ? f_index[p_idx] : p_idx;
+ const float *no = lnors ? *lnors++ : NULL;
+ if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
+ func(userData, v_idx, f_idx, mv[ml->v].co, no);
+ }
+ }
+ }
+}
+
static void ccgDM_drawVerts(DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
@@ -1623,7 +1671,7 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
}
}
-static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
+static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -1744,12 +1792,14 @@ static void ccgDM_gpuNormalFast(float *a, float *b, float *c, float *d)
}
/* Only used by non-editmesh types */
-static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, DMSetMaterial setMaterial)
+static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int gridSize = ccgSubSurf_getGridSize(ss);
+ int gridFaces = gridSize - 1;
DMFlagMat *faceFlags = ccgdm->faceFlags;
int step = (fast) ? gridSize - 1 : 1;
int i, totface = ccgSubSurf_getNumFaces(ss);
@@ -1760,7 +1810,9 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if (dm->numTessFaceData) {
- BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial, false);
+ BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
+ setMaterial, false);
+ GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
}
return;
@@ -1774,16 +1826,22 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int new_matnr, new_shademodel;
+ short (*ln)[4][3] = NULL;
if (faceFlags) {
- new_shademodel = (faceFlags[index].flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
+ new_shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
new_matnr = faceFlags[index].mat_nr;
}
else {
new_shademodel = GL_SMOOTH;
new_matnr = 0;
}
-
+
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
if (shademodel != new_shademodel) {
shademodel = new_shademodel;
@@ -1796,7 +1854,11 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
if (matnr != new_matnr) {
matnr = new_matnr;
- drawcurrent = setMaterial(matnr + 1, NULL);
+
+ if (setMaterial)
+ drawcurrent = setMaterial(matnr + 1, NULL);
+ else
+ drawcurrent = 1;
}
if (!drawcurrent)
@@ -1805,23 +1867,42 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
for (S = 0; S < numVerts; S++) {
CCGElem *faceGridData = (CCGElem*)ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (shademodel == GL_SMOOTH) {
- for (y = 0; y < gridSize - 1; y += step) {
- for (x = 0; x < gridSize - 1; x += step) {
- CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y);
- CCGElem *b = CCG_grid_elem(&key, faceGridData, x + step, y);
- CCGElem *c = CCG_grid_elem(&key, faceGridData, x + step, y + step);
- CCGElem *d = CCG_grid_elem(&key, faceGridData, x, y + step);
-
- gpuNormal3fv(CCG_elem_no(&key, d));
- gpuVertex3fv(CCG_elem_co(&key, d));
- gpuNormal3fv(CCG_elem_no(&key, c));
- gpuVertex3fv(CCG_elem_co(&key, c));
- gpuNormal3fv(CCG_elem_no(&key, b));
- gpuVertex3fv(CCG_elem_co(&key, b));
+ if (ln) {
+ /* Can't use quad strips here... */
+ gpuBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y += step) {
+ for (x = 0; x < gridFaces; x += step) {
+ float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
+ float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
+ float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step);
+
+ gpuNormal3sv(ln[0][1]);
+ gpuVertex3fv(d);
+ gpuNormal3sv(ln[0][2]);
+ gpuVertex3fv(c);
+ gpuNormal3sv(ln[0][3]);
+ gpuVertex3fv(b);
+ gpuNormal3sv(ln[0][0]);
+ gpuVertex3fv(a);
+ ln += step;
+ }
+ }
+ gpuEnd();
+ }
+ else if (shademodel == GL_SMOOTH) {
+ for (y = 0; y < gridFaces; y += step) {
+ gpuBegin(GL_QUAD_STRIP);
+ for (x = 0; x < gridSize; x += step) {
+ CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0);
+ CCGElem *b = CCG_grid_elem(&key, faceGridData, x, y + step);
+
gpuNormal3fv(CCG_elem_no(&key, a));
gpuVertex3fv(CCG_elem_co(&key, a));
+ gpuNormal3fv(CCG_elem_no(&key, b));
+ gpuVertex3fv(CCG_elem_co(&key, b));
}
+ gpuEnd();
}
}
else {
@@ -1984,6 +2065,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
int gridFaces = gridSize - 1;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, i, do_draw, numVerts, matnr, new_matnr, totface;
CCG_key_top_level(&key, ss);
@@ -2003,6 +2085,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
totface = ccgSubSurf_getNumFaces(ss);
for (a = 0, i = 0; i < totface; i++) {
CCGFace *f = ccgdm->faceMap[i].face;
+ short (*ln)[4][3] = NULL;
int S, x, y, drawSmooth;
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int origIndex = ccgDM_getFaceMapIndex(ss, f);
@@ -2010,7 +2093,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
numVerts = ccgSubSurf_getFaceNumVerts(f);
if (faceFlags) {
- drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
new_matnr = faceFlags[index].mat_nr + 1;
}
else {
@@ -2018,6 +2101,11 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
new_matnr = 1;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
if (new_matnr != matnr) {
do_draw = setMaterial(matnr = new_matnr, &gattribs);
if (do_draw)
@@ -2043,7 +2131,35 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
CCGElem *faceGridData = (CCGElem*)ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *vda, *vdb;
- if (drawSmooth) {
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
+ float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
+ float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ PASSATTRIB(0, 1, 1);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(dco);
+ PASSATTRIB(1, 1, 2);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(cco);
+ PASSATTRIB(1, 0, 3);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(bco);
+ PASSATTRIB(0, 0, 0);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(aco);
+
+ ln++;
+ a++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
gpuBegin(GL_TRIANGLE_STRIP);
for (x = 0; x < gridFaces; x++) {
@@ -2121,7 +2237,7 @@ static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
/* Only used by non-editmesh types */
static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
- void (*setMaterial)(void *userData, int, void *attribs),
+ void (*setMaterial)(void *userData, int matnr, void *attribs),
bool (*setFace)(void *userData, int index), void *userData)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
@@ -2133,6 +2249,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
int gridFaces = gridSize - 1;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, i, numVerts, matnr, new_matnr, totface;
CCG_key_top_level(&key, ss);
@@ -2151,6 +2268,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
totface = ccgSubSurf_getNumFaces(ss);
for (a = 0, i = 0; i < totface; i++) {
CCGFace *f = ccgdm->faceMap[i].face;
+ short (*ln)[4][3] = NULL;
int S, x, y, drawSmooth;
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int origIndex = ccgDM_getFaceMapIndex(ss, f);
@@ -2159,7 +2277,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
/* get flags */
if (faceFlags) {
- drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
new_matnr = faceFlags[index].mat_nr + 1;
}
else {
@@ -2167,6 +2285,11 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
new_matnr = 1;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
/* material */
if (new_matnr != matnr) {
setMaterial(userData, matnr = new_matnr, &gattribs);
@@ -2191,7 +2314,35 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
CCGElem *faceGridData = (CCGElem*)ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *vda, *vdb;
- if (drawSmooth) {
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ PASSATTRIB(0, 1, 1);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(dco);
+ PASSATTRIB(1, 1, 2);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(cco);
+ PASSATTRIB(1, 0, 3);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(bco);
+ PASSATTRIB(0, 0, 0);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(aco);
+
+ ln++;
+ a++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
gpuBegin(GL_TRIANGLE_STRIP);
for (x = 0; x < gridFaces; x++) {
@@ -2271,7 +2422,8 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
MCol *mcol = (MCol*)dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
- MTFace *tf = (MTFace*)DM_get_tessface_data_layer(dm, CD_MTFACE);
+ MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
DMFlagMat *faceFlags = ccgdm->faceFlags;
DMDrawOption draw_option;
int i, totface, gridSize = ccgSubSurf_getGridSize(ss);
@@ -2300,10 +2452,11 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
unsigned char *cp = NULL;
+ short (*ln)[4][3] = NULL;
int mat_nr;
if (faceFlags) {
- drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
mat_nr = faceFlags[origIndex].mat_nr;
}
else {
@@ -2318,6 +2471,10 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
else
draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMALLY : DM_DRAW_OPTION_SKIP;
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
if (draw_option == DM_DRAW_OPTION_SKIP) {
if (tf) tf += gridFaces * gridFaces * numVerts;
@@ -2336,7 +2493,46 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
CCGElem *faceGridData = (CCGElem*)ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *a, *b;
- if (drawSmooth) {
+ if (ln) {
+ // SSS Enable Smooth
+ GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
+
+ gpuBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ if (tf) gpuTexCoord2fv(tf->uv[1]);
+ if (cp) gpuColor3ub(cp[7], cp[6], cp[5]);
+ gpuNormal3sv(ln[0][1]);
+ gpuVertex3fv(d_co);
+
+ if (tf) gpuTexCoord2fv(tf->uv[2]);
+ if (cp) gpuColor3ub(cp[11], cp[10], cp[9]);
+ gpuNormal3sv(ln[0][2]);
+ gpuVertex3fv(c_co);
+
+ if (tf) gpuTexCoord2fv(tf->uv[3]);
+ if (cp) gpuColor3ub(cp[15], cp[14], cp[13]);
+ gpuNormal3sv(ln[0][3]);
+ gpuVertex3fv(b_co);
+
+ if (tf) gpuTexCoord2fv(tf->uv[0]);
+ if (cp) gpuColor3ub(cp[3], cp[2], cp[1]);
+ gpuNormal3sv(ln[0][0]);
+ gpuVertex3fv(a_co);
+
+ if (tf) tf++;
+ if (cp) cp += 16;
+ ln++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
@@ -2493,6 +2689,7 @@ static void ccgDM_drawMappedFaces(
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
MCol *mcol = NULL;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int i, gridSize = ccgSubSurf_getGridSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
@@ -2516,11 +2713,12 @@ static void ccgDM_drawMappedFaces(
int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
int origIndex;
unsigned char *cp = NULL;
+ short (*ln)[4][3] = NULL;
origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1;
- else if (faceFlags) drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
+ else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
else drawSmooth = 1;
if (mcol) {
@@ -2528,6 +2726,11 @@ static void ccgDM_drawMappedFaces(
mcol += gridFaces * gridFaces * numVerts * 4;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
{
DMDrawOption draw_option = DM_DRAW_OPTION_NORMALLY;
@@ -2553,7 +2756,36 @@ static void ccgDM_drawMappedFaces(
for (S = 0; S < numVerts; S++) {
CCGElem *faceGridData = (CCGElem*)ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (drawSmooth) {
+
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(d);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(c);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(b);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(a);
+
+ if (cp) cp += 16;
+ ln++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
CCGElem *a, *b;
gpuBegin(GL_TRIANGLE_STRIP);
@@ -2846,11 +3078,14 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
int a, index, totnone, totorig;
/* Avoid re-creation if the layer exists already */
+ BLI_rw_mutex_lock(&origindex_cache_rwlock, THREAD_LOCK_READ);
origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ BLI_rw_mutex_unlock(&origindex_cache_rwlock);
if (origindex) {
return origindex;
}
+ BLI_rw_mutex_lock(&origindex_cache_rwlock, THREAD_LOCK_WRITE);
DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
@@ -2865,6 +3100,7 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
CCGVert *v = ccgdm->vertMap[index].vert;
origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
}
+ BLI_rw_mutex_unlock(&origindex_cache_rwlock);
return origindex;
}
@@ -2934,6 +3170,39 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
return origindex;
}
+ if (type == CD_TESSLOOPNORMAL) {
+ /* Create tessloopnormal on demand to save memory. */
+ /* Note that since tessellated face corners are the same a loops in CCGDM, and since all faces have four
+ * loops/corners, we can simplify the code here by converting tessloopnormals from 'short (*)[4][3]'
+ * to 'short (*)[3]'.
+ */
+ short (*tlnors)[3];
+
+ /* Avoid re-creation if the layer exists already */
+ tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
+ if (!tlnors) {
+ float (*lnors)[3];
+ short (*tlnors_it)[3];
+ const int numLoops = ccgDM_getNumLoops(dm);
+ int i;
+
+ lnors = dm->getLoopDataArray(dm, CD_NORMAL);
+ if (!lnors) {
+ return NULL;
+ }
+
+ DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL);
+ tlnors = tlnors_it = (short (*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
+
+ /* With ccgdm, we have a simple one to one mapping between loops and tessellated face corners. */
+ for (i = 0; i < numLoops; ++i, ++tlnors_it, ++lnors) {
+ normal_float_to_short_v3(*tlnors_it, *lnors);
+ }
+ }
+
+ return tlnors;
+ }
+
return DM_get_tessface_data_layer(dm, type);
}
@@ -2995,8 +3264,8 @@ static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
{
- if (type == CD_ORIGINDEX) {
- /* ensure creation of CD_ORIGINDEX layer */
+ if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) {
+ /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
ccgDM_get_tessface_data_layer(dm, type);
}
@@ -3295,7 +3564,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int index, totvert, totedge, totface;
int i;
int vertNum, edgeNum, faceNum;
- int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused */
+ int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex;
short *edgeFlags;
DMFlagMat *faceFlags;
int *polyidx = NULL;
@@ -3305,7 +3574,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
BLI_array_declare(vertidx);
#endif
int loopindex, loopindex2;
- int edgeSize, has_edge_origindex;
+ int edgeSize;
int gridSize;
int gridFaces, gridCuts;
/*int gridSideVerts;*/
@@ -3318,6 +3587,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
MEdge *medge = NULL;
/* MFace *mface = NULL; */
MPoly *mpoly = NULL;
+ bool has_edge_cd;
DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
ccgSubSurf_getNumFinalVerts(ss),
@@ -3391,11 +3661,13 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.getPBVH = ccgDM_getPBVH;
ccgdm->dm.calcNormals = ccgDM_calcNormals;
+ ccgdm->dm.calcLoopNormals = CDDM_calc_loop_normals;
ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation;
ccgdm->dm.getVertCos = ccgdm_getVertCos;
ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
+ ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop;
ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
ccgdm->dm.drawVerts = ccgDM_drawVerts;
@@ -3471,11 +3743,13 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
- /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/
+ edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+ has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
+
#if 0
/* this is not in trunk, can gives problems because colors initialize
* as black, just don't do it!, it works fine - campbell */
@@ -3484,9 +3758,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
#endif
- has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
-
-
loopindex = loopindex2 = 0; /* current loop index */
for (index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
@@ -3576,10 +3847,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
}
}
- if (has_edge_origindex) {
- for (i = 0; i < numFinalEdges; ++i)
- *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
- CD_ORIGINDEX) = ORIGINDEX_NONE;
+ if (edgeOrigIndex) {
+ for (i = 0; i < numFinalEdges; ++i) {
+ edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
+ }
}
for (s = 0; s < numVerts; s++) {
@@ -3673,9 +3944,15 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
vertNum++;
}
- for (i = 0; i < numFinalEdges; ++i) {
- if (has_edge_origindex) {
- *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i, CD_ORIGINDEX) = mapIndex;
+ if (has_edge_cd) {
+ for (i = 0; i < numFinalEdges; ++i) {
+ CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, mapIndex, edgeNum + i, 1);
+ }
+ }
+
+ if (edgeOrigIndex) {
+ for (i = 0; i < numFinalEdges; ++i) {
+ edgeOrigIndex[edgeNum + i] = mapIndex;
}
}
@@ -3833,7 +4110,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
return (DerivedMesh *)result;
}
-void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
+void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
{
/* Finds the subsurf limit positions for the verts in a mesh
* and puts them in an array of floats. Please note that the
@@ -3873,9 +4150,9 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
mul_v3_fl(face_sum, (float)N / (float)numFaces);
co = ccgSubSurf_getVertData(ss, v);
- positions_r[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
- positions_r[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
- positions_r[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
+ r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
+ r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
+ r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
}
ccgVertIterator_free(vi);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index e1396c022cb..b6d7e8922c4 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -996,7 +996,8 @@ void txt_move_left(Text *text, const bool sel)
void txt_move_right(Text *text, const bool sel)
{
TextLine **linep;
- int *charp, do_tab = FALSE, i;
+ int *charp, i;
+ bool do_tab = false;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
@@ -1013,10 +1014,10 @@ void txt_move_right(Text *text, const bool sel)
// do nice right only if there are only spaces
// spaces hardcoded in DNA_text_types.h
if (text->flags & TXT_TABSTOSPACES && (*linep)->line[*charp] == ' ') {
- do_tab = TRUE;
+ do_tab = true;
for (i = 0; i < *charp; i++)
if ((*linep)->line[i] != ' ') {
- do_tab = FALSE;
+ do_tab = false;
break;
}
}
@@ -1366,7 +1367,7 @@ char *txt_to_buf(Text *text)
int txt_find_string(Text *text, const char *findstr, int wrap, int match_case)
{
TextLine *tl, *startl;
- char *s = NULL;
+ const char *s = NULL;
if (!text || !text->curl || !text->sell) return 0;
@@ -2536,7 +2537,7 @@ void txt_backspace_char(Text *text)
}
else { /* Just backspacing a char */
size_t c_len = 0;
- char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
+ const char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
c = BLI_str_utf8_as_unicode_and_size(prev, &c_len);
/* source and destination overlap, don't use memcpy() */
@@ -2573,11 +2574,11 @@ static void txt_convert_tab_to_spaces(Text *text)
* is added so that the indention of the line is the right width (i.e. aligned
* to multiples of TXT_TABSIZE)
*/
- char *sb = &tab_to_spaces[text->curc % TXT_TABSIZE];
+ const char *sb = &tab_to_spaces[text->curc % TXT_TABSIZE];
txt_insert_buf(text, sb);
}
-static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
+static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
{
char *tmp, ch[BLI_UTF8_MAX];
size_t add_len;
@@ -2620,12 +2621,12 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
return 1;
}
-int txt_add_char(Text *text, unsigned int add)
+bool txt_add_char(Text *text, unsigned int add)
{
- return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES);
+ return txt_add_char_intern(text, add, (text->flags & TXT_TABSTOSPACES) != 0);
}
-int txt_add_raw_char(Text *text, unsigned int add)
+bool txt_add_raw_char(Text *text, unsigned int add)
{
return txt_add_char_intern(text, add, 0);
}
@@ -2636,7 +2637,7 @@ void txt_delete_selected(Text *text)
txt_make_dirty(text);
}
-int txt_replace_char(Text *text, unsigned int add)
+bool txt_replace_char(Text *text, unsigned int add)
{
unsigned int del;
size_t del_size = 0, add_size;
@@ -2709,7 +2710,7 @@ void txt_indent(Text *text)
curc_old = text->curc;
num = 0;
- while (TRUE) {
+ while (true) {
/* don't indent blank lines */
if (text->curl->len != 0) {
@@ -2758,7 +2759,7 @@ void txt_unindent(Text *text)
int num = 0;
const char *remove = "\t";
int indentlen = 1;
- int unindented_first = FALSE;
+ bool unindented_first = false;
/* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE;
@@ -2773,23 +2774,22 @@ void txt_unindent(Text *text)
indentlen = spaceslen;
}
- while (TRUE) {
- int i = 0;
-
- if (BLI_strncasecmp(text->curl->line, remove, indentlen) == 0) {
- if (num == 0) unindented_first = TRUE;
- while (i < text->curl->len) {
- text->curl->line[i] = text->curl->line[i + indentlen];
- i++;
- }
+ while (true) {
+ bool changed = false;
+ if (strncmp(text->curl->line, remove, indentlen) == 0) {
+ if (num == 0)
+ unindented_first = true;
text->curl->len -= indentlen;
+ memmove(text->curl->line, text->curl->line + indentlen, text->curl->len + 1);
+ changed = true;
}
txt_make_dirty(text);
txt_clean_text(text);
if (text->curl == text->sell) {
- if (i > 0) text->selc = MAX2(text->selc - indentlen, 0);
+ if (changed)
+ text->selc = MAX2(text->selc - indentlen, 0);
break;
}
else {
@@ -2799,7 +2799,8 @@ void txt_unindent(Text *text)
}
- if (unindented_first) text->curc = MAX2(text->curc - indentlen, 0);
+ if (unindented_first)
+ text->curc = MAX2(text->curc - indentlen, 0);
while (num > 0) {
text->curl = text->curl->prev;
@@ -2822,7 +2823,7 @@ void txt_comment(Text *text)
if (!text->sell) return; // Need to change this need to check if only one line is selected to more than one
num = 0;
- while (TRUE) {
+ while (true) {
tmp = MEM_mallocN(text->curl->len + 2, "textline_string");
text->curc = 0;
@@ -2869,7 +2870,7 @@ void txt_uncomment(Text *text)
if (!text->curl) return;
if (!text->sell) return;
- while (TRUE) {
+ while (true) {
int i = 0;
if (text->curl->line[i] == remove) {
@@ -2961,7 +2962,8 @@ int txt_setcurr_tab_spaces(Text *text, int space)
* 2) within an identifier
* 3) after the cursor (text->curc), i.e. when creating space before a function def [#25414]
*/
- int a, is_indent = 0;
+ int a;
+ bool is_indent = false;
for (a = 0; (a < text->curc) && (text->curl->line[a] != '\0'); a++) {
char ch = text->curl->line[a];
if (ch == '#') {
@@ -3051,12 +3053,12 @@ bool text_check_identifier_nodigit(const char ch)
}
#ifndef WITH_PYTHON
-bool text_check_identifier_unicode(const unsigned int ch)
+int text_check_identifier_unicode(const unsigned int ch)
{
- return (ch < 255 && text_check_identifier((char)ch));
+ return (ch < 255 && text_check_identifier((unsigned int)ch));
}
-bool text_check_identifier_nodigit_unicode(const unsigned int ch)
+int text_check_identifier_nodigit_unicode(const unsigned int ch)
{
return (ch < 255 && text_check_identifier_nodigit((char)ch));
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index d192ca71c12..4fff50153ef 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -38,7 +38,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_dynlib.h"
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
@@ -52,12 +51,12 @@
#include "DNA_node_types.h"
#include "DNA_color_types.h"
#include "DNA_particle_types.h"
+#include "DNA_linestyle_types.h"
#include "IMB_imbuf.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_ocean.h"
#include "BKE_library.h"
#include "BKE_image.h"
@@ -789,7 +788,9 @@ void BKE_texture_make_local(Tex *tex)
Lamp *la;
Brush *br;
ParticleSettings *pa;
- int a, is_local = FALSE, is_lib = FALSE;
+ FreestyleLineStyle *ls;
+ int a;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -808,8 +809,8 @@ void BKE_texture_make_local(Tex *tex)
while (ma) {
for (a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a] && ma->mtex[a]->tex == tex) {
- if (ma->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (ma->id.lib) is_lib = true;
+ else is_local = true;
}
}
ma = ma->id.next;
@@ -818,8 +819,8 @@ void BKE_texture_make_local(Tex *tex)
while (la) {
for (a = 0; a < MAX_MTEX; a++) {
if (la->mtex[a] && la->mtex[a]->tex == tex) {
- if (la->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (la->id.lib) is_lib = true;
+ else is_local = true;
}
}
la = la->id.next;
@@ -828,8 +829,8 @@ void BKE_texture_make_local(Tex *tex)
while (wrld) {
for (a = 0; a < MAX_MTEX; a++) {
if (wrld->mtex[a] && wrld->mtex[a]->tex == tex) {
- if (wrld->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (wrld->id.lib) is_lib = true;
+ else is_local = true;
}
}
wrld = wrld->id.next;
@@ -837,12 +838,12 @@ void BKE_texture_make_local(Tex *tex)
br = bmain->brush.first;
while (br) {
if (br->mtex.tex == tex) {
- if (br->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (br->id.lib) is_lib = true;
+ else is_local = true;
}
if (br->mask_mtex.tex == tex) {
- if (br->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (br->id.lib) is_lib = true;
+ else is_local = true;
}
br = br->id.next;
}
@@ -850,14 +851,24 @@ void BKE_texture_make_local(Tex *tex)
while (pa) {
for (a = 0; a < MAX_MTEX; a++) {
if (pa->mtex[a] && pa->mtex[a]->tex == tex) {
- if (pa->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (pa->id.lib) is_lib = true;
+ else is_local = true;
}
}
pa = pa->id.next;
}
+ ls = bmain->linestyle.first;
+ while (ls) {
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (ls->mtex[a] && ls->mtex[a]->tex == tex) {
+ if (ls->id.lib) is_lib = true;
+ else is_local = true;
+ }
+ }
+ ls = ls->id.next;
+ }
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &tex->id);
extern_local_texture(tex);
}
@@ -939,6 +950,19 @@ void BKE_texture_make_local(Tex *tex)
}
pa = pa->id.next;
}
+ ls = bmain->linestyle.first;
+ while (ls) {
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (ls->mtex[a] && ls->mtex[a]->tex == tex) {
+ if (ls->id.lib == NULL) {
+ ls->mtex[a]->tex = tex_new;
+ tex_new->id.us++;
+ tex->id.us--;
+ }
+ }
+ }
+ ls = ls->id.next;
+ }
}
}
@@ -1000,6 +1024,41 @@ void set_current_lamp_texture(Lamp *la, Tex *newtex)
}
}
+Tex *give_current_linestyle_texture(FreestyleLineStyle *linestyle)
+{
+ MTex *mtex = NULL;
+ Tex *tex = NULL;
+
+ if (linestyle) {
+ mtex = linestyle->mtex[(int)(linestyle->texact)];
+ if (mtex) tex = mtex->tex;
+ }
+
+ return tex;
+}
+
+void set_current_linestyle_texture(FreestyleLineStyle *linestyle, Tex *newtex)
+{
+ int act = linestyle->texact;
+
+ if (linestyle->mtex[act] && linestyle->mtex[act]->tex)
+ id_us_min(&linestyle->mtex[act]->tex->id);
+
+ if (newtex) {
+ if (!linestyle->mtex[act]) {
+ linestyle->mtex[act] = add_mtex();
+ linestyle->mtex[act]->texco = TEXCO_STROKE;
+ }
+
+ linestyle->mtex[act]->tex = newtex;
+ id_us_plus(&newtex->id);
+ }
+ else if (linestyle->mtex[act]) {
+ MEM_freeN(linestyle->mtex[act]);
+ linestyle->mtex[act] = NULL;
+ }
+}
+
bNode *give_current_material_texture_node(Material *ma)
{
if (ma && ma->use_nodes && ma->nodetree)
@@ -1034,7 +1093,7 @@ Tex *give_current_material_texture(Material *ma)
return tex;
}
-int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
+bool give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
{
switch (GS(id->name)) {
case ID_MA:
@@ -1049,6 +1108,10 @@ int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
*mtex_ar = ((Lamp *)id)->mtex;
if (act) *act = (((Lamp *)id)->texact);
break;
+ case ID_LS:
+ *mtex_ar = ((FreestyleLineStyle *)id)->mtex;
+ if (act) *act = (((FreestyleLineStyle *)id)->texact);
+ break;
case ID_PA:
*mtex_ar = ((ParticleSettings *)id)->mtex;
if (act) *act = (((ParticleSettings *)id)->texact);
@@ -1056,10 +1119,10 @@ int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
default:
*mtex_ar = NULL;
if (act) *act = 0;
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
void set_active_mtex(ID *id, short act)
@@ -1077,6 +1140,9 @@ void set_active_mtex(ID *id, short act)
case ID_LA:
((Lamp *)id)->texact = act;
break;
+ case ID_LS:
+ ((FreestyleLineStyle *)id)->texact = act;
+ break;
case ID_PA:
((ParticleSettings *)id)->texact = act;
break;
@@ -1307,7 +1373,7 @@ PointDensity *BKE_add_pointdensity(void)
pd->falloff_curve->preset = CURVE_PRESET_LINE;
pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
- curvemapping_changed(pd->falloff_curve, FALSE);
+ curvemapping_changed(pd->falloff_curve, false);
return pd;
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index de20f4a8ac6..22005892535 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -47,7 +47,6 @@
#include "BLI_math.h"
#include "BLI_math_base.h"
#include "BLI_listbase.h"
-#include "BLI_ghash.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_threads.h"
@@ -55,7 +54,6 @@
#include "BLF_translation.h"
#include "BKE_fcurve.h"
-#include "BKE_global.h"
#include "BKE_tracking.h"
#include "BKE_movieclip.h"
#include "BKE_object.h"
@@ -197,9 +195,10 @@ void BKE_tracking_settings_init(MovieTracking *tracking)
tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
tracking->settings.default_minimum_correlation = 0.75;
- tracking->settings.default_pattern_size = 15;
- tracking->settings.default_search_size = 61;
+ tracking->settings.default_pattern_size = 21;
+ tracking->settings.default_search_size = 71;
tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE;
+ tracking->settings.default_weight = 1.0f;
tracking->settings.dist = 1;
tracking->settings.object_distance = 1;
@@ -418,7 +417,7 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tr
track->frames_limit = settings->default_frames_limit;
track->flag = settings->default_flag;
track->algorithm_flag = settings->default_algorithm_flag;
- track->weight = 1.0f;
+ track->weight = settings->default_weight;
memset(&marker, 0, sizeof(marker));
marker.pos[0] = x;
@@ -1732,32 +1731,19 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking,
/*********************** Distortion/Undistortion *************************/
-static void cameraIntrinscisOptionsFromTracking(libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- MovieTracking *tracking, int calibration_width, int calibration_height)
-{
- MovieTrackingCamera *camera = &tracking->camera;
- float aspy = 1.0f / tracking->camera.pixel_aspect;
-
- camera_intrinsics_options->focal_length = camera->focal;
-
- camera_intrinsics_options->principal_point_x = camera->principal[0];
- camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy;
-
- camera_intrinsics_options->k1 = camera->k1;
- camera_intrinsics_options->k2 = camera->k2;
- camera_intrinsics_options->k3 = camera->k3;
-
- camera_intrinsics_options->image_width = calibration_width;
- camera_intrinsics_options->image_height = (int) (calibration_height * aspy);
-}
-
-MovieDistortion *BKE_tracking_distortion_new(void)
+MovieDistortion *BKE_tracking_distortion_new(MovieTracking *tracking,
+ int calibration_width, int calibration_height)
{
MovieDistortion *distortion;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
- distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+ tracking_cameraIntrinscisOptionsFromTracking(tracking,
+ calibration_width,
+ calibration_height,
+ &camera_intrinsics_options);
- distortion->intrinsics = libmv_cameraIntrinsicsNewEmpty();
+ distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+ distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
return distortion;
}
@@ -1767,8 +1753,10 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
{
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
- cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking,
- calibration_width, calibration_height);
+ tracking_cameraIntrinscisOptionsFromTracking(tracking,
+ calibration_width,
+ calibration_height,
+ &camera_intrinsics_options);
libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
}
@@ -1844,7 +1832,9 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r
double x, y;
float aspy = 1.0f / tracking->camera.pixel_aspect;
- cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0);
+ tracking_cameraIntrinscisOptionsFromTracking(tracking,
+ 0, 0,
+ &camera_intrinsics_options);
/* normalize coords */
x = (co[0] - camera->principal[0]) / camera->focal;
@@ -1865,7 +1855,9 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float
double x = co[0], y = co[1];
float aspy = 1.0f / tracking->camera.pixel_aspect;
- cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0);
+ tracking_cameraIntrinscisOptionsFromTracking(tracking,
+ 0, 0,
+ &camera_intrinsics_options);
libmv_cameraIntrinsicsInvert(&camera_intrinsics_options, x, y, &x, &y);
@@ -1878,8 +1870,9 @@ ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int ca
{
MovieTrackingCamera *camera = &tracking->camera;
- if (camera->intrinsics == NULL)
- camera->intrinsics = BKE_tracking_distortion_new();
+ if (camera->intrinsics == NULL) {
+ camera->intrinsics = BKE_tracking_distortion_new(tracking, calibration_width, calibration_height);
+ }
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
calibration_height, overscan, true);
@@ -1890,8 +1883,9 @@ ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int cali
{
MovieTrackingCamera *camera = &tracking->camera;
- if (camera->intrinsics == NULL)
- camera->intrinsics = BKE_tracking_distortion_new();
+ if (camera->intrinsics == NULL) {
+ camera->intrinsics = BKE_tracking_distortion_new(tracking, calibration_width, calibration_height);
+ }
return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
calibration_height, overscan, false);
@@ -1980,11 +1974,9 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
if (num_samples_x <= 0 || num_samples_y <= 0)
return NULL;
- pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
-
- if (!search_ibuf->rect_float) {
- IMB_float_from_rect(search_ibuf);
- }
+ pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y,
+ 32,
+ search_ibuf->rect_float ? IB_rectfloat : IB_rect);
tracking_get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
@@ -2014,10 +2006,26 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
}
- 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);
+ 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);
+ }
+ else {
+ libmv_samplePlanarPatchByte((unsigned char *) search_ibuf->rect,
+ search_ibuf->x, search_ibuf->y, 4,
+ src_pixel_x, src_pixel_y,
+ num_samples_x, num_samples_y,
+ mask,
+ (unsigned char *) pattern_ibuf->rect,
+ &warped_position_x,
+ &warped_position_y);
+ }
if (pos) {
pos[0] = warped_position_x;
@@ -2339,8 +2347,8 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking)
BKE_tracking_object_get_reconstruction(tracking, object);
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
- short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY;
- short show_hidden = dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN;
+ bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0;
+ bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0;
for (track = tracksbase->first; track; track = track->next) {
MovieTrackingDopesheetChannel *channel;
@@ -2499,7 +2507,7 @@ void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
- dopesheet->ok = FALSE;
+ dopesheet->ok = false;
}
/* Do dopesheet update, if update is not needed nothing will happen. */
@@ -2522,5 +2530,5 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
/* frame coverage */
tracking_dopesheet_calc_coverage(tracking);
- dopesheet->ok = TRUE;
+ dopesheet->ok = true;
}
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
index a5a8ec87721..62039b761e8 100644
--- a/source/blender/blenkernel/intern/tracking_detect.c
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -31,8 +31,6 @@
* This file contains blender-side implementation of feature detection.
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h" /* SELECT */
diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c
index 7bada00655b..76b7ad5d982 100644
--- a/source/blender/blenkernel/intern/tracking_region_tracker.c
+++ b/source/blender/blenkernel/intern/tracking_region_tracker.c
@@ -595,6 +595,7 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac
src_pixel_x, src_pixel_y,
&result,
dst_pixel_x, dst_pixel_y);
+
MEM_freeN(patch_new);
return tracked;
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 5a28d8d264e..056220e27d8 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -66,11 +66,7 @@ typedef struct MovieReconstructContext {
bool is_camera;
short motion_flag;
- float focal_length;
- float principal_point[2];
- float k1, k2, k3;
-
- int width, height;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
float reprojection_error;
@@ -134,22 +130,11 @@ static void reconstruct_retrieve_libmv_intrinsics(MovieReconstructContext *conte
struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_reconstructionExtractIntrinsics(libmv_reconstruction);
- float aspy = 1.0f / tracking->camera.pixel_aspect;
-
- double focal_length, principal_x, principal_y, k1, k2, k3;
- int width, height;
-
- libmv_cameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
- &k1, &k2, &k3, &width, &height);
-
- tracking->camera.focal = focal_length;
-
- tracking->camera.principal[0] = principal_x;
- tracking->camera.principal[1] = principal_y / (double)aspy;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
+ libmv_cameraIntrinsicsExtractOptions(libmv_intrinsics, &camera_intrinsics_options);
- tracking->camera.k1 = k1;
- tracking->camera.k2 = k2;
- tracking->camera.k3 = k3;
+ tracking_trackingCameraFromIntrinscisOptions(tracking,
+ &camera_intrinsics_options);
}
/* Retrieve reconstructed tracks from libmv to blender.
@@ -369,7 +354,6 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
{
MovieTracking *tracking = &clip->tracking;
MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
- MovieTrackingCamera *camera = &tracking->camera;
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
float aspy = 1.0f / tracking->camera.pixel_aspect;
int num_tracks = BLI_countlist(tracksbase);
@@ -383,16 +367,9 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
context->select_keyframes =
(tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) != 0;
- context->focal_length = camera->focal;
- context->principal_point[0] = camera->principal[0];
- context->principal_point[1] = camera->principal[1] * aspy;
-
- context->width = width;
- context->height = height;
-
- context->k1 = camera->k1;
- context->k2 = camera->k2;
- context->k3 = camera->k3;
+ tracking_cameraIntrinscisOptionsFromTracking(tracking,
+ width, height,
+ &context->camera_intrinsics_options);
context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
@@ -456,27 +433,11 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const
if (progressdata->progress) {
*progressdata->progress = progress;
- *progressdata->do_update = TRUE;
+ *progressdata->do_update = true;
}
BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message);
}
-/* FIll in camera intrinsics structure from reconstruction context. */
-static void camraIntrincicsOptionsFromContext(libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- MovieReconstructContext *context)
-{
- camera_intrinsics_options->focal_length = context->focal_length;
-
- camera_intrinsics_options->principal_point_x = context->principal_point[0];
- camera_intrinsics_options->principal_point_y = context->principal_point[1];
-
- camera_intrinsics_options->k1 = context->k1;
- camera_intrinsics_options->k2 = context->k2;
- camera_intrinsics_options->k3 = context->k3;
-
- camera_intrinsics_options->image_width = context->width;
- camera_intrinsics_options->image_height = context->height;
-}
/* Fill in reconstruction options structure from reconstruction context. */
static void reconstructionOptionsFromContext(libmv_ReconstructionOptions *reconstruction_options,
@@ -506,7 +467,6 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *
ReconstructProgressData progressdata;
- libmv_CameraIntrinsicsOptions camera_intrinsics_options;
libmv_ReconstructionOptions reconstruction_options;
progressdata.stop = stop;
@@ -515,18 +475,17 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *
progressdata.stats_message = stats_message;
progressdata.message_size = message_size;
- camraIntrincicsOptionsFromContext(&camera_intrinsics_options, context);
reconstructionOptionsFromContext(&reconstruction_options, context);
if (context->motion_flag & TRACKING_MOTION_MODAL) {
context->reconstruction = libmv_solveModal(context->tracks,
- &camera_intrinsics_options,
+ &context->camera_intrinsics_options,
&reconstruction_options,
reconstruct_update_solve_cb, &progressdata);
}
else {
context->reconstruction = libmv_solveReconstruction(context->tracks,
- &camera_intrinsics_options,
+ &context->camera_intrinsics_options,
&reconstruction_options,
reconstruct_update_solve_cb, &progressdata);
@@ -576,7 +535,7 @@ bool BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieT
}
static void tracking_scale_reconstruction(ListBase *tracksbase, MovieTrackingReconstruction *reconstruction,
- float scale[3])
+ const float scale[3])
{
MovieTrackingTrack *track;
int i;
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index 567386733a3..8cdb547612c 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -33,8 +33,6 @@
#include <limits.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_movieclip_types.h"
#include "BLI_utildefines.h"
@@ -245,7 +243,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i
stab->scale = 1.0f;
}
- stab->ok = TRUE;
+ stab->ok = true;
return stab->scale;
}
@@ -289,7 +287,7 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i
stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median,
translation, scale, angle);
- stab->ok = TRUE;
+ stab->ok = true;
}
else {
stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median,
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 4b3c354dd12..4ebe8494101 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -51,6 +51,8 @@
#include "tracking_private.h"
+#include "libmv-capi.h"
+
/*********************** Tracks map *************************/
TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size)
@@ -386,3 +388,68 @@ void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrack
if (overwrite || !BKE_tracking_track_has_marker_at_frame(track, marker_new.framenr))
BKE_tracking_marker_insert(track, &marker_new);
}
+
+
+/* Fill in Libmv C-API camera intrinsics options from tracking structure.
+ */
+void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking,
+ int calibration_width, int calibration_height,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
+{
+ MovieTrackingCamera *camera = &tracking->camera;
+ float aspy = 1.0f / tracking->camera.pixel_aspect;
+
+ camera_intrinsics_options->focal_length = camera->focal;
+
+ camera_intrinsics_options->principal_point_x = camera->principal[0];
+ camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy;
+
+ switch (camera->distortion_model) {
+ case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
+ camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_POLYNOMIAL;
+ camera_intrinsics_options->polynomial_k1 = camera->k1;
+ camera_intrinsics_options->polynomial_k2 = camera->k2;
+ camera_intrinsics_options->polynomial_k3 = camera->k3;
+ camera_intrinsics_options->polynomial_p1 = 0.0;
+ camera_intrinsics_options->polynomial_p2 = 0.0;
+ break;
+ case TRACKING_DISTORTION_MODEL_DIVISION:
+ camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_DIVISION;
+ camera_intrinsics_options->division_k1 = camera->division_k1;
+ camera_intrinsics_options->division_k2 = camera->division_k2;
+ break;
+ default:
+ BLI_assert(!"Unknown distortion model");
+ }
+
+ camera_intrinsics_options->image_width = calibration_width;
+ camera_intrinsics_options->image_height = (int) (calibration_height * aspy);
+}
+
+void tracking_trackingCameraFromIntrinscisOptions(MovieTracking *tracking,
+ const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
+{
+ float aspy = 1.0f / tracking->camera.pixel_aspect;
+ MovieTrackingCamera *camera = &tracking->camera;
+
+ camera->focal = camera_intrinsics_options->focal_length;
+
+ camera->principal[0] = camera_intrinsics_options->principal_point_x;
+ camera->principal[1] = camera_intrinsics_options->principal_point_y / (double) aspy;
+
+ switch (camera_intrinsics_options->distortion_model) {
+ case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+ camera->distortion_model = TRACKING_DISTORTION_MODEL_POLYNOMIAL;
+ camera->k1 = camera_intrinsics_options->polynomial_k1;
+ camera->k2 = camera_intrinsics_options->polynomial_k2;
+ camera->k3 = camera_intrinsics_options->polynomial_k3;
+ break;
+ case LIBMV_DISTORTION_MODEL_DIVISION:
+ camera->distortion_model = TRACKING_DISTORTION_MODEL_DIVISION;
+ camera->division_k1 = camera_intrinsics_options->division_k1;
+ camera->division_k2 = camera_intrinsics_options->division_k2;
+ break;
+ default:
+ BLI_assert(!"Unknown distortion model");
+ }
+}
diff --git a/source/blender/blenkernel/intern/treehash.c b/source/blender/blenkernel/intern/treehash.c
index d1e9da72208..fb55e3d2137 100644
--- a/source/blender/blenkernel/intern/treehash.c
+++ b/source/blender/blenkernel/intern/treehash.c
@@ -76,11 +76,19 @@ static void tse_group_free(TseGroup *tse_group)
static unsigned int tse_hash(const void *ptr)
{
const TreeStoreElem *tse = ptr;
- unsigned int hash;
+ union {
+ short h_pair[2];
+ unsigned int u_int;
+ } hash;
+
BLI_assert(tse->type || !tse->nr);
- hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type));
- hash ^= BLI_ghashutil_inthash(tse->id);
- return hash;
+
+ hash.h_pair[0] = tse->type;
+ hash.h_pair[1] = tse->nr;
+
+ hash.u_int ^= BLI_ghashutil_ptrhash(tse->id);
+
+ return hash.u_int;
}
static int tse_cmp(const void *a, const void *b)
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 00c51f5b52d..de6424f3145 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -471,7 +471,7 @@ static const char *unit_find_str(const char *str, const char *substr)
/* previous char cannot be a letter */
if (str_found == str ||
/* weak unicode support!, so "µm" won't match up be replaced by "m"
- * since non ascii utf8 values will NEVER return TRUE */
+ * since non ascii utf8 values will NEVER return true */
isalpha_or_utf8(*BLI_str_prev_char_utf8(str_found)) == 0)
{
/* next char cannot be alphanum */
@@ -680,7 +680,7 @@ int bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double sca
* */
{
char *str_found = str;
- char *ch = str;
+ const char *ch = str;
while ((str_found = strchr(str_found, SEP_CHR))) {
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 0104efb4892..5065c3ae04f 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -75,7 +75,7 @@ void BKE_world_free_ex(World *wrld, bool do_id_user)
void BKE_world_free(World *wrld)
{
- BKE_world_free_ex(wrld, TRUE);
+ BKE_world_free_ex(wrld, true);
}
World *add_world(Main *bmain, const char *name)
@@ -166,7 +166,7 @@ void BKE_world_make_local(World *wrld)
{
Main *bmain = G.main;
Scene *sce;
- int is_local = FALSE, is_lib = FALSE;
+ bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
@@ -179,14 +179,14 @@ void BKE_world_make_local(World *wrld)
return;
}
- for (sce = bmain->scene.first; sce && ELEM(FALSE, is_lib, is_local); sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce && ELEM(false, is_lib, is_local); sce = sce->id.next) {
if (sce->world == wrld) {
- if (sce->id.lib) is_lib = TRUE;
- else is_local = TRUE;
+ if (sce->id.lib) is_lib = true;
+ else is_local = true;
}
}
- if (is_local && is_lib == FALSE) {
+ if (is_local && is_lib == false) {
id_clear_lib_data(bmain, &wrld->id);
}
else if (is_local && is_lib) {
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index 40bb593c108..a9f040b8650 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -236,7 +236,7 @@ static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *p
}
AVI_write_frame(avi, (frame - start_frame), AVI_FORMAT_RGB32, rectot, rectx * recty * 4);
-// printf ("added frame %3d (frame %3d in avi): ", frame, frame-start_frame);
+// printf("added frame %3d (frame %3d in avi): ", frame, frame-start_frame);
return 1;
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index ddd6780b0e9..dbceba288c7 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -103,6 +103,9 @@ static AUD_Device *audio_mixdown_device = 0;
#define PRINT if (G.debug & G_DEBUG_FFMPEG) printf
+static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value);
+static void ffmpeg_dict_set_float(AVDictionary **dict, const char *key, float value);
+
/* Delete a picture buffer */
static void delete_picture(AVFrame *f)
@@ -138,6 +141,7 @@ static int write_audio_frame(void)
#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
frame = avcodec_alloc_frame();
+ avcodec_get_frame_defaults(frame);
frame->pts = audio_time / av_q2d(c->time_base);
frame->nb_samples = audio_input_samples;
frame->format = c->sample_fmt;
@@ -421,11 +425,10 @@ static AVFrame *generate_video_frame(uint8_t *pixels, ReportList *reports)
return current_frame;
}
-static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
+static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop, AVDictionary **dictionary)
{
char name[128];
char *param;
- int fail = TRUE;
PRINT("FFMPEG expert option: %s: ", prop->name);
@@ -440,32 +443,28 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
switch (prop->type) {
case IDP_STRING:
PRINT("%s.\n", IDP_String(prop));
- fail = av_opt_set(c, prop->name, IDP_String(prop), 0);
+ av_dict_set(dictionary, name, IDP_String(prop), 0);
break;
case IDP_FLOAT:
PRINT("%g.\n", IDP_Float(prop));
- fail = av_opt_set_double(c, prop->name, IDP_Float(prop), 0);
+ ffmpeg_dict_set_float(dictionary, prop->name, IDP_Float(prop));
break;
case IDP_INT:
PRINT("%d.\n", IDP_Int(prop));
if (param) {
if (IDP_Int(prop)) {
- fail = av_opt_set(c, name, param, 0);
+ av_dict_set(dictionary, name, param, 0);
}
else {
return;
}
}
else {
- fail = av_opt_set_int(c, prop->name, IDP_Int(prop), 0);
+ ffmpeg_dict_set_int(dictionary, prop->name, IDP_Int(prop));
}
break;
}
-
- if (fail) {
- PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
- }
}
static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProperty *curr)
@@ -482,7 +481,8 @@ static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProp
return valid;
}
-static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char *prop_name)
+static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char *prop_name,
+ AVDictionary **dictionary)
{
IDProperty *prop;
void *iter;
@@ -501,7 +501,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
while ((curr = IDP_GroupIterNext(iter)) != NULL) {
if (ffmpeg_proprty_valid(c, prop_name, curr))
- set_ffmpeg_property_option(c, curr);
+ set_ffmpeg_property_option(c, curr, dictionary);
}
}
@@ -513,6 +513,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
AVStream *st;
AVCodecContext *c;
AVCodec *codec;
+ AVDictionary *opts = NULL;
error[0] = '\0';
@@ -605,7 +606,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
if (codec_id == AV_CODEC_ID_PNG) {
if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
- c->pix_fmt = PIX_FMT_ARGB;
+ c->pix_fmt = PIX_FMT_RGBA;
}
}
@@ -632,12 +633,14 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(((double) rd->xasp / (double) rd->yasp), 255);
- set_ffmpeg_properties(rd, c, "video");
-
- if (avcodec_open2(c, codec, NULL) < 0) {
+ set_ffmpeg_properties(rd, c, "video", &opts);
+
+ if (avcodec_open2(c, codec, &opts) < 0) {
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
+ av_dict_free(&opts);
return NULL;
}
+ av_dict_free(&opts);
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
@@ -651,6 +654,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
AVStream *st;
AVCodecContext *c;
AVCodec *codec;
+ AVDictionary *opts = NULL;
error[0] = '\0';
@@ -710,13 +714,19 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
st->codec->sample_rate = best;
}
- set_ffmpeg_properties(rd, c, "audio");
+ if (of->oformat->flags & AVFMT_GLOBALHEADER) {
+ c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ }
+
+ set_ffmpeg_properties(rd, c, "audio", &opts);
- if (avcodec_open2(c, codec, NULL) < 0) {
+ if (avcodec_open2(c, codec, &opts) < 0) {
//XXX error("Couldn't initialize audio codec");
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
+ av_dict_free(&opts);
return NULL;
}
+ av_dict_free(&opts);
/* need to prevent floating point exception when using vorbis audio codec,
* initialize this value in the same way as it's done in FFmpeg iteslf (sergey) */
@@ -767,6 +777,15 @@ static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value)
av_dict_set(dict, key, buffer, 0);
}
+static void ffmpeg_dict_set_float(AVDictionary **dict, const char *key, float value)
+{
+ char buffer[32];
+
+ BLI_snprintf(buffer, sizeof(buffer), "%.8f", value);
+
+ av_dict_set(dict, key, buffer, 0);
+}
+
static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, ReportList *reports)
{
/* Handle to the output file */
@@ -1123,7 +1142,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i
if (ffmpeg_autosplit) {
if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
- end_ffmpeg_impl(TRUE);
+ end_ffmpeg_impl(true);
ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(rd, rectx, recty, reports);
}
@@ -1149,7 +1168,7 @@ static void end_ffmpeg_impl(int is_autosplit)
#endif
#ifdef WITH_AUDASPACE
- if (is_autosplit == FALSE) {
+ if (is_autosplit == false) {
if (audio_mixdown_device) {
AUD_closeReadDevice(audio_mixdown_device);
audio_mixdown_device = 0;
@@ -1221,7 +1240,7 @@ static void end_ffmpeg_impl(int is_autosplit)
void BKE_ffmpeg_end(void)
{
- end_ffmpeg_impl(FALSE);
+ end_ffmpeg_impl(false);
}
/* properties */
@@ -1241,11 +1260,9 @@ void BKE_ffmpeg_property_del(RenderData *rd, void *type, void *prop_)
}
}
-IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_index, int parent_index)
+static IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, const AVOption *o, const AVOption *parent)
{
AVCodecContext c;
- const AVOption *o;
- const AVOption *parent;
IDProperty *group;
IDProperty *prop;
IDPropertyTemplate val;
@@ -1256,9 +1273,6 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
avcodec_get_context_defaults3(&c, NULL);
- o = c.av_class->option + opt_index;
- parent = c.av_class->option + parent_index;
-
if (!rd->ffcodecdata.properties) {
rd->ffcodecdata.properties = IDP_New(IDP_GROUP, &val, "ffmpeg");
}
@@ -1270,14 +1284,14 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
IDP_AddToGroup(rd->ffcodecdata.properties, group);
}
- if (parent_index) {
+ if (parent) {
BLI_snprintf(name, sizeof(name), "%s:%s", parent->name, o->name);
}
else {
BLI_strncpy(name, o->name, sizeof(name));
}
- PRINT("ffmpeg_property_add: %s %d %d %s\n", type, parent_index, opt_index, name);
+ PRINT("ffmpeg_property_add: %s %s\n", type, name);
prop = IDP_GetPropertyFromGroup(group, name);
if (prop) {
@@ -1315,22 +1329,6 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
/* not all versions of ffmpeg include that, so here we go ... */
-static const AVOption *my_av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
-{
- AVClass *c = *(AVClass **)v;
- const AVOption *o = c->option;
-
- for (; o && o->name; o++) {
- if (!strcmp(o->name, name) &&
- (!unit || (o->unit && !strcmp(o->unit, unit))) &&
- (o->flags & mask) == flags)
- {
- return o;
- }
- }
- return NULL;
-}
-
int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char *str)
{
AVCodecContext c;
@@ -1358,21 +1356,25 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
while (*param == ' ') param++;
}
- o = my_av_find_opt(&c, name, NULL, 0, 0);
+ o = av_opt_find(&c, name, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
if (!o) {
+ PRINT("Ignoring unknown expert option %s\n", str);
return 0;
}
if (param && o->type == AV_OPT_TYPE_CONST) {
return 0;
}
if (param && o->type != AV_OPT_TYPE_CONST && o->unit) {
- p = my_av_find_opt(&c, param, o->unit, 0, 0);
+ p = av_opt_find(&c, param, o->unit, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
if (p) {
- prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option);
+ prop = BKE_ffmpeg_property_add(rd, (char *) type, p, o);
+ }
+ else {
+ PRINT("Ignoring unknown expert option %s\n", str);
}
}
else {
- prop = BKE_ffmpeg_property_add(rd, (char *) type, o - c.av_class->option, 0);
+ prop = BKE_ffmpeg_property_add(rd, (char *) type, o, NULL);
}
@@ -1422,9 +1424,9 @@ static void ffmpeg_set_expert_options(RenderData *rd)
*/
// ffmpeg_property_add_string(rd, "video", "flags:loop"); // this breaks compatibility for QT
BKE_ffmpeg_property_add_string(rd, "video", "cmp:chroma");
- BKE_ffmpeg_property_add_string(rd, "video", "partitions:parti4x4");
- BKE_ffmpeg_property_add_string(rd, "video", "partitions:partp8x8");
- BKE_ffmpeg_property_add_string(rd, "video", "partitions:partb8x8");
+ BKE_ffmpeg_property_add_string(rd, "video", "partitions:parti4x4"); // Deprecated.
+ BKE_ffmpeg_property_add_string(rd, "video", "partitions:partp8x8"); // Deprecated.
+ BKE_ffmpeg_property_add_string(rd, "video", "partitions:partb8x8"); // Deprecated.
BKE_ffmpeg_property_add_string(rd, "video", "me:hex");
BKE_ffmpeg_property_add_string(rd, "video", "subq:6");
BKE_ffmpeg_property_add_string(rd, "video", "me_range:16");
@@ -1436,15 +1438,27 @@ static void ffmpeg_set_expert_options(RenderData *rd)
BKE_ffmpeg_property_add_string(rd, "video", "bf:3");
BKE_ffmpeg_property_add_string(rd, "video", "refs:2");
BKE_ffmpeg_property_add_string(rd, "video", "qcomp:0.6");
- BKE_ffmpeg_property_add_string(rd, "video", "directpred:3");
+
BKE_ffmpeg_property_add_string(rd, "video", "trellis:0");
- BKE_ffmpeg_property_add_string(rd, "video", "flags2:wpred");
+ BKE_ffmpeg_property_add_string(rd, "video", "weightb:1");
+#ifdef FFMPEG_HAVE_DEPRECATED_FLAGS2
BKE_ffmpeg_property_add_string(rd, "video", "flags2:dct8x8");
+ BKE_ffmpeg_property_add_string(rd, "video", "directpred:3");
BKE_ffmpeg_property_add_string(rd, "video", "flags2:fastpskip");
+ BKE_ffmpeg_property_add_string(rd, "video", "flags2:wpred");
+#else
+ BKE_ffmpeg_property_add_string(rd, "video", "8x8dct:1");
+ BKE_ffmpeg_property_add_string(rd, "video", "fast-pskip:1");
BKE_ffmpeg_property_add_string(rd, "video", "wpredp:2");
+#endif
- if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT)
+ if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) {
+#ifdef FFMPEG_HAVE_DEPRECATED_FLAGS2
BKE_ffmpeg_property_add_string(rd, "video", "cqp:0");
+#else
+ BKE_ffmpeg_property_add_string(rd, "video", "qp:0");
+#endif
+ }
}
else if (codec_id == AV_CODEC_ID_DNXHD) {
if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT)
@@ -1601,17 +1615,17 @@ bool BKE_ffmpeg_alpha_channel_is_supported(RenderData *rd)
int codec = rd->ffcodecdata.codec;
if (codec == AV_CODEC_ID_QTRLE)
- return TRUE;
+ return true;
if (codec == AV_CODEC_ID_PNG)
- return TRUE;
+ return true;
#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
if (codec == AV_CODEC_ID_FFV1)
- return TRUE;
+ return true;
#endif
- return FALSE;
+ return false;
}
#endif
diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c
index acbbcb0b043..746b99ffb52 100644
--- a/source/blender/blenkernel/intern/writeframeserver.c
+++ b/source/blender/blenkernel/intern/writeframeserver.c
@@ -252,7 +252,7 @@ static int handle_request(RenderData *rd, char *req)
}
if (strcmp(path, "/close.txt") == 0) {
safe_puts(good_bye);
- G.is_break = TRUE; /* Abort render */
+ G.is_break = true; /* Abort render */
return -1;
}
return -1;
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 981b7951097..6efa1533e3e 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -41,6 +41,8 @@ struct GHash;
struct MovieTracking;
struct MovieTrackingMarker;
+struct libmv_CameraIntrinsicsOptions;
+
/*********************** Tracks map *************************/
typedef struct TracksMap {
@@ -86,4 +88,11 @@ void tracking_set_marker_coords_from_tracking(int frame_width, int frame_height,
void tracking_marker_insert_disabled(struct MovieTrackingTrack *track, const struct MovieTrackingMarker *ref_marker,
bool before, bool overwrite);
+void tracking_cameraIntrinscisOptionsFromTracking(struct MovieTracking *tracking,
+ int calibration_width, int calibration_height,
+ struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
+
+void tracking_trackingCameraFromIntrinscisOptions(struct MovieTracking *tracking,
+ const struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
+
#endif /* __TRACKING_PRIVATE_H__ */
diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
index 06c3e8d8996..fd814940624 100644
--- a/source/blender/blenlib/BLI_alloca.h
+++ b/source/blender/blenlib/BLI_alloca.h
@@ -28,9 +28,6 @@
*/
/* BLI_array_alloca / alloca */
-#ifdef _MSC_VER
-# define alloca _alloca
-#endif
#if defined(__MINGW32__)
# include <malloc.h> /* mingw needs for alloca() */
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index fc16e7dbba6..f0d32670229 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -42,7 +42,7 @@
/* hint to mark function arguments expected to be non-null
* if no arguments are given to the macro, all of pointer
- * arguments owuld be expected to be non-null
+ * arguments would be expected to be non-null
*/
#ifdef __GNUC__
# define ATTR_NONNULL(args ...) __attribute__((nonnull(args)))
@@ -50,6 +50,13 @@
# define ATTR_NONNULL(...)
#endif
+/* never returns NULL */
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 /* gcc4.9+ only */
+# define ATTR_RETURNS_NONNULL __attribute__((returns_nonnull))
+#else
+# define ATTR_RETURNS_NONNULL
+#endif
+
/* hint to mark function as it wouldn't return */
#if defined(__GNUC__) || defined(__clang__)
# define ATTR_NORETURN __attribute__((noreturn))
diff --git a/source/blender/compositor/nodes/COM_CombineRGBANode.h b/source/blender/blenlib/BLI_compiler_compat.h
index 5cc0b1ea6da..60a7d8dbd02 100644
--- a/source/blender/compositor/nodes/COM_CombineRGBANode.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Blender Foundation.
+ * ***** 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
@@ -15,23 +15,21 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef _COM_CombineRGBANode_h_
-#define _COM_CombineRGBANode_h_
+#ifndef __BLI_COMPILER_COMPAT_H__
+#define __BLI_COMPILER_COMPAT_H__
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-/**
- * @brief CombineRGBANode
- * @ingroup Node
+/** \file BLI_compiler_compat.h
+ * \ingroup bli
+ *
+ * Use to help with cross platform portability.
*/
-class CombineRGBANode : public Node {
-public:
- CombineRGBANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
+
+#if defined(_MSC_VER)
+# define __func__ __FUNCTION__
+# define alloca _alloca
#endif
+
+#endif /* __BLI_COMPILER_COMPAT_H__ */
diff --git a/source/blender/blenlib/BLI_easing.h b/source/blender/blenlib/BLI_easing.h
new file mode 100644
index 00000000000..0f9f73f475e
--- /dev/null
+++ b/source/blender/blenlib/BLI_easing.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * 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 the author nor the names of 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 <COPYRIGHT HOLDER> 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 __BLI_EASING_H__
+#define __BLI_EASING_H__
+
+/** \file BLI_easing.h
+ * \ingroup bli
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float BLI_easing_back_ease_in(float time, float begin, float change, float duration, float overshoot);
+float BLI_easing_back_ease_out(float time, float begin, float change, float duration, float overshoot);
+float BLI_easing_back_ease_in_out(float time, float begin, float change, float duration, float overshoot);
+float BLI_easing_bounce_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_circ_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_circ_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_circ_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_cubic_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_cubic_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_elastic_ease_in(float time, float begin, float change, float duration, float amplitude, float period);
+float BLI_easing_elastic_ease_out(float time, float begin, float change, float duration, float amplitude, float period);
+float BLI_easing_elastic_ease_in_out(float time, float begin, float change, float duration, float amplitude, float period);
+float BLI_easing_expo_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_expo_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_expo_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_linear_ease(float time, float begin, float change, float duration);
+float BLI_easing_quad_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_quad_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_quad_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_quart_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_quart_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_quart_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_quint_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_quint_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_quint_ease_in_out(float time, float begin, float change, float duration);
+float BLI_easing_sine_ease_in(float time, float begin, float change, float duration);
+float BLI_easing_sine_ease_out(float time, float begin, float change, float duration);
+float BLI_easing_sine_ease_in_out(float time, float begin, float change, float duration);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BLI_EASING_H__ */
diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h
index 2ca011871d8..8e74ce3a9e3 100644
--- a/source/blender/blenlib/BLI_edgehash.h
+++ b/source/blender/blenlib/BLI_edgehash.h
@@ -32,9 +32,13 @@
#include "BLI_compiler_attrs.h"
struct EdgeHash;
-struct EdgeHashIterator;
typedef struct EdgeHash EdgeHash;
-typedef struct EdgeHashIterator EdgeHashIterator;
+
+typedef struct EdgeHashIterator {
+ EdgeHash *eh;
+ struct EdgeEntry *curEntry;
+ unsigned int curBucket;
+} EdgeHashIterator;
typedef void (*EdgeHashFreeFP)(void *key);
@@ -49,6 +53,7 @@ void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp);
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val);
bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val);
void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
+void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default) ATTR_WARN_UNUSED_RESULT;
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT;
@@ -59,13 +64,29 @@ void BLI_edgehash_flag_set(EdgeHash *eh, unsigned int flag);
void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned int flag);
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh);
void BLI_edgehashIterator_free(EdgeHashIterator *ehi);
-void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r);
-void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
-void **BLI_edgehashIterator_getValue_p(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
-void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val);
void BLI_edgehashIterator_step(EdgeHashIterator *ehi);
-bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
+
+BLI_INLINE bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *r_v0, unsigned int *r_v1);
+BLI_INLINE void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE void **BLI_edgehashIterator_getValue_p(EdgeHashIterator *ehi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val);
+
+struct _eh_Entry { void *next; unsigned int v0, v1; void *val; };
+BLI_INLINE void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *r_v0, unsigned int *r_v1)
+{ *r_v0 = ((struct _eh_Entry *)ehi->curEntry)->v0; *r_v1 = ((struct _eh_Entry *)ehi->curEntry)->v1; }
+BLI_INLINE void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) { return ((struct _eh_Entry *)ehi->curEntry)->val; }
+BLI_INLINE void **BLI_edgehashIterator_getValue_p(EdgeHashIterator *ehi) { return &((struct _eh_Entry *)ehi->curEntry)->val; }
+BLI_INLINE void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val) { ((struct _eh_Entry *)ehi->curEntry)->val = val; }
+BLI_INLINE bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) { return (((struct _eh_Entry *)ehi->curEntry) == NULL); }
+/* disallow further access */
+#ifdef __GNUC__
+# pragma GCC poison _eh_Entry
+#else
+# define _eh_Entry void
+#endif
#define BLI_EDGEHASH_SIZE_GUESS_FROM_LOOPS(totloop) ((totloop) / 2)
#define BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly) ((totpoly) * 2)
@@ -89,7 +110,7 @@ void BLI_edgeset_free(EdgeSet *es);
/* rely on inline api for now */
BLI_INLINE EdgeSetIterator *BLI_edgesetIterator_new(EdgeSet *gs) { return (EdgeSetIterator *)BLI_edgehashIterator_new((EdgeHash *)gs); }
BLI_INLINE void BLI_edgesetIterator_free(EdgeSetIterator *esi) { BLI_edgehashIterator_free((EdgeHashIterator *)esi); }
-BLI_INLINE void BLI_edgesetIterator_getKey(EdgeSetIterator *esi, unsigned int *v0_r, unsigned int *v1_r) { BLI_edgehashIterator_getKey((EdgeHashIterator *)esi, v0_r, v1_r); }
+BLI_INLINE void BLI_edgesetIterator_getKey(EdgeSetIterator *esi, unsigned int *r_v0, unsigned int *r_v1) { BLI_edgehashIterator_getKey((EdgeHashIterator *)esi, r_v0, r_v1); }
BLI_INLINE void BLI_edgesetIterator_step(EdgeSetIterator *esi) { BLI_edgehashIterator_step((EdgeHashIterator *)esi); }
BLI_INLINE bool BLI_edgesetIterator_isDone(EdgeSetIterator *esi) { return BLI_edgehashIterator_isDone((EdgeHashIterator *)esi); }
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index d934c35a003..289e53c46ac 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -89,7 +89,7 @@ bool BLI_file_is_writable(const char *file);
bool BLI_file_touch(const char *file);
int BLI_file_gzip(const char *from, const char *to);
-char *BLI_file_ungzip_to_mem(const char *from_file, bli_off_t *size_r); /* assumes unzipped files are less than 2GiB */
+char *BLI_file_ungzip_to_mem(const char *from_file, bli_off_t *r_size); /* assumes unzipped files are less than 2GiB */
bli_off_t BLI_file_descriptor_size(int file);
bli_off_t BLI_file_size(const char *file);
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 2f042b2ce07..a3edb0fa4d6 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -67,6 +67,7 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfre
void BLI_ghash_insert(GHash *gh, void *key, void *val);
bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
+void *BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT;
void **BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
@@ -84,13 +85,24 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RES
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh);
void BLI_ghashIterator_free(GHashIterator *ghi);
-
-void *BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
-void *BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
-void **BLI_ghashIterator_getValue_p(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
-
void BLI_ghashIterator_step(GHashIterator *ghi);
-bool BLI_ghashIterator_done(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
+
+BLI_INLINE void *BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE void *BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE void **BLI_ghashIterator_getValue_p(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
+BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT;
+
+struct _gh_Entry { void *next, *key, *val; };
+BLI_INLINE void *BLI_ghashIterator_getKey(GHashIterator *ghi) { return ((struct _gh_Entry *)ghi->curEntry)->key; }
+BLI_INLINE void *BLI_ghashIterator_getValue(GHashIterator *ghi) { return ((struct _gh_Entry *)ghi->curEntry)->val; }
+BLI_INLINE void **BLI_ghashIterator_getValue_p(GHashIterator *ghi) { return &((struct _gh_Entry *)ghi->curEntry)->val; }
+BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi->curEntry; }
+/* disallow further access */
+#ifdef __GNUC__
+# pragma GCC poison _gh_Entry
+#else
+# define _gh_Entry void
+#endif
#define GHASH_ITER(gh_iter_, ghash_) \
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
@@ -102,17 +114,37 @@ bool BLI_ghashIterator_done(GHashIterator *ghi) ATTR_WARN_UNUSED_RESUL
BLI_ghashIterator_done(&gh_iter_) == false; \
BLI_ghashIterator_step(&gh_iter_), i_++)
-/* *** */
+/** \name Callbacks for GHash
+ *
+ * \note '_p' suffix denotes void pointer arg,
+ * so we can have functions that take correctly typed args too.
+ * \{ */
unsigned int BLI_ghashutil_ptrhash(const void *key);
int BLI_ghashutil_ptrcmp(const void *a, const void *b);
-unsigned int BLI_ghashutil_strhash(const void *key);
+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);
-unsigned int BLI_ghashutil_inthash(const void *ptr);
+#define BLI_ghashutil_inthash(key) ( \
+ CHECK_TYPE_INLINE(key, int), \
+ BLI_ghashutil_uinthash((unsigned int)key))
+unsigned int BLI_ghashutil_uinthash(unsigned int key);
+#define BLI_ghashutil_inthash_v4(key) ( \
+ CHECK_TYPE_INLINE(key, int *), \
+ BLI_ghashutil_uinthash_v4((const 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)
+unsigned int BLI_ghashutil_inthash_p(const void *ptr);
int BLI_ghashutil_intcmp(const void *a, const void *b);
+/** \} */
+
GHash *BLI_ghash_ptr_new_ex(const char *info,
const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GHash *BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/blenlib/BLI_jitter.h b/source/blender/blenlib/BLI_jitter.h
index 936a5260a68..769fb445678 100644
--- a/source/blender/blenlib/BLI_jitter.h
+++ b/source/blender/blenlib/BLI_jitter.h
@@ -32,9 +32,9 @@
* \ingroup bli
*/
-void BLI_jitter_init(float *jitarr, int num);
-void BLI_jitterate1(float *jit1, float *jit2, int num, float radius1);
-void BLI_jitterate2(float *jit1, float *jit2, int num, float radius2);
+void BLI_jitter_init(float (*jitarr)[2], int num);
+void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float radius1);
+void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2);
#endif
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
index e3c81021351..ebf03b5bc67 100644
--- a/source/blender/blenlib/BLI_kdtree.h
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -44,17 +44,29 @@ typedef struct KDTreeNearest {
KDTree *BLI_kdtree_new(unsigned int maxsize);
void BLI_kdtree_free(KDTree *tree);
-
-void BLI_kdtree_insert(KDTree *tree, int index, const float co[3], const float nor[3]) ATTR_NONNULL(1, 3);
void BLI_kdtree_balance(KDTree *tree) ATTR_NONNULL(1);
-int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest *r_nearest) ATTR_NONNULL(1, 2);
-int BLI_kdtree_find_nearest_n(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest *r_nearest,
- unsigned int n) ATTR_NONNULL(1, 2, 4);
-int BLI_kdtree_range_search(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest **r_nearest,
- float range) ATTR_NONNULL(1, 2, 4) ATTR_WARN_UNUSED_RESULT;
+void BLI_kdtree_insert(
+ KDTree *tree, int index,
+ const float co[3]) ATTR_NONNULL(1, 3);
+int BLI_kdtree_find_nearest(
+ KDTree *tree, const float co[3],
+ KDTreeNearest *r_nearest) ATTR_NONNULL(1, 2);
+
+#define BLI_kdtree_find_nearest_n(tree, co, r_nearest, n) \
+ BLI_kdtree_find_nearest_n__normal(tree, co, NULL, r_nearest, n)
+#define BLI_kdtree_range_search(tree, co, r_nearest, range) \
+ BLI_kdtree_range_search__normal(tree, co, NULL, r_nearest, range)
+
+/* Normal use is deprecated */
+/* remove __normal functions when last users drop */
+int BLI_kdtree_find_nearest_n__normal(
+ KDTree *tree, const float co[3], const float nor[3],
+ KDTreeNearest *r_nearest,
+ unsigned int n) ATTR_NONNULL(1, 2, 4);
+int BLI_kdtree_range_search__normal(
+ KDTree *tree, const float co[3], const float nor[3],
+ KDTreeNearest **r_nearest,
+ float range) ATTR_NONNULL(1, 2, 4) ATTR_WARN_UNUSED_RESULT;
#endif /* __BLI_KDTREE_H__ */
diff --git a/source/blender/editors/include/ED_fluidsim.h b/source/blender/blenlib/BLI_link_utils.h
index 4790dc5e03d..d469b105f93 100644
--- a/source/blender/editors/include/ED_fluidsim.h
+++ b/source/blender/blenlib/BLI_link_utils.h
@@ -15,34 +15,32 @@
* 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) Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file ED_fluidsim.h
- * \ingroup editors
- */
-
-#ifndef __ED_FLUIDSIM_H__
-#define __ED_FLUIDSIM_H__
-
-struct Object;
-struct FluidsimSettings;
+#ifndef __BLI_LINK_UTILS_H__
+#define __BLI_LINK_UTILS_H__
+/** \file BLI_link_utils.h
+ * \ingroup bli
+ * \brief Single link-list utility macros. (header only api).
+ *
+ * Use this api when the structure defines its own ``next`` pointer
+ * and a double linked list such as #ListBase isnt needed.
+ */
-/* allocates and initializes fluidsim data */
-struct FluidsimSettings *fluidsimSettingsNew(struct Object *srcob);
-
-/* frees internal data itself */
-void fluidsimSettingsFree(struct FluidsimSettings *sb);
-
-/* duplicate internal data */
-struct FluidsimSettings *fluidsimSettingsCopy(struct FluidsimSettings *sb);
-
-#endif /* __ED_FLUIDSIM_H__ */
+#define BLI_LINKS_PREPEND(list, link) { \
+ CHECK_TYPE_PAIR(list, link); \
+ (link)->next = list; \
+ list = link; \
+} (void)0
+
+#define BLI_LINKS_FREE(list) { \
+ while (list) { \
+ void *next = list->next; \
+ MEM_freeN(list); \
+ list = next; \
+ } \
+} (void)0
+
+#endif /* __BLI_LINK_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h
index ef78fb9a305..5f4f98c5a4f 100644
--- a/source/blender/blenlib/BLI_linklist_stack.h
+++ b/source/blender/blenlib/BLI_linklist_stack.h
@@ -56,7 +56,7 @@
#define BLI_LINKSTACK_INIT(var) { \
var = NULL; \
- _##var##_pool = BLI_mempool_create(sizeof(LinkNode), 1, 64, 0); \
+ _##var##_pool = BLI_mempool_create(sizeof(LinkNode), 0, 64, BLI_MEMPOOL_NOP); \
} (void)0
#define BLI_LINKSTACK_SIZE(var) \
@@ -136,17 +136,32 @@
} (void)0
/* internal use, no null check */
+#define _BLI_SMALLSTACK_DEL_EX(var_src, var_dst) \
+ (void)((_##var_src##_temp = _##var_src##_stack->next), \
+ (_##var_src##_stack->next = _##var_dst##_free), \
+ (_##var_dst##_free = _##var_src##_stack), \
+ (_##var_src##_stack = _##var_src##_temp)) \
+
#define _BLI_SMALLSTACK_DEL(var) \
- (void)((_##var##_temp = _##var##_stack->next), \
- (_##var##_stack->next = _##var##_free), \
- (_##var##_free = _##var##_stack), \
- (_##var##_stack = _##var##_temp)) \
+ _BLI_SMALLSTACK_DEL_EX(var, var) \
/* check for typeof() */
#define BLI_SMALLSTACK_POP(var) \
(_BLI_SMALLSTACK_CAST(var) ((_##var##_stack) ? \
(_BLI_SMALLSTACK_DEL(var), (_##var##_free->link)) : NULL))
+/* support to put the free-node into another stack */
+#define BLI_SMALLSTACK_POP_EX(var_src, var_dst) \
+ (_BLI_SMALLSTACK_CAST(var_src) ((_##var_src##_stack) ? \
+ (_BLI_SMALLSTACK_DEL_EX(var_src, var_dst), (_##var_dst##_free->link)) : NULL))
+
+#define BLI_SMALLSTACK_LAST(var) \
+ (_BLI_SMALLSTACK_CAST(var) ((_##var##_stack) ? \
+ _##var##_stack->link : NULL))
+
+#define BLI_SMALLSTACK_IS_EMPTY(var) \
+ (_BLI_SMALLSTACK_CAST(var) (_##var##_stack != NULL))
+
/* loop over stack members last-added-first */
#define BLI_SMALLSTACK_ITER_BEGIN(var, item) \
{ \
@@ -158,6 +173,13 @@
} \
} (void)0
+#define BLI_SMALLSTACK_SWAP(var_a, var_b) \
+{ \
+ CHECK_TYPE_PAIR(_##var_a##_type, _##var_b##_type); \
+ SWAP(LinkNode *, _##var_a##_stack, _##var_b##_stack); \
+ SWAP(LinkNode *, _##var_a##_free, _##var_b##_free); \
+} (void)0
+
#define BLI_SMALLSTACK_FREE(var) { \
(void)&(_##var##_type); \
} (void)0
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 883f01d4eb6..5bd8490db6e 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -231,6 +231,9 @@ MINLINE int is_power_of_2_i(int n);
MINLINE int power_of_2_max_i(int n);
MINLINE int power_of_2_min_i(int n);
+MINLINE unsigned int power_of_2_max_u(unsigned int x);
+MINLINE unsigned int power_of_2_min_u(unsigned int x);
+
MINLINE int iroundf(float a);
MINLINE int divide_round_i(int a, int b);
MINLINE int mod_i(int i, int n);
@@ -238,9 +241,7 @@ MINLINE int mod_i(int i, int n);
MINLINE unsigned int highest_order_bit_i(unsigned int n);
MINLINE unsigned short highest_order_bit_s(unsigned short n);
-MINLINE float shell_angle_to_dist(const float angle);
-
-#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
+#if defined(_MSC_VER) && (_MSC_VER < 1800)
extern double copysign(double x, double y);
extern double round(double x);
#endif
@@ -269,18 +270,31 @@ double double_round(double x, int ndigits);
(fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON)); \
} (void)0
+# define BLI_ASSERT_UNIT_QUAT(q) { \
+ const float _test_unit = dot_qtqt(q, q); \
+ BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON * 10) || \
+ (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON * 10)); \
+} (void)0
+
# define BLI_ASSERT_ZERO_M3(m) { \
- BLI_assert(dot_vn_vn((const float *)m, (const float *)m, 9) != 0.0); \
+ BLI_assert(dot_vn_vn((const float *)m, (const float *)m, 9) != 0.0); \
} (void)0
# define BLI_ASSERT_ZERO_M4(m) { \
BLI_assert(dot_vn_vn((const float *)m, (const float *)m, 16) != 0.0); \
} (void)0
+# define BLI_ASSERT_UNIT_M3(m) { \
+ BLI_ASSERT_UNIT_V3((m)[0]); \
+ BLI_ASSERT_UNIT_V3((m)[1]); \
+ BLI_ASSERT_UNIT_V3((m)[2]); \
+} (void)0
#else
# define BLI_ASSERT_UNIT_V2(v) (void)(v)
# define BLI_ASSERT_UNIT_V3(v) (void)(v)
+# define BLI_ASSERT_UNIT_QUAT(v) (void)(v)
# define BLI_ASSERT_ZERO_M3(m) (void)(m)
# define BLI_ASSERT_ZERO_M4(m) (void)(m)
+# define BLI_ASSERT_UNIT_M3(m) (void)(m)
#endif
#endif /* __BLI_MATH_BASE_H__ */
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 3892c98e140..5c14ac55492 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -55,6 +55,8 @@ extern "C" {
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]);
+void hsl_to_rgb(float h, float c, float l, float *r, float *g, float *b);
+void hsl_to_rgb_v(const float hcl[3], float r_rgb[3]);
void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace);
@@ -69,6 +71,8 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]);
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll);
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]);
+void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll);
+void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]);
void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv);
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]);
void rgb_to_lab(float r, float g, float b, float *ll, float *la, float *lb);
@@ -128,10 +132,10 @@ void hsv_clamp_v(float hsv[3], float v_max);
void rgb_float_set_hue_float_offset(float *rgb, float hue_offset);
void rgb_byte_set_hue_float_offset(unsigned char *rgb, float hue_offset);
-void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3]);
-void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4]);
-void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3]);
-void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4]);
+void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3]);
+void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4]);
+void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3]);
+void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4]);
void xyz_to_lab(float x, float y, float z, float *l, float *a, float *b);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index e800369a682..f4bcc810846 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -37,10 +37,6 @@ extern "C" {
#include "BLI_compiler_attrs.h"
#include "BLI_math_inline.h"
-#if BLI_MATH_DO_INLINE
-#include "intern/math_geom_inline.c"
-#endif
-
#ifdef BLI_MATH_GCC_WARN_PRAGMA
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wredundant-decls"
@@ -53,17 +49,19 @@ void cent_quad_v3(float r[3], const float a[3], const float b[3], const float c[
float normal_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
float normal_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
+float normal_poly_v3(float r[3], const float verts[][3], unsigned int nr);
MINLINE float area_tri_v2(const float a[2], const float b[2], const float c[2]);
MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
float area_tri_v3(const float a[3], const float b[3], const float c[3]);
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
-float area_poly_v3(int nr, float verts[][3], const float normal[3]);
-float area_poly_v2(int nr, float verts[][2]);
+float area_poly_v3(const float verts[][3], unsigned int nr);
+float area_poly_v2(const float verts[][2], unsigned int nr);
+float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3]);
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2]);
-float cross_poly_v2(int nr, float verts[][2]);
+float cross_poly_v2(const float verts[][2], unsigned int nr);
/********************************* Planes **********************************/
@@ -75,8 +73,9 @@ MINLINE float plane_point_side_v3(const float plane[4], const float co[3]);
float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
-int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
-int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
+bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
+bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
+bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
/********************************* Distance **********************************/
@@ -84,7 +83,7 @@ float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
-void closest_to_line_segment_v2(float closest[2], const float p[2], const float l1[2], const float l2[2]);
+void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);
float dist_squared_to_plane_v3(const float p[3], const float plane[4]);
float dist_to_plane_v3(const float p[3], const float plane[4]);
@@ -94,8 +93,8 @@ float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);
-void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
-void closest_to_plane_v3(float close_r[3], const float plane[4], const float pt[3]);
+void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
+void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3]);
/* Set 'r' to the point in triangle (t1, t2, t3) closest to point 'p' */
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3], const float t2[3], const float t3[3]);
@@ -125,7 +124,7 @@ int isect_line_line_v2_int(const int a1[2], const int a2[2], const int b1[2], co
int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]);
int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], const float r, float r_p1[2], float r_p2[2]);
int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]);
-int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
+bool isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
int isect_line_line_v3(const float v1[3], const float v2[3],
const float v3[3], const float v4[3],
@@ -165,9 +164,9 @@ bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsign
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
-int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
-int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
-int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
+int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
+bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
+int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
/* axis-aligned bounding box */
@@ -216,16 +215,19 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2],
const float co[2], float w[3]);
+void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4],
+ const float co[2], float w[3]);
void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
const float co[2], float w[4]);
bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
int barycentric_inside_triangle_v2(const float w[3]);
-void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
-void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
-void resolve_quad_uv_deriv(float r_uv[2], float r_deriv[2][2],
- const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
+void resolve_tri_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
+void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]);
+void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
+void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
+ const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
/* use to find the point of a UV on a face */
void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]);
@@ -303,15 +305,29 @@ bool form_factor_visible_quad(const float p[3], const float n[3],
float form_factor_hemi_poly(float p[3], float n[3],
float v1[3], float v2[3], float v3[3], float v4[3]);
-bool axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]);
-void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
-float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) ATTR_WARN_UNUSED_RESULT;
+void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]);
+
+MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
+MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE int axis_dominant_v3_single(const float vec[3]);
MINLINE int max_axis_v3(const float vec[3]);
MINLINE int min_axis_v3(const float vec[3]);
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
+MINLINE float shell_angle_to_dist(const float angle);
+MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]);
+MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]);
+MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]);
+MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]);
+
+/**************************** Inline Definitions ******************************/
+
+#if BLI_MATH_DO_INLINE
+#include "intern/math_geom_inline.c"
+#endif
+
#ifdef BLI_MATH_GCC_WARN_PRAGMA
# pragma GCC diagnostic pop
#endif
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 56486a4731b..4237376d4d4 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -118,13 +118,13 @@ void mul_m3_fl(float R[3][3], float f);
void mul_m4_fl(float R[4][4], float f);
void mul_mat3_m4_fl(float R[4][4], float f);
-int invert_m3_ex(float m[3][3], const float epsilon);
-int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
+bool invert_m3_ex(float m[3][3], const float epsilon);
+bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
-int invert_m3(float R[3][3]);
-int invert_m3_m3(float R[3][3], float A[3][3]);
-int invert_m4(float R[4][4]);
-int invert_m4_m4(float R[4][4], const float A[4][4]);
+bool invert_m3(float R[3][3]);
+bool invert_m3_m3(float R[3][3], float A[3][3]);
+bool invert_m4(float R[4][4]);
+bool invert_m4_m4(float R[4][4], const float A[4][4]);
/* double ariphmetics */
void mul_m4_v4d(float M[4][4], double r[4]);
@@ -173,6 +173,8 @@ void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
bool has_zero_axis_m4(float matrix[4][4]);
+void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
+
/****************************** Transformations ******************************/
void scale_m3_fl(float R[3][3], float scale);
@@ -230,6 +232,9 @@ void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3]);
void print_m3(const char *str, float M[3][3]);
void print_m4(const char *str, float M[3][4]);
+#define print_m3_id(M) print_m3(STRINGIFY(M), M)
+#define print_m4_id(M) print_m4(STRINGIFY(M), M)
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index c9f553c6fa5..905889a33d7 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -69,6 +69,7 @@ float normalize_qt_qt(float q1[4], const float q2[4]);
bool is_zero_qt(const float q[4]);
/* interpolation */
+void interp_dot_slerp(const float t, const float cosom, float w[2]);
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], const float t);
void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t);
@@ -80,24 +81,34 @@ void mat3_to_quat(float q[4], float mat[3][3]);
void mat4_to_quat(float q[4], float mat[4][4]);
void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3],
const float no_orig[3]);
-void tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
-void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag);
+float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
+void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag);
/* note: v1 and v2 must be normalized */
+void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
+float angle_normalized_qt(const float q[4]);
+float angle_normalized_qtqt(const float q1[4], const float q2[4]);
+float angle_qt(const float q[4]);
+float angle_qtqt(const float q1[4], const float q2[4]);
+
/* TODO: don't what this is, but it's not the same as mat3_to_quat */
void mat3_to_quat_is_ok(float q[4], float mat[3][3]);
/* other */
void print_qt(const char *str, const float q[4]);
+#define print_qt_id(q) print_qt(STRINGIFY(q), q)
+
/******************************** Axis Angle *********************************/
/* conversion */
void axis_angle_normalized_to_quat(float r[4], const float axis[3], const float angle);
void axis_angle_to_quat(float r[4], const float axis[3], const float angle);
void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle);
+void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3],
+ const float angle_sin, const float angle_cos);
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const float angle);
void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle);
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 22ff9a3ce6e..f816ad53d15 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -117,6 +117,8 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
+MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]);
+MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]);
MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
@@ -163,6 +165,7 @@ MINLINE int len_manhattan_v2_int(const int v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_manhattan_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float len_v2v2_int(const int v1[2], const int v2[2]);
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
@@ -189,6 +192,12 @@ void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const fl
void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]);
void interp_v3_v3v3v3_uv(float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2]);
+bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t) ATTR_WARN_UNUSED_RESULT;
+bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], const float t) ATTR_WARN_UNUSED_RESULT;
+
+void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t);
+void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[2], const float t);
+
void interp_v3_v3v3_char(char target[3], const char a[3], const char b[3], const float t);
void interp_v3_v3v3_uchar(unsigned char target[3], const unsigned char a[3], const unsigned char b[3], const float t);
void interp_v4_v4v4_char(char target[4], const char a[4], const char b[4], const float t);
@@ -252,7 +261,9 @@ void project_v2_v2v2(float c[2], const float v1[2], const float v2[2]);
void project_v3_v3v3(float r[3], const float p[3], const float n[3]);
void project_v3_plane(float v[3], const float n[3], const float p[3]);
void reflect_v3_v3v3(float r[3], const float v[3], const float n[3]);
-void ortho_basis_v3v3_v3(float r1[3], float r2[3], const float a[3]);
+void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
+void ortho_v3_v3(float p[3], const float v[3]);
+void ortho_v2_v2(float p[3], const float v[3]);
void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
@@ -264,6 +275,11 @@ void print_v3(const char *str, const float a[3]);
void print_v4(const char *str, const float a[4]);
void print_vn(const char *str, const float v[], const int n);
+#define print_v2_id(v) print_v2(STRINGIFY(v), v)
+#define print_v3_id(v) print_v3(STRINGIFY(v), v)
+#define print_v4_id(v) print_v4(STRINGIFY(v), v)
+#define print_vn_id(v, n) print_vn(STRINGIFY(v), v, n)
+
MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
@@ -278,6 +294,7 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3]);
/***************************** Array Functions *******************************/
/* attempted to follow fixed length vertex functions. names could be improved*/
double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) ATTR_WARN_UNUSED_RESULT;
+double len_squared_vn(const float *array, const int size) ATTR_WARN_UNUSED_RESULT;
float normalize_vn_vn(float *array_tar, const float *array_src, const int size);
float normalize_vn(float *array_tar, const int size);
void range_vn_i(int *array_tar, const int size, const int start);
@@ -296,6 +313,7 @@ void msub_vn_vn(float *array_tar, const float *array_src, const float f, const i
void msub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size);
void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size);
void fill_vn_i(int *array_tar, const int size, const int val);
+void fill_vn_short(short *array_tar, const int size, const short val);
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val);
void fill_vn_fl(float *array_tar, const int size, const float val);
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 3fab77f2cb2..25694f4445b 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -81,8 +81,8 @@ typedef struct BLI_mempool_iter {
/* flag */
enum {
- BLI_MEMPOOL_SYSMALLOC = (1 << 0),
- BLI_MEMPOOL_ALLOW_ITER = (1 << 1)
+ BLI_MEMPOOL_NOP = 0,
+ BLI_MEMPOOL_ALLOW_ITER = (1 << 0),
};
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h
index d9457fbaae7..f3292d26b1e 100644
--- a/source/blender/blenlib/BLI_noise.h
+++ b/source/blender/blenlib/BLI_noise.h
@@ -57,7 +57,7 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity
void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype);
/* newnoise: cellNoise & cellNoiseV (for vector/point/color) */
float cellNoise(float x, float y, float z);
-void cellNoiseV(float x, float y, float z, float *ca);
+void cellNoiseV(float x, float y, float z, float r_ca[3]);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index efc5731c7cf..3e98e2ceeae 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -165,6 +165,14 @@ bool BLI_path_cwd(char *path) ATTR_NONNULL();
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL();
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+bool BLI_path_is_unc(const char *path);
+
+#if defined(WIN32)
+void BLI_cleanup_unc_16(wchar_t *path_16);
+void BLI_cleanup_unc(char *path_16, int maxlen);
+#endif
+
+bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) ATTR_NONNULL();
/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
#if defined(WIN32)
diff --git a/source/blender/blenlib/BLI_quadric.h b/source/blender/blenlib/BLI_quadric.h
index e71a6473852..82c39463dd2 100644
--- a/source/blender/blenlib/BLI_quadric.h
+++ b/source/blender/blenlib/BLI_quadric.h
@@ -51,6 +51,6 @@ void BLI_quadric_mul(Quadric *a, const float scalar);
/* solve */
float BLI_quadric_evaluate(const Quadric *q, const float v[3]);
-int BLI_quadric_optimize(const Quadric *q, float v[3], const float epsilon);
+bool BLI_quadric_optimize(const Quadric *q, float v[3], const float epsilon);
#endif /* __BLI_QUADRIC_H__ */
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index 378beff3aa0..045cadbcc6f 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -47,9 +47,11 @@ void BLI_rng_free(struct RNG *rng);
void BLI_rng_seed(struct RNG *rng, unsigned int seed);
void BLI_rng_srandom(struct RNG *rng, unsigned int seed);
int BLI_rng_get_int(struct RNG *rng);
+unsigned int BLI_rng_get_uint(struct RNG *rng);
double BLI_rng_get_double(struct RNG *rng);
float BLI_rng_get_float(struct RNG *rng);
-void BLI_rng_shuffle_array(struct RNG *rng, void *data, int elemSize, int numElems);
+void BLI_rng_get_float_unit_v3(struct RNG *rng, float v[3]);
+void BLI_rng_shuffle_array(struct RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot);
/** Note that skipping is as slow as generating n numbers! */
void BLI_rng_skip(struct RNG *rng, int n);
@@ -62,6 +64,7 @@ int BLI_rand(void);
/** Return a pseudo-random number N where 0.0f<=N<1.0f */
float BLI_frand(void);
+void BLI_frand_unit_v3(float v[3]);
/** Return a pseudo-random (hash) float from an integer value */
float BLI_hash_frand(unsigned int seed);
@@ -70,7 +73,7 @@ float BLI_hash_frand(unsigned int seed);
* contents. This routine does not use nor modify
* the state of the BLI random number generator.
*/
-void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed);
+void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_tot, unsigned int seed);
/** Better seed for the random number generator, using noise.c hash[] */
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index dddfb8c6ea9..a132ac40206 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -52,6 +52,8 @@ void BLI_rctf_init_minmax(struct rctf *rect);
void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]);
void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]);
+void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2]);
+
void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_recenter(struct rcti *rect, int x, int y);
@@ -90,6 +92,9 @@ void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src);
void print_rctf(const char *str, const struct rctf *rect);
void print_rcti(const char *str, const struct rcti *rect);
+#define print_rctf_id(rect) print_rctf(STRINGIFY(rect), rect)
+#define print_rcti_id(rect) print_rcti(STRINGIFY(rect), rect)
+
BLI_INLINE float BLI_rcti_cent_x_fl(const struct rcti *rct) { return (float)(rct->xmin + rct->xmax) / 2.0f; }
BLI_INLINE float BLI_rcti_cent_y_fl(const struct rcti *rct) { return (float)(rct->ymin + rct->ymax) / 2.0f; }
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct) { return (rct->xmin + rct->xmax) / 2; }
diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h
index 9151e6ab93f..564ff513490 100644
--- a/source/blender/blenlib/BLI_stack.h
+++ b/source/blender/blenlib/BLI_stack.h
@@ -48,7 +48,7 @@ void BLI_stack_push(BLI_Stack *stack, void *src);
* If stack is empty, 'dst' will not be modified. */
void BLI_stack_pop(BLI_Stack *stack, void *dst);
-/* Returns TRUE if the stack is empty, FALSE otherwise */
+/* Returns true if the stack is empty, false otherwise */
int BLI_stack_empty(const BLI_Stack *stack);
#endif
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index 5c5a6f45f0c..1d595ff3bf3 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -36,6 +36,22 @@
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 /* gcc4.8+ only (behavior changed to ignore globals)*/
# pragma GCC diagnostic error "-Wshadow"
# endif
+/* pedantic gives too many issues, developers can define this for own use */
+# ifdef WARN_PEDANTIC
+# pragma GCC diagnostic error "-Wpedantic"
+# ifdef __clang__ /* pedantic causes clang error */
+# pragma GCC diagnostic ignored "-Wlanguage-extension-token"
+# endif
+# endif
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(error:4018) /* signed/unsigned mismatch */
+# pragma warning(error:4244) /* conversion from 'type1' to 'type2', possible loss of data */
+# pragma warning(error:4245) /* conversion from 'int' to 'unsigned int' */
+# pragma warning(error:4267) /* conversion from 'size_t' to 'type', possible loss of data */
+# pragma warning(error:4305) /* truncation from 'type1' to 'type2' */
+# pragma warning(error:4389) /* signed/unsigned mismatch */
#endif
#endif /* __BLI_STRICT_FLAGS_H__ */
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index 45910666a1e..b4d354b7e37 100644
--- a/source/blender/blenlib/BLI_string_cursor_utf8.h
+++ b/source/blender/blenlib/BLI_string_cursor_utf8.h
@@ -41,8 +41,8 @@ typedef enum strCursorJumpDirection {
STRCUR_DIR_NEXT
} strCursorJumpDirection;
-int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos);
-int BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos);
+bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos);
+bool BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos);
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
int *pos, strCursorJumpDirection direction,
diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h
index b7a70a8cb38..b0a8adeef22 100644
--- a/source/blender/blenlib/BLI_sys_types.h
+++ b/source/blender/blenlib/BLI_sys_types.h
@@ -197,9 +197,8 @@ typedef uint64_t u_int64_t;
#endif /* ifdef platform for types */
+#include <stddef.h> /* size_t define */
-/* note: use of (int, TRUE / FALSE) is deprecated,
- * use (bool, true / false) instead */
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#elif !defined(__bool_true_false_are_defined) && !defined(__BOOL_DEFINED)
@@ -219,21 +218,6 @@ typedef bool _BLI_Bool;
# define __bool_true_false_are_defined 1
#endif
-/* remove this when we're ready to remove TRUE/FALSE completely */
-#ifdef WITH_BOOL_COMPAT
-/* interim until all occurrences of these can be updated to stdbool */
-/* XXX Why not use the true/false velues here? */
-# ifndef FALSE
-# define FALSE 0
-# endif
-
-# ifndef TRUE
-# define TRUE 1
-# endif
-#endif
-
-
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_cpu.h b/source/blender/blenlib/BLI_system.h
index fa29162e59e..8cdc9e4e6c5 100644
--- a/source/blender/blenlib/BLI_cpu.h
+++ b/source/blender/blenlib/BLI_system.h
@@ -18,14 +18,21 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_CPU_H__
-#define __BLI_CPU_H__
+#ifndef __BLI_SYSTEM_H__
+#define __BLI_SYSTEM_H__
-/** \file BLI_cpu.h
+/** \file BLI_system.h
* \ingroup bli
*/
int BLI_cpu_support_sse2(void);
+/* getpid */
+#ifdef WIN32
+# define BLI_SYSTEM_PID_H <process.h>
+#else
+# define BLI_SYSTEM_PID_H <unistd.h>
#endif
+#endif /* __BLI_SYSTEM_H__ */
+
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 3ccfcc023da..1c9e75d950a 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -75,6 +75,8 @@ int BLI_system_thread_count(void); /* gets the number of threads the system
void BLI_system_num_threads_override_set(int num);
int BLI_system_num_threads_override_get(void);
+int BLI_system_thread_count_omp(void);
+
/* Global Mutex Locks
*
* One custom lock available now. can be extended. */
@@ -88,6 +90,7 @@ int BLI_system_num_threads_override_get(void);
#define LOCK_NODES 6
#define LOCK_MOVIECLIP 7
#define LOCK_COLORMANAGE 8
+#define LOCK_FFTW 9
void BLI_lock_thread(int type);
void BLI_unlock_thread(int type);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index f7fc8cd274f..36940a99ef0 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -34,6 +34,7 @@
/* avoid many includes for now */
#include "BLI_sys_types.h"
+#include "BLI_compiler_compat.h"
#ifndef NDEBUG /* for BLI_assert */
#include <stdio.h>
@@ -50,26 +51,42 @@
/* min/max */
#if defined(__GNUC__) || defined(__clang__)
-#define MIN2(x, y) ({ \
- typeof(x) x_ = (x); \
- typeof(y) y_ = (y); \
- ((x_) < (y_) ? (x_) : (y_)); })
+#define MIN2(a, b) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); \
+ ((a_) < (b_) ? (a_) : (b_)); })
-#define MAX2(x, y) ({ \
- typeof(x) x_ = (x); \
- typeof(y) y_ = (y); \
- ((x_) > (y_) ? (x_) : (y_)); })
+#define MAX2(a, b) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); \
+ ((a_) > (b_) ? (a_) : (b_)); })
+
+#define MIN3(a, b, c) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); typeof(c) c_ = (c); \
+ ((a_ < b_) ? ((a_ < c_) ? a_ : c_) : ((b_ < c_) ? b_ : c_)); })
+
+#define MAX3(a, b, c) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); typeof(c) c_ = (c); \
+ ((a_ > b_) ? ((a_ > c_) ? a_ : c_) : ((b_ > c_) ? b_ : c_)); })
+
+#define MIN4(a, b, c, d) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); typeof(c) c_ = (c); typeof(d) d_ = (d); \
+ ((a_ < b_) ? ((a_ < c_) ? ((a_ < d_) ? a_ : d_) : ((c_ < d_) ? c_ : d_)) : \
+ ((b_ < c_) ? ((b_ < d_) ? b_ : d_) : ((c_ < d_) ? c_ : d_))); })
+
+#define MAX4(a, b, c, d) __extension__ ({ \
+ typeof(a) a_ = (a); typeof(b) b_ = (b); typeof(c) c_ = (c); typeof(d) d_ = (d); \
+ ((a_ > b_) ? ((a_ > c_) ? ((a_ > d_) ? a_ : d_) : ((c_ > d_) ? c_ : d_)) : \
+ ((b_ > c_) ? ((b_ > d_) ? b_ : d_) : ((c_ > d_) ? c_ : d_))); })
#else
-#define MIN2(x, y) ((x) < (y) ? (x) : (y))
-#define MAX2(x, y) ((x) > (y) ? (x) : (y))
-#endif
+#define MIN2(a, b) ((a) < (b) ? (a) : (b))
+#define MAX2(a, b) ((a) > (b) ? (a) : (b))
-#define MIN3(x, y, z) (MIN2(MIN2((x), (y)), (z)))
-#define MIN4(x, y, z, a) (MIN2(MIN2((x), (y)), MIN2((z), (a))))
+#define MIN3(a, b, c) (MIN2(MIN2((a), (b)), (c)))
+#define MIN4(a, b, c, d) (MIN2(MIN2((a), (b)), MIN2((c), (d))))
-#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
-#define MAX4(x, y, z, a) (MAX2(MAX2((x), (y)), MAX2((z), (a))))
+#define MAX3(a, b, c) (MAX2(MAX2((a), (b)), (c)))
+#define MAX4(a, b, c, d) (MAX2(MAX2((a), (b)), MAX2((c), (d))))
+#endif
/* min/max that return a value of our choice */
#define MAX3_PAIR(cmp_a, cmp_b, cmp_c, ret_a, ret_b, ret_c) \
@@ -195,8 +212,10 @@
} (void)0
-#define FTOCHAR(val) (char)(((val) <= 0.0f) ? 0 : (((val) > (1.0f - 0.5f / 255.0f)) ? 255 : ((255.0f * (val)) + 0.5f)))
-#define FTOUSHORT(val) ((val >= 1.0f - 0.5f / 65535) ? 65535 : (val <= 0.0f) ? 0 : (unsigned short)(val * 65535.0f + 0.5f))
+#define FTOCHAR(val) ((CHECK_TYPE_INLINE(val, float)), \
+ (char)(((val) <= 0.0f) ? 0 : (((val) > (1.0f - 0.5f / 255.0f)) ? 255 : ((255.0f * (val)) + 0.5f))))
+#define FTOUSHORT(val) ((CHECK_TYPE_INLINE(val, float)), \
+ ((val >= 1.0f - 0.5f / 65535) ? 65535 : (val <= 0.0f) ? 0 : (unsigned short)(val * 65535.0f + 0.5f)))
#define USHORTTOUCHAR(val) ((unsigned char)(((val) >= 65535 - 128) ? 255 : ((val) + 128) >> 8))
#define F3TOCHAR3(v2, v1) { \
(v1)[0] = FTOCHAR((v2[0])); \
@@ -277,27 +296,19 @@
/* some misc stuff.... */
-/* avoid multiple access & type conversions for supported compilers */
+/* avoid multiple access for supported compilers */
#if defined(__GNUC__) || defined(__clang__)
#define ABS(a) ({ \
typeof(a) a_ = (a); \
((a_) < 0 ? (-(a_)) : (a_)); })
-#define CLAMPIS(a, b, c) ({ \
- typeof(a) a_ = (a), b_ = (b), c_ = (c); \
- ((a_) < (b_) ? (b_) : (a_) > (c_) ? (c_) : (a_)); })
-
-#define CLAMP(a, b, c) { \
- typeof(a) b_ = (b), c_ = (c); \
- if ((a) < (b_)) (a) = (b_); \
- else if ((a) > (c_)) (a) = (c_); \
-} (void)0
-
#else
#define ABS(a) ((a) < 0 ? (-(a)) : (a))
+#endif
+
#define CLAMPIS(a, b, c) ((a) < (b) ? (b) : (a) > (c) ? (c) : (a))
#define CLAMP(a, b, c) { \
@@ -305,8 +316,13 @@
else if ((a) > (c)) (a) = (c); \
} (void)0
-#endif
+#define CLAMP_MAX(a, c) { \
+ if ((a) > (c)) (a) = (c); \
+} (void)0
+#define CLAMP_MIN(a, b) { \
+ if ((a) < (b)) (a) = (b); \
+} (void)0
#define IS_EQ(a, b) ( \
CHECK_TYPE_INLINE(a, double), CHECK_TYPE_INLINE(b, double), \
@@ -392,16 +408,9 @@
#define STRCASEEQLEN(a, b, n) (strncasecmp(a, b, n) == 0)
#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
-
-
/* useful for debugging */
#define AT __FILE__ ":" STRINGIFY(__LINE__)
-/* so we can use __func__ everywhere */
-#if defined(_MSC_VER)
-# define __func__ __FUNCTION__
-#endif
-
/* UNUSED macro, for function argument */
#ifdef __GNUC__
@@ -466,13 +475,13 @@
#if (!defined(__cplusplus)) && \
(!defined(__COVERITY__)) && \
(defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
-# define BLI_STATIC_ASSERT(a, msg) _Static_assert(a, msg);
+# define BLI_STATIC_ASSERT(a, msg) __extension__ _Static_assert(a, msg);
#else
/* TODO msvc, clang */
# define BLI_STATIC_ASSERT(a, msg)
#endif
-/* hints for branch pradiction, only use in code that runs a _lot_ where */
+/* hints for branch prediction, only use in code that runs a _lot_ where */
#ifdef __GNUC__
# define LIKELY(x) __builtin_expect(!!(x), 1)
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index b6bc5fad317..75b333cf1ef 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -37,9 +37,7 @@
# error "This include is for Windows only!"
#endif
-#ifndef FREE_WINDOWS
-# pragma warning(once: 4761 4305 4244 4018)
-#else
+#ifdef FREE_WINDOWS
# ifdef WINVER
# undef WINVER
# endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 9194bb5a54c..9e360741b23 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -55,8 +55,8 @@ set(SRC
intern/buffer.c
intern/callbacks.c
intern/convexhull2d.c
- intern/cpu.c
intern/dynlib.c
+ intern/easing.c
intern/edgehash.c
intern/endian_switch.c
intern/fileops.c
@@ -96,6 +96,7 @@ set(SRC
intern/string.c
intern/string_cursor_utf8.c
intern/string_utf8.c
+ intern/system.c
intern/task.c
intern/threads.c
intern/time.c
@@ -115,11 +116,12 @@ set(SRC
BLI_buffer.h
BLI_callbacks.h
BLI_compiler_attrs.h
+ BLI_compiler_compat.h
BLI_convexhull2d.h
- BLI_cpu.h
BLI_dlrbTree.h
BLI_dynlib.h
BLI_dynstr.h
+ BLI_easing.h
BLI_edgehash.h
BLI_endian_switch.h
BLI_endian_switch_inline.h
@@ -134,6 +136,7 @@ set(SRC
BLI_kdopbvh.h
BLI_kdtree.h
BLI_lasso.h
+ BLI_link_utils.h
BLI_linklist.h
BLI_linklist_stack.h
BLI_listbase.h
@@ -166,6 +169,7 @@ set(SRC
BLI_string_cursor_utf8.h
BLI_string_utf8.h
BLI_sys_types.h
+ BLI_system.h
BLI_task.h
BLI_threads.h
BLI_timecode.h
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index fb35b55a935..8bd35f651b7 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -49,7 +49,7 @@ typedef struct bArgDoc {
const char *short_arg;
const char *long_arg;
const char *documentation;
- int done;
+ bool done;
} bArgDoc;
typedef struct bAKey {
@@ -243,7 +243,7 @@ void BLI_argsPrintArgDoc(struct bArgs *ba, const char *arg)
internalDocPrint(d);
- d->done = TRUE;
+ d->done = true;
}
}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index f3ebddddc8c..7b48744bcdf 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -191,7 +191,7 @@ static GHash *ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info,
}
gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
- gh->entrypool = BLI_mempool_create(entry_size, 64, 64, 0);
+ gh->entrypool = BLI_mempool_create(entry_size, 64, 64, BLI_MEMPOOL_NOP);
return gh;
}
@@ -384,6 +384,16 @@ void *BLI_ghash_lookup(GHash *gh, const void *key)
}
/**
+ * A version of #BLI_ghash_lookup which accepts a fallback argument.
+ */
+void *BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default)
+{
+ Entry *e = ghash_lookup_entry(gh, key);
+ IS_GHASH_ASSERT(gh);
+ return e ? e->val : val_default;
+}
+
+/**
* Lookup a pointer to the value of \a key in \a gh.
*
* \param key The key to lookup.
@@ -559,11 +569,31 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
ghi->gh = gh;
ghi->curEntry = NULL;
ghi->curBucket = UINT_MAX; /* wraps to zero */
- while (!ghi->curEntry) {
- ghi->curBucket++;
- if (ghi->curBucket == ghi->gh->nbuckets)
- break;
- ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
+ if (gh->nentries) {
+ while (!ghi->curEntry) {
+ ghi->curBucket++;
+ if (UNLIKELY(ghi->curBucket == ghi->gh->nbuckets))
+ break;
+ ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
+ }
+ }
+}
+
+/**
+ * Steps the iterator to the next index.
+ *
+ * \param ghi The iterator.
+ */
+void BLI_ghashIterator_step(GHashIterator *ghi)
+{
+ if (ghi->curEntry) {
+ ghi->curEntry = ghi->curEntry->next;
+ while (!ghi->curEntry) {
+ ghi->curBucket++;
+ if (ghi->curBucket == ghi->gh->nbuckets)
+ break;
+ ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
+ }
}
}
@@ -577,6 +607,8 @@ void BLI_ghashIterator_free(GHashIterator *ghi)
MEM_freeN(ghi);
}
+/* inline functions now */
+#if 0
/**
* Retrieve the key from an iterator.
*
@@ -586,7 +618,7 @@ void BLI_ghashIterator_free(GHashIterator *ghi)
*/
void *BLI_ghashIterator_getKey(GHashIterator *ghi)
{
- return ghi->curEntry ? ghi->curEntry->key : NULL;
+ return ghi->curEntry->key;
}
/**
@@ -598,7 +630,7 @@ void *BLI_ghashIterator_getKey(GHashIterator *ghi)
*/
void *BLI_ghashIterator_getValue(GHashIterator *ghi)
{
- return ghi->curEntry ? ghi->curEntry->val : NULL;
+ return ghi->curEntry->val;
}
/**
@@ -610,25 +642,7 @@ void *BLI_ghashIterator_getValue(GHashIterator *ghi)
*/
void **BLI_ghashIterator_getValue_p(GHashIterator *ghi)
{
- return ghi->curEntry ? &ghi->curEntry->val : NULL;
-}
-
-/**
- * Steps the iterator to the next index.
- *
- * \param ghi The iterator.
- */
-void BLI_ghashIterator_step(GHashIterator *ghi)
-{
- if (ghi->curEntry) {
- ghi->curEntry = ghi->curEntry->next;
- while (!ghi->curEntry) {
- ghi->curBucket++;
- if (ghi->curBucket == ghi->gh->nbuckets)
- break;
- ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
- }
- }
+ return &ghi->curEntry->val;
}
/**
@@ -642,6 +656,7 @@ bool BLI_ghashIterator_done(GHashIterator *ghi)
{
return ghi->curEntry == NULL;
}
+#endif
/** \} */
@@ -676,7 +691,32 @@ int BLI_ghashutil_ptrcmp(const void *a, const void *b)
return (a < b) ? -1 : 1;
}
-unsigned int BLI_ghashutil_inthash(const void *ptr)
+unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4])
+{
+ unsigned int hash;
+ hash = key[0];
+ hash *= 37;
+ hash += key[1];
+ hash *= 37;
+ hash += key[2];
+ hash *= 37;
+ hash += key[3];
+ return hash;
+}
+
+unsigned int BLI_ghashutil_uinthash(unsigned int key)
+{
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
+
+ return key;
+}
+
+unsigned int BLI_ghashutil_inthash_p(const void *ptr)
{
uintptr_t key = (uintptr_t)ptr;
@@ -707,7 +747,18 @@ int BLI_ghashutil_intcmp(const void *a, const void *b)
*
* note: this is the same hash method that glib 2.34.0 uses.
*/
-unsigned int BLI_ghashutil_strhash(const void *ptr)
+unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n)
+{
+ const signed char *p;
+ unsigned int h = 5381;
+
+ for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
+ h = (h << 5) + h + (unsigned int)*p;
+ }
+
+ return h;
+}
+unsigned int BLI_ghashutil_strhash_p(const void *ptr)
{
const signed char *p;
unsigned int h = 5381;
@@ -774,7 +825,7 @@ GHash *BLI_ghash_ptr_new(const char *info)
GHash *BLI_ghash_str_new_ex(const char *info,
const unsigned int nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, info,
+ return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info,
nentries_reserve);
}
GHash *BLI_ghash_str_new(const char *info)
@@ -785,7 +836,7 @@ GHash *BLI_ghash_str_new(const char *info)
GHash *BLI_ghash_int_new_ex(const char *info,
const unsigned int nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, info,
+ return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info,
nentries_reserve);
}
GHash *BLI_ghash_int_new(const char *info)
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 5d97c1c22d2..6b1fbe855a1 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -109,7 +109,7 @@ typedef struct BVHRayCastData {
} BVHRayCastData;
-/*
+/**
* Bounding Volume Hierarchy Definition
*
* Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below
@@ -127,10 +127,12 @@ MINLINE axis_t min_axis(axis_t a, axis_t b)
{
return (a < b) ? a : b;
}
+#if 0
MINLINE axis_t max_axis(axis_t a, axis_t b)
{
return (b < a) ? a : b;
}
+#endif
#if 0
@@ -200,7 +202,7 @@ static bool ADJUST_MEMORY(void *local_memblock, void **memblock, int new_size, i
}
#endif
-/*
+/**
* Introsort
* with permission deriven from the following Java code:
* http://ralphunden.net/content/tutorials/a-guide-to-introsort/
@@ -209,17 +211,28 @@ static bool ADJUST_MEMORY(void *local_memblock, void **memblock, int new_size, i
//static int size_threshold = 16;
-/*
+#if 0
+/**
* Common methods for all algorithms
*/
-#if 0
static int floor_lg(int a)
{
return (int)(floor(log(a) / log(2)));
}
#endif
-/*
+static void node_minmax_init(const BVHTree *tree, BVHNode *node)
+{
+ axis_t axis_iter;
+ float (*bv)[2] = (float (*)[2])node->bv;
+
+ for (axis_iter = tree->start_axis; axis_iter != tree->stop_axis; axis_iter++) {
+ bv[axis_iter][0] = FLT_MAX;
+ bv[axis_iter][1] = -FLT_MAX;
+ }
+}
+
+/**
* Insertion sort algorithm
*/
static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
@@ -251,10 +264,10 @@ static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
}
}
-/*
+#if 0
+/**
* Heapsort algorithm
*/
-#if 0
static void bvh_downheap(BVHNode **a, int i, int n, int lo, int axis)
{
BVHNode *d = a[lo + i - 1];
@@ -343,7 +356,8 @@ static void sort_along_axis(BVHTree *tree, int start, int end, int axis)
}
#endif
-/* after a call to this function you can expect one of:
+/**
+ * \note after a call to this function you can expect one of:
* - every node to left of a[n] are smaller or equal to it
* - every node to the right of a[n] are greater or equal to it */
static int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis)
@@ -391,12 +405,9 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, const float *co, int
/* don't init boudings for the moving case */
if (!moving) {
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- bv[2 * axis_iter] = FLT_MAX;
- bv[2 * axis_iter + 1] = -FLT_MAX;
- }
+ node_minmax_init(tree, node);
}
-
+
for (k = 0; k < numpoints; k++) {
/* for all Axes. */
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
@@ -409,7 +420,9 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, const float *co, int
}
}
-/* depends on the fact that the BVH's for each face is already build */
+/**
+ * \note depends on the fact that the BVH's for each face is already build
+ */
static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
{
float newmin, newmax;
@@ -417,10 +430,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
int j;
axis_t axis_iter;
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- bv[(2 * axis_iter)] = FLT_MAX;
- bv[(2 * axis_iter) + 1] = -FLT_MAX;
- }
+ node_minmax_init(tree, node);
for (j = start; j < end; j++) {
/* for all Axes. */
@@ -437,7 +447,8 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
}
-/* only supports x,y,z axis in the moment
+/**
+ * only supports x,y,z axis in the moment
* but we should use a plain and simple function here for speed sake */
static char get_largest_axis(const float *bv)
{
@@ -460,17 +471,15 @@ static char get_largest_axis(const float *bv)
}
}
-/* bottom-up update of bvh node BV
+/**
+ * bottom-up update of bvh node BV
* join the children on the parent BV */
static void node_join(BVHTree *tree, BVHNode *node)
{
int i;
axis_t axis_iter;
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- node->bv[(2 * axis_iter)] = FLT_MAX;
- node->bv[(2 * axis_iter) + 1] = -FLT_MAX;
- }
+ node_minmax_init(tree, node);
for (i = 0; i < tree->tree_type; i++) {
if (node->children[i]) {
@@ -608,9 +617,7 @@ static void build_implicit_tree_helper(BVHTree *tree, BVHBuildHelper *data)
data->branches_on_level[0] = 1;
- /* We could stop the loop first (but I am lazy to find out when) */
- /* note: this often causes integer overflow, may be worth avoiding? - campbell */
- for (depth = 1; depth < 32; depth++) {
+ for (depth = 1; (depth < 32) && data->leafs_per_child[depth - 1]; depth++) {
data->branches_on_level[depth] = data->branches_on_level[depth - 1] * data->tree_type;
data->leafs_per_child[depth] = data->leafs_per_child[depth - 1] / data->tree_type;
}
@@ -666,7 +673,7 @@ static int implicit_needed_branches(int tree_type, int leafs)
return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1) );
}
-/*
+/**
* This function handles the problem of "sorting" the leafs (along the split_axis).
*
* It arranges the elements in the given partitions such that:
@@ -689,7 +696,7 @@ static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int spl
}
}
-/*
+/**
* This functions builds an optimal implicit tree from the given leafs.
* Where optimal stands for:
* - The resulting tree will have the smallest number of branches;
@@ -804,20 +811,18 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array,
}
}
+/* -------------------------------------------------------------------- */
+/* BLI_bvhtree api */
-/*
- * BLI_bvhtree api
+/**
+ * \note many callers don't check for ``NULL`` return.
*/
BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
{
BVHTree *tree;
int numnodes, i;
-
- /* theres not support for trees below binary-trees :P */
- if (tree_type < 2)
- return NULL;
- BLI_assert(tree_type <= MAX_TREETYPE);
+ BLI_assert(tree_type >= 2 && tree_type <= MAX_TREETYPE);
tree = MEM_callocN(sizeof(BVHTree), "BVHTree");
@@ -828,9 +833,9 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
if (tree) {
tree->epsilon = epsilon;
- tree->tree_type = tree_type;
+ tree->tree_type = tree_type;
tree->axis = axis;
-
+
if (axis == 26) {
tree->start_axis = 0;
tree->stop_axis = 13;
@@ -852,8 +857,10 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
tree->stop_axis = 3;
}
else {
- MEM_freeN(tree);
- return NULL;
+ /* should never happen! */
+ BLI_assert(0);
+
+ goto fail;
}
@@ -861,44 +868,37 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type;
tree->nodes = MEM_callocN(sizeof(BVHNode *) * (size_t)numnodes, "BVHNodes");
-
- if (!tree->nodes) {
- MEM_freeN(tree);
- return NULL;
- }
-
tree->nodebv = MEM_callocN(sizeof(float) * (size_t)(axis * numnodes), "BVHNodeBV");
- if (!tree->nodebv) {
- MEM_freeN(tree->nodes);
- MEM_freeN(tree);
- }
-
tree->nodechild = MEM_callocN(sizeof(BVHNode *) * (size_t)(tree_type * numnodes), "BVHNodeBV");
- if (!tree->nodechild) {
- MEM_freeN(tree->nodebv);
- MEM_freeN(tree->nodes);
- MEM_freeN(tree);
- }
-
tree->nodearray = MEM_callocN(sizeof(BVHNode) * (size_t)numnodes, "BVHNodeArray");
- if (!tree->nodearray) {
- MEM_freeN(tree->nodechild);
- MEM_freeN(tree->nodebv);
- MEM_freeN(tree->nodes);
- MEM_freeN(tree);
- return NULL;
+ if (UNLIKELY((!tree->nodes) ||
+ (!tree->nodebv) ||
+ (!tree->nodechild) ||
+ (!tree->nodearray)))
+ {
+ goto fail;
}
/* link the dynamic bv and child links */
for (i = 0; i < numnodes; i++) {
- tree->nodearray[i].bv = tree->nodebv + i * axis;
- tree->nodearray[i].children = tree->nodechild + i * tree_type;
+ tree->nodearray[i].bv = &tree->nodebv[i * axis];
+ tree->nodearray[i].children = &tree->nodechild[i * tree_type];
}
}
-
return tree;
+
+
+fail:
+ MEM_SAFE_FREE(tree->nodes);
+ MEM_SAFE_FREE(tree->nodebv);
+ MEM_SAFE_FREE(tree->nodechild);
+ MEM_SAFE_FREE(tree->nodearray);
+
+ MEM_freeN(tree);
+
+ return NULL;
}
void BLI_bvhtree_free(BVHTree *tree)
@@ -1004,10 +1004,12 @@ float BLI_bvhtree_getepsilon(const BVHTree *tree)
}
-/*
- * BLI_bvhtree_overlap
- *
- * overlap - is it possible for 2 bv's to collide ? */
+/* -------------------------------------------------------------------- */
+/* BLI_bvhtree_overlap */
+
+/**
+ * overlap - is it possible for 2 bv's to collide ?
+ */
static int tree_overlap(BVHNode *node1, BVHNode *node2, axis_t start_axis, axis_t stop_axis)
{
const float *bv1 = node1->bv;
@@ -1135,7 +1137,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int
}
/* Determines the nearest point of the given node BV. Returns the squared distance to that point. */
-static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float *nearest)
+static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float nearest[3])
{
int i;
const float *bv = node->bv;
@@ -1271,7 +1273,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node)
else {
/* adjust heap size */
if ((heap_size >= max_heap_size) &&
- ADJUST_MEMORY(default_heap, (void **)&heap, heap_size + 1, &max_heap_size, sizeof(heap[0])) == FALSE)
+ ADJUST_MEMORY(default_heap, (void **)&heap, heap_size + 1, &max_heap_size, sizeof(heap[0])) == false)
{
printf("WARNING: bvh_find_nearest got out of memory\n");
@@ -1349,7 +1351,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *n
}
-/*
+/**
* Raycast - BLI_bvhtree_ray_cast
*
* raycast is done by performing a DFS on the BVHTree and saving the closest hit
@@ -1391,7 +1393,8 @@ static float ray_nearest_hit(BVHRayCastData *data, const float bv[6])
return low;
}
-/* Determines the distance that the ray must travel to hit the bounding volume of the given node
+/**
+ * Determines the distance that the ray must travel to hit the bounding volume of the given node
* Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe
* [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9]
*
@@ -1425,7 +1428,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
/* ray-bv is really fast.. and simple tests revealed its worth to test it
* before calling the ray-primitive functions */
/* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
- float dist = (data->ray.radius > 0.0f) ? ray_nearest_hit(data, node->bv) : fast_ray_nearest_hit(data, node);
+ float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
if (dist >= data->hit.dist) return;
if (node->totnode == 0) {
@@ -1440,7 +1443,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
}
else {
/* pick loop direction to dive into the tree (based on ray direction and split axis) */
- if (data->ray_dot_axis[(int)node->main_axis] > 0.0f) {
+ if (data->ray_dot_axis[node->main_axis] > 0.0f) {
for (i = 0; i != node->totnode; i++) {
dfs_raycast(data, node->children[i]);
}
@@ -1541,29 +1544,24 @@ float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], cons
data.hit.dist = FLT_MAX;
/* get light direction */
- data.ray.direction[0] = light_end[0] - light_start[0];
- data.ray.direction[1] = light_end[1] - light_start[1];
- data.ray.direction[2] = light_end[2] - light_start[2];
+ sub_v3_v3v3(data.ray.direction, light_end, light_start);
data.ray.radius = 0.0;
- data.ray.origin[0] = light_start[0];
- data.ray.origin[1] = light_start[1];
- data.ray.origin[2] = light_start[2];
-
+ copy_v3_v3(data.ray.origin, light_start);
+
normalize_v3(data.ray.direction);
copy_v3_v3(data.ray_dot_axis, data.ray.direction);
dist = ray_nearest_hit(&data, bv);
-
- if (dist > 0.0f) {
- madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist);
- }
+
+ madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist);
+
return dist;
}
-/*
+/**
* Range Query - as request by broken :P
*
* Allocs and fills an array with the indexs of node that are on the given spherical range (center, radius)
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index c8ee0c11fc7..ed6e6e3ab92 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -35,7 +35,7 @@
typedef struct KDTreeNode {
struct KDTreeNode *left, *right;
- float co[3], nor[3];
+ float co[3];
int index;
unsigned int d; /* range is only (0-2) */
} KDTreeNode;
@@ -85,7 +85,7 @@ void BLI_kdtree_free(KDTree *tree)
/**
* Construction: first insert points, then call balance. Normal is optional.
*/
-void BLI_kdtree_insert(KDTree *tree, int index, const float co[3], const float nor[3])
+void BLI_kdtree_insert(KDTree *tree, int index, const float co[3])
{
KDTreeNode *node = &tree->nodes[tree->totnode++];
@@ -98,11 +98,6 @@ void BLI_kdtree_insert(KDTree *tree, int index, const float co[3], const float n
node->left = node->right = NULL;
copy_v3_v3(node->co, co);
- if (nor)
- copy_v3_v3(node->nor, nor);
- else
- zero_v3(node->nor);
-
node->index = index;
node->d = 0;
@@ -167,7 +162,7 @@ void BLI_kdtree_balance(KDTree *tree)
#endif
}
-static float squared_distance(const float v2[3], const float v1[3], const float UNUSED(n1[3]), const float n2[3])
+static float squared_distance(const float v2[3], const float v1[3], const float n2[3])
{
float d[3], dist;
@@ -175,9 +170,7 @@ static float squared_distance(const float v2[3], const float v1[3], const float
d[1] = v2[1] - v1[1];
d[2] = v2[2] - v1[2];
- dist = dot_v3v3(d, d);
-
- //if (n1 && n2 && (dot_v3v3(n1, n2) < 0.0f))
+ dist = len_squared_v3(d);
/* can someone explain why this is done?*/
if (n2 && (dot_v3v3(d, n2) < 0.0f)) {
@@ -201,8 +194,9 @@ static KDTreeNode **realloc_nodes(KDTreeNode **stack, unsigned int *totstack, co
/**
* Find nearest returns index, and -1 if no node is found.
*/
-int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest *r_nearest)
+int BLI_kdtree_find_nearest(
+ KDTree *tree, const float co[3],
+ KDTreeNearest *r_nearest)
{
KDTreeNode *root, *node, *min_node;
KDTreeNode **stack, *defaultstack[KD_STACK_INIT];
@@ -221,7 +215,7 @@ int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3],
root = tree->root;
min_node = root;
- min_dist = squared_distance(root->co, co, root->nor, nor);
+ min_dist = len_squared_v3v3(root->co, co);
if (co[root->d] < root->co[root->d]) {
if (root->right)
@@ -245,7 +239,7 @@ int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3],
cur_dist = -cur_dist * cur_dist;
if (-cur_dist < min_dist) {
- cur_dist = squared_distance(node->co, co, node->nor, nor);
+ cur_dist = len_squared_v3v3(node->co, co);
if (cur_dist < min_dist) {
min_dist = cur_dist;
min_node = node;
@@ -260,7 +254,7 @@ int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3],
cur_dist = cur_dist * cur_dist;
if (cur_dist < min_dist) {
- cur_dist = squared_distance(node->co, co, node->nor, nor);
+ cur_dist = len_squared_v3v3(node->co, co);
if (cur_dist < min_dist) {
min_dist = cur_dist;
min_node = node;
@@ -313,9 +307,10 @@ static void add_nearest(KDTreeNearest *ptn, unsigned int *found, unsigned int n,
*
* \param r_nearest An array of nearest, sized at least \a n.
*/
-int BLI_kdtree_find_nearest_n(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest r_nearest[],
- unsigned int n)
+int BLI_kdtree_find_nearest_n__normal(
+ KDTree *tree, const float co[3], const float nor[3],
+ KDTreeNearest r_nearest[],
+ unsigned int n)
{
KDTreeNode *root, *node = NULL;
KDTreeNode **stack, *defaultstack[KD_STACK_INIT];
@@ -335,7 +330,7 @@ int BLI_kdtree_find_nearest_n(KDTree *tree, const float co[3], const float nor[3
root = tree->root;
- cur_dist = squared_distance(root->co, co, root->nor, nor);
+ cur_dist = squared_distance(root->co, co, nor);
add_nearest(r_nearest, &found, n, root->index, cur_dist, root->co);
if (co[root->d] < root->co[root->d]) {
@@ -360,7 +355,7 @@ int BLI_kdtree_find_nearest_n(KDTree *tree, const float co[3], const float nor[3
cur_dist = -cur_dist * cur_dist;
if (found < n || -cur_dist < r_nearest[found - 1].dist) {
- cur_dist = squared_distance(node->co, co, node->nor, nor);
+ cur_dist = squared_distance(node->co, co, nor);
if (found < n || cur_dist < r_nearest[found - 1].dist)
add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co);
@@ -375,7 +370,7 @@ int BLI_kdtree_find_nearest_n(KDTree *tree, const float co[3], const float nor[3
cur_dist = cur_dist * cur_dist;
if (found < n || cur_dist < r_nearest[found - 1].dist) {
- cur_dist = squared_distance(node->co, co, node->nor, nor);
+ cur_dist = squared_distance(node->co, co, nor);
if (found < n || cur_dist < r_nearest[found - 1].dist)
add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co);
@@ -436,8 +431,9 @@ static void add_in_range(KDTreeNearest **ptn, unsigned int found, unsigned int *
* Normal is optional, but if given will limit results to points in normal direction from co.
* Remember to free nearest after use!
*/
-int BLI_kdtree_range_search(KDTree *tree, const float co[3], const float nor[3],
- KDTreeNearest **r_nearest, float range)
+int BLI_kdtree_range_search__normal(
+ KDTree *tree, const float co[3], const float nor[3],
+ KDTreeNearest **r_nearest, float range)
{
KDTreeNode *root, *node = NULL;
KDTreeNode **stack, *defaultstack[KD_STACK_INIT];
@@ -466,7 +462,7 @@ int BLI_kdtree_range_search(KDTree *tree, const float co[3], const float nor[3],
stack[cur++] = root->right;
}
else {
- dist2 = squared_distance(root->co, co, root->nor, nor);
+ dist2 = squared_distance(root->co, co, nor);
if (dist2 <= range2)
add_in_range(&foundstack, found++, &totfoundstack, root->index, dist2, root->co);
@@ -488,7 +484,7 @@ int BLI_kdtree_range_search(KDTree *tree, const float co[3], const float nor[3],
stack[cur++] = node->right;
}
else {
- dist2 = squared_distance(node->co, co, node->nor, nor);
+ dist2 = squared_distance(node->co, co, nor);
if (dist2 <= range2)
add_in_range(&foundstack, found++, &totfoundstack, node->index, dist2, node->co);
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 7dc43bb1494..448fefa5979 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -35,12 +35,9 @@
#include <stdlib.h>
#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
#include "BLI_mempool.h" /* own include */
-#include "DNA_listBase.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_strict_flags.h" /* keep last */
@@ -59,6 +56,7 @@
#endif
#define FREEWORD MAKE_ID('f', 'r', 'e', 'e')
+#define USEDWORD MAKE_ID('u', 's', 'e', 'd')
/* currently totalloc isnt used */
// #define USE_TOTALLOC
@@ -66,6 +64,10 @@
/* when undefined, merge the allocs for BLI_mempool_chunk and its data */
// #define USE_DATA_PTR
+/* optimize pool size */
+#define USE_CHUNK_POW2
+
+
#ifndef NDEBUG
static bool mempool_debug_memset = false;
#endif
@@ -86,7 +88,7 @@ typedef struct BLI_freenode {
* #BLI_mempool.chunks as a double linked list.
*/
typedef struct BLI_mempool_chunk {
- struct BLI_mempool_chunk *next, *prev;
+ struct BLI_mempool_chunk *next;
#ifdef USE_DATA_PTR
void *_data;
#endif
@@ -96,7 +98,11 @@ typedef struct BLI_mempool_chunk {
* The mempool, stores and tracks memory \a chunks and elements within those chunks \a free.
*/
struct BLI_mempool {
- struct ListBase chunks;
+ BLI_mempool_chunk *chunks; /* single linked list of allocated chunks */
+ /* keep a pointer to the last, so we can append new chunks there
+ * this is needed for iteration so we can loop over chunks in the order added */
+ BLI_mempool_chunk *chunk_tail;
+
unsigned int esize; /* element size in bytes */
unsigned int csize; /* chunk size in bytes */
unsigned int pchunk; /* number of elements per chunk */
@@ -119,33 +125,57 @@ struct BLI_mempool {
# define CHUNK_DATA(chunk) (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
#endif
+#define NODE_STEP_NEXT(node) ((void *)((char *)(node) + esize))
+#define NODE_STEP_PREV(node) ((void *)((char *)(node) - esize))
+
+/* extra bytes implicitly used for every chunk alloc */
+#ifdef USE_DATA_PTR
+# define CHUNK_OVERHEAD (unsigned int)(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))
+#else
+# define CHUNK_OVERHEAD (unsigned int)(MEM_SIZE_OVERHEAD)
+#endif
+
+#ifdef USE_CHUNK_POW2
+static unsigned int power_of_2_max_u(unsigned int x)
+{
+ x -= 1;
+ x = x | (x >> 1);
+ x = x | (x >> 2);
+ x = x | (x >> 4);
+ x = x | (x >> 8);
+ x = x | (x >> 16);
+ return x + 1;
+}
+#endif
+
+BLI_INLINE BLI_mempool_chunk *mempool_chunk_find(BLI_mempool_chunk *head, unsigned int index)
+{
+ while (index-- && head) {
+ head = head->next;
+ }
+ return head;
+}
+
/**
* \return the number of chunks to allocate based on how many elements are needed.
+ *
+ * \note for small pools 1 is a good default, the elements need to be initialized,
+ * adding overhead on creation which is redundant if they aren't used.
+ *
*/
BLI_INLINE unsigned int mempool_maxchunks(const unsigned int totelem, const unsigned int pchunk)
{
- return totelem / pchunk + 1;
+ return (totelem <= pchunk) ? 1 : ((totelem / pchunk) + 1);
}
static BLI_mempool_chunk *mempool_chunk_alloc(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk;
#ifdef USE_DATA_PTR
- if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
- mpchunk = malloc(sizeof(BLI_mempool_chunk));
- CHUNK_DATA(mpchunk) = malloc((size_t)pool->csize);
- }
- else {
- mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
- CHUNK_DATA(mpchunk) = MEM_mallocN((size_t)pool->csize, "BLI Mempool Chunk Data");
- }
+ mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
+ CHUNK_DATA(mpchunk) = MEM_mallocN((size_t)pool->csize, "BLI Mempool Chunk Data");
#else
- if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
- mpchunk = malloc(sizeof(BLI_mempool_chunk) + (size_t)pool->csize);
- }
- else {
- mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk) + (size_t)pool->csize, "BLI_Mempool Chunk");
- }
+ mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk) + (size_t)pool->csize, "BLI_Mempool Chunk");
#endif
return mpchunk;
@@ -163,35 +193,45 @@ static BLI_mempool_chunk *mempool_chunk_alloc(BLI_mempool *pool)
static BLI_freenode *mempool_chunk_add(BLI_mempool *pool, BLI_mempool_chunk *mpchunk,
BLI_freenode *lasttail)
{
- BLI_freenode *curnode = NULL;
- const unsigned int pchunk_last = pool->pchunk - 1;
- char *addr;
+ const unsigned int esize = pool->esize;
+ BLI_freenode *curnode = CHUNK_DATA(mpchunk);
unsigned int j;
- mpchunk->next = mpchunk->prev = NULL;
- BLI_addtail(&(pool->chunks), mpchunk);
+ /* append */
+ if (pool->chunk_tail) {
+ pool->chunk_tail->next = mpchunk;
+ }
+ else {
+ BLI_assert(pool->chunks == NULL);
+ pool->chunks = mpchunk;
+ }
- if (pool->free == NULL) {
- pool->free = CHUNK_DATA(mpchunk); /* start of the list */
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- pool->free->freeword = FREEWORD;
- }
+ mpchunk->next = NULL;
+ pool->chunk_tail = mpchunk;
+
+ if (UNLIKELY(pool->free == NULL)) {
+ pool->free = curnode;
}
/* loop through the allocated data, building the pointer structures */
- for (addr = CHUNK_DATA(mpchunk), j = 0; j != pchunk_last; j++) {
- curnode = ((BLI_freenode *)addr);
- addr += pool->esize;
- curnode->next = (BLI_freenode *)addr;
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- if (j != pchunk_last)
- curnode->next->freeword = FREEWORD;
+ j = pool->pchunk;
+ if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
curnode->freeword = FREEWORD;
+ curnode = curnode->next;
+ }
+ }
+ else {
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
+ curnode = curnode->next;
}
}
- /* terminate the list,
+ /* terminate the list (rewind one)
* will be overwritten if 'curnode' gets passed in again as 'lasttail' */
+ curnode = NODE_STEP_PREV(curnode);
curnode->next = NULL;
#ifdef USE_TOTALLOC
@@ -201,55 +241,39 @@ static BLI_freenode *mempool_chunk_add(BLI_mempool *pool, BLI_mempool_chunk *mpc
/* final pointer in the previously allocated chunk is wrong */
if (lasttail) {
lasttail->next = CHUNK_DATA(mpchunk);
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- lasttail->freeword = FREEWORD;
- }
}
return curnode;
}
-static void mempool_chunk_free(BLI_mempool_chunk *mpchunk, const unsigned int flag)
+static void mempool_chunk_free(BLI_mempool_chunk *mpchunk)
{
- if (flag & BLI_MEMPOOL_SYSMALLOC) {
-#ifdef USE_DATA_PTR
- free(CHUNK_DATA(mpchunk));
-#endif
- free(mpchunk);
- }
- else {
+
#ifdef USE_DATA_PTR
- MEM_freeN(CHUNK_DATA(mpchunk));
+ MEM_freeN(CHUNK_DATA(mpchunk));
#endif
- MEM_freeN(mpchunk);
- }
+ MEM_freeN(mpchunk);
}
-static void mempool_chunk_free_all(ListBase *chunks, const unsigned int flag)
+static void mempool_chunk_free_all(BLI_mempool_chunk *mpchunk)
{
- BLI_mempool_chunk *mpchunk, *mpchunk_next;
+ BLI_mempool_chunk *mpchunk_next;
- for (mpchunk = chunks->first; mpchunk; mpchunk = mpchunk_next) {
+ for (; mpchunk; mpchunk = mpchunk_next) {
mpchunk_next = mpchunk->next;
- mempool_chunk_free(mpchunk, flag);
+ mempool_chunk_free(mpchunk);
}
- BLI_listbase_clear(chunks);
}
BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
unsigned int pchunk, unsigned int flag)
{
- BLI_mempool *pool = NULL;
+ BLI_mempool *pool;
BLI_freenode *lasttail = NULL;
unsigned int i, maxchunks;
/* allocate the pool structure */
- if (flag & BLI_MEMPOOL_SYSMALLOC) {
- pool = malloc(sizeof(BLI_mempool));
- }
- else {
- pool = MEM_mallocN(sizeof(BLI_mempool), "memory pool");
- }
+ pool = MEM_mallocN(sizeof(BLI_mempool), "memory pool");
/* set the elem size */
if (esize < (int)MEMPOOL_ELEM_SIZE_MIN) {
@@ -257,18 +281,29 @@ BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
}
if (flag & BLI_MEMPOOL_ALLOW_ITER) {
- pool->esize = MAX2(esize, (unsigned int)sizeof(BLI_freenode));
- }
- else {
- pool->esize = esize;
+ esize = MAX2(esize, (unsigned int)sizeof(BLI_freenode));
}
maxchunks = mempool_maxchunks(totelem, pchunk);
- pool->flag = flag;
- pool->pchunk = pchunk;
+ pool->chunks = NULL;
+ pool->chunk_tail = NULL;
+ pool->esize = esize;
pool->csize = esize * pchunk;
- BLI_listbase_clear(&pool->chunks);
+
+
+ /* Optimize chunk size to powers of 2, accounting for slop-space */
+#ifdef USE_CHUNK_POW2
+ {
+ BLI_assert(pool->csize > CHUNK_OVERHEAD);
+ pool->csize = power_of_2_max_u(pool->csize) - CHUNK_OVERHEAD;
+ pchunk = pool->csize / esize;
+ }
+#endif
+
+
+ pool->pchunk = pchunk;
+ pool->flag = flag;
pool->free = NULL; /* mempool_chunk_add assigns */
pool->maxchunks = maxchunks;
#ifdef USE_TOTALLOC
@@ -276,10 +311,12 @@ BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
#endif
pool->totused = 0;
- /* allocate the actual chunks */
- for (i = 0; i < maxchunks; i++) {
- BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
- lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
+ if (totelem) {
+ /* allocate the actual chunks */
+ for (i = 0; i < maxchunks; i++) {
+ BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
+ lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
+ }
}
#ifdef WITH_MEM_VALGRIND
@@ -291,9 +328,7 @@ BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
void *BLI_mempool_alloc(BLI_mempool *pool)
{
- void *retval = NULL;
-
- pool->totused++;
+ BLI_freenode *free_pop;
if (UNLIKELY(pool->free == NULL)) {
/* need to allocate a new chunk */
@@ -301,19 +336,22 @@ void *BLI_mempool_alloc(BLI_mempool *pool)
mempool_chunk_add(pool, mpchunk, NULL);
}
- retval = pool->free;
+ free_pop = pool->free;
+
+ BLI_assert(pool->chunk_tail->next == NULL);
if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- pool->free->freeword = 0x7FFFFFFF;
+ free_pop->freeword = USEDWORD;
}
- pool->free = pool->free->next;
+ pool->free = free_pop->next;
+ pool->totused++;
#ifdef WITH_MEM_VALGRIND
- VALGRIND_MEMPOOL_ALLOC(pool, retval, pool->esize);
+ VALGRIND_MEMPOOL_ALLOC(pool, free_pop, pool->esize);
#endif
- return retval;
+ return (void *)free_pop;
}
void *BLI_mempool_calloc(BLI_mempool *pool)
@@ -336,7 +374,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
{
BLI_mempool_chunk *chunk;
bool found = false;
- for (chunk = pool->chunks.first; chunk; chunk = chunk->next) {
+ for (chunk = pool->chunks; chunk; chunk = chunk->next) {
if (ARRAY_HAS_ITEM((char *)addr, (char *)CHUNK_DATA(chunk), pool->csize)) {
found = true;
break;
@@ -372,14 +410,16 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
/* nothing is in use; free all the chunks except the first */
if (UNLIKELY(pool->totused == 0)) {
- BLI_freenode *curnode = NULL;
- char *tmpaddr = NULL;
- unsigned int i;
+ const unsigned int esize = pool->esize;
+ BLI_freenode *curnode;
+ unsigned int j;
BLI_mempool_chunk *first;
- first = BLI_pophead(&pool->chunks);
- mempool_chunk_free_all(&pool->chunks, pool->flag);
- BLI_addtail(&pool->chunks, first);
+ first = pool->chunks;
+ mempool_chunk_free_all(first->next);
+ first->next = NULL;
+ pool->chunk_tail = first;
+
#ifdef USE_TOTALLOC
pool->totalloc = pool->pchunk;
#endif
@@ -388,12 +428,16 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
#ifdef WITH_MEM_VALGRIND
VALGRIND_MEMPOOL_ALLOC(pool, CHUNK_DATA(first), pool->csize);
#endif
- pool->free = CHUNK_DATA(first); /* start of the list */
- for (tmpaddr = CHUNK_DATA(first), i = 0; i < pool->pchunk; i++) {
- curnode = ((BLI_freenode *)tmpaddr);
- tmpaddr += pool->esize;
- curnode->next = (BLI_freenode *)tmpaddr;
+
+ curnode = CHUNK_DATA(first);
+ pool->free = curnode;
+
+ j = pool->pchunk;
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
+ curnode = curnode->next;
}
+ curnode = NODE_STEP_PREV(curnode);
curnode->next = NULL; /* terminate the list */
#ifdef WITH_MEM_VALGRIND
@@ -460,15 +504,16 @@ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr)
*/
void BLI_mempool_as_array(BLI_mempool *pool, void *data)
{
+ const unsigned int esize = pool->esize;
BLI_mempool_iter iter;
char *elem, *p = data;
BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
BLI_mempool_iternew(pool, &iter);
while ((elem = BLI_mempool_iterstep(&iter))) {
- memcpy(p, elem, (size_t)pool->esize);
- p += pool->esize;
+ memcpy(p, elem, (size_t)esize);
+ p = NODE_STEP_NEXT(p);
}
- BLI_assert((unsigned int)(p - (char *)data) == pool->totused * pool->esize);
+ BLI_assert((unsigned int)(p - (char *)data) == pool->totused * esize);
}
/**
@@ -489,7 +534,7 @@ void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
iter->pool = pool;
- iter->curchunk = pool->chunks.first;
+ iter->curchunk = pool->chunks;
iter->curindex = 0;
}
@@ -567,7 +612,7 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
BLI_mempool_chunk *mpchunk_next;
unsigned int maxchunks;
- ListBase chunks_temp;
+ BLI_mempool_chunk *chunks_temp;
BLI_freenode *lasttail = NULL;
#ifdef WITH_MEM_VALGRIND
@@ -583,11 +628,17 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
}
/* free all after pool->maxchunks */
-
- for (mpchunk = BLI_findlink(&pool->chunks, (int)maxchunks); mpchunk; mpchunk = mpchunk_next) {
+ mpchunk = mempool_chunk_find(pool->chunks, maxchunks - 1);
+ if (mpchunk && mpchunk->next) {
+ /* terminate */
mpchunk_next = mpchunk->next;
- BLI_remlink(&pool->chunks, mpchunk);
- mempool_chunk_free(mpchunk, pool->flag);
+ mpchunk->next = NULL;
+ mpchunk = mpchunk_next;
+
+ do {
+ mpchunk_next = mpchunk->next;
+ mempool_chunk_free(mpchunk);
+ } while ((mpchunk = mpchunk_next));
}
/* re-initialize */
@@ -598,9 +649,11 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
#endif
chunks_temp = pool->chunks;
- BLI_listbase_clear(&pool->chunks);
+ pool->chunks = NULL;
+ pool->chunk_tail = NULL;
- while ((mpchunk = BLI_pophead(&chunks_temp))) {
+ while ((mpchunk = chunks_temp)) {
+ chunks_temp = mpchunk->next;
lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
}
}
@@ -618,18 +671,13 @@ void BLI_mempool_clear(BLI_mempool *pool)
*/
void BLI_mempool_destroy(BLI_mempool *pool)
{
- mempool_chunk_free_all(&pool->chunks, pool->flag);
+ mempool_chunk_free_all(pool->chunks);
#ifdef WITH_MEM_VALGRIND
VALGRIND_DESTROY_MEMPOOL(pool);
#endif
- if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
- free(pool);
- }
- else {
- MEM_freeN(pool);
- }
+ MEM_freeN(pool);
}
#ifndef NDEBUG
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c
index 4b51aefbd87..5d01706ebb1 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack2d.c
@@ -25,16 +25,27 @@
*/
#include <stdlib.h> /* for qsort */
+#include <math.h> /* for fabsf */
#include "MEM_guardedalloc.h"
-#include "BLI_strict_flags.h"
+#include "BLI_utildefines.h"
#include "BLI_boxpack2d.h" /* own include */
+#include "BLI_strict_flags.h"
+
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wpadded"
#endif
+/* de-duplicate as we pack */
+#define USE_MERGE
+/* use strip-free */
+#define USE_FREE_STRIP
+/* slight bias, needed when packing many boxes the _exact_ same size */
+#define USE_PACK_BIAS
+
+
/* BoxPacker for backing 2D rectangles into a square
*
* The defined Below are for internal use only */
@@ -42,7 +53,9 @@ typedef struct BoxVert {
float x;
float y;
- int free; /* could be a char */
+ int free : 8; /* vert status */
+ unsigned int used : 1;
+ unsigned int _pad : 23;
unsigned int index;
struct BoxPack *trb; /* top right box */
@@ -53,68 +66,156 @@ typedef struct BoxVert {
/* Store last intersecting boxes here
* speedup intersection testing */
struct BoxPack *isect_cache[4];
+
+#ifdef USE_PACK_BIAS
+ float bias;
+ int _pad2;
+#endif
} BoxVert;
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+
/* free vert flags */
#define EPSILON 0.0000001f
+#define EPSILON_MERGE 0.00001f
+#ifdef USE_PACK_BIAS
+# define EPSILON_BIAS 0.000001f
+#endif
#define BLF 1
#define TRF 2
#define TLF 4
#define BRF 8
#define CORNERFLAGS (BLF | TRF | TLF | BRF)
+BLI_INLINE int quad_flag(unsigned int q)
+{
+ BLI_assert(q < 4 && q >= 0);
+ return (1 << q);
+}
+
#define BL 0
#define TR 1
#define TL 2
#define BR 3
-#define BOXLEFT(b) ((b)->v[BL]->x)
-#define BOXRIGHT(b) ((b)->v[TR]->x)
-#define BOXBOTTOM(b) ((b)->v[BL]->y)
-#define BOXTOP(b) ((b)->v[TR]->y)
-#define BOXAREA(b) ((b)->w * (b)->h)
-
-#define UPDATE_V34X(b) ((b)->v[TL]->x = (b)->v[BL]->x); \
- ((b)->v[BR]->x = (b)->v[TR]->x)
-#define UPDATE_V34Y(b) ((b)->v[TL]->y = (b)->v[TR]->y); \
- ((b)->v[BR]->y = (b)->v[BL]->y)
-
-/* UNUSED */
-// #define UPDATE_V34(b) UPDATE_V34X(b); UPDATE_V34Y(b)
-
-#define SET_BOXLEFT(b, f) (b)->v[TR]->x = f + (b)->w; \
- (b)->v[BL]->x = f; \
- UPDATE_V34X(b)
-#define SET_BOXRIGHT(b, f) (b)->v[BL]->x = f - (b)->w; \
- (b)->v[TR]->x = f; \
- UPDATE_V34X(b)
-#define SET_BOXBOTTOM(b, f) (b)->v[TR]->y = f + (b)->h; \
- (b)->v[BL]->y = f; \
- UPDATE_V34Y(b)
-#define SET_BOXTOP(b, f) (b)->v[BL]->y = f - (b)->h; \
- (b)->v[TR]->y = f; \
- UPDATE_V34Y(b)
-#define BOXINTERSECT(b1, b2) \
- !(BOXLEFT(b1) + EPSILON >= BOXRIGHT(b2) || \
- BOXBOTTOM(b1) + EPSILON >= BOXTOP(b2) || \
- BOXRIGHT(b1) - EPSILON <= BOXLEFT(b2) || \
- BOXTOP(b1) - EPSILON <= BOXBOTTOM(b2))
+/** \name Box Accessor Functions
+ * \{ */
+
+static float box_xmin_get(const BoxPack *box)
+{
+ return box->v[BL]->x;
+}
+
+static float box_xmax_get(const BoxPack *box)
+{
+ return box->v[TR]->x;
+}
+
+static float box_ymin_get(const BoxPack *box)
+{
+ return box->v[BL]->y;
+}
+
+static float box_ymax_get(const BoxPack *box)
+{
+ return box->v[TR]->y;
+}
+/** \} */
+
+
+/** \name Box Placement
+ * \{ */
+
+BLI_INLINE void box_v34x_update(BoxPack *box)
+{
+ box->v[TL]->x = box->v[BL]->x;
+ box->v[BR]->x = box->v[TR]->x;
+}
+
+BLI_INLINE void box_v34y_update(BoxPack *box)
+{
+ box->v[TL]->y = box->v[TR]->y;
+ box->v[BR]->y = box->v[BL]->y;
+}
+
+static void box_xmin_set(BoxPack *box, const float f)
+{
+ box->v[TR]->x = f + box->w;
+ box->v[BL]->x = f;
+ box_v34x_update(box);
+}
+
+static void box_xmax_set(BoxPack *box, const float f)
+{
+ box->v[BL]->x = f - box->w;
+ box->v[TR]->x = f;
+ box_v34x_update(box);
+}
+
+static void box_ymin_set(BoxPack *box, const float f)
+{
+ box->v[TR]->y = f + box->h;
+ box->v[BL]->y = f;
+ box_v34y_update(box);
+}
+
+static void box_ymax_set(BoxPack *box, const float f)
+{
+ box->v[BL]->y = f - box->h;
+ box->v[TR]->y = f;
+ box_v34y_update(box);
+}
+/** \} */
+
+
+/** \name Box Utils
+ * \{ */
+
+static float box_area(const BoxPack *box)
+{
+ return box->w * box->h;
+}
+
+static bool box_isect(const BoxPack *box_a, const BoxPack *box_b)
+{
+ return !(box_xmin_get(box_a) + EPSILON >= box_xmax_get(box_b) ||
+ box_ymin_get(box_a) + EPSILON >= box_ymax_get(box_b) ||
+ box_xmax_get(box_a) - EPSILON <= box_xmin_get(box_b) ||
+ box_ymax_get(box_a) - EPSILON <= box_ymin_get(box_b));
+}
+
+/** \} */
+
/* compiler should inline */
static float max_ff(const float a, const float b) { return b > a ? b : a; }
+#ifdef USE_PACK_BIAS
+/* set when used is enabled */
+static void vert_bias_update(BoxVert *v)
+{
+ BLI_assert(v->used);
+ v->bias = (v->x * v->y) * EPSILON_BIAS;
+}
+#endif
+
#if 0
#define BOXDEBUG(b) \
printf("\tBox Debug i %i, w:%.3f h:%.3f x:%.3f y:%.3f\n", \
b->index, b->w, b->h, b->x, b->y)
#endif
+/** \name Box/Vert Sorting
+ * \{ */
+
/* qsort function - sort largest to smallest */
static int box_areasort(const void *p1, const void *p2)
{
const BoxPack *b1 = p1, *b2 = p2;
- const float a1 = BOXAREA(b1);
- const float a2 = BOXAREA(b2);
+ const float a1 = box_area(b1);
+ const float a2 = box_area(b2);
if (a1 < a2) return 1;
else if (a1 > a2) return -1;
@@ -122,7 +223,7 @@ static int box_areasort(const void *p1, const void *p2)
}
/* qsort vertex sorting function
- * sorts from lower left to top right It uses the current box's width and height
+ * sorts from lower left to top right It uses the current box's width and height
* as offsets when sorting, this has the result of not placing boxes outside
* the bounds of the existing backed area where possible
* */
@@ -138,40 +239,55 @@ static int vertex_sort(const void *p1, const void *p2)
v1 = vertarray + ((int *)p1)[0];
v2 = vertarray + ((int *)p2)[0];
+#ifdef USE_FREE_STRIP
+ /* push free verts to the end so we can strip */
+ if (UNLIKELY(v1->free == 0 && v2->free == 0)) return 0;
+ else if (UNLIKELY(v1->free == 0)) return 1;
+ else if (UNLIKELY(v2->free == 0)) return -1;
+#endif
+
a1 = max_ff(v1->x + box_width, v1->y + box_height);
a2 = max_ff(v2->x + box_width, v2->y + box_height);
+#ifdef USE_PACK_BIAS
+ a1 += v1->bias;
+ a2 += v2->bias;
+#endif
+
/* sort largest to smallest */
if (a1 > a2) return 1;
else if (a1 < a2) return -1;
return 0;
}
-/* Main boxpacking function accessed from other functions
+/** \} */
+
+/**
+ * Main boxpacking function accessed from other functions
* This sets boxes x,y to positive values, sorting from 0,0 outwards.
* There is no limit to the space boxes may take, only that they will be packed
* tightly into the lower left hand corner (0,0)
*
- * boxarray - a pre allocated array of boxes.
+ * \param boxarray: a pre allocated array of boxes.
* only the 'box->x' and 'box->y' are set, 'box->w' and 'box->h' are used,
* 'box->index' is not used at all, the only reason its there
* is that the box array is sorted by area and programs need to be able
* to have some way of writing the boxes back to the original data.
- * len - the number of boxes in the array.
- * tot_width and tot_height are set so you can normalize the data.
+ * \param len: the number of boxes in the array.
+ * \param r_tot_x, r_tot_y: set so you can normalize the data.
* */
-void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width, float *tot_height)
+void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x, float *r_tot_y)
{
- const int quad_flags[4] = {BLF, TRF, TLF, BRF}; /* use for looping */
unsigned int box_index, verts_pack_len, i, j, k;
unsigned int *vertex_pack_indices; /* an array of indices used for sorting verts */
bool isect;
+ float tot_x = 0.0f, tot_y = 0.0f;
BoxPack *box, *box_test; /*current box and another for intersection tests*/
BoxVert *vert; /* the current vert */
if (!len) {
- *tot_width = 0.0f;
- *tot_height = 0.0f;
+ *r_tot_x = tot_x;
+ *r_tot_y = tot_y;
return;
}
@@ -189,32 +305,36 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~TRF;
vert->trb = box;
+ vert->used = false;
vert->index = i++;
- box->v[BL] = vert; vert++;
+ box->v[BL] = vert++;
vert->trb = vert->brb = vert->tlb =
vert->isect_cache[0] = vert->isect_cache[1] =
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~BLF;
vert->blb = box;
+ vert->used = false;
vert->index = i++;
- box->v[TR] = vert; vert++;
+ box->v[TR] = vert++;
vert->trb = vert->blb = vert->tlb =
vert->isect_cache[0] = vert->isect_cache[1] =
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~BRF;
vert->brb = box;
+ vert->used = false;
vert->index = i++;
- box->v[TL] = vert; vert++;
+ box->v[TL] = vert++;
vert->trb = vert->blb = vert->brb =
vert->isect_cache[0] = vert->isect_cache[1] =
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~TLF;
- vert->tlb = box;
+ vert->tlb = box;
+ vert->used = false;
vert->index = i++;
- box->v[BR] = vert; vert++;
+ box->v[BR] = vert++;
}
vert = NULL;
@@ -227,14 +347,21 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
box->v[BR]->free &= ~(BLF | BRF);
box->v[TL]->free &= ~(BLF | TLF);
- *tot_width = box->w;
- *tot_height = box->h;
+ tot_x = box->w;
+ tot_y = box->h;
/* This sets all the vertex locations */
- SET_BOXLEFT(box, 0.0f);
- SET_BOXBOTTOM(box, 0.0f);
+ box_xmin_set(box, 0.0f);
+ box_ymin_set(box, 0.0f);
box->x = box->y = 0.0f;
+ for (i = 0; i < 4; i++) {
+ box->v[i]->used = true;
+#ifdef USE_PACK_BIAS
+ vert_bias_update(box->v[i]);
+#endif
+ }
+
for (i = 0; i < 3; i++)
vertex_pack_indices[i] = box->v[i + 1]->index;
verts_pack_len = 3;
@@ -250,6 +377,15 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
qsort(vertex_pack_indices, (size_t)verts_pack_len, sizeof(int), vertex_sort);
+#ifdef USE_FREE_STRIP
+ /* strip free vertices */
+ i = verts_pack_len - 1;
+ while ((i != 0) && vertarray[vertex_pack_indices[i]].free == 0) {
+ i--;
+ }
+ verts_pack_len = i + 1;
+#endif
+
/* Pack the box in with the others */
/* sort the verts */
isect = true;
@@ -265,23 +401,23 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
* */
for (j = 0; (j < 4) && isect; j++) {
- if (vert->free & quad_flags[j]) {
+ if (vert->free & quad_flag(j)) {
switch (j) {
case BL:
- SET_BOXRIGHT(box, vert->x);
- SET_BOXTOP(box, vert->y);
+ box_xmax_set(box, vert->x);
+ box_ymax_set(box, vert->y);
break;
case TR:
- SET_BOXLEFT(box, vert->x);
- SET_BOXBOTTOM(box, vert->y);
+ box_xmin_set(box, vert->x);
+ box_ymin_set(box, vert->y);
break;
case TL:
- SET_BOXRIGHT(box, vert->x);
- SET_BOXBOTTOM(box, vert->y);
+ box_xmax_set(box, vert->x);
+ box_ymin_set(box, vert->y);
break;
case BR:
- SET_BOXLEFT(box, vert->x);
- SET_BOXTOP(box, vert->y);
+ box_xmin_set(box, vert->x);
+ box_ymax_set(box, vert->y);
break;
}
@@ -291,10 +427,10 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
isect = false;
if ( /* Constrain boxes to positive X/Y values */
- BOXLEFT(box) < 0.0f || BOXBOTTOM(box) < 0.0f ||
+ box_xmin_get(box) < 0.0f || box_ymin_get(box) < 0.0f ||
/* check for last intersected */
(vert->isect_cache[j] &&
- BOXINTERSECT(box, vert->isect_cache[j])))
+ box_isect(box, vert->isect_cache[j])))
{
/* Here we check that the last intersected
* box will intersect with this one using
@@ -308,7 +444,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
* this is really slow, some spatially divided
* data-structure would be better */
for (box_test = boxarray; box_test != box; box_test++) {
- if (BOXINTERSECT(box, box_test)) {
+ if (box_isect(box, box_test)) {
/* Store the last intersecting here as cache
* for faster checking next time around */
vert->isect_cache[j] = box_test;
@@ -321,11 +457,11 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
if (!isect) {
/* maintain the total width and height */
- (*tot_width) = max_ff(BOXRIGHT(box), (*tot_width));
- (*tot_height) = max_ff(BOXTOP(box), (*tot_height));
+ tot_x = max_ff(box_xmax_get(box), tot_x);
+ tot_y = max_ff(box_ymax_get(box), tot_y);
/* Place the box */
- vert->free &= ~quad_flags[j];
+ vert->free &= (signed char)(~quad_flag(j));
switch (j) {
case TR:
@@ -352,11 +488,11 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
*
* We can do an else/if here because only the first
* box can be at the very bottom left corner */
- if (BOXLEFT(box) <= 0) {
+ if (box_xmin_get(box) <= 0) {
box->v[TL]->free &= ~(TLF | BLF);
box->v[BL]->free &= ~(TLF | BLF);
}
- else if (BOXBOTTOM(box) <= 0) {
+ else if (box_ymin_get(box) <= 0) {
box->v[BL]->free &= ~(BRF | BLF);
box->v[BR]->free &= ~(BRF | BLF);
}
@@ -367,58 +503,139 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
* as being used by checking the width or
* height of both boxes */
if (vert->tlb && vert->trb && (box == vert->tlb || box == vert->trb)) {
- if (vert->tlb->h > vert->trb->h) {
+ if (UNLIKELY(fabsf(vert->tlb->h - vert->trb->h) < EPSILON_MERGE)) {
+#ifdef USE_MERGE
+# define A (vert->trb->v[TL])
+# define B (vert->tlb->v[TR])
+# define MASK (BLF | BRF)
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
+# undef A
+# undef B
+# undef MASK
+#else
+ vert->tlb->v[TR]->free &= ~BLF;
+ vert->trb->v[TL]->free &= ~BRF;
+#endif
+ }
+ else if (vert->tlb->h > vert->trb->h) {
vert->trb->v[TL]->free &= ~(TLF | BLF);
}
- else if (vert->tlb->h < vert->trb->h) {
+ else /* if (vert->tlb->h < vert->trb->h) */ {
vert->tlb->v[TR]->free &= ~(TRF | BRF);
}
- else { /*same*/
- vert->tlb->v[TR]->free &= ~BLF;
- vert->trb->v[TL]->free &= ~BRF;
- }
}
else if (vert->blb && vert->brb && (box == vert->blb || box == vert->brb)) {
- if (vert->blb->h > vert->brb->h) {
+ if (UNLIKELY(fabsf(vert->blb->h - vert->brb->h) < EPSILON_MERGE)) {
+#ifdef USE_MERGE
+# define A (vert->blb->v[BR])
+# define B (vert->brb->v[BL])
+# define MASK (TRF | TLF)
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
+# undef A
+# undef B
+# undef MASK
+#else
+ vert->blb->v[BR]->free &= ~TRF;
+ vert->brb->v[BL]->free &= ~TLF;
+#endif
+ }
+ else if (vert->blb->h > vert->brb->h) {
vert->brb->v[BL]->free &= ~(TLF | BLF);
}
- else if (vert->blb->h < vert->brb->h) {
+ else /* if (vert->blb->h < vert->brb->h) */ {
vert->blb->v[BR]->free &= ~(TRF | BRF);
}
- else { /*same*/
- vert->blb->v[BR]->free &= ~TRF;
- vert->brb->v[BL]->free &= ~TLF;
- }
}
/* Horizontal */
if (vert->tlb && vert->blb && (box == vert->tlb || box == vert->blb)) {
- if (vert->tlb->w > vert->blb->w) {
+ if (UNLIKELY(fabsf(vert->tlb->w - vert->blb->w) < EPSILON_MERGE)) {
+#ifdef USE_MERGE
+# define A (vert->blb->v[TL])
+# define B (vert->tlb->v[BL])
+# define MASK (TRF | BRF)
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
+# undef A
+# undef B
+# undef MASK
+#else
+ vert->blb->v[TL]->free &= ~TRF;
+ vert->tlb->v[BL]->free &= ~BRF;
+#endif
+ }
+ else if (vert->tlb->w > vert->blb->w) {
vert->blb->v[TL]->free &= ~(TLF | TRF);
}
- else if (vert->tlb->w < vert->blb->w) {
+ else /* if (vert->tlb->w < vert->blb->w) */ {
vert->tlb->v[BL]->free &= ~(BLF | BRF);
}
- else { /*same*/
- vert->blb->v[TL]->free &= ~TRF;
- vert->tlb->v[BL]->free &= ~BRF;
- }
}
else if (vert->trb && vert->brb && (box == vert->trb || box == vert->brb)) {
- if (vert->trb->w > vert->brb->w) {
+ if (UNLIKELY(fabsf(vert->trb->w - vert->brb->w) < EPSILON_MERGE)) {
+
+#ifdef USE_MERGE
+# define A (vert->brb->v[TR])
+# define B (vert->trb->v[BR])
+# define MASK (TLF | BLF)
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
+# undef A
+# undef B
+# undef MASK
+#else
+ vert->brb->v[TR]->free &= ~TLF;
+ vert->trb->v[BR]->free &= ~BLF;
+#endif
+ }
+ else if (vert->trb->w > vert->brb->w) {
vert->brb->v[TR]->free &= ~(TLF | TRF);
}
- else if (vert->trb->w < vert->brb->w) {
+ else /* if (vert->trb->w < vert->brb->w) */ {
vert->trb->v[BR]->free &= ~(BLF | BRF);
}
- else { /*same*/
- vert->brb->v[TR]->free &= ~TLF;
- vert->trb->v[BR]->free &= ~BLF;
- }
}
/* End logical check */
for (k = 0; k < 4; k++) {
- if (box->v[k] != vert) {
+ if (box->v[k]->used == false) {
+ box->v[k]->used = true;
+#ifdef USE_PACK_BIAS
+ vert_bias_update(box->v[k]);
+#endif
vertex_pack_indices[verts_pack_len] = box->v[k]->index;
verts_pack_len++;
}
@@ -426,14 +643,17 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
/* The Box verts are only used internally
* Update the box x and y since thats what external
* functions will see */
- box->x = BOXLEFT(box);
- box->y = BOXBOTTOM(box);
+ box->x = box_xmin_get(box);
+ box->y = box_ymin_get(box);
}
}
}
}
}
+ *r_tot_x = tot_x;
+ *r_tot_y = tot_y;
+
/* free all the verts, not really needed because they shouldn't be
* touched anymore but accessing the pointers would crash blender */
for (box_index = 0; box_index < len; box_index++) {
@@ -443,4 +663,3 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width
MEM_freeN(vertex_pack_indices);
MEM_freeN(vertarray);
}
-
diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull2d.c
index 2c29ef042a1..34ee39d8a9b 100644
--- a/source/blender/blenlib/intern/convexhull2d.c
+++ b/source/blender/blenlib/intern/convexhull2d.c
@@ -167,21 +167,17 @@ struct PointRef {
const float *pt; /* 2d vector */
};
-static int pointref_cmp_x(const void *a_, const void *b_)
+static int pointref_cmp_yx(const void *a_, const void *b_)
{
const struct PointRef *a = a_;
const struct PointRef *b = b_;
- if (a->pt[0] > b->pt[0]) return 1;
- else if (a->pt[0] < b->pt[0]) return -1;
- else return 0;
-}
-static int pointref_cmp_y(const void *a_, const void *b_)
-{
- const struct PointRef *a = a_;
- const struct PointRef *b = b_;
if (a->pt[1] > b->pt[1]) return 1;
else if (a->pt[1] < b->pt[1]) return -1;
+
+ if (a->pt[0] > b->pt[0]) return 1;
+ else if (a->pt[0] < b->pt[0]) return -1;
+
else return 0;
}
@@ -207,8 +203,7 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
}
/* Sort the points by X, then by Y (required by the algorithm) */
- qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_x);
- qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_y);
+ qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_yx);
for (i = 0; i < n; i++) {
memcpy(points_sort[i], points_ref[i].pt, sizeof(float[2]));
@@ -253,28 +248,24 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
{
unsigned int i, i_prev;
float area_best = FLT_MAX;
- float angle_best = 0.0f;
+ float dvec_best[2]; /* best angle, delay atan2 */
i_prev = n - 1;
for (i = 0; i < n; i++) {
const float *ev_a = points_hull[i];
const float *ev_b = points_hull[i_prev];
- float dvec[2];
+ float dvec[2]; /* 2d rotation matrix */
sub_v2_v2v2(dvec, ev_a, ev_b);
if (normalize_v2(dvec) != 0.0f) {
- float mat[2][2];
+ /* rotation matrix */
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
-
unsigned int j;
- const float angle = atan2f(dvec[0], dvec[1]);
float area;
- angle_to_mat2(mat, angle);
-
for (j = 0; j < n; j++) {
float tvec[2];
- mul_v2_m2v2(tvec, mat, points_hull[j]);
+ mul_v2_v2_cw(tvec, dvec, points_hull[j]);
min[0] = min_ff(min[0], tvec[0]);
min[1] = min_ff(min[1], tvec[1]);
@@ -290,14 +281,14 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
if (area < area_best) {
area_best = area;
- angle_best = angle;
+ copy_v2_v2(dvec_best, dvec);
}
}
i_prev = i;
}
- return angle_best;
+ return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
}
/**
diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c
new file mode 100644
index 00000000000..1f39c2f57b5
--- /dev/null
+++ b/source/blender/blenlib/intern/easing.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * 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 the author nor the names of 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 <COPYRIGHT HOLDER> 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.
+ */
+
+/** \file blender/blenlib/intern/easing.c
+ * \ingroup bli
+ */
+
+#include "BLI_math_base.h"
+
+#include "BLI_easing.h" /* own include */
+
+#include "BLI_strict_flags.h"
+
+/* blend if (amplitude < fabsf(change) */
+#define USE_ELASTIC_BLEND
+
+float BLI_easing_back_ease_in(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0.0f)
+ overshoot = 1.70158f;
+ time /= duration;
+ return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
+}
+
+float BLI_easing_back_ease_out(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0.0f)
+ overshoot = 1.70158f;
+ time = time / duration - 1;
+ return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
+}
+
+float BLI_easing_back_ease_in_out(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0.0f)
+ overshoot = 1.70158f;
+ overshoot *= 1.525f;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
+ }
+ time -= 2.0f;
+ return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
+
+}
+
+float BLI_easing_bounce_ease_out(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ if (time < (1 / 2.75f)) {
+ return change * (7.5625f * time * time) + begin;
+ }
+ else if (time < (2 / 2.75f)) {
+ time -= (1.5f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.75f) + begin;
+ }
+ else if (time < (2.5f / 2.75f)) {
+ time -= (2.25f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.9375f) + begin;
+ }
+ else {
+ time -= (2.625f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.984375f) + begin;
+ }
+}
+
+float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
+{
+ return change - BLI_easing_bounce_ease_out(duration - time, 0, change, duration) + begin;
+}
+
+float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float duration)
+{
+ if (time < duration / 2)
+ return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
+ else
+ return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f + change * 0.5f + begin;
+}
+
+float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return -change * (sqrtf(1 - time * time) - 1) + begin;
+}
+
+float BLI_easing_circ_ease_out(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * sqrtf(1 - time * time) + begin;
+}
+
+float BLI_easing_circ_ease_in_out(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1.0f)
+ return -change / 2 * (sqrtf(1 - time * time) - 1) + begin;
+ time -= 2.0f;
+ return change / 2 * (sqrtf(1 - time * time) + 1) + begin;
+}
+
+float BLI_easing_cubic_ease_in(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time + begin;
+}
+
+float BLI_easing_cubic_ease_out(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * (time * time * time + 1) + begin;
+}
+
+float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1.0f)
+ return change / 2 * time * time * time + begin;
+ time -= 2.0f;
+ return change / 2 * (time * time * time + 2) + begin;
+}
+
+#ifdef USE_ELASTIC_BLEND
+/**
+ * When the amplitude is less then the change, we need to blend
+ * \a f when we're close to the crossing point (int time), else we get an ugly sharp falloff.
+ */
+static float elastic_blend(float time, float change, float duration, float amplitude, float s, float f)
+{
+ if (change) {
+ /* Looks like a magic number,
+ * but this is a part of the sine curve we need to blend from */
+ const float t = fabsf(s);
+ if (amplitude) {
+ f *= amplitude / fabsf(change);
+ }
+ else {
+ f = 0.0f;
+ }
+
+ if (fabsf(time * duration) < t) {
+ float l = fabsf(time * duration) / t;
+ f = (f * l) + (1.0f - l);
+ }
+ }
+
+ return f;
+}
+#endif
+
+float BLI_easing_elastic_ease_in(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f)
+ return begin;
+
+ if ((time /= duration) == 1.0f)
+ return begin + change;
+ time -= 1.0f;
+ if (!period)
+ period = duration * 0.3f;
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
+#ifdef USE_ELASTIC_BLEND
+ f = elastic_blend(time, change, duration, amplitude, s, f);
+#endif
+ amplitude = change;
+ }
+ else
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+
+ return (-f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin;
+}
+
+float BLI_easing_elastic_ease_out(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f)
+ return begin;
+ if ((time /= duration) == 1.0f)
+ return begin + change;
+ time = -time;
+ if (!period)
+ period = duration * 0.3f;
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
+#ifdef USE_ELASTIC_BLEND
+ f = elastic_blend(time, change, duration, amplitude, s, f);
+#endif
+ amplitude = change;
+ }
+ else
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+
+ return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin;
+}
+
+float BLI_easing_elastic_ease_in_out(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f)
+ return begin;
+ if ((time /= duration / 2) == 2.0f)
+ return begin + change;
+ time -= 1.0f;
+ if (!period)
+ period = duration * (0.3f * 1.5f);
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
+#ifdef USE_ELASTIC_BLEND
+ f = elastic_blend(time, change, duration, amplitude, s, f);
+#endif
+ amplitude = change;
+ }
+ else
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+
+ if (time < 0.0f) {
+ f *= -0.5f;
+ return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin;
+ }
+ else {
+ time = -time;
+ f *= 0.5f;
+ return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin;
+ }
+}
+
+float BLI_easing_expo_ease_in(float time, float begin, float change, float duration)
+{
+ return (time == 0.0f) ? begin : change * powf(2, 10 * (time / duration - 1)) + begin;
+}
+
+float BLI_easing_expo_ease_out(float time, float begin, float change, float duration)
+{
+ return (time == duration) ? begin + change : change * (-powf(2, -10 * time / duration) + 1) + begin;
+}
+
+float BLI_easing_expo_ease_in_out(float time, float begin, float change, float duration)
+{
+ if (time == 0.0f)
+ return begin;
+ if (time == duration)
+ return begin + change;
+ if ((time /= duration / 2) < 1)
+ return change / 2 * powf(2, 10 * (time - 1)) + begin;
+ time -= 1.0f;
+ return change / 2 * (-powf(2, -10 * time) + 2) + begin;
+}
+
+float BLI_easing_linear_ease(float time, float begin, float change, float duration)
+{
+ return change * time / duration + begin;
+}
+
+float BLI_easing_quad_ease_in(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time + begin;
+}
+
+float BLI_easing_quad_ease_out(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return -change * time * (time - 2) + begin;
+}
+
+float BLI_easing_quad_ease_in_out(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1.0f)
+ return change / 2 * time * time + begin;
+ time -= 1.0f;
+ return -change / 2 * (time * (time - 2) - 1) + begin;
+}
+
+
+float BLI_easing_quart_ease_in(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time * time + begin;
+}
+
+float BLI_easing_quart_ease_out(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return -change * (time * time * time * time - 1) + begin;
+}
+
+float BLI_easing_quart_ease_in_out(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1.0f)
+ return change / 2 * time * time * time * time + begin;
+ time -= 2.0f;
+ return -change / 2 * ( time * time * time * time - 2) + begin;
+}
+
+float BLI_easing_quint_ease_in(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time * time * time + begin;
+}
+float BLI_easing_quint_ease_out(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * (time * time * time * time * time + 1) + begin;
+}
+float BLI_easing_quint_ease_in_out(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1.0f)
+ return change / 2 * time * time * time * time * time + begin;
+ time -= 2.0f;
+ return change / 2 * (time * time * time * time * time + 2) + begin;
+}
+
+float BLI_easing_sine_ease_in(float time, float begin, float change, float duration)
+{
+ return -change * cosf(time / duration * (float)M_PI_2) + change + begin;
+}
+
+float BLI_easing_sine_ease_out(float time, float begin, float change, float duration)
+{
+ return change * sinf(time / duration * (float)M_PI_2) + begin;
+}
+
+float BLI_easing_sine_ease_in_out(float time, float begin, float change, float duration)
+{
+ return -change / 2 * (cosf((float)M_PI * time / duration) - 1) + begin;
+}
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 1d0c9b20550..51a22cc46ab 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -190,7 +190,7 @@ static EdgeHash *edgehash_new(const char *info,
}
eh->buckets = MEM_callocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets");
- eh->epool = BLI_mempool_create(entry_size, 512, 512, BLI_MEMPOOL_SYSMALLOC);
+ eh->epool = BLI_mempool_create(entry_size, nentries_reserve, 512, BLI_MEMPOOL_NOP);
return eh;
}
@@ -356,6 +356,16 @@ void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1)
}
/**
+ * A version of #BLI_edgehash_lookup which accepts a fallback argument.
+ */
+void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default)
+{
+ EdgeEntry *e = edgehash_lookup_entry(eh, v0, v1);
+ IS_EDGEHASH_ASSERT(eh);
+ return e ? e->val : val_default;
+}
+
+/**
* Return boolean true/false if edge (v0,v1) in hash.
*/
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1)
@@ -427,13 +437,6 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned int flag)
/** \name Iterator API
* \{ */
-struct EdgeHashIterator {
- EdgeHash *eh;
- unsigned int curBucket;
- EdgeEntry *curEntry;
-};
-
-
/**
* Create a new EdgeHashIterator. The hash table must not be mutated
* while the iterator is in use, and the iterator will step exactly
@@ -442,16 +445,51 @@ struct EdgeHashIterator {
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
{
EdgeHashIterator *ehi = MEM_mallocN(sizeof(*ehi), "eh iter");
+ BLI_edgehashIterator_init(ehi, eh);
+ return ehi;
+}
+
+/**
+ * Init an already allocated EdgeHashIterator. The hash table must not
+ * be mutated while the iterator is in use, and the iterator will
+ * step exactly BLI_edgehash_size(eh) times before becoming done.
+ *
+ * \param ehi The EdgeHashIterator to initialize.
+ * \param eh The EdgeHash to iterate over.
+ */
+void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh)
+{
ehi->eh = eh;
ehi->curEntry = NULL;
ehi->curBucket = UINT_MAX; /* wraps to zero */
- while (!ehi->curEntry) {
- ehi->curBucket++;
- if (ehi->curBucket == ehi->eh->nbuckets)
- break;
- ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
+ if (eh->nentries) {
+ while (!ehi->curEntry) {
+ ehi->curBucket++;
+ if (UNLIKELY(ehi->curBucket == ehi->eh->nbuckets)) {
+ break;
+ }
+
+ ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
+ }
+ }
+}
+
+/**
+ * Steps the iterator to the next index.
+ */
+void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
+{
+ if (ehi->curEntry) {
+ ehi->curEntry = ehi->curEntry->next;
+ while (!ehi->curEntry) {
+ ehi->curBucket++;
+ if (UNLIKELY(ehi->curBucket == ehi->eh->nbuckets)) {
+ break;
+ }
+
+ ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
+ }
}
- return ehi;
}
/**
@@ -462,15 +500,15 @@ void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
MEM_freeN(ehi);
}
+/* inline functions now */
+#if 0
/**
* Retrieve the key from an iterator.
*/
-void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r)
+void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *r_v0, unsigned int *r_v1)
{
- if (ehi->curEntry) {
- *v0_r = ehi->curEntry->v0;
- *v1_r = ehi->curEntry->v1;
- }
+ *r_v0 = ehi->curEntry->v0;
+ *r_v1 = ehi->curEntry->v1;
}
/**
@@ -478,7 +516,7 @@ void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsi
*/
void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi)
{
- return ehi->curEntry ? ehi->curEntry->val : NULL;
+ return ehi->curEntry->val;
}
/**
@@ -486,7 +524,7 @@ void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi)
*/
void **BLI_edgehashIterator_getValue_p(EdgeHashIterator *ehi)
{
- return ehi->curEntry ? &ehi->curEntry->val : NULL;
+ return &ehi->curEntry->val;
}
/**
@@ -494,27 +532,7 @@ void **BLI_edgehashIterator_getValue_p(EdgeHashIterator *ehi)
*/
void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
{
- if (ehi->curEntry) {
- ehi->curEntry->val = val;
- }
-}
-
-/**
- * Steps the iterator to the next index.
- */
-void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
-{
- if (ehi->curEntry) {
- ehi->curEntry = ehi->curEntry->next;
- while (!ehi->curEntry) {
- ehi->curBucket++;
- if (ehi->curBucket == ehi->eh->nbuckets) {
- break;
- }
-
- ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
- }
- }
+ ehi->curEntry->val = val;
}
/**
@@ -524,6 +542,7 @@ bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi)
{
return (ehi->curEntry == NULL);
}
+#endif
/** \} */
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 38ec7a10498..8fa01a700f6 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -61,7 +61,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
@@ -86,7 +85,7 @@ int BLI_file_gzip(const char *from, const char *to)
if (gzfile == NULL)
return -1;
file = BLI_open(from, O_BINARY | O_RDONLY, 0);
- if (file < 0)
+ if (file == -1)
return -2;
while (1) {
@@ -116,7 +115,7 @@ int BLI_file_gzip(const char *from, const char *to)
/* gzip the file in from_file and write it to memory to_mem, at most size bytes.
* return the unziped size
*/
-char *BLI_file_ungzip_to_mem(const char *from_file, bli_off_t *size_r)
+char *BLI_file_ungzip_to_mem(const char *from_file, bli_off_t *r_size)
{
gzFile gzfile;
int readsize, size, alloc_size = 0;
@@ -154,7 +153,7 @@ char *BLI_file_ungzip_to_mem(const char *from_file, bli_off_t *size_r)
else if (alloc_size != size)
mem = MEM_reallocN(mem, size);
- *size_r = size;
+ *r_size = size;
return mem;
}
@@ -360,7 +359,7 @@ int BLI_copy(const char *file, const char *to)
UTF16_ENCODE(file);
UTF16_ENCODE(str);
- err = !CopyFileW(file_16, str_16, FALSE);
+ err = !CopyFileW(file_16, str_16, false);
UTF16_UN_ENCODE(str);
UTF16_UN_ENCODE(file);
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 43cf6c665c2..b3392e28223 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -32,11 +32,6 @@
* \ingroup bli
*/
-
-#ifdef _MSC_VER
-# pragma warning (disable:4244)
-#endif
-
#include <ft2build.h>
#include FT_FREETYPE_H
/* not needed yet */
@@ -78,7 +73,7 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
FT_UInt glyph_index;
FT_Outline ftoutline;
float dx, dy;
- int j, k, l, m = 0;
+ int j, k, l, l_first = 0;
/*
* Generate the character 3D data
@@ -89,7 +84,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
/* If loading succeeded, convert the FT glyph to the internal format */
if (!err) {
- int *npoints;
+ /* initialize as -1 to add 1 on first loop each time */
+ int contour_prev;
int *onpoints;
/* First we create entry for the new character to the character list */
@@ -106,28 +102,24 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
BLI_ghash_insert(vfd->characters, SET_UINT_IN_POINTER(che->index), che);
/* Start converting the FT data */
- npoints = (int *)MEM_mallocN((ftoutline.n_contours) * sizeof(int), "endpoints");
onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
- /* calculate total points of each contour */
- for (j = 0; j < ftoutline.n_contours; j++) {
- if (j == 0)
- npoints[j] = ftoutline.contours[j] + 1;
- else
- npoints[j] = ftoutline.contours[j] - ftoutline.contours[j - 1];
- }
-
/* get number of on-curve points for beziertriples (including conic virtual on-points) */
- for (j = 0; j < ftoutline.n_contours; j++) {
- for (k = 0; k < npoints[j]; k++) {
+ for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
+ const int n = ftoutline.contours[j] - contour_prev;
+ contour_prev = ftoutline.contours[j];
+
+ for (k = 0; k < n; k++) {
l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
+ if (k == 0) l_first = l;
if (ftoutline.tags[l] == FT_Curve_Tag_On)
onpoints[j]++;
- if (k < npoints[j] - 1) {
- if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
- ftoutline.tags[l + 1] == FT_Curve_Tag_Conic)
+ {
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+ if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
+ ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
{
onpoints[j]++;
}
@@ -136,7 +128,10 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
}
/* contour loop, bezier & conic styles merged */
- for (j = 0; j < ftoutline.n_contours; j++) {
+ for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
+ const int n = ftoutline.contours[j] - contour_prev;
+ contour_prev = ftoutline.contours[j];
+
/* add new curve */
nu = (Nurb *)MEM_callocN(sizeof(struct Nurb), "objfnt_nurb");
bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt");
@@ -150,15 +145,18 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
nu->bezt = bezt;
/* individual curve loop, start-end */
- for (k = 0; k < npoints[j]; k++) {
- if (j > 0) l = k + ftoutline.contours[j - 1] + 1; else l = k;
- if (k == 0) m = l;
+ for (k = 0; k < n; k++) {
+ l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
+ if (k == 0) l_first = l;
/* virtual conic on-curve points */
- if (k < npoints[j] - 1) {
- if (ftoutline.tags[l] == FT_Curve_Tag_Conic && ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) {
- dx = (ftoutline.points[l].x + ftoutline.points[l + 1].x) * scale / 2.0f;
- dy = (ftoutline.points[l].y + ftoutline.points[l + 1].y) * scale / 2.0f;
+ {
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+ if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
+ ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
+ {
+ dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f;
+ dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f;
/* left handle */
bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f;
@@ -169,8 +167,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
bezt->vec[1][1] = dy;
/* right handle */
- bezt->vec[2][0] = (dx + (2 * ftoutline.points[l + 1].x) * scale) / 3.0f;
- bezt->vec[2][1] = (dy + (2 * ftoutline.points[l + 1].y) * scale) / 3.0f;
+ bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f;
+ bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f;
bezt->h1 = bezt->h2 = HD_ALIGN;
bezt->radius = 1.0f;
@@ -180,40 +178,24 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
/* on-curve points */
if (ftoutline.tags[l] == FT_Curve_Tag_On) {
+ const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j];
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+
/* left handle */
- if (k > 0) {
- if (ftoutline.tags[l - 1] == FT_Curve_Tag_Cubic) {
- bezt->vec[0][0] = ftoutline.points[l - 1].x * scale;
- bezt->vec[0][1] = ftoutline.points[l - 1].y * scale;
- bezt->h1 = HD_FREE;
- }
- else if (ftoutline.tags[l - 1] == FT_Curve_Tag_Conic) {
- bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l - 1].x)) * scale / 3.0f;
- bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l - 1].y)) * scale / 3.0f;
- bezt->h1 = HD_FREE;
- }
- else {
- bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l - 1].x) * scale / 3.0f;
- bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l - 1].y) * scale / 3.0f;
- bezt->h1 = HD_VECT;
- }
+ if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) {
+ bezt->vec[0][0] = ftoutline.points[l_prev].x * scale;
+ bezt->vec[0][1] = ftoutline.points[l_prev].y * scale;
+ bezt->h1 = HD_FREE;
}
- else { /* first point on curve */
- if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Cubic) {
- bezt->vec[0][0] = ftoutline.points[ftoutline.contours[j]].x * scale;
- bezt->vec[0][1] = ftoutline.points[ftoutline.contours[j]].y * scale;
- bezt->h1 = HD_FREE;
- }
- else if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Conic) {
- bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[ftoutline.contours[j]].x)) * scale / 3.0f;
- bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[ftoutline.contours[j]].y)) * scale / 3.0f;
- bezt->h1 = HD_FREE;
- }
- else {
- bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[ftoutline.contours[j]].x) * scale / 3.0f;
- bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[ftoutline.contours[j]].y) * scale / 3.0f;
- bezt->h1 = HD_VECT;
- }
+ else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) {
+ bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale / 3.0f;
+ bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale / 3.0f;
+ bezt->h1 = HD_FREE;
+ }
+ else {
+ bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f;
+ bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f;
+ bezt->h1 = HD_VECT;
}
/* midpoint (on-curve point) */
@@ -221,39 +203,20 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
bezt->vec[1][1] = ftoutline.points[l].y * scale;
/* right handle */
- if (k < (npoints[j] - 1)) {
- if (ftoutline.tags[l + 1] == FT_Curve_Tag_Cubic) {
- bezt->vec[2][0] = ftoutline.points[l + 1].x * scale;
- bezt->vec[2][1] = ftoutline.points[l + 1].y * scale;
- bezt->h2 = HD_FREE;
- }
- else if (ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) {
- bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l + 1].x)) * scale / 3.0f;
- bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l + 1].y)) * scale / 3.0f;
- bezt->h2 = HD_FREE;
- }
- else {
- bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l + 1].x) * scale / 3.0f;
- bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l + 1].y) * scale / 3.0f;
- bezt->h2 = HD_VECT;
- }
+ if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) {
+ bezt->vec[2][0] = ftoutline.points[l_next].x * scale;
+ bezt->vec[2][1] = ftoutline.points[l_next].y * scale;
+ bezt->h2 = HD_FREE;
+ }
+ else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
+ bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale / 3.0f;
+ bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale / 3.0f;
+ bezt->h2 = HD_FREE;
}
- else { /* last point on curve */
- if (ftoutline.tags[m] == FT_Curve_Tag_Cubic) {
- bezt->vec[2][0] = ftoutline.points[m].x * scale;
- bezt->vec[2][1] = ftoutline.points[m].y * scale;
- bezt->h2 = HD_FREE;
- }
- else if (ftoutline.tags[m] == FT_Curve_Tag_Conic) {
- bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[m].x)) * scale / 3.0f;
- bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[m].y)) * scale / 3.0f;
- bezt->h2 = HD_FREE;
- }
- else {
- bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[m].x) * scale / 3.0f;
- bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[m].y) * scale / 3.0f;
- bezt->h2 = HD_VECT;
- }
+ else {
+ bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f;
+ bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f;
+ bezt->h2 = HD_VECT;
}
/* get the handles that are aligned, tricky...
@@ -278,8 +241,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
}
}
}
- if (npoints) MEM_freeN(npoints);
- if (onpoints) MEM_freeN(onpoints);
+
+ MEM_freeN(onpoints);
return che;
}
@@ -306,7 +269,7 @@ static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
}
}
else {
- err = TRUE;
+ err = true;
return NULL;
}
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index e7651b70a5b..d4d87dfdbf6 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -722,13 +722,13 @@ static void testAxialSymmetry(BGraph *graph, BNode *root_node, BNode *node1, BNo
cross_v3_v3v3(nor, vec, axis);
- if (abs(nor[0]) > abs(nor[1]) && abs(nor[0]) > abs(nor[2]) && nor[0] < 0) {
+ if (fabsf(nor[0]) > fabsf(nor[1]) && fabsf(nor[0]) > fabsf(nor[2]) && nor[0] < 0) {
negate_v3(nor);
}
- else if (abs(nor[1]) > abs(nor[0]) && abs(nor[1]) > abs(nor[2]) && nor[1] < 0) {
+ else if (fabsf(nor[1]) > fabsf(nor[0]) && fabsf(nor[1]) > fabsf(nor[2]) && nor[1] < 0) {
negate_v3(nor);
}
- else if (abs(nor[2]) > abs(nor[1]) && abs(nor[2]) > abs(nor[0]) && nor[2] < 0) {
+ else if (fabsf(nor[2]) > fabsf(nor[1]) && fabsf(nor[2]) > fabsf(nor[0]) && nor[2] < 0) {
negate_v3(nor);
}
diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c
index 7141bedcf05..bc2b5677fa5 100644
--- a/source/blender/blenlib/intern/jitter.c
+++ b/source/blender/blenlib/intern/jitter.c
@@ -37,23 +37,25 @@
#include "BLI_rand.h"
#include "BLI_jitter.h"
+#include "BLI_strict_flags.h"
-void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1)
+
+void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float rad1)
{
int i, j, k;
float vecx, vecy, dvecx, dvecy, x, y, len;
- for (i = 2 * num - 2; i >= 0; i -= 2) {
+ for (i = num - 1; i >= 0; i--) {
dvecx = dvecy = 0.0;
- x = jit1[i];
- y = jit1[i + 1];
- for (j = 2 * num - 2; j >= 0; j -= 2) {
+ x = jit1[i][0];
+ y = jit1[i][1];
+ for (j = num - 1; j >= 0; j--) {
if (i != j) {
- vecx = jit1[j] - x - 1.0f;
- vecy = jit1[j + 1] - y - 1.0f;
+ vecx = jit1[j][0] - x - 1.0f;
+ vecy = jit1[j][1] - y - 1.0f;
for (k = 3; k > 0; k--) {
if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrt(vecx * vecx + vecy * vecy);
+ len = sqrtf(vecx * vecx + vecy * vecy);
if (len > 0 && len < rad1) {
len = len / rad1;
dvecx += vecx / len;
@@ -63,7 +65,7 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1)
vecx += 1.0f;
if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrt(vecx * vecx + vecy * vecy);
+ len = sqrtf(vecx * vecx + vecy * vecy);
if (len > 0 && len < rad1) {
len = len / rad1;
dvecx += vecx / len;
@@ -73,7 +75,7 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1)
vecx += 1.0f;
if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrt(vecx * vecx + vecy * vecy);
+ len = sqrtf(vecx * vecx + vecy * vecy);
if (len > 0 && len < rad1) {
len = len / rad1;
dvecx += vecx / len;
@@ -90,25 +92,25 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1)
y -= dvecy / 18.0f;
x -= floorf(x);
y -= floorf(y);
- jit2[i] = x;
- jit2[i + 1] = y;
+ jit2[i][0] = x;
+ jit2[i][1] = y;
}
- memcpy(jit1, jit2, 2 * num * sizeof(float));
+ memcpy(jit1, jit2, 2 * (unsigned int)num * sizeof(float));
}
-void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2)
+void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float rad2)
{
int i, j;
float vecx, vecy, dvecx, dvecy, x, y;
- for (i = 2 * num - 2; i >= 0; i -= 2) {
+ for (i = num - 1; i >= 0; i--) {
dvecx = dvecy = 0.0;
- x = jit1[i];
- y = jit1[i + 1];
- for (j = 2 * num - 2; j >= 0; j -= 2) {
+ x = jit1[i][0];
+ y = jit1[i][1];
+ for (j = num - 1; j >= 0; j--) {
if (i != j) {
- vecx = jit1[j] - x - 1.0f;
- vecy = jit1[j + 1] - y - 1.0f;
+ vecx = jit1[j][0] - x - 1.0f;
+ vecy = jit1[j][1] - y - 1.0f;
if (fabsf(vecx) < rad2) dvecx += vecx * rad2;
vecx += 1.0f;
@@ -129,32 +131,39 @@ void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2)
y -= dvecy / 2.0f;
x -= floorf(x);
y -= floorf(y);
- jit2[i] = x;
- jit2[i + 1] = y;
+ jit2[i][0] = x;
+ jit2[i][1] = y;
}
- memcpy(jit1, jit2, 2 * num * sizeof(float));
+ memcpy(jit1, jit2, (unsigned int)num * sizeof(float[2]));
}
-void BLI_jitter_init(float *jitarr, int num)
+void BLI_jitter_init(float (*jitarr)[2], int num)
{
- float *jit2, x, rad1, rad2, rad3;
+ float (*jit2)[2];
+ float num_fl, num_fl_sqrt;
+ float x, rad1, rad2, rad3;
RNG *rng;
int i;
- if (num == 0) return;
+ if (num == 0) {
+ return;
+ }
+
+ num_fl = (float)num;
+ num_fl_sqrt = sqrtf(num_fl);
- jit2 = MEM_mallocN(12 + 2 * sizeof(float) * num, "initjit");
- rad1 = 1.0f / sqrtf((float)num);
- rad2 = 1.0f / ((float)num);
- rad3 = sqrtf((float)num) / ((float)num);
+ jit2 = MEM_mallocN(12 + (unsigned int)num * sizeof(float[2]), "initjit");
+ rad1 = 1.0f / num_fl_sqrt;
+ rad2 = 1.0f / num_fl;
+ rad3 = num_fl_sqrt / num_fl;
- rng = BLI_rng_new(31415926 + num);
+ rng = BLI_rng_new(31415926 + (unsigned int)num);
x = 0;
- for (i = 0; i < 2 * num; i += 2) {
- jitarr[i] = x + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
- jitarr[i + 1] = ((float)i / 2) / num + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
+ for (i = 0; i < num; i++) {
+ jitarr[i][0] = x + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
+ jitarr[i][1] = (float)i / num_fl + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
x += rad3;
x -= floorf(x);
}
@@ -170,12 +179,8 @@ void BLI_jitter_init(float *jitarr, int num)
MEM_freeN(jit2);
/* finally, move jittertab to be centered around (0, 0) */
- for (i = 0; i < 2 * num; i += 2) {
- jitarr[i] -= 0.5f;
- jitarr[i + 1] -= 0.5f;
+ for (i = 0; i < num; i++) {
+ jitarr[i][0] -= 0.5f;
+ jitarr[i][1] -= 0.5f;
}
-
}
-
-
-/* eof */
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index facc7150ab8..e6217329145 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -44,9 +44,6 @@
# define UNLIKELY(x) (x)
#endif
-/* A few small defines. Keep'em local! */
-#define SMALL_NUMBER 1.e-8f
-
MINLINE float sqrt3f(float f)
{
if (UNLIKELY(f == 0.0f)) return 0.0f;
@@ -111,15 +108,6 @@ MINLINE float interpf(float target, float origin, float fac)
return (fac * target) + (1.0f - fac) * origin;
}
-/* useful to calculate an even width shell, by taking the angle between 2 planes.
- * The return value is a scale on the offset.
- * no angle between planes is 1.0, as the angle between the 2 planes approaches 180d
- * the distance gets very high, 180d would be inf, but this case isn't valid */
-MINLINE float shell_angle_to_dist(const float angle)
-{
- return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
-}
-
/* used for zoom values*/
MINLINE float power_of_2(float val)
{
@@ -151,6 +139,27 @@ MINLINE int power_of_2_min_i(int n)
return n;
}
+MINLINE unsigned int power_of_2_max_u(unsigned int x)
+{
+ x -= 1;
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return x + 1;
+}
+
+MINLINE unsigned power_of_2_min_u(unsigned x)
+{
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return x - (x >> 1);
+}
+
MINLINE int iroundf(float a)
{
return (int)floorf(a + 0.5f);
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 51980ad36cb..57a48bb5fa8 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -29,10 +29,8 @@
#include <assert.h>
-#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_rand.h"
#include "BLI_utildefines.h"
#include "BLI_strict_flags.h"
@@ -94,12 +92,71 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
}
}
+/* HSL to rgb conversion from https://en.wikipedia.org/wiki/HSL_and_HSV */
+void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b)
+{
+ float i, f, c;
+ h = (h - floorf(h)) * 6.0f;
+ c = (l > 0.5f) ? (2.0f * (1.0f - l) * s) : (2.0f * l * s);
+ i = floorf(h);
+ f = h - i;
+
+#define x2 (c * f)
+#define x1 (c * (1.0f - f))
+
+ /* faster to compare floats then int conversion */
+ if (i < 1.0f) {
+ *r = c;
+ *g = x2;
+ *b = 0;
+ }
+ else if (i < 2.0f) {
+ *r = x1;
+ *g = c;
+ *b = 0;
+ }
+ else if (i < 3.0f) {
+ *r = 0;
+ *g = c;
+ *b = x2;
+ }
+ else if (i < 4.0f) {
+ *r = 0;
+ *g = x1;
+ *b = c;
+ }
+ else if (i < 5.0f) {
+ *r = x2;
+ *g = 0;
+ *b = c;
+ }
+ else {
+ *r = c;
+ *g = 0;
+ *b = x1;
+ }
+
+#undef x1
+#undef x2
+
+ f = l - 0.5f * c;
+ *r += f;
+ *g += f;
+ *b += f;
+}
+
/* convenience function for now */
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
{
hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
}
+/* convenience function for now */
+void hsl_to_rgb_v(const float hcl[3], float r_rgb[3])
+{
+ hsl_to_rgb(hcl[0], hcl[1], hcl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
+}
+
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
{
float y, u, v;
@@ -290,7 +347,7 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
{
const float cmax = max_fff(r, g, b);
const float cmin = min_fff(r, g, b);
- float h, s, l = (cmax + cmin) / 2.0f;
+ float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f);
if (cmax == cmin) {
h = s = 0.0f; // achromatic
@@ -315,6 +372,33 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
*ll = l;
}
+void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll)
+{
+ float orig_s = *ls;
+ float orig_h = *lh;
+
+ rgb_to_hsl(r, g, b, lh, ls, ll);
+
+ if (*ll <= 0.0f) {
+ *lh = orig_h;
+ *ls = orig_s;
+ }
+ else if (*ls <= 0.0f) {
+ *lh = orig_h;
+ *ls = orig_s;
+ }
+
+ if (*lh == 0.0f && orig_h >= 1.0f) {
+ *lh = 1.0f;
+ }
+}
+
+void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
+{
+ rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
+}
+
+
/* convenience function for now */
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
{
@@ -422,29 +506,29 @@ void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
*b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
}
-void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3])
+void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
{
- col_r[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
- col_r[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
- col_r[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
+ r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
}
-void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4])
+void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
{
- col_r[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
- col_r[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
- col_r[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
- col_r[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
+ r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
+ r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
}
-void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3])
+void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
{
- F3TOCHAR3(col_f, col_r);
+ F3TOCHAR3(col_f, r_col);
}
-void rgba_float_to_uchar(unsigned char col_r[4], const float col_f[4])
+void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
{
- F4TOCHAR4(col_f, col_r);
+ F4TOCHAR4(col_f, r_col);
}
/* ********************************* color transforms ********************************* */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 3b49ad5db8d..5f3ab5eb73e 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -30,7 +30,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_strict_flags.h"
@@ -88,6 +87,27 @@ float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const flo
return normalize_v3(n);
}
+/**
+ * Computes the normal of a planar
+ * polygon See Graphics Gems for
+ * computing newell normal.
+ */
+float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+{
+ const float *v_prev = verts[nr - 1];
+ const float *v_curr = verts[0];
+ unsigned int i;
+
+ zero_v3(n);
+
+ /* Newell's Method */
+ for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
+ add_newell_cross_v3_v3v3(n, v_prev, v_curr);
+ }
+
+ return normalize_v3(n);
+}
+
/* only convex Quadrilaterals */
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
@@ -134,29 +154,15 @@ float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3]
return area;
}
-float area_poly_v3(int nr, float verts[][3], const float normal[3])
+float area_poly_v3(const float verts[][3], unsigned int nr)
{
- int a, px, py;
- const float max = axis_dominant_v3_max(&px, &py, normal);
- float area;
- float *co_curr, *co_prev;
-
- /* The Trapezium Area Rule */
- co_prev = verts[nr - 1];
- co_curr = verts[0];
- area = 0.0f;
- for (a = 0; a < nr; a++) {
- area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]);
- co_prev = co_curr;
- co_curr += 3;
- }
-
- return fabsf(0.5f * area / max);
+ float n[3];
+ return normal_poly_v3(n, verts, nr) * 0.5f;
}
-float cross_poly_v2(int nr, float verts[][2])
+float cross_poly_v2(const float verts[][2], unsigned int nr)
{
- int a;
+ unsigned int a;
float cross;
const float *co_curr, *co_prev;
@@ -173,9 +179,27 @@ float cross_poly_v2(int nr, float verts[][2])
return cross;
}
-float area_poly_v2(int nr, float verts[][2])
+float area_poly_v2(const float verts[][2], unsigned int nr)
{
- return fabsf(0.5f * cross_poly_v2(nr, verts));
+ return fabsf(0.5f * cross_poly_v2(verts, nr));
+}
+
+float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
+{
+ float a[3], b[3], c[3], c_len;
+
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v3, v1);
+ cross_v3_v3v3(c, a, b);
+
+ c_len = len_v3(c);
+
+ if (c_len > FLT_EPSILON) {
+ return dot_v3v3(a, b) / c_len;
+ }
+ else {
+ return 0.0f;
+ }
}
/********************************* Planes **********************************/
@@ -295,49 +319,49 @@ float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l
}
/* point closest to v1 on line v2-v3 in 2D */
-void closest_to_line_segment_v2(float close_r[2], const float p[2], const float l1[2], const float l2[2])
+void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
{
float lambda, cp[2];
lambda = closest_to_line_v2(cp, p, l1, l2);
if (lambda <= 0.0f)
- copy_v2_v2(close_r, l1);
+ copy_v2_v2(r_close, l1);
else if (lambda >= 1.0f)
- copy_v2_v2(close_r, l2);
+ copy_v2_v2(r_close, l2);
else
- copy_v2_v2(close_r, cp);
+ copy_v2_v2(r_close, cp);
}
/* point closest to v1 on line v2-v3 in 3D */
-void closest_to_line_segment_v3(float close_r[3], const float v1[3], const float v2[3], const float v3[3])
+void closest_to_line_segment_v3(float r_close[3], const float v1[3], const float v2[3], const float v3[3])
{
float lambda, cp[3];
lambda = closest_to_line_v3(cp, v1, v2, v3);
if (lambda <= 0.0f)
- copy_v3_v3(close_r, v2);
+ copy_v3_v3(r_close, v2);
else if (lambda >= 1.0f)
- copy_v3_v3(close_r, v3);
+ copy_v3_v3(r_close, v3);
else
- copy_v3_v3(close_r, cp);
+ copy_v3_v3(r_close, cp);
}
/**
* Find the closest point on a plane.
*
- * \param close_r Return coordinate
+ * \param r_close Return coordinate
* \param plane The plane to test against.
* \param pt The point to find the nearest of
*
* \note non-unit-length planes are supported.
*/
-void closest_to_plane_v3(float close_r[3], const float plane[4], const float pt[3])
+void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
{
const float len_sq = len_squared_v3(plane);
const float side = plane_point_side_v3(plane, pt);
- madd_v3_v3v3fl(close_r, pt, plane, -side / len_sq);
+ madd_v3_v3v3fl(r_close, pt, plane, -side / len_sq);
}
float dist_squared_to_plane_v3(const float pt[3], const float plane[4])
@@ -600,7 +624,7 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[
return -1;
}
-int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+bool isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
#define CCW(A, B, C) ((C[1] - A[1]) * (B[0] - A[0]) > (B[1]-A[1]) * (C[0]-A[0]))
@@ -637,7 +661,7 @@ int isect_line_sphere_v3(const float l1[3], const float l2[3],
l2[2] - l1[2]
};
- const float a = dot_v3v3(ldir, ldir);
+ const float a = len_squared_v3(ldir);
const float b = 2.0f *
(ldir[0] * (l1[0] - sp[0]) +
@@ -645,8 +669,8 @@ int isect_line_sphere_v3(const float l1[3], const float l2[3],
ldir[2] * (l1[2] - sp[2]));
const float c =
- dot_v3v3(sp, sp) +
- dot_v3v3(l1, l1) -
+ len_squared_v3(sp) +
+ len_squared_v3(l1) -
(2.0f * dot_v3v3(sp, l1)) -
(r * r);
@@ -853,7 +877,7 @@ bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsign
/* point in tri */
/* only single direction */
-int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
+bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
{
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
@@ -1112,7 +1136,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
{
float p[3], s[3], e1[3], e2[3], q[3];
float a, f, u, v;
- float du = 0, dv = 0;
+ float du, dv;
sub_v3_v3v3(e1, v1, v0);
sub_v3_v3v3(e2, v2, v0);
@@ -1131,20 +1155,25 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
u = f * dot_v3v3(s, p);
v = f * dot_v3v3(d, q);
- if (u < 0) du = u;
- if (u > 1) du = u - 1;
- if (v < 0) dv = v;
- if (v > 1) dv = v - 1;
if (u > 0 && v > 0 && u + v > 1) {
- float t = u + v - 1;
- du = u - t / 2;
- dv = v - t / 2;
+ float t = (u + v - 1) / 2;
+ du = u - t;
+ dv = v - t;
+ }
+ else {
+ if (u < 0) du = u;
+ else if (u > 1) du = u - 1;
+ else du = 0.0f;
+
+ if (v < 0) dv = v;
+ else if (v > 1) dv = v - 1;
+ else dv = 0.0f;
}
mul_v3_fl(e1, du);
mul_v3_fl(e2, dv);
- if (dot_v3v3(e1, e1) + dot_v3v3(e2, e2) > threshold * threshold) {
+ if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) {
return 0;
}
@@ -1243,7 +1272,7 @@ static bool getLowestRoot(const float a, const float b, const float c, const flo
if (determinant >= 0.0f) {
/* calculate the two roots: (if determinant == 0 then
* x1==x2 but lets disregard that slight optimization) */
- float sqrtD = (float)sqrt(determinant);
+ float sqrtD = sqrtf(determinant);
float r1 = (-b - sqrtD) / (2.0f * a);
float r2 = (-b + sqrtD) / (2.0f * a);
@@ -2103,59 +2132,22 @@ void fill_poly_v2i_n(
* \param r_mat The matrix to return.
* \param normal A unit length vector.
*/
-bool axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
+void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
{
- float up[3] = {0.0f, 0.0f, 1.0f};
- float axis[3];
- float angle;
-
- /* double check they are normalized */
BLI_ASSERT_UNIT_V3(normal);
- cross_v3_v3v3(axis, normal, up);
- angle = saacos(dot_v3v3(normal, up));
+ copy_v3_v3(r_mat[2], normal);
+ ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
- if (angle >= FLT_EPSILON) {
- if (len_squared_v3(axis) < FLT_EPSILON) {
- axis[0] = 0.0f;
- axis[1] = 1.0f;
- axis[2] = 0.0f;
- }
+ BLI_ASSERT_UNIT_V3(r_mat[0]);
+ BLI_ASSERT_UNIT_V3(r_mat[1]);
- axis_angle_to_mat3(r_mat, axis, angle);
- return true;
- }
- else {
- unit_m3(r_mat);
- return false;
- }
-}
-
-/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
-void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
-{
- const float xn = fabsf(axis[0]);
- const float yn = fabsf(axis[1]);
- const float zn = fabsf(axis[2]);
-
- if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
- else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
- else { *r_axis_a = 1; *r_axis_b = 2; }
-}
-
-/* same as axis_dominant_v3 but return the max value */
-float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
-{
- const float xn = fabsf(axis[0]);
- const float yn = fabsf(axis[1]);
- const float zn = fabsf(axis[2]);
+ transpose_m3(r_mat);
- if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
- else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
- else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
+ BLI_assert(!is_negative_m3(r_mat));
+ BLI_assert(fabsf(dot_m3_v3_row_z(r_mat, normal) - 1.0f) < BLI_ASSERT_UNIT_EPSILON);
}
-
/****************************** Interpolation ********************************/
static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
@@ -2164,7 +2156,7 @@ static float tri_signed_area(const float v1[3], const float v2[3], const float v
}
/* return 1 when degenerate */
-static int barycentric_weights(const float v1[3], const float v2[3], const float v3[3], const float co[3], const float n[3], float w[3])
+static bool barycentric_weights(const float v1[3], const float v2[3], const float v3[3], const float co[3], const float n[3], float w[3])
{
float wtot;
int i, j;
@@ -2206,7 +2198,7 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co
else {
/* otherwise compute barycentric interpolation weights */
float n1[3], n2[3], n[3];
- int degenerate;
+ bool degenerate;
sub_v3_v3v3(n1, v1, v3);
if (v4) {
@@ -2279,8 +2271,9 @@ bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[
return false;
}
-/* used by projection painting
- * note: using area_tri_signed_v2 means locations outside the triangle are correctly weighted */
+/**
+ * \note: using #area_tri_signed_v2 means locations outside the triangle are correctly weighted
+ */
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
float wtot;
@@ -2298,6 +2291,26 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
}
}
+/**
+ * still use 2D X,Y space but this works for verts transformed by a perspective matrix,
+ * using their 4th component as a weight
+ */
+void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
+{
+ float wtot;
+
+ w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
+ w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
+ w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
+ wtot = w[0] + w[1] + w[2];
+
+ if (wtot != 0.0f) {
+ mul_v3_fl(w, 1.0f / wtot);
+ }
+ else /* dummy values for zero area face */
+ w[0] = w[1] = w[2] = 1.0f / 3.0f;
+}
+
/* same as #barycentric_weights_v2 but works with a quad,
* note: untested for values outside the quad's bounds
* this is #interp_weights_poly_v2 expanded for quads only */
@@ -2343,7 +2356,7 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
#endif
/* inline mean_value_half_tan four times here */
- float t[4] = {
+ const float t[4] = {
MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
@@ -2380,13 +2393,12 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
{
/* this works by moving the source triangle so its normal is pointing on the Z
- * axis where its barycentric wights can be calculated in 2D and its Z offset can
+ * axis where its barycentric weights can be calculated in 2D and its Z offset can
* be re-applied. The weights are applied directly to the targets 3D points and the
* z-depth is used to scale the targets normal as an offset.
* This saves transforming the target into its Z-Up orientation and back (which could also work) */
- const float z_up[3] = {0, 0, 1};
float no_tar[3], no_src[3];
- float quat_src[4];
+ float mat_src[3][3];
float pt_src_xy[3];
float tri_xy_src[3][3];
float w_src[3];
@@ -2396,19 +2408,14 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
normal_tri_v3(no_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3);
normal_tri_v3(no_src, tri_src_p1, tri_src_p2, tri_src_p3);
- rotation_between_vecs_to_quat(quat_src, no_src, z_up);
- normalize_qt(quat_src);
-
- copy_v3_v3(pt_src_xy, pt_src);
- copy_v3_v3(tri_xy_src[0], tri_src_p1);
- copy_v3_v3(tri_xy_src[1], tri_src_p2);
- copy_v3_v3(tri_xy_src[2], tri_src_p3);
+ axis_dominant_v3_to_m3(mat_src, no_src);
/* make the source tri xy space */
- mul_qt_v3(quat_src, pt_src_xy);
- mul_qt_v3(quat_src, tri_xy_src[0]);
- mul_qt_v3(quat_src, tri_xy_src[1]);
- mul_qt_v3(quat_src, tri_xy_src[2]);
+ mul_v3_m3v3(pt_src_xy, mat_src, pt_src);
+ mul_v3_m3v3(tri_xy_src[0], mat_src, tri_src_p1);
+ mul_v3_m3v3(tri_xy_src[1], mat_src, tri_src_p2);
+ mul_v3_m3v3(tri_xy_src[2], mat_src, tri_src_p3);
+
barycentric_weights_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2], pt_src_xy, w_src);
interp_v3_v3v3v3(pt_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3, w_src);
@@ -2546,7 +2553,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
{
const float eps = 0.00001f; /* take care, low values cause [#36105] */
const float eps_sq = eps * eps;
- float *v_curr, *v_next;
+ const float *v_curr, *v_next;
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
@@ -2615,7 +2622,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
{
const float eps = 0.00001f; /* take care, low values cause [#36105] */
const float eps_sq = eps * eps;
- float *v_curr, *v_next;
+ const float *v_curr, *v_next;
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
@@ -2708,8 +2715,13 @@ void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3
#define IS_ZERO(x) ((x > (-DBL_EPSILON) && x < DBL_EPSILON) ? 1 : 0)
-/* Barycentric reverse */
-void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
+/**
+ * Barycentric reverse
+ *
+ * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2)
+ */
+void resolve_tri_uv_v2(float r_uv[2], const float st[2],
+ const float st0[2], const float st1[2], const float st2[2])
{
/* find UV such that
* t = u * t0 + v * t1 + (1 - u - v) * t2
@@ -2718,8 +2730,9 @@ void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const
const double c = st0[1] - st2[1], d = st1[1] - st2[1];
const double det = a * d - c * b;
- if (IS_ZERO(det) == 0) { /* det should never be zero since the determinant is the signed ST area of the triangle. */
- const double x[] = {st[0] - st2[0], st[1] - st2[1]};
+ /* det should never be zero since the determinant is the signed ST area of the triangle. */
+ if (IS_ZERO(det) == 0) {
+ const double x[2] = {st[0] - st2[0], st[1] - st2[1]};
r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
@@ -2729,15 +2742,51 @@ void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const
}
}
+/**
+ * Barycentric reverse 3d
+ *
+ * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2)
+ */
+void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3])
+{
+ float v0[3], v1[3], v2[3];
+ double d00, d01, d11, d20, d21, det;
+
+ sub_v3_v3v3(v0, st1, st0);
+ sub_v3_v3v3(v1, st2, st0);
+ sub_v3_v3v3(v2, st, st0);
+
+ d00 = dot_v3v3(v0, v0);
+ d01 = dot_v3v3(v0, v1);
+ d11 = dot_v3v3(v1, v1);
+ d20 = dot_v3v3(v2, v0);
+ d21 = dot_v3v3(v2, v1);
+
+ det = d00 * d11 - d01 * d01;
+
+ /* det should never be zero since the determinant is the signed ST area of the triangle. */
+ if (IS_ZERO(det) == 0) {
+ float w;
+
+ w = (float)((d00 * d21 - d01 * d20) / det);
+ r_uv[1] = (float)((d11 * d20 - d01 * d21) / det);
+ r_uv[0] = 1.0f - r_uv[1] - w;
+ }
+ else {
+ zero_v2(r_uv);
+ }
+}
+
/* bilinear reverse */
-void resolve_quad_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
+void resolve_quad_uv_v2(float r_uv[2], const float st[2],
+ const float st0[2], const float st1[2], const float st2[2], const float st3[2])
{
- resolve_quad_uv_deriv(r_uv, NULL, st, st0, st1, st2, st3);
+ resolve_quad_uv_v2_deriv(r_uv, NULL, st, st0, st1, st2, st3);
}
/* bilinear reverse with derivatives */
-void resolve_quad_uv_deriv(float r_uv[2], float r_deriv[2][2],
- const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
+void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
+ const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
{
const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) + (st1[0] * st2[1] - st1[1] * st2[0]) +
(st2[0] * st3[1] - st2[1] * st3[0]) + (st3[0] * st0[1] - st3[1] * st0[0]);
@@ -2946,9 +2995,10 @@ void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, fl
void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
{
float sine, cosine, hyp, hyp1, dx, dy, dz;
- float mat1[4][4] = MAT4_UNITY;
+ float mat1[4][4];
unit_m4(mat);
+ unit_m4(mat1);
rotate_m4(mat, 'Z', -twist);
@@ -2956,8 +3006,8 @@ void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py
dy = py - vy;
dz = pz - vz;
hyp = dx * dx + dz * dz; /* hyp squared */
- hyp1 = (float)sqrt(dy * dy + hyp);
- hyp = (float)sqrt(hyp); /* the real hyp */
+ hyp1 = sqrtf(dy * dy + hyp);
+ hyp = sqrtf(hyp); /* the real hyp */
if (hyp1 != 0.0f) { /* rotate X */
sine = -dy / hyp1;
@@ -3079,7 +3129,7 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
if (x == 0.0f && y == 0.0f) *r_u = 0.0f; /* othwise domain error */
else *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f;
- *r_v = 1.0f - (float)saacos(z / len) / (float)M_PI;
+ *r_v = 1.0f - saacos(z / len) / (float)M_PI;
}
else {
*r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
@@ -3773,7 +3823,7 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
}
/* evaluate if entire quad is a proper convex quad */
-int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
float nor[3], nor_a[3], nor_b[3], vec[4][2];
float mat[3][3];
@@ -3823,8 +3873,47 @@ int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], c
return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0);
}
-int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
/* linetests, the 2 diagonals have to instersect to be convex */
return (isect_line_line_v2(v1, v3, v2, v4) > 0);
}
+
+bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
+{
+ unsigned int sign_flag = 0;
+ unsigned int a;
+ const float *co_curr, *co_prev;
+ float dir_curr[2], dir_prev[2];
+
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+
+ sub_v2_v2v2(dir_prev, verts[nr - 2], co_prev);
+
+ for (a = 0; a < nr; a++) {
+ float cross;
+
+ sub_v2_v2v2(dir_curr, co_prev, co_curr);
+
+ cross = cross_v2v2(dir_prev, dir_curr);
+
+ if (cross < 0.0f) {
+ sign_flag |= 1;
+ }
+ else if (cross > 0.0f) {
+ sign_flag |= 2;
+ }
+
+ if (sign_flag == (1 | 2)) {
+ return false;
+ }
+
+ copy_v2_v2(dir_prev, dir_curr);
+
+ co_prev = co_curr;
+ co_curr += 2;
+ }
+
+ return true;
+}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index a5906dbdf6c..5a64ed63ecf 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -34,6 +34,9 @@
#include <string.h>
+/* A few small defines. Keep'em local! */
+#define SMALL_NUMBER 1.e-8f
+
/********************************** Polygons *********************************/
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
@@ -155,6 +158,41 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[9], const float f)
add_sh_shsh(r, r, tmp);
}
+/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
+MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
+{
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
+ else { *r_axis_a = 1; *r_axis_b = 2; }
+}
+
+/* same as axis_dominant_v3 but return the max value */
+MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
+{
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
+ else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
+}
+
+/* get the single dominant axis value, 0==X, 1==Y, 2==Z */
+MINLINE int axis_dominant_v3_single(const float vec[3])
+{
+ const float x = fabsf(vec[0]);
+ const float y = fabsf(vec[1]);
+ const float z = fabsf(vec[2]);
+ return ((x > y) ?
+ ((x > z) ? 0 : 2) :
+ ((y > z) ? 1 : 2));
+}
+
MINLINE int max_axis_v3(const float vec[3])
{
const float x = vec[0];
@@ -178,28 +216,13 @@ MINLINE int min_axis_v3(const float vec[3])
/**
* Simple method to find how many tri's we need when we already know the corner+poly count.
*
- * Formula is:
- *
- * tri = ((corner_count / poly_count) - 2) * poly_count;
- *
- * Use doubles since this is used for allocating and we
- * don't want float precision to give incorrect results.
- *
* \param poly_count The number of ngon's/tris (1-2 sided faces will give incorrect results)
* \param corner_count - also known as loops in BMesh/DNA
*/
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
{
- if (poly_count != 0) {
- const double poly_count_d = (double)poly_count;
- const double corner_count_d = (double)corner_count;
- BLI_assert(poly_count > 0);
- BLI_assert(corner_count > 0);
- return (int)((((corner_count_d / poly_count_d) - 2.0) * poly_count_d) + 0.5);
- }
- else {
- return 0;
- }
+ BLI_assert(!poly_count || corner_count > poly_count * 2);
+ return corner_count - (poly_count * 2);
}
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
@@ -207,4 +230,63 @@ MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
return dot_v3v3(co, plane) + plane[3];
}
+/* useful to calculate an even width shell, by taking the angle between 2 planes.
+ * The return value is a scale on the offset.
+ * no angle between planes is 1.0, as the angle between the 2 planes approaches 180d
+ * the distance gets very high, 180d would be inf, but this case isn't valid */
+MINLINE float shell_angle_to_dist(const float angle)
+{
+ return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
+}
+/**
+ * equivalent to ``shell_angle_to_dist(angle_normalized_v3v3(a, b))``
+ */
+MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3])
+{
+ const float angle_cos = fabsf(dot_v3v3(a, b));
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+}
+/**
+ * equivalent to ``shell_angle_to_dist(angle_normalized_v2v2(a, b))``
+ */
+MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2])
+{
+ const float angle_cos = fabsf(dot_v2v2(a, b));
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+}
+
+/**
+ * equivalent to ``shell_angle_to_dist(angle_normalized_v3v3(a, b) / 2)``
+ */
+MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3])
+{
+ float angle_cos;
+ float ab[3];
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+ add_v3_v3v3(ab, a, b);
+ angle_cos = (normalize_v3(ab) != 0.0f) ? fabsf(dot_v3v3(a, ab)) : 0.0f;
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+}
+
+/**
+ * equivalent to ``shell_angle_to_dist(angle_normalized_v2v2(a, b) / 2)``
+ */
+MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2])
+{
+ float angle_cos;
+ float ab[2];
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+ add_v2_v2v2(ab, a, b);
+ angle_cos = (normalize_v2(ab) != 0.0f) ? fabsf(dot_v2v2(a, ab)) : 0.0f;
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+}
+
+#undef SMALL_NUMBER
+
#endif /* __MATH_GEOM_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 2f5ec135aad..b915ec64d11 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -648,10 +648,10 @@ float determinant_m3_array(float m[3][3])
m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
}
-int invert_m3_ex(float m[3][3], const float epsilon)
+bool invert_m3_ex(float m[3][3], const float epsilon)
{
float tmp[3][3];
- int success;
+ bool success;
success = invert_m3_m3_ex(tmp, m, epsilon);
copy_m3_m3(m, tmp);
@@ -659,10 +659,11 @@ int invert_m3_ex(float m[3][3], const float epsilon)
return success;
}
-int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
+bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
{
float det;
- int a, b, success;
+ int a, b;
+ bool success;
BLI_assert(epsilon >= 0.0f);
@@ -685,10 +686,10 @@ int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
return success;
}
-int invert_m3(float m[3][3])
+bool invert_m3(float m[3][3])
{
float tmp[3][3];
- int success;
+ bool success;
success = invert_m3_m3(tmp, m);
copy_m3_m3(m, tmp);
@@ -696,10 +697,11 @@ int invert_m3(float m[3][3])
return success;
}
-int invert_m3_m3(float m1[3][3], float m2[3][3])
+bool invert_m3_m3(float m1[3][3], float m2[3][3])
{
float det;
- int a, b, success;
+ int a, b;
+ bool success;
/* calc adjoint */
adjoint_m3_m3(m1, m2);
@@ -721,10 +723,10 @@ int invert_m3_m3(float m1[3][3], float m2[3][3])
return success;
}
-int invert_m4(float m[4][4])
+bool invert_m4(float m[4][4])
{
float tmp[4][4];
- int success;
+ bool success;
success = invert_m4_m4(tmp, m);
copy_m4_m4(m, tmp);
@@ -735,13 +737,13 @@ int invert_m4(float m[4][4])
/*
* invertmat -
* computes the inverse of mat and puts it in inverse. Returns
- * TRUE on success (i.e. can always find a pivot) and FALSE on failure.
+ * true on success (i.e. can always find a pivot) and false on failure.
* Uses Gaussian Elimination with partial (maximal column) pivoting.
*
* Mark Segal - 1992
*/
-int invert_m4_m4(float inverse[4][4], const float mat[4][4])
+bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
{
int i, j, k;
double temp;
@@ -2299,3 +2301,23 @@ bool has_zero_axis_m4(float matrix[4][4])
len_squared_v3(matrix[1]) < FLT_EPSILON ||
len_squared_v3(matrix[2]) < FLT_EPSILON;
}
+
+void invert_m4_m4_safe(float Ainv[4][4], float A[4][4])
+{
+ if (!invert_m4_m4(Ainv, A)) {
+ float Atemp[4][4];
+
+ copy_m4_m4(Atemp, A);
+
+ /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
+ * never be in this situation, but try to invert it anyway with tweak.
+ */
+ Atemp[0][0] += 1e-8f;
+ Atemp[1][1] += 1e-8f;
+ Atemp[2][2] += 1e-8f;
+
+ if (!invert_m4_m4(Ainv, Atemp)) {
+ unit_m4(Ainv);
+ }
+ }
+}
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 0392598769f..de272b12ebd 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -400,17 +400,73 @@ float normalize_qt_qt(float r[4], const float q[4])
return normalize_qt(r);
}
+/**
+ * Calculate a rotation matrix from 2 normalized vectors.
+ */
+void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
+{
+ float axis[3];
+ /* avoid calculating the angle */
+ float angle_sin;
+ float angle_cos;
+
+ BLI_ASSERT_UNIT_V3(v1);
+ BLI_ASSERT_UNIT_V3(v2);
+
+ cross_v3_v3v3(axis, v1, v2);
+
+ angle_sin = normalize_v3(axis);
+ angle_cos = dot_v3v3(v1, v2);
+
+ if (angle_sin > FLT_EPSILON) {
+axis_calc:
+ BLI_ASSERT_UNIT_V3(axis);
+ axis_angle_normalized_to_mat3_ex(m, axis, angle_sin, angle_cos);
+ BLI_ASSERT_UNIT_M3(m);
+ }
+ else {
+ if (angle_cos > 0.0f) {
+ /* Same vectors, zero rotation... */
+ unit_m3(m);
+ }
+ else {
+ /* Colinear but opposed vectors, 180 rotation... */
+ ortho_v3_v3(axis, v1);
+ normalize_v3(axis);
+ angle_sin = 0.0f; /* sin(M_PI) */
+ angle_cos = -1.0f; /* cos(M_PI) */
+ goto axis_calc;
+ }
+ }
+}
+
/* note: expects vectors to be normalized */
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
{
float axis[3];
- float angle;
cross_v3_v3v3(axis, v1, v2);
- angle = angle_normalized_v3v3(v1, v2);
+ if (normalize_v3(axis) > FLT_EPSILON) {
+ float angle;
- axis_angle_to_quat(q, axis, angle);
+ angle = angle_normalized_v3v3(v1, v2);
+
+ axis_angle_normalized_to_quat(q, axis, angle);
+ }
+ else {
+ /* degenerate case */
+
+ if (dot_v3v3(v1, v2) > 0.0f) {
+ /* Same vectors, zero rotation... */
+ unit_qt(q);
+ }
+ else {
+ /* Colinear but opposed vectors, 180 rotation... */
+ ortho_v3_v3(axis, v1);
+ axis_angle_to_quat(q, axis, (float)M_PI);
+ }
+ }
}
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
@@ -424,8 +480,47 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
mul_qt_qtqt(q, tquat, q2);
}
+
+float angle_normalized_qt(const float q[4])
+{
+ BLI_ASSERT_UNIT_QUAT(q);
+ return 2.0f * saacos(q[0]);
+}
+
+float angle_qt(const float q[4])
+{
+ float tquat[4];
+
+ normalize_qt_qt(tquat, q);
+
+ return angle_normalized_qt(tquat);
+}
+
+float angle_normalized_qtqt(const float q1[4], const float q2[4])
+{
+ float qdelta[4];
+
+ BLI_ASSERT_UNIT_QUAT(q1);
+ BLI_ASSERT_UNIT_QUAT(q2);
+
+ rotation_between_quats_to_quat(qdelta, q1, q2);
+
+ return angle_normalized_qt(qdelta);
+}
+
+float angle_qtqt(const float q1[4], const float q2[4])
+{
+ float quat1[4], quat2[4];
+
+ normalize_qt_qt(quat1, q1);
+ normalize_qt_qt(quat2, q2);
+
+ return angle_normalized_qtqt(quat1, quat2);
+}
+
void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
{
+ const float eps = 0.0001f;
float nor[3], tvec[3];
float angle, si, co, len;
@@ -459,7 +554,7 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
nor[1] = -tvec[2];
nor[2] = tvec[1];
- if (fabsf(tvec[1]) + fabsf(tvec[2]) < 0.0001f)
+ if (fabsf(tvec[1]) + fabsf(tvec[2]) < eps)
nor[1] = 1.0f;
co = tvec[0];
@@ -469,7 +564,7 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
nor[1] = 0.0;
nor[2] = -tvec[0];
- if (fabsf(tvec[0]) + fabsf(tvec[2]) < 0.0001f)
+ if (fabsf(tvec[0]) + fabsf(tvec[2]) < eps)
nor[2] = 1.0f;
co = tvec[1];
@@ -479,7 +574,7 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
nor[1] = tvec[0];
nor[2] = 0.0;
- if (fabsf(tvec[0]) + fabsf(tvec[1]) < 0.0001f)
+ if (fabsf(tvec[0]) + fabsf(tvec[1]) < eps)
nor[0] = 1.0f;
co = tvec[2];
@@ -488,12 +583,7 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
normalize_v3(nor);
- angle = 0.5f * saacos(co);
- si = sinf(angle);
- q[0] = cosf(angle);
- q[1] = nor[0] * si;
- q[2] = nor[1] * si;
- q[3] = nor[2] * si;
+ axis_angle_normalized_to_quat(q, nor, saacos(co));
if (axis != upflag) {
float mat[3][3];
@@ -569,9 +659,42 @@ void QuatInterpolW(float *result, float quat1[4], float quat2[4], float t)
}
#endif
+/**
+ * Generic function for implementing slerp
+ * (quaternions and spherical vector coords).
+ *
+ * \param t: factor in [0..1]
+ * \param cosom: dot product from normalized vectors/quats.
+ * \param r_w: calculated weights.
+ */
+void interp_dot_slerp(const float t, const float cosom, float r_w[2])
+{
+ const float eps = 0.0001f;
+
+ BLI_assert(IN_RANGE_INCL(cosom, -1.0001f, 1.0001f));
+
+ /* within [-1..1] range, avoid aligned axis */
+ if (LIKELY(fabsf(cosom) < (1.0f - eps))) {
+ float omega, sinom;
+
+ omega = acosf(cosom);
+ sinom = sinf(omega);
+ r_w[0] = sinf((1.0f - t) * omega) / sinom;
+ r_w[1] = sinf(t * omega) / sinom;
+ }
+ else {
+ /* fallback to lerp */
+ r_w[0] = 1.0f - t;
+ r_w[1] = t;
+ }
+}
+
void interp_qt_qtqt(float result[4], const float quat1[4], const float quat2[4], const float t)
{
- float quat[4], omega, cosom, sinom, sc1, sc2;
+ float quat[4], cosom, w[2];
+
+ BLI_ASSERT_UNIT_QUAT(quat1);
+ BLI_ASSERT_UNIT_QUAT(quat2);
cosom = dot_qtqt(quat1, quat2);
@@ -584,21 +707,12 @@ void interp_qt_qtqt(float result[4], const float quat1[4], const float quat2[4],
copy_qt_qt(quat, quat1);
}
- if ((1.0f - cosom) > 0.0001f) {
- omega = acosf(cosom);
- sinom = sinf(omega);
- sc1 = sinf((1.0f - t) * omega) / sinom;
- sc2 = sinf(t * omega) / sinom;
- }
- else {
- sc1 = 1.0f - t;
- sc2 = t;
- }
+ interp_dot_slerp(t, cosom, w);
- result[0] = sc1 * quat[0] + sc2 * quat2[0];
- result[1] = sc1 * quat[1] + sc2 * quat2[1];
- result[2] = sc1 * quat[2] + sc2 * quat2[2];
- result[3] = sc1 * quat[3] + sc2 * quat2[3];
+ result[0] = w[0] * quat[0] + w[1] * quat2[0];
+ result[1] = w[0] * quat[1] + w[1] * quat2[1];
+ result[2] = w[0] * quat[2] + w[1] * quat2[2];
+ result[3] = w[0] * quat[3] + w[1] * quat2[3];
}
void add_qt_qtqt(float result[4], const float quat1[4], const float quat2[4], const float t)
@@ -663,11 +777,17 @@ void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const f
mul_qt_qtqt(quat, q1, q2);
}
-void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const float v3[3])
+/**
+ * \return the length of the normal, use to test for degenerate triangles.
+ */
+float tri_to_quat(float quat[4], const float v1[3], const float v2[3], const float v3[3])
{
float vec[3];
- normal_tri_v3(vec, v1, v2, v3);
+ float len;
+
+ len = normal_tri_v3(vec, v1, v2, v3);
tri_to_quat_ex(quat, v1, v2, v3, vec);
+ return len;
}
void print_qt(const char *str, const float q[4])
@@ -746,31 +866,51 @@ void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const s
quat_to_axis_angle(axis, angle, q);
}
-/* axis angle to 3x3 matrix - note: requires that axis is normalized */
-void axis_angle_normalized_to_mat3(float mat[3][3], const float nor[3], const float angle)
+/**
+ * axis angle to 3x3 matrix
+ *
+ * This takes the angle with sin/cos applied so we can avoid calculating it in some cases.
+ *
+ * \param axis rotation axis (must be normalized).
+ * \param co cos(angle)
+ * \param si sin(angle)
+ */
+void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3],
+ const float angle_sin, const float angle_cos)
{
- float nsi[3], co, si, ico;
+ float nsi[3], ico;
+ float n_00, n_01, n_11, n_02, n_12, n_22;
- BLI_ASSERT_UNIT_V3(nor);
+ BLI_ASSERT_UNIT_V3(axis);
/* now convert this to a 3x3 matrix */
- co = cosf(angle);
- si = sinf(angle);
- ico = (1.0f - co);
- nsi[0] = nor[0] * si;
- nsi[1] = nor[1] * si;
- nsi[2] = nor[2] * si;
+ ico = (1.0f - angle_cos);
+ nsi[0] = axis[0] * angle_sin;
+ nsi[1] = axis[1] * angle_sin;
+ nsi[2] = axis[2] * angle_sin;
+
+ n_00 = (axis[0] * axis[0]) * ico;
+ n_01 = (axis[0] * axis[1]) * ico;
+ n_11 = (axis[1] * axis[1]) * ico;
+ n_02 = (axis[0] * axis[2]) * ico;
+ n_12 = (axis[1] * axis[2]) * ico;
+ n_22 = (axis[2] * axis[2]) * ico;
+
+ mat[0][0] = n_00 + angle_cos;
+ mat[0][1] = n_01 + nsi[2];
+ mat[0][2] = n_02 - nsi[1];
+ mat[1][0] = n_01 - nsi[2];
+ mat[1][1] = n_11 + angle_cos;
+ mat[1][2] = n_12 + nsi[0];
+ mat[2][0] = n_02 + nsi[1];
+ mat[2][1] = n_12 - nsi[0];
+ mat[2][2] = n_22 + angle_cos;
+}
- mat[0][0] = ((nor[0] * nor[0]) * ico) + co;
- mat[0][1] = ((nor[0] * nor[1]) * ico) + nsi[2];
- mat[0][2] = ((nor[0] * nor[2]) * ico) - nsi[1];
- mat[1][0] = ((nor[0] * nor[1]) * ico) - nsi[2];
- mat[1][1] = ((nor[1] * nor[1]) * ico) + co;
- mat[1][2] = ((nor[1] * nor[2]) * ico) + nsi[0];
- mat[2][0] = ((nor[0] * nor[2]) * ico) + nsi[1];
- mat[2][1] = ((nor[1] * nor[2]) * ico) - nsi[0];
- mat[2][2] = ((nor[2] * nor[2]) * ico) + co;
+void axis_angle_normalized_to_mat3(float mat[3][3], const float axis[3], const float angle)
+{
+ axis_angle_normalized_to_mat3_ex(mat, axis, sinf(angle), cosf(angle));
}
@@ -951,7 +1091,7 @@ static void mat3_to_eul2(float tmat[3][3], float eul1[3], float eul2[3])
copy_m3_m3(mat, tmat);
normalize_m3(mat);
- cy = (float)sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1]);
+ cy = sqrtf(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1]);
if (cy > 16.0f * FLT_EPSILON) {
@@ -1296,11 +1436,15 @@ void eulO_to_mat4(float M[4][4], const float e[3], const short order)
void mat3_to_eulO(float eul[3], const short order, float M[3][3])
{
float eul1[3], eul2[3];
+ float d1, d2;
mat3_to_eulo2(M, eul1, eul2, order);
+ d1 = fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]);
+ d2 = fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2]);
+
/* return best, which is just the one with lowest values it in */
- if (fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]) > fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2])) {
+ if (d1 > d2) {
copy_v3_v3(eul, eul2);
}
else {
@@ -1334,10 +1478,12 @@ void mat3_to_compatible_eulO(float eul[3], float oldrot[3], const short order, f
d2 = fabsf(eul2[0] - oldrot[0]) + fabsf(eul2[1] - oldrot[1]) + fabsf(eul2[2] - oldrot[2]);
/* return best, which is just the one with lowest difference */
- if (d1 > d2)
+ if (d1 > d2) {
copy_v3_v3(eul, eul2);
- else
+ }
+ else {
copy_v3_v3(eul, eul1);
+ }
}
void mat4_to_compatible_eulO(float eul[3], float oldrot[3], const short order, float M[4][4])
@@ -1358,7 +1504,8 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang)
assert(axis >= 'X' && axis <= 'Z');
- eul[0] = eul[1] = eul[2] = 0.0f;
+ zero_v3(eul);
+
if (axis == 'X')
eul[0] = ang;
else if (axis == 'Y')
@@ -1394,9 +1541,7 @@ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order
/* Last axis is global */
- gmat[R->axis[2]][0] = 0;
- gmat[R->axis[2]][1] = 0;
- gmat[R->axis[2]][2] = 0;
+ zero_v3(gmat[R->axis[2]]);
gmat[R->axis[2]][R->axis[2]] = 1;
}
@@ -1516,7 +1661,7 @@ void dquat_to_mat4(float mat[4][4], const DualQuat *dq)
void add_weighted_dq_dq(DualQuat *dqsum, const DualQuat *dq, float weight)
{
- int flipped = 0;
+ bool flipped = false;
/* make sure we interpolate quats in the right direction */
if (dot_qtqt(dq->quat, dqsum->quat) < 0) {
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 098272c9bc0..7d3829f04d3 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -68,6 +68,103 @@ void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const f
target[3] = s * a[3] + t * b[3];
}
+/**
+ * slerp, treat vectors as spherical coordinates
+ * \see #interp_qt_qtqt
+ *
+ * \return success
+ */
+bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t)
+{
+ float cosom, w[2];
+
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+
+ cosom = dot_v3v3(a, b);
+
+ /* direct opposites */
+ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
+ return false;
+ }
+
+ interp_dot_slerp(t, cosom, w);
+
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
+ target[2] = w[0] * a[2] + w[1] * b[2];
+
+ return true;
+}
+bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], const float t)
+{
+ float cosom, w[2];
+
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+
+ cosom = dot_v2v2(a, b);
+
+ /* direct opposites */
+ if (UNLIKELY(cosom < (1.0f + FLT_EPSILON))) {
+ return false;
+ }
+
+ interp_dot_slerp(t, cosom, w);
+
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
+
+ return true;
+}
+
+/**
+ * Same as #interp_v3_v3v3_slerp buy uses fallback values
+ * for opposite vectors.
+ */
+void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
+{
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[3];
+ ortho_v3_v3(ab_ortho, a);
+ normalize_v3(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, b);
+ }
+ }
+ }
+}
+void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[2], const float t)
+{
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[2];
+ ortho_v2_v2(ab_ortho, a);
+ // normalize_v2(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, b);
+ }
+ }
+ }
+}
+
/* weight 3 vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
@@ -471,49 +568,92 @@ void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const
normalize_v3(out);
}
-/* Returns a reflection vector from a vector and a normal vector
+/**
+ * Returns a reflection vector from a vector and a normal vector
* reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
*/
-void reflect_v3_v3v3(float out[3], const float v1[3], const float v2[3])
+void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3])
{
- float vec[3], normal[3];
- float reflect[3] = {0.0f, 0.0f, 0.0f};
- float dot2;
-
- copy_v3_v3(vec, v1);
- copy_v3_v3(normal, v2);
+ const float dot2 = 2.0f * dot_v3v3(vec, normal);
- dot2 = 2 * dot_v3v3(vec, normal);
+ BLI_ASSERT_UNIT_V3(normal);
- reflect[0] = vec[0] - (dot2 * normal[0]);
- reflect[1] = vec[1] - (dot2 * normal[1]);
- reflect[2] = vec[2] - (dot2 * normal[2]);
-
- copy_v3_v3(out, reflect);
+ out[0] = vec[0] - (dot2 * normal[0]);
+ out[1] = vec[1] - (dot2 * normal[1]);
+ out[2] = vec[2] - (dot2 * normal[2]);
}
-void ortho_basis_v3v3_v3(float v1[3], float v2[3], const float v[3])
+/**
+ * Takes a vector and computes 2 orthogonal directions.
+ *
+ * \note if \a n is n unit length, computed values will be too.
+ */
+void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
{
- const float f = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
+ const float eps = FLT_EPSILON;
+ const float f = len_squared_v2(n);
- if (f < 1e-35f) {
- // degenerate case
- v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f;
- v1[1] = v1[2] = v2[0] = v2[2] = 0.0f;
- v2[1] = 1.0f;
+ if (f > eps) {
+ const float d = 1.0f / sqrtf(f);
+
+ BLI_assert(finite(d));
+
+ r_n1[0] = n[1] * d;
+ r_n1[1] = -n[0] * d;
+ r_n1[2] = 0.0f;
+ r_n2[0] = -n[2] * r_n1[1];
+ r_n2[1] = n[2] * r_n1[0];
+ r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
}
else {
- const float d = 1.0f / f;
+ /* degenerate case */
+ r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
+ r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
+ r_n2[1] = 1.0f;
+ }
+}
+
+/**
+ * Calculates \a p - a perpendicular vector to \a v
+ *
+ * \note return vector won't maintain same length.
+ */
+void ortho_v3_v3(float p[3], const float v[3])
+{
+ const int axis = axis_dominant_v3_single(v);
- v1[0] = v[1] * d;
- v1[1] = -v[0] * d;
- v1[2] = 0.0f;
- v2[0] = -v[2] * v1[1];
- v2[1] = v[2] * v1[0];
- v2[2] = v[0] * v1[1] - v[1] * v1[0];
+ BLI_assert(p != v);
+
+ switch (axis) {
+ case 0:
+ p[0] = -v[1] - v[2];
+ p[1] = v[0];
+ p[2] = v[0];
+ break;
+ case 1:
+ p[0] = v[1];
+ p[1] = -v[0] - v[2];
+ p[2] = v[1];
+ break;
+ case 2:
+ p[0] = v[2];
+ p[1] = v[2];
+ p[2] = -v[0] - v[1];
+ break;
}
}
+/**
+ * no brainer compared to v3, just have for consistency.
+ */
+void ortho_v2_v2(float p[3], const float v[3])
+{
+ BLI_assert(p != v);
+
+ p[0] = -v[1];
+ p[1] = v[0];
+}
+
/* Rotate a point p by angle theta around an arbitrary axis r
* http://local.wasp.uwa.edu.au/~pbourke/geometry/
*/
@@ -641,6 +781,11 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
/***************************** Array Functions *******************************/
+MINLINE double sqr_db(double f)
+{
+ return f * f;
+}
+
double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size)
{
double d = 0.0f;
@@ -653,9 +798,20 @@ double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int s
return d;
}
+double len_squared_vn(const float *array, const int size)
+{
+ double d = 0.0f;
+ const float *array_pt = array + (size - 1);
+ int i = size;
+ while (i--) {
+ d += sqr_db((double)(*(array_pt--)));
+ }
+ return d;
+}
+
float normalize_vn_vn(float *array_tar, const float *array_src, const int size)
{
- double d = dot_vn_vn(array_tar, array_src, size);
+ double d = len_squared_vn(array_src, size);
float d_sqrt;
if (d > 1.0e-35) {
d_sqrt = (float)sqrt(d);
@@ -836,6 +992,15 @@ void fill_vn_i(int *array_tar, const int size, const int val)
}
}
+void fill_vn_short(short *array_tar, const int size, const short val)
+{
+ short *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
+}
+
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val)
{
unsigned short *tar = array_tar + (size - 1);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 00e9eb01c8d..2639767fcb1 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -445,6 +445,31 @@ MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
r[3] = a[3] * f;
}
+/**
+ * Avoid doing:
+ *
+ * angle = atan2f(dvec[0], dvec[1]);
+ * angle_to_mat2(mat, angle);
+ *
+ * instead use a vector as a matrix.
+ */
+
+MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2])
+{
+ BLI_assert(r != vec);
+
+ r[0] = mat[0] * vec[0] + (+mat[1]) * vec[1];
+ r[1] = mat[1] * vec[0] + (-mat[0]) * vec[1];
+}
+
+MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
+{
+ BLI_assert(r != vec);
+
+ r[0] = mat[0] * vec[0] + (-mat[1]) * vec[1];
+ r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
+}
+
/* note: could add a matrix inline */
MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
{
@@ -689,6 +714,15 @@ MINLINE float len_v2v2(const float v1[2], const float v2[2])
return sqrtf(x * x + y * y);
}
+MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
+{
+ float x, y;
+
+ x = (float)(v1[0] - v2[0]);
+ y = (float)(v1[1] - v2[1]);
+ return sqrtf(x * x + y * y);
+}
+
MINLINE float len_v3(const float a[3])
{
return sqrtf(dot_v3v3(a, a));
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 5b9fefe77bb..f002ea54b32 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -30,12 +30,6 @@
* \ingroup bli
*/
-
-#ifdef _MSC_VER
-# pragma warning (disable:4244) /* "conversion from double to float" */
-# pragma warning (disable:4305) /* "truncation from const double to float" */
-#endif
-
#include <math.h>
#include "BLI_noise.h"
@@ -1413,7 +1407,7 @@ float cellNoise(float x, float y, float z)
}
/* returns a vector/point/color in ca, using point hasharray directly */
-void cellNoiseV(float x, float y, float z, float *ca)
+void cellNoiseV(float x, float y, float z, float ca[3])
{
int xi = (int)(floor(x));
int yi = (int)(floor(y));
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index ca8a6ad4f97..6ae6e55b9a0 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -31,14 +31,11 @@
* \ingroup bli
*/
-
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_listBase.h"
#include "BLI_utildefines.h"
@@ -53,6 +50,8 @@
#include "GHOST_Path-api.h"
#ifdef WIN32
+# include "MEM_guardedalloc.h"
+
# include "utf_winfunc.h"
# include "utfconv.h"
# include <io.h>
@@ -331,7 +330,7 @@ void BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim
BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
}
-
+static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
/* ******************** string encoding ***************** */
@@ -396,7 +395,9 @@ void BLI_cleanup_path(const char *relabase, char *path)
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(path, "\\\\")) ) {
+ /* remove two consecutive backslashes, but skip the UNC prefix,
+ * which needs to be preserved */
+ while ( (start = strstr(path + BLI_path_unc_prefix_len(path), "\\\\")) ) {
eind = start + strlen("\\\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
@@ -465,6 +466,110 @@ bool BLI_path_is_rel(const char *path)
return path[0] == '/' && path[1] == '/';
}
+/* return true if the path is a UNC share */
+bool BLI_path_is_unc(const char *name)
+{
+ return name[0] == '\\' && name[1] == '\\';
+}
+
+/**
+ * Returns the length of the identifying prefix
+ * of a UNC path which can start with '\\' (short version)
+ * or '\\?\' (long version)
+ * If the path is not a UNC path, return 0
+ *
+ * \param name the path name
+ */
+static int BLI_path_unc_prefix_len(const char *path)
+{
+ if (BLI_path_is_unc(path)) {
+ if ((path[2] == '?') && (path[3] == '\\') ) {
+ /* we assume long UNC path like \\?\server\share\folder etc... */
+ return 4;
+ }
+ else {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+#if defined(WIN32)
+
+/* return true if the path is absolute ie starts with a drive specifier (eg A:\) or is a UNC path */
+static bool BLI_path_is_abs(const char *name)
+{
+ return (name[1] == ':' && (name[2] == '\\' || name[2] == '/') ) || BLI_path_is_unc(name);
+}
+
+static wchar_t *next_slash(wchar_t *path)
+{
+ wchar_t *slash = path;
+ while (*slash && *slash != L'\\') slash++;
+ return slash;
+}
+
+/* adds a slash if the unc path points sto a share */
+static void BLI_path_add_slash_to_share(wchar_t *uncpath)
+{
+ wchar_t *slash_after_server = next_slash(uncpath + 2);
+ if (*slash_after_server) {
+ wchar_t *slash_after_share = next_slash(slash_after_server + 1);
+ if (!(*slash_after_share)) {
+ slash_after_share[0] = L'\\';
+ slash_after_share[1] = L'\0';
+ }
+ }
+}
+
+static void BLI_path_unc_to_short(wchar_t *unc)
+{
+ wchar_t tmp[PATH_MAX];
+
+ int len = wcslen(unc);
+ int copy_start = 0;
+ /* convert:
+ * \\?\UNC\server\share\folder\... to \\server\share\folder\...
+ * \\?\C:\ to C:\ and \\?\C:\folder\... to C:\folder\...
+ */
+ if ((len > 3) &&
+ (unc[0] == L'\\') &&
+ (unc[1] == L'\\') &&
+ (unc[2] == L'?') &&
+ ((unc[3] == L'\\') || (unc[3] == L'/')))
+ {
+ if ((len > 5) && (unc[5] == L':')) {
+ wcsncpy(tmp, unc + 4, len - 4);
+ tmp[len - 4] = L'\0';
+ wcscpy(unc, tmp);
+ }
+ else if ((len > 7) && (wcsncmp(&unc[4], L"UNC", 3) == 0) &&
+ ((unc[7] == L'\\') || (unc[7] == L'/')))
+ {
+ tmp[0] = L'\\';
+ tmp[1] = L'\\';
+ wcsncpy(tmp + 2, unc + 8, len - 8);
+ tmp[len - 6] = L'\0';
+ wcscpy(unc, tmp);
+ }
+ }
+}
+
+void BLI_cleanup_unc(char *path, int maxlen)
+{
+ wchar_t *tmp_16 = alloc_utf16_from_8(path, 1);
+ BLI_cleanup_unc_16(tmp_16);
+ conv_utf_16_to_8(tmp_16, path, maxlen);
+}
+
+void BLI_cleanup_unc_16(wchar_t *path_16)
+{
+ BLI_path_unc_to_short(path_16);
+ BLI_path_add_slash_to_share(path_16);
+}
+#endif
+
/**
* Replaces *file with a relative version (prefixed by "//") such that BLI_path_abs, given
* the same *relfile, will convert it back to its original value.
@@ -486,7 +591,7 @@ void BLI_path_rel(char *file, const char *relfile)
}
#ifdef WIN32
- if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') {
+ if (BLI_strnlen(relfile, 3) > 2 && !BLI_path_is_abs(relfile)) {
char *ptemp;
/* fix missing volume name in relative base,
* can happen with old recent-files.txt files */
@@ -502,15 +607,35 @@ void BLI_path_rel(char *file, const char *relfile)
}
if (BLI_strnlen(file, 3) > 2) {
- if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0])
+ bool is_unc = BLI_path_is_unc(file);
+
+ /* Ensure paths are both UNC paths or are both drives */
+ if (BLI_path_is_unc(temp) != is_unc) {
+ return;
+ }
+
+ /* Ensure both UNC paths are on the same share */
+ if (is_unc) {
+ int off;
+ int slash = 0;
+ for (off = 0; temp[off] && slash < 4; off++) {
+ if (temp[off] != file[off])
+ return;
+
+ if (temp[off] == '\\')
+ slash++;
+ }
+ }
+ else if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) {
return;
+ }
}
#else
BLI_strncpy(temp, relfile, FILE_MAX);
#endif
- BLI_char_switch(temp, '\\', '/');
- BLI_char_switch(file, '\\', '/');
+ BLI_char_switch(temp + BLI_path_unc_prefix_len(temp), '\\', '/');
+ BLI_char_switch(file + BLI_path_unc_prefix_len(file), '\\', '/');
/* remove /./ which confuse the following slash counting... */
BLI_cleanup_path(NULL, file);
@@ -522,8 +647,8 @@ void BLI_path_rel(char *file, const char *relfile)
if (lslash) {
/* find the prefix of the filename that is equal for both filenames.
* This is replaced by the two slashes at the beginning */
- char *p = temp;
- char *q = file;
+ const char *p = temp;
+ const char *q = file;
char *r = res;
#ifdef WIN32
@@ -578,6 +703,48 @@ void BLI_path_rel(char *file, const char *relfile)
}
/**
+ * Appends a suffix to the string, fitting it before the extension
+ *
+ * string = Foo.png, suffix = 123, separator = _
+ * Foo.png -> Foo_123.png
+ *
+ * \param string original (and final) string
+ * \param maxlen Maximum length of string
+ * \param suffix String to append to the original string
+ * \param sep Optional separator character
+ * \return true if succeeded
+ */
+bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep)
+{
+ const size_t string_len = strlen(string);
+ const size_t suffix_len = strlen(suffix);
+ const size_t sep_len = strlen(sep);
+ ssize_t a;
+ char extension[FILE_MAX];
+ bool has_extension = false;
+
+ if (string_len + sep_len + suffix_len >= maxlen)
+ return false;
+
+ for (a = string_len - 1; a >= 0; a--) {
+ if (string[a] == '.') {
+ has_extension = true;
+ break;
+ }
+ else if (ELEM(string[a], '/', '\\')) {
+ break;
+ }
+ }
+
+ if (!has_extension)
+ a = string_len;
+
+ BLI_strncpy(extension, string + a, sizeof(extension));
+ sprintf(string + a, "%s%s%s", sep, suffix, extension);
+ return true;
+}
+
+/**
* Replaces path with the path of its parent directory, returning true if
* it was able to find a parent directory within the pathname.
*/
@@ -729,7 +896,7 @@ bool BLI_path_abs(char *path, const char *basepath)
* blend file as a lib main - we are basically checking for the case that a
* UNIX root '/' is passed.
*/
- if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) {
+ if (!wasrelative && !BLI_path_is_abs(path)) {
char *p = path;
get_default_root(tmp);
// get rid of the slashes at the beginning of the path
@@ -759,24 +926,28 @@ bool BLI_path_abs(char *path, const char *basepath)
#endif
- BLI_strncpy(base, basepath, sizeof(base));
-
- /* file component is ignored, so don't bother with the trailing slash */
- BLI_cleanup_path(NULL, base);
-
/* push slashes into unix mode - strings entering this part are
* potentially messed up: having both back- and forward slashes.
* Here we push into one conform direction, and at the end we
* push them into the system specific dir. This ensures uniformity
* of paths and solving some problems (and prevent potential future
- * ones) -jesterKing. */
- BLI_char_switch(tmp, '\\', '/');
- BLI_char_switch(base, '\\', '/');
+ * ones) -jesterKing.
+ * For UNC paths the first characters containing the UNC prefix
+ * shouldn't be switched as we need to distinguish them from
+ * paths relative to the .blend file -elubie */
+ BLI_char_switch(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/');
/* Paths starting with // will get the blend file as their base,
* this isn't standard in any os but is used in blender all over the place */
if (wasrelative) {
- const char * const lslash = BLI_last_slash(base);
+ const char *lslash;
+ BLI_strncpy(base, basepath, sizeof(base));
+
+ /* file component is ignored, so don't bother with the trailing slash */
+ BLI_cleanup_path(NULL, base);
+ lslash = BLI_last_slash(base);
+ BLI_char_switch(base + BLI_path_unc_prefix_len(base), '\\', '/');
+
if (lslash) {
const int baselen = (int) (lslash - base) + 1; /* length up to and including last "/" */
/* use path for temp storage here, we copy back over it right away */
@@ -825,7 +996,7 @@ bool BLI_path_cwd(char *path)
const int filelen = strlen(path);
#ifdef WIN32
- if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
+ if ((filelen >= 3 && BLI_path_is_abs(path)) || BLI_path_is_unc(path))
wasrelative = false;
#else
if (filelen >= 2 && path[0] == '/')
@@ -1371,7 +1542,7 @@ void BLI_clean(char *path)
BLI_char_switch(path + 2, '/', '\\');
}
#else
- BLI_char_switch(path, '\\', '/');
+ BLI_char_switch(path + BLI_path_unc_prefix_len(path), '\\', '/');
#endif
}
@@ -1488,9 +1659,12 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir, c
BLI_strncpy(string, dir, 3);
dir += 2;
}
+ else if (BLI_strnlen(dir, 3) >= 2 && BLI_path_is_unc(dir)) {
+ string[0] = 0;
+ }
else { /* no drive specified */
/* first option: get the drive from the relabase if it has one */
- if (relabase && strlen(relabase) >= 2 && relabase[1] == ':') {
+ if (relabase && BLI_strnlen(relabase, 3) >= 2 && relabase[1] == ':') {
BLI_strncpy(string, relabase, 3);
string[2] = '\\';
string[3] = '\0';
@@ -1592,7 +1766,7 @@ bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
char pattern[16];
while (ext_step[0]) {
- char *ext_next;
+ const char *ext_next;
int len_ext;
if ((ext_next = strchr(ext_step, ';'))) {
@@ -1926,8 +2100,8 @@ int BLI_rebase_path(char *abs, size_t abs_len,
*/
const char *BLI_first_slash(const char *string)
{
- char * const ffslash = strchr(string, '/');
- char * const fbslash = strchr(string, '\\');
+ const char * const ffslash = strchr(string, '/');
+ const char * const fbslash = strchr(string, '\\');
if (!ffslash) return fbslash;
else if (!fbslash) return ffslash;
@@ -2070,7 +2244,7 @@ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name
if (GetModuleFileNameW(0, fullname_16, maxlen)) {
conv_utf_16_to_8(fullname_16, fullname, maxlen);
if (!BLI_exists(fullname)) {
- printf("path can't be found: \"%.*s\"\n", maxlen, fullname);
+ printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname);
MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK);
}
MEM_freeN(fullname_16);
diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill2d.c
index 9168d2f3228..6dff597c530 100644
--- a/source/blender/blenlib/intern/polyfill2d.c
+++ b/source/blender/blenlib/intern/polyfill2d.c
@@ -368,11 +368,11 @@ static unsigned int pf_index_next(const PolyFill *pf, unsigned index)
}
/**
-* Triangulates the given (convex or concave) simple polygon to a list of triangle vertices.
-* \param vertices pairs describing vertices of the polygon, in either clockwise or counterclockwise order.
-* \return triples of triangle indices in clockwise order.
-* Note the returned array is reused for later calls to the same method.
-*/
+ * Triangulates the given (convex or concave) simple polygon to a list of triangle vertices.
+ * \param vertices pairs describing vertices of the polygon, in either clockwise or counterclockwise order.
+ * \return triples of triangle indices in clockwise order.
+ * Note the returned array is reused for later calls to the same method.
+ */
void BLI_polyfill_calc_ex(
const float (*coords)[2],
const unsigned int coords_tot,
@@ -400,7 +400,7 @@ void BLI_polyfill_calc_ex(
pf.tris_tot = 0;
if ((coords_tot < 3) ||
- cross_poly_v2((int)coords_tot, (float(*)[2])coords) > 0.0f)
+ cross_poly_v2(coords, coords_tot) > 0.0f)
{
for (i = 0; i < coords_tot; i++) {
indices[i] = i;
diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c
index 8c831bdada0..814d05ca80e 100644
--- a/source/blender/blenlib/intern/quadric.c
+++ b/source/blender/blenlib/intern/quadric.c
@@ -109,7 +109,7 @@ float BLI_quadric_evaluate(const Quadric *q, const float v[3])
q->d2);
}
-int BLI_quadric_optimize(const Quadric *q, float v[3], const float epsilon)
+bool BLI_quadric_optimize(const Quadric *q, float v[3], const float epsilon)
{
float m[3][3];
@@ -120,9 +120,9 @@ int BLI_quadric_optimize(const Quadric *q, float v[3], const float epsilon)
mul_m3_v3(m, v);
negate_v3(v);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index c5b58e5a61b..5d78608e70c 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "MEM_guardedalloc.h"
@@ -39,29 +40,24 @@
#include "BLI_threads.h"
#include "BLI_rand.h"
+#include "BLI_math.h"
-#ifdef _MSC_VER
-typedef unsigned __int64 r_uint64;
-
-#define MULTIPLIER 0x5DEECE66Di64
-#define MASK 0x0000FFFFFFFFFFFFi64
-#else
-typedef unsigned long long r_uint64;
+#include "BLI_sys_types.h"
+#include "BLI_strict_flags.h"
#define MULTIPLIER 0x5DEECE66Dll
#define MASK 0x0000FFFFFFFFFFFFll
-#endif
#define ADDEND 0xB
-
#define LOWSEED 0x330E
extern unsigned char hash[]; // noise.c
-/***/
-
+/**
+ * Random Number Generator.
+ */
struct RNG {
- r_uint64 X;
+ uint64_t X;
};
RNG *BLI_rng_new(unsigned int seed)
@@ -89,15 +85,15 @@ void BLI_rng_free(RNG *rng)
void BLI_rng_seed(RNG *rng, unsigned int seed)
{
- rng->X = (((r_uint64) seed) << 16) | LOWSEED;
+ rng->X = (((uint64_t) seed) << 16) | LOWSEED;
}
void BLI_rng_srandom(RNG *rng, unsigned int seed)
{
BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_int(rng);
+ seed = BLI_rng_get_uint(rng);
BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_int(rng);
+ seed = BLI_rng_get_uint(rng);
BLI_rng_seed(rng, seed + hash[seed & 255]);
}
@@ -107,6 +103,12 @@ int BLI_rng_get_int(RNG *rng)
return (int) (rng->X >> 17);
}
+unsigned int BLI_rng_get_uint(RNG *rng)
+{
+ rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
+ return (unsigned int) (rng->X >> 17);
+}
+
double BLI_rng_get_double(RNG *rng)
{
return (double) BLI_rng_get_int(rng) / 0x80000000;
@@ -117,27 +119,41 @@ float BLI_rng_get_float(RNG *rng)
return (float) BLI_rng_get_int(rng) / 0x80000000;
}
-void BLI_rng_shuffle_array(RNG *rng, void *data, int elemSize, int numElems)
+void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
{
- int i = numElems;
+ float r;
+ v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
+ if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
+ float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
+ r = sqrtf(r);
+ v[0] = r * cosf(a);
+ v[1] = r * sinf(a);
+ }
+ else {
+ v[2] = 1.0f;
+ }
+}
+
+void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
+{
+ const size_t elem_size = (unsigned int)elem_size_i;
+ unsigned int i = elem_tot;
void *temp;
- if (numElems <= 0) {
+ if (elem_tot <= 1) {
return;
}
- temp = malloc(elemSize);
+ temp = malloc(elem_size);
- /* XXX Shouldn't it rather be "while (i--) {" ?
- * Else we have no guaranty first (0) element has a chance to be shuffled... --mont29 */
- while (--i) {
- int j = BLI_rng_get_int(rng) % numElems;
+ while (i--) {
+ unsigned int j = BLI_rng_get_uint(rng) % elem_tot;
if (i != j) {
- void *iElem = (unsigned char *)data + i * elemSize;
- void *jElem = (unsigned char *)data + j * elemSize;
- memcpy(temp, iElem, elemSize);
- memcpy(iElem, jElem, elemSize);
- memcpy(jElem, temp, elemSize);
+ void *iElem = (unsigned char *)data + i * elem_size_i;
+ void *jElem = (unsigned char *)data + j * elem_size_i;
+ memcpy(temp, iElem, elem_size);
+ memcpy(iElem, jElem, elem_size);
+ memcpy(jElem, temp, elem_size);
}
}
@@ -173,6 +189,11 @@ float BLI_frand(void)
return BLI_rng_get_float(&theBLI_rng);
}
+void BLI_frand_unit_v3(float v[3])
+{
+ BLI_rng_get_float_unit_v3(&theBLI_rng, v);
+}
+
float BLI_hash_frand(unsigned int seed)
{
RNG rng;
@@ -181,12 +202,12 @@ float BLI_hash_frand(unsigned int seed)
return BLI_rng_get_float(&rng);
}
-void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int seed)
+void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_tot, unsigned int seed)
{
RNG rng;
BLI_rng_seed(&rng, seed);
- BLI_rng_shuffle_array(&rng, data, elemSize, numElems);
+ BLI_rng_shuffle_array(&rng, data, elem_size, elem_tot);
}
/* ********* for threaded random ************** */
@@ -199,9 +220,9 @@ void BLI_thread_srandom(int thread, unsigned int seed)
thread = 0;
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
- seed = BLI_rng_get_int(&rng_tab[thread]);
+ seed = BLI_rng_get_uint(&rng_tab[thread]);
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
- seed = BLI_rng_get_int(&rng_tab[thread]);
+ seed = BLI_rng_get_uint(&rng_tab[thread]);
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 51bd9eee0a6..61e5783cd3e 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -347,6 +347,16 @@ void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2])
if (xy[1] > rect->ymax) rect->ymax = xy[1];
}
+/* given 2 rectangles - transform a point from one to another */
+void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2])
+{
+ xy_dst[0] = ((xy_src[0] - src->xmin) / (src->xmax - src->xmin));
+ xy_dst[0] = dst->xmin + ((dst->xmax - dst->xmin) * xy_dst[0]);
+
+ xy_dst[1] = ((xy_src[1] - src->ymin) / (src->ymax - src->ymin));
+ xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
+}
+
void BLI_rcti_translate(rcti *rect, int x, int y)
{
rect->xmin += x;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 0610414b710..05e4984d9a3 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -42,10 +42,11 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
-#include "BLI_strict_flags.h"
#include "BLI_scanfill.h" /* own include */
+#include "BLI_strict_flags.h"
+
/* local types */
typedef struct PolyFill {
unsigned int edges, verts;
@@ -864,7 +865,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* Newell's Method */
/* Similar code used elsewhere, but this checks for double ups
* which historically this function supports so better not change */
- float *v_prev;
+ const float *v_prev;
zero_v3(n);
eve = sf_ctx->fillvertbase.last;
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index a6477d45054..828cb3a580b 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -35,22 +35,17 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_strict_flags.h"
#include "BLI_ghash.h"
#include "BLI_scanfill.h" /* own include */
+#include "BLI_strict_flags.h"
typedef struct PolyInfo {
ScanFillEdge *edge_first, *edge_last;
ScanFillVert *vert_outer;
} PolyInfo;
-typedef struct PolySort {
- float area;
- unsigned short poly_nr;
-} PolySort;
-
typedef struct ScanFillIsect {
struct ScanFillIsect *next, *prev;
float co[3];
@@ -166,14 +161,14 @@ static ScanFillEdge *edge_step(PolyInfo *poly_info,
eed = (e_curr->next && e_curr != poly_info[poly_nr].edge_last) ? e_curr->next : poly_info[poly_nr].edge_first;
if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
- (v_prev == eed->v1 || v_prev == eed->v2) == false)
+ (v_prev == eed->v1 || v_prev == eed->v2) == false)
{
return eed;
}
eed = (e_curr->prev && e_curr != poly_info[poly_nr].edge_first) ? e_curr->prev : poly_info[poly_nr].edge_last;
if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
- (v_prev == eed->v1 || v_prev == eed->v2) == false)
+ (v_prev == eed->v1 || v_prev == eed->v2) == false)
{
return eed;
}
@@ -258,6 +253,12 @@ static bool scanfill_preprocess_self_isect(
LinkData *isect_link;
+ if (UNLIKELY(e_ls == NULL)) {
+ /* only happens in very rare cases (entirely overlapping splines).
+ * in this case se can't do much useful. but at least don't crash */
+ continue;
+ }
+
/* maintain coorect terminating edge */
if (pi->edge_last == eed) {
pi->edge_last = NULL;
@@ -318,7 +319,7 @@ static bool scanfill_preprocess_self_isect(
ScanFillVert *v_prev;
ScanFillVert *v_curr;
- int inside = false;
+ bool inside = false;
/* first vert */
#if 0
@@ -404,7 +405,13 @@ bool BLI_scanfill_calc_self_isect(
int totvert_new = 0;
bool changed = false;
- PolyInfo *poly_info = MEM_callocN(sizeof(*poly_info) * poly_tot, __func__);
+ PolyInfo *poly_info;
+
+ if (UNLIKELY(sf_ctx->poly_nr == SF_POLY_UNSET)) {
+ return false;
+ }
+
+ poly_info = MEM_callocN(sizeof(*poly_info) * poly_tot, __func__);
/* get the polygon span */
if (sf_ctx->poly_nr == 0) {
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 9177b2fae36..d6b2383bd47 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -55,7 +55,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
#include "BLI_smallhash.h"
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index edbce13ce84..cd79518cf87 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -361,7 +361,7 @@ static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
BLI_strncpy(file->owner, pwuser->pw_name, sizeof(file->owner));
}
else {
- BLI_snprintf(file->owner, sizeof(file->owner), "%d", file->s.st_uid);
+ BLI_snprintf(file->owner, sizeof(file->owner), "%u", file->s.st_uid);
}
}
#endif
@@ -478,16 +478,29 @@ int BLI_exists(const char *name)
#else
struct _stati64 st;
#endif
- /* in Windows stat doesn't recognize dir ending on a slash
- * To not break code where the ending slash is expected we
- * don't mess with the argument name directly here - elubie */
- wchar_t *tmp_16 = alloc_utf16_from_8(name, 0);
+ wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
int len, res;
unsigned int old_error_mode;
len = wcslen(tmp_16);
- if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/'))
+ /* in Windows #stat doesn't recognize dir ending on a slash
+ * so we remove it here */
+ if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/')) {
tmp_16[len - 1] = '\0';
+ }
+ /* two special cases where the trailing slash is needed:
+ * 1. after the share part of a UNC path
+ * 2. after the C:\ when the path is the volume only
+ */
+ if ((len >= 3) && (tmp_16[0] == L'\\') && (tmp_16[1] == L'\\')) {
+ BLI_cleanup_unc_16(tmp_16);
+ }
+
+ if ((tmp_16[1] == L':') && (tmp_16[2] == L'\0')) {
+ tmp_16[2] = L'\\';
+ tmp_16[3] = L'\0';
+ }
+
/* change error mode so user does not get a "no disk in drive" popup
* when looking for a file on an empty CD/DVD drive */
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index bbc135479ef..892bb16a543 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -289,7 +289,7 @@ escape_finish:
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
size_t prefixLen = strlen(prefix);
- char *startMatch, *endMatch;
+ const char *startMatch, *endMatch;
/* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */
startMatch = strstr(str, prefix) + prefixLen + 1;
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 2d2c03add97..09b7ecb2277 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -116,7 +116,7 @@ static strCursorDelimType cursor_delim_type_utf8(const char *ch_utf8)
return cursor_delim_type_unicode(uch);
}
-int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
+bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
{
const char *str_end = str + (maxlen + 1);
const char *str_pos = str + (*pos);
@@ -126,24 +126,24 @@ int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
if ((*pos) > (int)maxlen) {
(*pos) = (int)maxlen;
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
+bool BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
{
if ((*pos) > 0) {
const char *str_pos = str + (*pos);
const char *str_prev = BLI_str_find_prev_char_utf8(str, str_pos);
if (str_prev) {
(*pos) -= (str_pos - str_prev);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index e7beaaa33a0..74e979a8579 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -195,7 +195,7 @@ static const size_t utf8_skip_data[256] = {
char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
- char *dst_r = dst;
+ char *r_dst = dst;
BLI_assert(maxncpy != 0);
@@ -206,7 +206,7 @@ char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t
/* note: currently we don't attempt to deal with invalid utf8 chars */
BLI_STR_UTF8_CPY(dst, src, maxncpy);
- return dst_r;
+ return r_dst;
}
char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
@@ -439,7 +439,7 @@ int BLI_str_utf8_size(const char *p)
int mask = 0, len;
const unsigned char c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
(void)mask; /* quiet warning */
@@ -452,7 +452,7 @@ int BLI_str_utf8_size_safe(const char *p)
int mask = 0, len;
const unsigned char c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, 1);
+ UTF8_COMPUTE(c, mask, len, 1);
(void)mask; /* quiet warning */
@@ -479,10 +479,10 @@ unsigned int BLI_str_utf8_as_unicode(const char *p)
unsigned int result;
const unsigned char c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1))
return BLI_UTF8_ERR;
- UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
return result;
}
@@ -495,10 +495,10 @@ unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *
unsigned int result;
const unsigned char c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1))
return BLI_UTF8_ERR;
- UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
*index += (size_t)len;
return result;
}
@@ -510,12 +510,12 @@ unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, siz
unsigned int result;
const unsigned char c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1)) {
*index += 1;
return c;
}
- UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
*index += (size_t)len;
return result;
}
@@ -532,11 +532,11 @@ unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__re
p += *index;
c = (unsigned char) *p;
- UTF8_COMPUTE (c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1)) {
/* when called with NULL end, result will never be NULL,
* checks for a NULL character */
- char *p_next = BLI_str_find_next_char_utf8(p, NULL);
+ const char *p_next = BLI_str_find_next_char_utf8(p, NULL);
/* will never return the same pointer unless '\0',
* eternal loop is prevented */
*index += (size_t)(p_next - p);
@@ -546,12 +546,12 @@ unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__re
/* this is tricky since there are a few ways we can bail out of bad unicode
* values, 3 possible solutions. */
#if 0
- UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
#elif 1
/* WARNING: this is NOT part of glib, or supported by similar functions.
* this is added for text drawing because some filepaths can have latin1
* characters */
- UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
if (result == BLI_UTF8_ERR) {
len = 1;
result = *p;
@@ -559,7 +559,7 @@ unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__re
/* end warning! */
#else
/* without a fallback like '?', text drawing will stop on this value */
- UTF8_GET (result, p, i, mask, len, '?');
+ UTF8_GET(result, p, i, mask, len, '?');
#endif
*index += (size_t)len;
diff --git a/source/blender/blenlib/intern/cpu.c b/source/blender/blenlib/intern/system.c
index d942ffdf2c9..e6389bc68f3 100644
--- a/source/blender/blenlib/intern/cpu.c
+++ b/source/blender/blenlib/intern/system.c
@@ -4,7 +4,7 @@
* 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.
+ * 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
@@ -18,12 +18,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/blenlib/intern/cpu.c
+/** \file blender/blenlib/intern/system.c
* \ingroup bli
*/
-#include "BLI_cpu.h"
+#include "BLI_system.h"
int BLI_cpu_support_sse2(void)
{
@@ -52,8 +52,8 @@ int BLI_cpu_support_sse2(void)
mov d, edx
}
return (d & 0x04000000) != 0;
-#endif
-
+#else
return 0;
+#endif
}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index c9f4e9ddc15..ded2fd7e06d 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -121,6 +121,7 @@ static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
static int thread_levels = 0; /* threads can be invoked inside threads */
static int num_threads_override = 0;
@@ -399,6 +400,8 @@ void BLI_lock_thread(int type)
pthread_mutex_lock(&_movieclip_lock);
else if (type == LOCK_COLORMANAGE)
pthread_mutex_lock(&_colormanage_lock);
+ else if (type == LOCK_FFTW)
+ pthread_mutex_lock(&_fftw_lock);
}
void BLI_unlock_thread(int type)
@@ -421,6 +424,8 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_movieclip_lock);
else if (type == LOCK_COLORMANAGE)
pthread_mutex_unlock(&_colormanage_lock);
+ else if (type == LOCK_FFTW)
+ pthread_mutex_unlock(&_fftw_lock);
}
/* Mutex Locks */
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
index cd703741831..7b2ac9e112b 100644
--- a/source/blender/blenlib/intern/timecode.c
+++ b/source/blender/blenlib/intern/timecode.c
@@ -38,10 +38,9 @@
#include "BLI_timecode.h" /* own include */
-#include "BLI_strict_flags.h"
-
#include "DNA_userdef_types.h" /* for eTimecodeStyles only */
+#include "BLI_strict_flags.h"
/**
* Generate timecode/frame number string and store in \a str
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index 730ab01bfd2..cf6a6366e9a 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -58,7 +58,7 @@ void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo
if (uci->do_pano) {
float angle = atan2f(pv4[0], -pv4[2]) / ((float)M_PI * 2.0f); /* angle around the camera */
- if (uci->do_persp == FALSE) {
+ if (uci->do_persp == false) {
target[0] = angle; /* no correct method here, just map to 0-1 */
target[1] = pv4[1] / uci->camsize;
}
@@ -74,7 +74,7 @@ void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo
if (pv4[2] == 0.0f)
pv4[2] = 0.00001f; /* don't allow div by 0 */
- if (uci->do_persp == FALSE) {
+ if (uci->do_persp == false) {
target[0] = (pv4[0] / uci->camsize);
target[1] = (pv4[1] / uci->camsize);
}
@@ -152,10 +152,10 @@ ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float(*rotmat)[4], float w
/* normal projection */
if (rotmat) {
copy_m4_m4(uci.rotmat, rotmat);
- uci.do_rotmat = TRUE;
+ uci.do_rotmat = true;
}
else {
- uci.do_rotmat = FALSE;
+ uci.do_rotmat = false;
}
/* also make aspect ratio adjustment factors */
diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c
index 731536ff0df..e0cbe278ffb 100644
--- a/source/blender/blenlib/intern/voronoi.c
+++ b/source/blender/blenlib/intern/voronoi.c
@@ -58,9 +58,9 @@ typedef struct VoronoiEvent {
typedef struct VoronoiParabola {
struct VoronoiParabola *left, *right, *parent;
VoronoiEvent *event;
- int is_leaf;
- float site[2];
VoronoiEdge *edge;
+ float site[2];
+ bool is_leaf;
} VoronoiParabola;
typedef struct VoronoiProcess {
@@ -118,7 +118,7 @@ static VoronoiParabola *voronoiParabola_new(void)
{
VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola");
- parabola->is_leaf = FALSE;
+ parabola->is_leaf = false;
parabola->event = NULL;
parabola->edge = NULL;
parabola->parent = NULL;
@@ -131,7 +131,7 @@ static VoronoiParabola *voronoiParabola_newSite(float site[2])
VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site");
copy_v2_v2(parabola->site, site);
- parabola->is_leaf = TRUE;
+ parabola->is_leaf = true;
parabola->event = NULL;
parabola->edge = NULL;
parabola->parent = NULL;
@@ -364,7 +364,7 @@ static void voronoi_addParabola(VoronoiProcess *process, float site[2])
float *fp = root->site;
float s[2];
- root->is_leaf = FALSE;
+ root->is_leaf = false;
voronoiParabola_setLeft(root, voronoiParabola_newSite(fp));
voronoiParabola_setRight(root, voronoiParabola_newSite(site));
@@ -399,7 +399,7 @@ static void voronoi_addParabola(VoronoiProcess *process, float site[2])
BLI_addtail(&process->edges, el);
par->edge = er;
- par->is_leaf = FALSE;
+ par->is_leaf = false;
p0 = voronoiParabola_newSite(par->site);
p1 = voronoiParabola_newSite(site);
@@ -566,29 +566,29 @@ static int voronoi_getNextSideCoord(ListBase *edges, float coord[2], int dim, in
int other_dim = dim ? 0 : 1;
while (edge) {
- int ok = FALSE;
+ bool ok = false;
float co[2], cur_distance;
if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS &&
len_squared_v2v2(coord, edge->start) > VORONOI_EPS)
{
copy_v2_v2(co, edge->start);
- ok = TRUE;
+ ok = true;
}
if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS &&
len_squared_v2v2(coord, edge->end) > VORONOI_EPS)
{
copy_v2_v2(co, edge->end);
- ok = TRUE;
+ ok = true;
}
if (ok) {
if (dir > 0 && coord[dim] > co[dim]) {
- ok = FALSE;
+ ok = false;
}
else if (dir < 0 && coord[dim] < co[dim]) {
- ok = FALSE;
+ ok = false;
}
}
@@ -693,7 +693,7 @@ void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, i
BLI_movelisttolist(edges, &process.edges);
}
-static int testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge)
+static bool testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge)
{
float p[2];
@@ -701,11 +701,11 @@ static int testVoronoiEdge(const float site[2], const float point[2], const Voro
if (len_squared_v2v2(p, edge->start) > VORONOI_EPS &&
len_squared_v2v2(p, edge->end) > VORONOI_EPS)
{
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
static int voronoi_addTriangulationPoint(const float coord[2], const float color[3],
@@ -787,16 +787,16 @@ void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, ListBase
edge = boundary_edges.first;
while (edge) {
VoronoiEdge *test_edge = boundary_edges.first;
- int ok_start = TRUE, ok_end = TRUE;
+ bool ok_start = true, ok_end = true;
while (test_edge) {
if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge)) {
- ok_start = FALSE;
+ ok_start = false;
break;
}
if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge)) {
- ok_end = FALSE;
+ ok_end = false;
break;
}
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 7db33ff79be..65ded37eb7b 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -82,7 +82,7 @@ void RegisterBlendExtension(void)
LONG lresult;
HKEY hkey = 0;
HKEY root = 0;
- BOOL usr_mode = FALSE;
+ BOOL usr_mode = false;
DWORD dwd = 0;
char buffer[256];
@@ -103,7 +103,7 @@ void RegisterBlendExtension(void)
lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
if (lresult != ERROR_SUCCESS) {
/* try HKCU on failure */
- usr_mode = TRUE;
+ usr_mode = true;
lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
if (lresult != ERROR_SUCCESS)
RegisterBlendExtension_Fail(0);
@@ -157,7 +157,7 @@ void RegisterBlendExtension(void)
ThumbHandlerDLL = "BlendThumb.dll";
#else
IsWow64Process(GetCurrentProcess(), &IsWOW64);
- if (IsWOW64 == TRUE)
+ if (IsWOW64 == true)
ThumbHandlerDLL = "BlendThumb64.dll";
else
ThumbHandlerDLL = "BlendThumb.dll";
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index ba87a437032..7f557d3de22 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
intern/undofile.c
intern/versioning_250.c
intern/versioning_260.c
+ intern/versioning_270.c
intern/versioning_defaults.c
intern/versioning_legacy.c
intern/writefile.c
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 5dcf875a32b..d9bcfc2e8f9 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -42,7 +42,6 @@
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
-#include "BLI_fileops.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
@@ -55,7 +54,6 @@
#include "BKE_main.h"
#include "BKE_library.h" // for BKE_main_free
#include "BKE_idcode.h"
-#include "BKE_report.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
@@ -102,8 +100,8 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
if (bhead->code == ENDB)
break;
else {
- short *sp = fd->filesdna->structs[bhead->SDNAnr];
- char *name = fd->filesdna->types[sp[0]];
+ const short *sp = fd->filesdna->structs[bhead->SDNAnr];
+ const char *name = fd->filesdna->types[sp[0]];
char buf[4];
buf[0] = (bhead->code >> 24) & 0xFF;
@@ -131,7 +129,7 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
if (bhead->code == ofblocktype) {
- char *idname = bhead_id_name(fd, bhead);
+ const char *idname = bhead_id_name(fd, bhead);
BLI_linklist_prepend(&names, strdup(idname + 2));
tot++;
@@ -156,7 +154,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
if (bhead->code == ofblocktype) {
- char *idname = bhead_id_name(fd, bhead);
+ const char *idname = bhead_id_name(fd, bhead);
switch (GS(idname)) {
case ID_MA: /* fall through */
case ID_TE: /* fall through */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 72a6d854295..56996d46d2f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -106,54 +106,40 @@
#include "BLI_endian_switch.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BLI_threads.h"
#include "BLI_mempool.h"
#include "BLF_translation.h"
-#include "BKE_anim.h"
-#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_brush.h"
-#include "BKE_colortools.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
-#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h" // for G
#include "BKE_group.h"
-#include "BKE_image.h"
-#include "BKE_lattice.h"
#include "BKE_library.h" // for which_libbase
#include "BKE_idcode.h"
-#include "BKE_idprop.h"
#include "BKE_material.h"
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_node.h" // for tree type defines
-#include "BKE_ocean.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "BKE_property.h" // for BKE_bproperty_object_get
#include "BKE_report.h"
#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
-#include "BKE_text.h" // for txt_extended_ascii_as_utf8
-#include "BKE_texture.h"
-#include "BKE_tracking.h"
#include "BKE_treehash.h"
#include "BKE_sound.h"
-#include "BKE_writeffmpeg.h"
#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
@@ -537,7 +523,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
// printf("blo_find_main: converted to %s\n", name1);
for (m = mainlist->first; m; m = m->next) {
- char *libname = (m->curlib) ? m->curlib->filepath : m->name;
+ const char *libname = (m->curlib) ? m->curlib->filepath : m->name;
if (BLI_path_cmp(name1, libname) == 0) {
if (G.debug & G_DEBUG) printf("blo_find_main: found library %s\n", libname);
@@ -2394,6 +2380,7 @@ static bNodeTree *nodetree_from_id(ID *id)
case ID_WO: return ((World *)id)->nodetree;
case ID_LA: return ((Lamp *)id)->nodetree;
case ID_TE: return ((Tex *)id)->nodetree;
+ case ID_LS: return ((FreestyleLineStyle *)id)->nodetree;
}
return NULL;
}
@@ -2462,7 +2449,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
} FOREACH_NODETREE_END
{
- int has_old_groups = 0;
+ bool has_old_groups = false;
/* XXX this should actually be part of do_versions, but since we need
* finished library linking, it is not possible there. Instead in do_versions
* we have set the NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2 flag, so at this point we can do the
@@ -2534,7 +2521,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
* the ntree interface sockets, which need to be redirected to new interface nodes.
*/
for (link = ntree->links.first; link; link = next_link) {
- int free_link = FALSE;
+ bool free_link = false;
next_link = link->next;
if (link->fromnode == NULL) {
@@ -2549,8 +2536,9 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
input_locy += link->tonode->locy;
}
}
- else
- free_link = TRUE;
+ else {
+ free_link = true;
+ }
}
if (link->tonode == NULL) {
@@ -2565,8 +2553,9 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
output_locy += link->fromnode->locy;
}
}
- else
- free_link = TRUE;
+ else {
+ free_link = true;
+ }
}
if (free_link)
@@ -2626,7 +2615,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
bNodeLink *link;
ntree->init = 0; /* to set callbacks and force setting types */
- ntree->is_updating = FALSE;
+ ntree->is_updating = false;
ntree->typeinfo= NULL;
ntree->interface_type = NULL;
@@ -2750,12 +2739,12 @@ typedef struct tConstraintLinkData {
ID *id;
} tConstraintLinkData;
/* callback function used to relink constraint ID-links */
-static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *userdata)
+static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, bool is_reference, void *userdata)
{
tConstraintLinkData *cld= (tConstraintLinkData *)userdata;
/* for reference types, we need to increment the usercounts on load... */
- if (isReference) {
+ if (is_reference) {
/* reference type - with usercount */
*idpoin = newlibadr_us(cld->fd, cld->id->lib, *idpoin);
}
@@ -2785,7 +2774,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
cld.fd = fd;
cld.id = id;
- BKE_id_loop_constraints(conlist, lib_link_constraint_cb, &cld);
+ BKE_constraints_id_loop(conlist, lib_link_constraint_cb, &cld);
}
static void direct_link_constraints(FileData *fd, ListBase *lb)
@@ -3050,7 +3039,7 @@ static void lib_link_key(FileData *fd, Main *main)
static void switch_endian_keyblock(Key *key, KeyBlock *kb)
{
int elemsize, a, b;
- char *data, *poin, *cp;
+ const char *data, *poin, *cp;
elemsize = key->elemsize;
data = kb->data;
@@ -3848,7 +3837,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
psys->childcache = NULL;
BLI_listbase_clear(&psys->pathcachebufs);
BLI_listbase_clear(&psys->childcachebufs);
- psys->frand = NULL;
psys->pdd = NULL;
psys->renderdata = NULL;
@@ -4332,7 +4320,7 @@ static void lib_link_object(FileData *fd, Main *main)
/* When the object is local and the data is library its possible
* the material list size gets out of sync. [#22663] */
if (ob->data && ob->id.lib != ((ID *)ob->data)->lib) {
- short *totcol_data = give_totcolp(ob);
+ const short *totcol_data = give_totcolp(ob);
/* Only expand so as not to loose any object materials that might be set. */
if (totcol_data && (*totcol_data > ob->totcol)) {
/* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
@@ -5362,7 +5350,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
seq->strip = newdataadr(fd, seq->strip);
if (seq->strip && seq->strip->done==0) {
- seq->strip->done = TRUE;
+ seq->strip->done = true;
if (ELEM4(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
seq->strip->stripdata = newdataadr(fd, seq->strip->stripdata);
@@ -5494,7 +5482,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
rbw->effector_weights = BKE_add_effector_weights(NULL);
/* link cache */
- direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE);
+ direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false);
/* make sure simulation starts from the beginning after loading file */
if (rbw->pointcache) {
rbw->ltime = (float)rbw->pointcache->startframe;
@@ -5796,16 +5784,23 @@ static void lib_link_screen(FileData *fd, Main *main)
}
}
-static bool restore_pointer(ID *id, ID *newid, int user)
+/* how to handle user count on pointer restore */
+typedef enum ePointerUserMode {
+ USER_IGNORE, /* ignore user count */
+ USER_ONE, /* ensure at least one user (fake also counts) */
+ USER_REAL /* ensure at least one real user (fake user ignored) */
+} ePointerUserMode;
+
+static bool restore_pointer(ID *id, ID *newid, ePointerUserMode user)
{
if (strcmp(newid->name + 2, id->name + 2) == 0) {
if (newid->lib == id->lib) {
- if (user == 1) {
+ if (user == USER_ONE) {
if (newid->us == 0) {
newid->us++;
}
}
- else if (user == 2) {
+ else if (user == USER_REAL) {
id_us_ensure_real(newid);
}
return true;
@@ -5822,7 +5817,7 @@ static bool restore_pointer(ID *id, ID *newid, int user)
* - 1: ensure a user
* - 2: ensure a real user (even if a fake one is set)
*/
-static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
+static void *restore_pointer_by_name(Main *mainp, ID *id, ePointerUserMode user)
{
if (id) {
ListBase *lb = which_libbase(mainp, GS(id->name));
@@ -5845,7 +5840,7 @@ static void lib_link_seq_clipboard_pt_restore(ID *id, Main *newmain)
if (id) {
/* clipboard must ensure this */
BLI_assert(id->newid != NULL);
- id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, 1);
+ id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, USER_ONE);
}
}
static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
@@ -5879,7 +5874,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
/* first windowmanager */
for (wm = newmain->wm.first; wm; wm = wm->id.next) {
for (win= wm->windows.first; win; win= win->next) {
- win->screen = restore_pointer_by_name(newmain, (ID *)win->screen, 1);
+ win->screen = restore_pointer_by_name(newmain, (ID *)win->screen, USER_ONE);
if (win->screen == NULL)
win->screen = curscreen;
@@ -5892,7 +5887,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
for (sc = newmain->screen.first; sc; sc = sc->id.next) {
Scene *oldscene = sc->scene;
- sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene, 1);
+ sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene, USER_ONE);
if (sc->scene == NULL)
sc->scene = curscene;
@@ -5911,14 +5906,14 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
if (v3d->scenelock)
v3d->camera = NULL; /* always get from scene */
else
- v3d->camera = restore_pointer_by_name(newmain, (ID *)v3d->camera, 1);
+ v3d->camera = restore_pointer_by_name(newmain, (ID *)v3d->camera, USER_ONE);
if (v3d->camera == NULL)
v3d->camera = sc->scene->camera;
- v3d->ob_centre = restore_pointer_by_name(newmain, (ID *)v3d->ob_centre, 1);
+ v3d->ob_centre = restore_pointer_by_name(newmain, (ID *)v3d->ob_centre, USER_ONE);
for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
- bgpic->ima = restore_pointer_by_name(newmain, (ID *)bgpic->ima, 1);
- bgpic->clip = restore_pointer_by_name(newmain, (ID *)bgpic->clip, 1);
+ bgpic->ima = restore_pointer_by_name(newmain, (ID *)bgpic->ima, USER_ONE);
+ bgpic->clip = restore_pointer_by_name(newmain, (ID *)bgpic->clip, USER_ONE);
}
if (v3d->localvd) {
/*Base *base;*/
@@ -5960,10 +5955,10 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
bDopeSheet *ads = sipo->ads;
if (ads) {
- ads->source = restore_pointer_by_name(newmain, (ID *)ads->source, 1);
+ ads->source = restore_pointer_by_name(newmain, (ID *)ads->source, USER_ONE);
if (ads->filter_grp)
- ads->filter_grp = restore_pointer_by_name(newmain, (ID *)ads->filter_grp, 0);
+ ads->filter_grp = restore_pointer_by_name(newmain, (ID *)ads->filter_grp, USER_IGNORE);
}
/* force recalc of list of channels (i.e. includes calculating F-Curve colors)
@@ -5973,8 +5968,11 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
}
else if (sl->spacetype == SPACE_BUTS) {
SpaceButs *sbuts = (SpaceButs *)sl;
- sbuts->pinid = restore_pointer_by_name(newmain, sbuts->pinid, 0);
- //XXX if (sbuts->ri) sbuts->ri->curtile = 0;
+ sbuts->pinid = restore_pointer_by_name(newmain, sbuts->pinid, USER_IGNORE);
+
+ /* TODO: restore path pointers: T40046
+ * (complicated because this contains data pointers too, not just ID)*/
+ MEM_SAFE_FREE(sbuts->path);
}
else if (sl->spacetype == SPACE_FILE) {
SpaceFile *sfile = (SpaceFile *)sl;
@@ -5983,11 +5981,11 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sl;
- saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, 1);
- saction->ads.source = restore_pointer_by_name(newmain, (ID *)saction->ads.source, 1);
+ saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, USER_ONE);
+ saction->ads.source = restore_pointer_by_name(newmain, (ID *)saction->ads.source, USER_ONE);
if (saction->ads.filter_grp)
- saction->ads.filter_grp = restore_pointer_by_name(newmain, (ID *)saction->ads.filter_grp, 0);
+ saction->ads.filter_grp = restore_pointer_by_name(newmain, (ID *)saction->ads.filter_grp, USER_IGNORE);
/* force recalc of list of channels, potentially updating the active action
@@ -5998,7 +5996,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 2);
+ sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, USER_REAL);
/* this will be freed, not worth attempting to find same scene,
* since it gets initialized later */
@@ -6013,8 +6011,8 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
* so assume that here we're doing for undo only...
*/
- sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1);
- sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 2);
+ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, USER_ONE);
+ sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, USER_REAL);
}
else if (sl->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = (SpaceSeq *)sl;
@@ -6022,29 +6020,29 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
* so assume that here we're doing for undo only...
*/
- sseq->gpd = restore_pointer_by_name(newmain, (ID *)sseq->gpd, 1);
+ sseq->gpd = restore_pointer_by_name(newmain, (ID *)sseq->gpd, USER_ONE);
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla = (SpaceNla *)sl;
bDopeSheet *ads = snla->ads;
if (ads) {
- ads->source = restore_pointer_by_name(newmain, (ID *)ads->source, 1);
+ ads->source = restore_pointer_by_name(newmain, (ID *)ads->source, USER_ONE);
if (ads->filter_grp)
- ads->filter_grp = restore_pointer_by_name(newmain, (ID *)ads->filter_grp, 0);
+ ads->filter_grp = restore_pointer_by_name(newmain, (ID *)ads->filter_grp, USER_IGNORE);
}
}
else if (sl->spacetype == SPACE_TEXT) {
SpaceText *st = (SpaceText *)sl;
- st->text = restore_pointer_by_name(newmain, (ID *)st->text, 1);
+ st->text = restore_pointer_by_name(newmain, (ID *)st->text, USER_ONE);
if (st->text == NULL) st->text = newmain->text.first;
}
else if (sl->spacetype == SPACE_SCRIPT) {
SpaceScript *scpt = (SpaceScript *)sl;
- scpt->script = restore_pointer_by_name(newmain, (ID *)scpt->script, 1);
+ scpt->script = restore_pointer_by_name(newmain, (ID *)scpt->script, USER_ONE);
/*sc->script = NULL; - 2.45 set to null, better re-run the script */
if (scpt->script) {
@@ -6054,7 +6052,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, 0);
+ so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, USER_IGNORE);
if (so->treestore) {
TreeStoreElem *tselem;
@@ -6062,7 +6060,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
BLI_mempool_iternew(so->treestore, &iter);
while ((tselem = BLI_mempool_iterstep(&iter))) {
- tselem->id = restore_pointer_by_name(newmain, tselem->id, 0);
+ tselem->id = restore_pointer_by_name(newmain, tselem->id, USER_IGNORE);
}
if (so->treehash) {
/* rebuild hash table, because it depends on ids too */
@@ -6076,14 +6074,14 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
bNodeTree *ntree;
/* node tree can be stored locally in id too, link this first */
- snode->id = restore_pointer_by_name(newmain, snode->id, 1);
- snode->from = restore_pointer_by_name(newmain, snode->from, 0);
+ snode->id = restore_pointer_by_name(newmain, snode->id, USER_ONE);
+ snode->from = restore_pointer_by_name(newmain, snode->from, USER_IGNORE);
ntree = nodetree_from_id(snode->id);
if (ntree)
snode->nodetree = ntree;
else
- snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, 0);
+ snode->nodetree = restore_pointer_by_name(newmain, (ID*)snode->nodetree, USER_REAL);
for (path = snode->treepath.first; path; path = path->next) {
if (path == snode->treepath.first) {
@@ -6091,7 +6089,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
path->nodetree = snode->nodetree;
}
else
- path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 2);
+ path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, USER_REAL);
if (!path->nodetree)
break;
@@ -6117,15 +6115,15 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
- sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 2);
- sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 2);
+ sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, USER_REAL);
+ sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, USER_REAL);
sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
- slogic->gpd = restore_pointer_by_name(newmain, (ID *)slogic->gpd, 1);
+ slogic->gpd = restore_pointer_by_name(newmain, (ID *)slogic->gpd, USER_ONE);
}
}
}
@@ -6160,6 +6158,8 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
IDP_DirectLinkGroup_OrFree(&ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
+ link_list(fd, &ar->ui_previews);
+
if (spacetype == SPACE_EMPTY) {
/* unkown space type, don't leak regiondata */
ar->regiondata = NULL;
@@ -6914,6 +6914,8 @@ static void lib_link_linestyle(FileData *fd, Main *main)
{
FreestyleLineStyle *linestyle;
LineStyleModifier *m;
+ MTex *mtex;
+ int a;
linestyle = main->linestyle.first;
while (linestyle) {
@@ -6954,6 +6956,17 @@ static void lib_link_linestyle(FileData *fd, Main *main)
break;
}
}
+ for (a=0; a < MAX_MTEX; a++) {
+ mtex = linestyle->mtex[a];
+ if (mtex) {
+ mtex->tex = newlibadr_us(fd, linestyle->id.lib, mtex->tex);
+ mtex->object = newlibadr(fd, linestyle->id.lib, mtex->object);
+ }
+ }
+ if (linestyle->nodetree) {
+ lib_link_ntree(fd, &linestyle->id, linestyle->nodetree);
+ linestyle->nodetree->id.lib = linestyle->id.lib;
+ }
}
linestyle = linestyle->id.next;
}
@@ -7063,6 +7076,7 @@ static void direct_link_linestyle_geometry_modifier(FileData *UNUSED(fd), LineSt
static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
{
+ int a;
LineStyleModifier *modifier;
linestyle->adt= newdataadr(fd, linestyle->adt);
@@ -7079,6 +7093,14 @@ static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
link_list(fd, &linestyle->geometry_modifiers);
for (modifier = linestyle->geometry_modifiers.first; modifier; modifier = modifier->next)
direct_link_linestyle_geometry_modifier(fd, modifier);
+ for (a = 0; a < MAX_MTEX; a++) {
+ linestyle->mtex[a] = newdataadr(fd, linestyle->mtex[a]);
+ }
+ linestyle->nodetree = newdataadr(fd, linestyle->nodetree);
+ if (linestyle->nodetree) {
+ direct_link_id(fd, &linestyle->nodetree->id);
+ direct_link_nodetree(fd, linestyle->nodetree);
+ }
}
/* ************** GENERAL & MAIN ******************** */
@@ -7150,7 +7172,7 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a
return bhead;
}
-static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **id_r)
+static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **r_id)
{
/* this routine reads a libblock and its direct data. Use link functions
* to connect it all
@@ -7162,8 +7184,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
/* read libblock */
id = read_struct(fd, bhead, "lib block");
- if (id_r)
- *id_r = id;
+ if (r_id)
+ *r_id = id;
if (!id)
return blo_nextbhead(fd, bhead);
@@ -7438,6 +7460,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
blo_do_versions_pre250(fd, lib, main);
blo_do_versions_250(fd, lib, main);
blo_do_versions_260(fd, lib, main);
+ blo_do_versions_270(fd, lib, main);
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
@@ -7647,7 +7670,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
lib_link_all(fd, bfd->main);
//do_versions_after_linking(fd, NULL, bfd->main); // XXX: not here (or even in this function at all)! this causes crashes on many files - Aligorith (July 04, 2010)
- lib_verify_nodetree(bfd->main, TRUE);
+ lib_verify_nodetree(bfd->main, true);
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
link_global(fd, bfd); /* as last */
@@ -8197,7 +8220,7 @@ typedef struct tConstraintExpandData {
Main *mainvar;
} tConstraintExpandData;
/* callback function used to expand constraint ID-links */
-static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *userdata)
+static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, bool UNUSED(is_reference), void *userdata)
{
tConstraintExpandData *ced = (tConstraintExpandData *)userdata;
expand_doit(ced->fd, ced->mainvar, *idpoin);
@@ -8212,7 +8235,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
ced.fd = fd;
ced.mainvar = mainvar;
- BKE_id_loop_constraints(lb, expand_constraint_cb, &ced);
+ BKE_constraints_id_loop(lb, expand_constraint_cb, &ced);
/* deprecated manual expansion stuff */
for (curcon = lb->first; curcon; curcon = curcon->next) {
@@ -8478,6 +8501,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
{
if (seq->scene) expand_doit(fd, mainvar, seq->scene);
if (seq->scene_camera) expand_doit(fd, mainvar, seq->scene_camera);
+ if (seq->clip) expand_doit(fd, mainvar, seq->clip);
+ if (seq->mask) expand_doit(fd, mainvar, seq->mask);
if (seq->sound) expand_doit(fd, mainvar, seq->sound);
}
SEQ_END
@@ -8563,8 +8588,18 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *linestyle)
{
+ int a;
LineStyleModifier *m;
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) {
+ expand_doit(fd, mainvar, linestyle->mtex[a]->tex);
+ expand_doit(fd, mainvar, linestyle->mtex[a]->object);
+ }
+ }
+ if (linestyle->nodetree)
+ expand_nodetree(fd, mainvar, linestyle->nodetree);
+
if (linestyle->adt)
expand_animdata(fd, mainvar, linestyle->adt);
for (m = linestyle->color_modifiers.first; m; m = m->next) {
@@ -8591,10 +8626,11 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
ListBase *lbarray[MAX_LIBARRAY];
FileData *fd = fdhandle;
ID *id;
- int a, do_it = TRUE;
+ int a;
+ bool do_it = true;
while (do_it) {
- do_it = FALSE;
+ do_it = false;
a = set_listbasepointers(mainvar, lbarray);
while (a--) {
@@ -8676,7 +8712,7 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
break;
}
- do_it = TRUE;
+ do_it = true;
id->flag -= LIB_NEED_EXPAND;
}
@@ -8716,27 +8752,27 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
*
* (ob->id.flag & LIB_PRE_EXISTING)==0 means that this is a newly appended object - Campbell */
if (is_group_append==0 || (ob->id.flag & LIB_PRE_EXISTING)==0) {
- int do_it = FALSE;
+ bool do_it = false;
if (ob->id.us == 0) {
- do_it = TRUE;
+ do_it = true;
}
else if (idcode==ID_GR) {
- if (ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) {
+ if (ob->id.us == 1 && is_link == false && ob->id.lib == lib) {
if ((ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) {
- do_it = TRUE;
+ do_it = true;
}
}
}
else {
/* when appending, make sure any indirectly loaded objects
* get a base else they cant be accessed at all [#27437] */
- if (ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) {
+ if (ob->id.us==1 && is_link == false && ob->id.lib == lib) {
/* we may be appending from a scene where we already
* have a linked object which is not in any scene [#27616] */
if ((ob->id.flag & LIB_PRE_EXISTING)==0) {
if (object_in_any_scene(mainvar, ob)==0) {
- do_it = TRUE;
+ do_it = true;
}
}
}
@@ -8921,7 +8957,7 @@ ID *BLO_library_append_named_part_ex(const bContext *C, Main *mainl, BlendHandle
return append_named_part_ex(C, mainl, fd, idname, idcode, flag);
}
-static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
+static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **r_id)
{
BHead *bhead;
@@ -8932,7 +8968,7 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
id->flag &= ~LIB_READ;
id->flag |= LIB_NEED_EXPAND;
// printf("read lib block %s\n", id->name);
- read_libblock(fd, mainvar, bhead, id->flag, id_r);
+ read_libblock(fd, mainvar, bhead, id->flag, r_id);
break;
}
@@ -9005,7 +9041,7 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
lib_link_all(*fd, mainvar);
- lib_verify_nodetree(mainvar, FALSE);
+ lib_verify_nodetree(mainvar, false);
fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */
if (C) {
@@ -9080,13 +9116,14 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
Main *mainl = mainlist->first;
Main *mainptr;
ListBase *lbarray[MAX_LIBARRAY];
- int a, do_it = TRUE;
+ int a;
+ bool do_it = true;
/* expander now is callback function */
BLO_main_expander(expand_doit_library);
while (do_it) {
- do_it = FALSE;
+ do_it = false;
/* test 1: read libdata */
mainptr= mainl->next;
@@ -9173,7 +9210,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
}
}
if (fd) {
- do_it = TRUE;
+ do_it = true;
a = set_listbasepointers(mainptr, lbarray);
while (a--) {
ID *id = lbarray[a]->first;
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index fe22499d16f..d56f58d1b37 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -161,6 +161,7 @@ void blo_do_versions_key_uidgen(struct Key *key);
void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *main);
void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main);
+void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main);
#endif
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index 45ace5367fc..264e470ba2b 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -72,7 +72,7 @@ int BLO_is_a_runtime(const char *path)
int datastart;
char buf[8];
- if (fd < 0)
+ if (fd == -1)
goto cleanup;
lseek(fd, -12, SEEK_END);
@@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports)
fd = BLI_open(path, O_BINARY | O_RDONLY, 0);
- if (fd < 0) {
+ if (fd == -1) {
BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno));
goto cleanup;
}
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index c276bd0876c..06d871c8db0 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -69,7 +69,6 @@
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BKE_anim.h"
#include "BKE_armature.h"
@@ -1141,7 +1140,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
World *wo;
Tex *tex;
ParticleSettings *part;
- int do_gravity = FALSE;
+ bool do_gravity = false;
for (sce = main->scene.first; sce; sce = sce->id.next)
if (sce->unit.scale_length == 0.0f)
@@ -1197,7 +1196,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
sce->physics_settings.gravity[0] = sce->physics_settings.gravity[1] = 0.0f;
sce->physics_settings.gravity[2] = -9.81f;
sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
- do_gravity = TRUE;
+ do_gravity = true;
}
}
@@ -1267,7 +1266,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
Lattice *lt;
Curve *cu;
Key *key;
- float *data;
+ const float *data;
int a, tot;
/* shape keys are no longer applied to the mesh itself, but rather
@@ -2561,7 +2560,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
tex->pd->falloff_curve->preset = CURVE_PRESET_LINE;
tex->pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
curvemap_reset(tex->pd->falloff_curve->cm, &tex->pd->falloff_curve->clipr, tex->pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
- curvemapping_changed(tex->pd->falloff_curve, FALSE);
+ curvemapping_changed(tex->pd->falloff_curve, false);
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 89fe63fda81..40d7bd5d2cb 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -1200,7 +1200,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
ARegion *ar;
- int hide = FALSE;
+ bool hide = false;
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_PREVIEW) {
@@ -1209,7 +1209,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
ar->v2d.flag &= ~V2D_IS_INITIALISED;
ar->alignment = RGN_ALIGN_NONE;
- hide = TRUE;
+ hide = true;
}
}
}
@@ -1532,7 +1532,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 19)) {
Scene *scene;
Image *ima;
- int colormanagement_disabled = FALSE;
+ bool colormanagement_disabled = false;
/* make scenes which are not using color management have got None as display device,
* so they wouldn't perform linear-to-sRGB conversion on display
@@ -1546,7 +1546,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
- colormanagement_disabled = TRUE;
+ colormanagement_disabled = true;
}
}
@@ -2501,7 +2501,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
else {
tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
- tmd->ngon_method = MOD_TRIANGULATE_NGON_SCANFILL;
+ tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
}
}
}
@@ -2674,46 +2674,33 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "float", "profile")) {
- Object *ob;
+ if (!MAIN_VERSION_ATLEAST(main, 269, 11)) {
+ bScreen *sc;
- 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->profile = 0.5f;
- bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
- }
- }
- }
- }
+ for (sc = main->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *space_link;
- {
- /* nodes don't use fixed node->id any more, clean up */
- FOREACH_NODETREE(main, ntree, id) {
- if (ntree->type == NTREE_COMPOSIT) {
- bNode *node;
- for (node = ntree->nodes.first; node; node = node->next) {
- if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) {
- node->id = NULL;
- }
- }
- }
- } FOREACH_NODETREE_END
+ for (space_link = sa->spacedata.first; space_link; space_link = space_link->next) {
+ if (space_link->spacetype == SPACE_IMAGE) {
+ ARegion *ar;
+ ListBase *lb;
- {
- bScreen *screen;
-
- for (screen = main->screen.first; screen; screen = screen->id.next) {
- ScrArea *area;
- for (area = screen->areabase.first; area; area = area->next) {
- SpaceLink *space_link;
- for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
- if (space_link->spacetype == SPACE_CLIP) {
- SpaceClip *space_clip = (SpaceClip *) space_link;
- if (space_clip->mode != SC_MODE_MASKEDIT) {
- space_clip->mode = SC_MODE_TRACKING;
+ if (space_link == sa->spacedata.first) {
+ lb = &sa->regionbase;
+ }
+ else {
+ lb = &space_link->regionbase;
+ }
+
+ for (ar = lb->first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_PREVIEW) {
+ ar->regiontype = RGN_TYPE_TOOLS;
+ ar->alignment = RGN_ALIGN_LEFT;
+ }
+ else if (ar->regiontype == RGN_TYPE_UI) {
+ ar->alignment = RGN_ALIGN_RIGHT;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
new file mode 100644
index 00000000000..ada32aadbe2
--- /dev/null
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -0,0 +1,282 @@
+/*
+ * ***** 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): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/blenloader/intern/versioning_270.c
+ * \ingroup blenloader
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_compiler_attrs.h"
+
+/* for MinGW32 definition of NULL, could use BLI_blenlib.h instead too */
+#include <stddef.h>
+
+/* allow readfile to use deprecated functionality */
+#define DNA_DEPRECATED_ALLOW
+
+#include "DNA_constraint_types.h"
+#include "DNA_sdna_types.h"
+#include "DNA_space_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_linestyle_types.h"
+
+#include "DNA_genfile.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#include "BKE_main.h"
+#include "BKE_node.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+
+#include "BLO_readfile.h"
+
+#include "readfile.h"
+
+
+static void do_version_constraints_radians_degrees_270_1(ListBase *lb)
+{
+ bConstraint *con;
+
+ for (con = lb->first; con; con = con->next) {
+ if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
+ bTransformConstraint *data = (bTransformConstraint *)con->data;
+ const float deg_to_rad_f = DEG2RADF(1.0f);
+
+ if (data->from == TRANS_ROTATION) {
+ mul_v3_fl(data->from_min, deg_to_rad_f);
+ mul_v3_fl(data->from_max, deg_to_rad_f);
+ }
+
+ if (data->to == TRANS_ROTATION) {
+ mul_v3_fl(data->to_min, deg_to_rad_f);
+ mul_v3_fl(data->to_max, deg_to_rad_f);
+ }
+ }
+ }
+}
+
+static void do_version_constraints_radians_degrees_270_5(ListBase *lb)
+{
+ bConstraint *con;
+
+ for (con = lb->first; con; con = con->next) {
+ if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
+ bTransformConstraint *data = (bTransformConstraint *)con->data;
+
+ if (data->from == TRANS_ROTATION) {
+ copy_v3_v3(data->from_min_rot, data->from_min);
+ copy_v3_v3(data->from_max_rot, data->from_max);
+ }
+ else if (data->from == TRANS_SCALE) {
+ copy_v3_v3(data->from_min_scale, data->from_min);
+ copy_v3_v3(data->from_max_scale, data->from_max);
+ }
+
+ if (data->to == TRANS_ROTATION) {
+ copy_v3_v3(data->to_min_rot, data->to_min);
+ copy_v3_v3(data->to_max_rot, data->to_max);
+ }
+ else if (data->to == TRANS_SCALE) {
+ copy_v3_v3(data->to_min_scale, data->to_min);
+ copy_v3_v3(data->to_max_scale, data->to_max);
+ }
+ }
+ }
+}
+
+void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
+{
+ if (!MAIN_VERSION_ATLEAST(main, 270, 0)) {
+
+ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "float", "profile")) {
+ 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->profile = 0.5f;
+ bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
+ }
+ }
+ }
+ }
+
+ /* nodes don't use fixed node->id any more, clean up */
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_COMPOSIT) {
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) {
+ node->id = NULL;
+ }
+ }
+ }
+ } FOREACH_NODETREE_END
+
+ {
+ bScreen *screen;
+
+ for (screen = main->screen.first; screen; screen = screen->id.next) {
+ ScrArea *area;
+ for (area = screen->areabase.first; area; area = area->next) {
+ SpaceLink *space_link;
+ for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
+ if (space_link->spacetype == SPACE_CLIP) {
+ SpaceClip *space_clip = (SpaceClip *) space_link;
+ if (space_clip->mode != SC_MODE_MASKEDIT) {
+ space_clip->mode = SC_MODE_TRACKING;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingSettings", "float", "default_weight")) {
+ MovieClip *clip;
+ for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ clip->tracking.settings.default_weight = 1.0f;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 270, 1)) {
+ Scene *sce;
+ Object *ob;
+
+ /* Update Transform constraint (another deg -> rad stuff). */
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ do_version_constraints_radians_degrees_270_1(&ob->constraints);
+
+ if (ob->pose) {
+ /* Bones constraints! */
+ bPoseChannel *pchan;
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ do_version_constraints_radians_degrees_270_1(&pchan->constraints);
+ }
+ }
+ }
+
+ for (sce = main->scene.first; sce; sce = sce->id.next) {
+ if (sce->r.raytrace_structure == R_RAYSTRUCTURE_BLIBVH) {
+ sce->r.raytrace_structure = R_RAYSTRUCTURE_AUTO;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 270, 2)) {
+ Mesh *me;
+
+ /* Mesh smoothresh deg->rad. */
+ for (me = main->mesh.first; me; me = me->id.next) {
+ me->smoothresh = DEG2RADF(me->smoothresh);
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 270, 3)) {
+ FreestyleLineStyle *linestyle;
+
+ for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ linestyle->flag |= LS_NO_SORTING;
+ linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
+ linestyle->integration_type = LS_INTEGRATION_MEAN;
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 270, 4)) {
+ /* ui_previews were not handled correctly when copying areas, leading to corrupted files (see T39847).
+ * This will always reset situation to a valid state.
+ */
+ bScreen *sc;
+
+ for (sc = main->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) {
+ ARegion *ar;
+ ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
+
+ for (ar = lb->first; ar; ar = ar->next) {
+ BLI_listbase_clear(&ar->ui_previews);
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 270, 5)) {
+ Object *ob;
+
+ /* Update Transform constraint (again :|). */
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ do_version_constraints_radians_degrees_270_5(&ob->constraints);
+
+ if (ob->pose) {
+ /* Bones constraints! */
+ bPoseChannel *pchan;
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ do_version_constraints_radians_degrees_270_5(&pchan->constraints);
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "Material", "int", "mode2")) {
+ Material *ma;
+
+ for (ma = main->mat.first; ma; ma = ma->id.next)
+ ma->mode2 = MA_CASTSHADOW;
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "BakeData", "bake")) {
+ Scene *sce;
+
+ for (sce = main->scene.first; sce; sce = sce->id.next) {
+ sce->r.bake.flag = R_BAKE_CLEAR;
+ sce->r.bake.width = 512;
+ sce->r.bake.height = 512;
+ sce->r.bake.margin = 16;
+ sce->r.bake.normal_space = R_BAKE_SPACE_TANGENT;
+ sce->r.bake.normal_swizzle[0] = R_BAKE_POSX;
+ sce->r.bake.normal_swizzle[1] = R_BAKE_POSY;
+ sce->r.bake.normal_swizzle[2] = R_BAKE_POSZ;
+ BLI_strncpy(sce->r.bake.filepath, U.renderdir, sizeof(sce->r.bake.filepath));
+
+ sce->r.bake.im_format.planes = R_IMF_PLANES_RGBA;
+ sce->r.bake.im_format.imtype = R_IMF_IMTYPE_PNG;
+ sce->r.bake.im_format.depth = R_IMF_CHAN_DEPTH_8;
+ sce->r.bake.im_format.quality = 90;
+ sce->r.bake.im_format.compress = 15;
+ }
+ }
+}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index b14402e72db..1e881eb11f9 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -26,6 +26,7 @@
*/
#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "DNA_freestyle_types.h"
#include "DNA_linestyle_types.h"
@@ -33,6 +34,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_mesh_types.h"
#include "BKE_main.h"
@@ -45,6 +47,7 @@ void BLO_update_defaults_startup_blend(Main *main)
Scene *scene;
SceneRenderLayer *srl;
FreestyleLineStyle *linestyle;
+ Mesh *me;
for (scene = main->scene.first; scene; scene = scene->id.next) {
scene->r.im_format.planes = R_IMF_PLANES_RGBA;
@@ -56,8 +59,12 @@ void BLO_update_defaults_startup_blend(Main *main)
}
}
- for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next)
- linestyle->flag = LS_SAME_OBJECT;
+ for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
+ linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
+ linestyle->integration_type = LS_INTEGRATION_MEAN;
+ linestyle->texstep = 1.0;
+ }
{
bScreen *screen;
@@ -75,5 +82,9 @@ void BLO_update_defaults_startup_blend(Main *main)
}
}
}
+
+ for (me = main->mesh.first; me; me = me->id.next) {
+ me->smoothresh = DEG2RADF(180.0f);
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 0283d9b04fb..572c6d0a02d 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -77,14 +77,12 @@
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BKE_armature.h"
#include "BKE_colortools.h"
#include "BKE_constraint.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
-#include "BKE_global.h" // for G
#include "BKE_image.h"
#include "BKE_lattice.h"
#include "BKE_main.h" // for Main
@@ -541,7 +539,7 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
{
/* create new trackto constraint from the relationship */
if (ob->track) {
- bConstraint *con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ bConstraint *con = BKE_constraint_add_for_object(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
bTrackToConstraint *data = con->data;
/* copy tracking settings from the object */
@@ -3572,8 +3570,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
Object *ob;
World *wrld;
for (ob = main->object.first; ob; ob = ob->id.next) {
- /* pad3 is used for m_contactProcessingThreshold */
- ob->m_contactProcessingThreshold = 1.0f;
if (ob->parent) {
/* check if top parent has compound shape set and if yes, set this object
* to compound shaper as well (was the behavior before, now it's optional) */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 854e9d8cec9..45139789f1e 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -81,13 +81,12 @@
#include "zlib.h"
-#ifndef WIN32
-# include <unistd.h>
-#else
+#ifdef WIN32
# include "winsock2.h"
# include <io.h>
-# include <process.h> // for getpid
# include "BLI_winstuff.h"
+#else
+# include <unistd.h> /* FreeBSD, for write() and close(). */
#endif
#include "BLI_utildefines.h"
@@ -144,7 +143,6 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BLI_math.h"
#include "BLI_mempool.h"
#include "BKE_action.h"
@@ -153,7 +151,6 @@
#include "BKE_curve.h"
#include "BKE_constraint.h"
#include "BKE_global.h" // for G
-#include "BKE_idprop.h"
#include "BKE_library.h" // for set_listbasepointers
#include "BKE_main.h"
#include "BKE_node.h"
@@ -345,7 +342,7 @@ static int endwrite(WriteData *wd)
static void writestruct_at_address(WriteData *wd, int filecode, const char *structname, int nr, void *adr, void *data)
{
BHead bh;
- short *sp;
+ const short *sp;
if (adr==NULL || data==NULL || nr==0) return;
@@ -444,7 +441,7 @@ static void IDP_WriteIDPArray(IDProperty *prop, void *wd)
static void IDP_WriteString(IDProperty *prop, void *wd)
{
/*REMEMBER to set totalen to len in the linking code!!*/
- writedata(wd, DATA, prop->len+1, prop->data.pointer);
+ writedata(wd, DATA, prop->len, prop->data.pointer);
}
static void IDP_WriteGroup(IDProperty *prop, void *wd)
@@ -1266,7 +1263,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
bConstraint *con;
for (con=conlist->first; con; con=con->next) {
- bConstraintTypeInfo *cti= BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti= BKE_constraint_typeinfo_get(con);
/* Write the specific data */
if (cti && con->data) {
@@ -1338,7 +1335,7 @@ static void write_pose(WriteData *wd, bPose *pose)
/* write IK param */
if (pose->ikparam) {
- char *structname = (char *)BKE_pose_ikparam_get_name(pose);
+ const char *structname = (char *)BKE_pose_ikparam_get_name(pose);
if (structname)
writestruct(wd, DATA, structname, 1, pose->ikparam);
}
@@ -1785,7 +1782,7 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data,
write_mdisps(wd, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
}
else if (layer->type == CD_PAINT_MASK) {
- float *layer_data = layer->data;
+ const float *layer_data = layer->data;
writedata(wd, DATA, sizeof(*layer_data) * count, layer_data);
}
else if (layer->type == CD_GRID_PAINT_MASK) {
@@ -2092,7 +2089,7 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
if (wrld->mtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]);
}
- /* nodetree is integral part of lamps, no libdata */
+ /* nodetree is integral part of world, no libdata */
if (wrld->nodetree) {
writestruct(wd, DATA, "bNodeTree", 1, wrld->nodetree);
write_nodetree(wd, wrld->nodetree);
@@ -2229,7 +2226,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
SEQ_BEGIN (ed, seq)
{
- if (seq->strip) seq->strip->done = FALSE;
+ if (seq->strip) seq->strip->done = false;
writestruct(wd, DATA, "Sequence", 1, seq);
}
SEQ_END
@@ -2275,7 +2272,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
else if (seq->type==SEQ_TYPE_MOVIE || seq->type==SEQ_TYPE_SOUND_RAM || seq->type == SEQ_TYPE_SOUND_HD)
writestruct(wd, DATA, "StripElem", 1, strip->stripdata);
- strip->done = TRUE;
+ strip->done = true;
}
write_sequence_modifiers(wd, &seq->modifiers);
@@ -2490,6 +2487,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
SpaceLink *sl;
Panel *pa;
uiList *ui_list;
+ uiPreview *ui_preview;
PanelCategoryStack *pc_act;
ARegion *ar;
@@ -2506,6 +2504,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next)
write_uilist(wd, ui_list);
+
+ for (ui_preview = ar->ui_previews.first; ui_preview; ui_preview = ui_preview->next)
+ writestruct(wd, DATA, "uiPreview", 1, ui_preview);
}
sl= sa->spacedata.first;
@@ -2625,7 +2626,8 @@ static void write_libraries(WriteData *wd, Main *main)
{
ListBase *lbarray[MAX_LIBARRAY];
ID *id;
- int a, tot, foundone;
+ int a, tot;
+ bool found_one;
for (; main; main= main->next) {
@@ -2633,24 +2635,24 @@ static void write_libraries(WriteData *wd, Main *main)
/* test: is lib being used */
if (main->curlib && main->curlib->packedfile)
- foundone = TRUE;
+ found_one = true;
else {
- foundone = FALSE;
+ found_one = false;
while (tot--) {
for (id= lbarray[tot]->first; id; id= id->next) {
if (id->us>0 && (id->flag & LIB_EXTERN)) {
- foundone = TRUE;
+ found_one = true;
break;
}
}
- if (foundone) break;
+ if (found_one) break;
}
}
/* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */
/* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the]
* quit.blend and temp saves */
- if (foundone) {
+ if (found_one) {
writestruct(wd, ID_LI, "Library", 1, main->curlib);
if (main->curlib->packedfile) {
@@ -3246,6 +3248,7 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier
static void write_linestyles(WriteData *wd, ListBase *idbase)
{
FreestyleLineStyle *linestyle;
+ int a;
for (linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) {
if (linestyle->id.us>0 || wd->current) {
@@ -3258,6 +3261,13 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers);
write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers);
write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers);
+ for (a=0; a<MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) writestruct(wd, DATA, "MTex", 1, linestyle->mtex[a]);
+ }
+ if (linestyle->nodetree) {
+ writestruct(wd, DATA, "bNodeTree", 1, linestyle->nodetree);
+ write_nodetree(wd, linestyle->nodetree);
+ }
}
}
}
@@ -3465,7 +3475,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
- if (file < 0) {
+ if (file == -1) {
BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno));
return 0;
}
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 01e4c911d19..83b02764046 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -66,7 +66,7 @@ typedef struct BMHeader {
int index; /* notes:
* - Use BM_elem_index_get/set macros for index
* - Uninitialized to -1 so we can easily tell its not set.
- * - Used for edge/vert/face, check BMesh.elem_index_dirty for valid index values,
+ * - Used for edge/vert/face/loop, check BMesh.elem_index_dirty for valid index values,
* this is abused by various tools which set it dirty.
* - For loops this is used for sorting during tessellation. */
@@ -188,9 +188,8 @@ typedef struct BMesh {
int totvertsel, totedgesel, totfacesel;
/* flag index arrays as being dirty so we can check if they are clean and
- * avoid looping over the entire vert/edge/face array in those cases.
- * valid flags are - BM_VERT | BM_EDGE | BM_FACE.
- * BM_LOOP isn't handled so far. */
+ * avoid looping over the entire vert/edge/face/loop array in those cases.
+ * valid flags are - BM_VERT | BM_EDGE | BM_FACE | BM_LOOP. */
char elem_index_dirty;
/* flag array table as being dirty so we know when its safe to use it,
@@ -286,6 +285,12 @@ extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
typedef bool (*BMElemFilterFunc)(BMElem *, void *user_data);
/* defines */
+#define BM_ELEM_CD_SET_INT(ele, offset, f) \
+ { assert(offset != -1); *((int *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
+
+#define BM_ELEM_CD_GET_INT(ele, offset) \
+ (assert(offset != -1), *((int *)((char *)(ele)->head.data + (offset))))
+
#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
(assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 109f964a5f9..eef1e7bbb4f 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -388,7 +388,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len,
float cent[3], nor[3];
- float *far = NULL, *far_cross = NULL;
+ const float *far = NULL, *far_cross = NULL;
float far_vec[3];
float far_cross_vec[3];
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index bbfee692df4..1f81b59badc 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -29,7 +29,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_math_vector.h"
-#include "BLI_listbase.h"
#include "BLI_array.h"
#include "BLI_alloca.h"
#include "BLI_smallhash.h"
@@ -60,7 +59,11 @@
BMVert *BM_vert_create(BMesh *bm, const float co[3],
const BMVert *v_example, const eBMCreateFlag create_flag)
{
- BMVert *v = BLI_mempool_calloc(bm->vpool);
+ BMVert *v = BLI_mempool_alloc(bm->vpool);
+
+
+ /* --- assign all members --- */
+ v->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
DEBUG_MEMCHECK_INDEX_INVALIDATE(v)
@@ -68,6 +71,26 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3],
BM_elem_index_set(v, -1); /* set_ok_invalid */
#endif
+ v->head.htype = BM_VERT;
+ v->head.hflag = 0;
+ v->head.api_flag = 0;
+
+ /* allocate flags */
+ v->oflags = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
+
+ /* 'v->no' is handled by BM_elem_attrs_copy */
+ if (co) {
+ copy_v3_v3(v->co, co);
+ }
+ else {
+ zero_v3(v->co);
+ }
+ zero_v3(v->no);
+
+ v->e = NULL;
+ /* --- done --- */
+
+
/* disallow this flag for verts - its meaningless */
BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
@@ -77,18 +100,6 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3],
bm->totvert++;
- v->head.htype = BM_VERT;
-
- /* 'v->no' is handled by BM_elem_attrs_copy */
- if (co) {
- copy_v3_v3(v->co, co);
- }
-
- /* allocate flags */
- if (bm->vtoolflagpool) {
- v->oflags = BLI_mempool_calloc(bm->vtoolflagpool);
- }
-
if (!(create_flag & BM_CREATE_SKIP_CD)) {
if (v_example) {
int *keyi;
@@ -121,11 +132,18 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2,
const BMEdge *e_example, const eBMCreateFlag create_flag)
{
BMEdge *e;
-
+
+ BLI_assert(v1 != v2);
+ BLI_assert(v1->head.htype == BM_VERT && v2->head.htype == BM_VERT);
+
if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2)))
return e;
- e = BLI_mempool_calloc(bm->epool);
+ e = BLI_mempool_alloc(bm->epool);
+
+
+ /* --- assign all members --- */
+ e->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
DEBUG_MEMCHECK_INDEX_INVALIDATE(e)
@@ -133,27 +151,30 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2,
BM_elem_index_set(e, -1); /* set_ok_invalid */
#endif
- /* may add to middle of the pool */
- bm->elem_index_dirty |= BM_EDGE;
- bm->elem_table_dirty |= BM_EDGE;
-
- bm->totedge++;
-
e->head.htype = BM_EDGE;
-
+ e->head.hflag = BM_ELEM_SMOOTH | BM_ELEM_DRAW;
+ e->head.api_flag = 0;
+
/* allocate flags */
- if (bm->etoolflagpool) {
- e->oflags = BLI_mempool_calloc(bm->etoolflagpool);
- }
+ e->oflags = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
e->v1 = v1;
e->v2 = v2;
-
- BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW);
-
+ e->l = NULL;
+
+ memset(&e->v1_disk_link, 0, sizeof(BMDiskLink) * 2);
+ /* --- done --- */
+
+
bmesh_disk_edge_append(e, e->v1);
bmesh_disk_edge_append(e, e->v2);
-
+
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_EDGE;
+ bm->elem_table_dirty |= BM_EDGE;
+
+ bm->totedge++;
+
if (!(create_flag & BM_CREATE_SKIP_CD)) {
if (e_example) {
BM_elem_attrs_copy(bm, bm, e_example, e);
@@ -163,7 +184,6 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2,
}
}
-
BM_CHECK_ELEMENT(e);
return e;
@@ -174,14 +194,27 @@ static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f,
{
BMLoop *l = NULL;
- l = BLI_mempool_calloc(bm->lpool);
- l->next = l->prev = NULL;
+ l = BLI_mempool_alloc(bm->lpool);
+
+ /* --- assign all members --- */
+ l->head.data = NULL;
+ BM_elem_index_set(l, 0); /* set_loop */
+ l->head.hflag = 0;
+ l->head.htype = BM_LOOP;
+ l->head.api_flag = 0;
+
l->v = v;
l->e = e;
l->f = f;
- l->radial_next = l->radial_prev = NULL;
- l->head.data = NULL;
- l->head.htype = BM_LOOP;
+
+ l->radial_next = NULL;
+ l->radial_prev = NULL;
+ l->next = NULL;
+ l->prev = NULL;
+ /* --- done --- */
+
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_LOOP;
bm->totloop++;
@@ -284,36 +317,48 @@ BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
/**
* only create the face, since this calloc's the length is initialized to 0,
* leave adding loops to the caller.
+ *
+ * \note, caller needs to handle customdata.
*/
-BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag create_flag)
+BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
{
BMFace *f;
- f = BLI_mempool_calloc(bm->fpool);
+ f = BLI_mempool_alloc(bm->fpool);
+
+ /* --- assign all members --- */
+ f->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
DEBUG_MEMCHECK_INDEX_INVALIDATE(f)
#else
BM_elem_index_set(f, -1); /* set_ok_invalid */
#endif
+ f->head.htype = BM_FACE;
+ f->head.hflag = 0;
+ f->head.api_flag = 0;
+
+ /* allocate flags */
+ f->oflags = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
+
+#ifdef USE_BMESH_HOLES
+ BLI_listbase_clear(&f->loops);
+#else
+ f->l_first = NULL;
+#endif
+ f->len = 0;
+ zero_v3(f->no);
+ f->mat_nr = 0;
+ /* --- done --- */
+
+
/* may add to middle of the pool */
bm->elem_index_dirty |= BM_FACE;
bm->elem_table_dirty |= BM_FACE;
bm->totface++;
- f->head.htype = BM_FACE;
-
- /* allocate flags */
- if (bm->ftoolflagpool) {
- f->oflags = BLI_mempool_calloc(bm->ftoolflagpool);
- }
-
- if (!(create_flag & BM_CREATE_SKIP_CD)) {
- CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
- }
-
#ifdef USE_BMESH_HOLES
f->totbounds = 0;
#endif
@@ -353,7 +398,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
}
}
- f = bm_face_create__internal(bm, create_flag);
+ f = bm_face_create__internal(bm);
startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag);
@@ -634,6 +679,7 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
{
bm->totloop--;
+ bm->elem_index_dirty |= BM_LOOP;
if (l->head.data)
CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
@@ -759,13 +805,13 @@ void BM_edge_kill(BMesh *bm, BMEdge *e)
void BM_vert_kill(BMesh *bm, BMVert *v)
{
if (v->e) {
- BMEdge *e, *nexte;
+ BMEdge *e, *e_next;
e = v->e;
while (v->e) {
- nexte = bmesh_disk_edge_next(e, v);
+ e_next = bmesh_disk_edge_next(e, v);
BM_edge_kill(bm, e);
- e = nexte;
+ e = e_next;
}
}
@@ -982,12 +1028,8 @@ static bool disk_is_flagged(BMVert *v, int flag)
do {
if (!BM_ELEM_API_FLAG_TEST(l->f, flag))
return false;
-
- l = l->radial_next;
- } while (l != e->l);
-
- e = bmesh_disk_edge_next(e, v);
- } while (e != v->e);
+ } while ((l = l->radial_next) != e->l);
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
return true;
}
@@ -1201,14 +1243,14 @@ error:
return NULL;
}
-static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example))
+static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
{
BMFace *f;
#ifdef USE_BMESH_HOLES
BMLoopList *lst;
#endif
- f = bm_face_create__internal(bm, 0);
+ f = bm_face_create__internal(bm);
#ifdef USE_BMESH_HOLES
lst = BLI_mempool_calloc(bm->looplistpool);
@@ -1219,6 +1261,8 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example))
f->totbounds = 1;
#endif
+ BM_elem_attrs_copy(bm, bm, f_example, f);
+
return f;
}
@@ -1609,7 +1653,10 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
BMVert *v_old, *tv;
BMLoop *l_kill;
int len, radlen = 0, i;
- bool edok, halt = false;
+ bool halt = false;
+#ifndef NDEBUG
+ bool edok;
+#endif
if (BM_vert_in_edge(e_kill, v_kill) == 0) {
return NULL;
@@ -1692,12 +1739,12 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
BLI_mempool_free(bm->lpool, loops[i]);
}
}
-
+#ifndef NDEBUG
/* Validate radial cycle of e_old */
edok = bmesh_radial_validate(radlen, e_old->l);
BMESH_ASSERT(edok != false);
+#endif
}
-
/* deallocate edge */
bm_kill_only_edge(bm, e_kill);
diff --git a/source/blender/bmesh/intern/bmesh_delete.c b/source/blender/bmesh/intern/bmesh_delete.c
index 42b1c09b7ef..c5c9403884b 100644
--- a/source/blender/bmesh/intern/bmesh_delete.c
+++ b/source/blender/bmesh/intern/bmesh_delete.c
@@ -31,7 +31,6 @@
* BM remove functions.
*/
-#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index 4c91f22759b..bbf4b661a1b 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -298,7 +298,7 @@ bool BM_mesh_edgeloops_find_path(BMesh *bm, ListBase *r_eloops,
BMVert *v_match[2] = {NULL, NULL};
ListBase lb_src = {NULL, NULL};
ListBase lb_dst = {NULL, NULL};
- BLI_mempool *vs_pool = BLI_mempool_create(sizeof(struct VertStep), 1, 512, 0);
+ BLI_mempool *vs_pool = BLI_mempool_create(sizeof(struct VertStep), 0, 512, BLI_MEMPOOL_NOP);
/* edge args are dummy */
vs_add(vs_pool, &lb_src, v_src, v_src->e, 1);
@@ -544,9 +544,9 @@ void BM_edgeloop_calc_center(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
LinkData *node_first = el_store->verts.first;
LinkData *node_next = node_first;
- float const *v_prev = NODE_AS_CO(node_prev);
- float const *v_curr = NODE_AS_CO(node_curr);
- float const *v_next = NODE_AS_CO(node_next);
+ const float *v_prev = NODE_AS_CO(node_prev);
+ const float *v_curr = NODE_AS_CO(node_curr);
+ const float *v_next = NODE_AS_CO(node_next);
float totw = 0.0f;
float w_prev;
@@ -582,8 +582,8 @@ void BM_edgeloop_calc_center(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
{
LinkData *node_curr = el_store->verts.first;
- float const *v_prev = NODE_AS_CO(el_store->verts.last);
- float const *v_curr = NODE_AS_CO(node_curr);
+ const float *v_prev = NODE_AS_CO(el_store->verts.last);
+ const float *v_curr = NODE_AS_CO(node_curr);
zero_v3(el_store->no);
@@ -619,8 +619,8 @@ bool BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal_aligned(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, const float no_align[3])
{
LinkData *node_curr = el_store->verts.first;
- float const *v_prev = NODE_AS_CO(el_store->verts.last);
- float const *v_curr = NODE_AS_CO(node_curr);
+ const float *v_prev = NODE_AS_CO(el_store->verts.last);
+ const float *v_curr = NODE_AS_CO(node_curr);
zero_v3(el_store->no);
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 2afb9c9cdee..2250b8135d7 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -33,7 +33,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_alloca.h"
@@ -257,24 +256,24 @@ static int compute_mdisp_quad(BMLoop *l, float v1[3], float v2[3], float v3[3],
}
/* funnily enough, I think this is identical to face_to_crn_interp, heh */
-static float quad_coord(float aa[3], float bb[3], float cc[3], float dd[3], int a1, int a2)
+static float quad_coord(const float aa[3], const float bb[3], const float cc[3], const float dd[3], int a1, int a2)
{
float x, y, z, f1;
+ float div;
x = aa[a1] * cc[a2] - cc[a1] * aa[a2];
y = aa[a1] * dd[a2] + bb[a1] * cc[a2] - cc[a1] * bb[a2] - dd[a1] * aa[a2];
z = bb[a1] * dd[a2] - dd[a1] * bb[a2];
-
- if (fabsf(2.0f * (x - y + z)) > FLT_EPSILON * 10.0f) {
- float f2;
- f1 = ( sqrtf(y * y - 4.0f * x * z) - y + 2.0f * z) / (2.0f * (x - y + z));
- f2 = (-sqrtf(y * y - 4.0f * x * z) - y + 2.0f * z) / (2.0f * (x - y + z));
+ div = 2.0f * (x - y + z);
- f1 = fabsf(f1);
- f2 = fabsf(f2);
- f1 = min_ff(f1, f2);
- CLAMP(f1, 0.0f, 1.0f + FLT_EPSILON);
+ if (fabsf(div) > FLT_EPSILON * 10.0f) {
+ const float f_tmp = sqrtf(y * y - 4.0f * x * z);
+
+ f1 = min_ff(fabsf(( f_tmp - y + 2.0f * z) / div),
+ fabsf((-f_tmp - y + 2.0f * z) / div));
+
+ CLAMP_MAX(f1, 1.0f + FLT_EPSILON);
}
else {
f1 = -z / (y - 2 * z);
@@ -295,8 +294,9 @@ static float quad_coord(float aa[3], float bb[3], float cc[3], float dd[3], int
return f1;
}
-static int quad_co(float *x, float *y, float v1[3], float v2[3], float v3[3], float v4[3],
- float p[3], float n[3])
+static int quad_co(float *x, float *y,
+ const float v1[3], const float v2[3], const float v3[3], const float v4[3],
+ const float p[3], const float n[3])
{
float projverts[5][3], n2[3];
float dprojverts[4][3], origin[3] = {0.0f, 0.0f, 0.0f};
@@ -317,12 +317,7 @@ static int quad_co(float *x, float *y, float v1[3], float v2[3], float v3[3], fl
/* rotate */
poly_rotate_plane(n, projverts, 5);
-
- /* flatten */
- for (i = 0; i < 5; i++) {
- projverts[i][2] = 0.0f;
- }
-
+
/* subtract origin */
for (i = 0; i < 4; i++) {
sub_v3_v3(projverts[i], projverts[4]);
@@ -389,8 +384,8 @@ static bool mdisp_in_mdispquad(BMLoop *l, BMLoop *tl, float p[3], float *x, floa
return 1;
}
-static float bm_loop_flip_equotion(float mat[2][2], float b[2], float target_axis_x[3], float target_axis_y[3],
- float coord[3], int i, int j)
+static float bm_loop_flip_equotion(float mat[2][2], float b[2], const float target_axis_x[3], const float target_axis_y[3],
+ const float coord[3], int i, int j)
{
mat[0][0] = target_axis_x[i];
mat[0][1] = target_axis_y[i];
@@ -889,7 +884,7 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
float BM_elem_float_data_get(CustomData *cd, void *element, int type)
{
- float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
+ const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
return f ? *f : 0.0f;
}
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index b302ca7b8b2..7d3bc0e16b3 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -47,6 +47,9 @@
#include "bmesh_log.h"
#include "range_tree_c_api.h"
+#include "BLI_strict_flags.h"
+
+
struct BMLogEntry {
struct BMLogEntry *next, *prev;
@@ -64,6 +67,7 @@ struct BMLogEntry {
/* Vertices whose coordinates, mask value, or hflag have changed */
GHash *modified_verts;
+ GHash *modified_faces;
BLI_mempool *pool_verts;
BLI_mempool *pool_faces;
@@ -117,6 +121,7 @@ typedef struct {
typedef struct {
unsigned int v_ids[3];
+ char hflag;
} BMLogFace;
/************************* Get/set element IDs ************************/
@@ -125,13 +130,13 @@ typedef struct {
static unsigned int bm_log_vert_id_get(BMLog *log, BMVert *v)
{
BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
- return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v));
+ return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v));
}
/* Set the vertex's unique ID in the log */
static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
{
- void *vid = SET_INT_IN_POINTER(id);
+ void *vid = SET_UINT_IN_POINTER(id);
BLI_ghash_reinsert(log->id_to_elem, vid, v, NULL, NULL);
BLI_ghash_reinsert(log->elem_to_id, v, vid, NULL, NULL);
@@ -140,7 +145,7 @@ static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
/* Get a vertex from its unique ID */
static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
{
- void *key = SET_INT_IN_POINTER(id);
+ void *key = SET_UINT_IN_POINTER(id);
BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
return BLI_ghash_lookup(log->id_to_elem, key);
}
@@ -149,13 +154,13 @@ static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
static unsigned int bm_log_face_id_get(BMLog *log, BMFace *f)
{
BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
- return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f));
+ return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f));
}
/* Set the face's unique ID in the log */
static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
{
- void *fid = SET_INT_IN_POINTER(id);
+ void *fid = SET_UINT_IN_POINTER(id);
BLI_ghash_reinsert(log->id_to_elem, fid, f, NULL, NULL);
BLI_ghash_reinsert(log->elem_to_id, f, fid, NULL, NULL);
@@ -164,7 +169,7 @@ static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
/* Get a face from its unique ID */
static BMFace *bm_log_face_from_id(BMLog *log, unsigned int id)
{
- void *key = SET_INT_IN_POINTER(id);
+ void *key = SET_UINT_IN_POINTER(id);
BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
return BLI_ghash_lookup(log->id_to_elem, key);
}
@@ -175,12 +180,10 @@ static BMFace *bm_log_face_from_id(BMLog *log, unsigned int id)
/* Get a vertex's paint-mask value
*
* Returns zero if no paint-mask layer is present */
-static float vert_mask_get(BMesh *bm, BMVert *v)
+static float vert_mask_get(BMVert *v, const int cd_vert_mask_offset)
{
- float *mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
- BLI_assert((CustomData_has_layer(&bm->vdata, CD_PAINT_MASK) == 0) == (mask == NULL));
- if (mask) {
- return *mask;
+ if (cd_vert_mask_offset != -1) {
+ return BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
}
else {
return 0.0f;
@@ -190,31 +193,29 @@ static float vert_mask_get(BMesh *bm, BMVert *v)
/* Set a vertex's paint-mask value
*
* Has no effect is no paint-mask layer is present */
-static void vert_mask_set(BMesh *bm, BMVert *v, float new_mask)
+static void vert_mask_set(BMVert *v, const float new_mask, const int cd_vert_mask_offset)
{
- float *mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
- BLI_assert((CustomData_has_layer(&bm->vdata, CD_PAINT_MASK) == 0) == (mask == NULL));
- if (*mask) {
- *mask = new_mask;
+ if (cd_vert_mask_offset != -1) {
+ BM_ELEM_CD_SET_FLOAT(v, cd_vert_mask_offset, new_mask);
}
}
/* Update a BMLogVert with data from a BMVert */
-static void bm_log_vert_bmvert_copy(BMesh *bm, BMLogVert *lv, BMVert *v)
+static void bm_log_vert_bmvert_copy(BMLogVert *lv, BMVert *v, const int cd_vert_mask_offset)
{
copy_v3_v3(lv->co, v->co);
normal_float_to_short_v3(lv->no, v->no);
- lv->mask = vert_mask_get(bm, v);
+ lv->mask = vert_mask_get(v, cd_vert_mask_offset);
lv->hflag = v->head.hflag;
}
/* Allocate and initialize a BMLogVert */
-static BMLogVert *bm_log_vert_alloc(BMesh *bm, BMLog *log, BMVert *v)
+static BMLogVert *bm_log_vert_alloc(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogEntry *entry = log->current_entry;
BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
- bm_log_vert_bmvert_copy(bm, lv, v);
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
return lv;
}
@@ -235,6 +236,7 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
lf->v_ids[1] = bm_log_vert_id_get(log, v[1]);
lf->v_ids[2] = bm_log_vert_id_get(log, v[2]);
+ lf->hflag = f->head.hflag;
return lf;
}
@@ -243,16 +245,18 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
{
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
GHashIterator gh_iter;
GHASH_ITER (gh_iter, verts) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- unsigned int id = GET_INT_FROM_POINTER(key);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
BMVert *v = bm_log_vert_from_id(log, id);
/* Ensure the log has the final values of the vertex before
* deleting it */
- bm_log_vert_bmvert_copy(bm, lv, v);
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
BM_vert_kill(bm, v);
}
@@ -263,7 +267,7 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
GHashIterator gh_iter;
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_INT_FROM_POINTER(key);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
BMFace *f = bm_log_face_from_id(log, id);
BMEdge *e_tri[3];
BMLoop *l_iter;
@@ -286,15 +290,17 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
{
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
GHashIterator gh_iter;
GHASH_ITER (gh_iter, verts) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
BMVert *v = BM_vert_create(bm, lv->co, NULL, BM_CREATE_NOP);
+ vert_mask_set(v, lv->mask, cd_vert_mask_offset);
v->head.hflag = lv->hflag;
- vert_mask_set(bm, v, lv->mask);
normal_short_to_float_v3(v->no, lv->no);
- bm_log_vert_id_set(log, v, GET_INT_FROM_POINTER(key));
+ bm_log_vert_id_set(log, v, GET_UINT_FROM_POINTER(key));
}
}
@@ -310,17 +316,20 @@ static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
BMFace *f;
f = BM_face_create_verts(bm, v, 3, NULL, BM_CREATE_NOP, true);
- bm_log_face_id_set(log, f, GET_INT_FROM_POINTER(key));
+ f->head.hflag = lf->hflag;
+ bm_log_face_id_set(log, f, GET_UINT_FROM_POINTER(key));
}
}
static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
{
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
GHashIterator gh_iter;
GHASH_ITER (gh_iter, verts) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- unsigned int id = GET_INT_FROM_POINTER(key);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
BMVert *v = bm_log_vert_from_id(log, id);
float mask;
short normal[3];
@@ -331,8 +340,21 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
normal_short_to_float_v3(v->no, normal);
SWAP(char, v->head.hflag, lv->hflag);
mask = lv->mask;
- lv->mask = vert_mask_get(bm, v);
- vert_mask_set(bm, v, mask);
+ lv->mask = vert_mask_get(v, cd_vert_mask_offset);
+ vert_mask_set(v, mask, cd_vert_mask_offset);
+ }
+}
+
+static void bm_log_face_values_swap(BMLog *log, GHash *faces)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
+ BMFace *f = bm_log_face_from_id(log, id);
+
+ SWAP(char, f->head.hflag, lf->hflag);
}
}
@@ -362,16 +384,17 @@ static void bm_log_assign_ids(BMesh *bm, BMLog *log)
/* Allocate an empty log entry */
static BMLogEntry *bm_log_entry_create(void)
{
- BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), AT);
+ BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), __func__);
- entry->deleted_verts = BLI_ghash_ptr_new(AT);
- entry->deleted_faces = BLI_ghash_ptr_new(AT);
- entry->added_verts = BLI_ghash_ptr_new(AT);
- entry->added_faces = BLI_ghash_ptr_new(AT);
- entry->modified_verts = BLI_ghash_ptr_new(AT);
+ entry->deleted_verts = BLI_ghash_ptr_new(__func__);
+ entry->deleted_faces = BLI_ghash_ptr_new(__func__);
+ entry->added_verts = BLI_ghash_ptr_new(__func__);
+ entry->added_faces = BLI_ghash_ptr_new(__func__);
+ entry->modified_verts = BLI_ghash_ptr_new(__func__);
+ entry->modified_faces = BLI_ghash_ptr_new(__func__);
- entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 1, 64, 0);
- entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 1, 64, 0);
+ entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 0, 64, BLI_MEMPOOL_NOP);
+ entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 0, 64, BLI_MEMPOOL_NOP);
return entry;
}
@@ -386,6 +409,7 @@ static void bm_log_entry_free(BMLogEntry *entry)
BLI_ghash_free(entry->added_verts, NULL, NULL);
BLI_ghash_free(entry->added_faces, NULL, NULL);
BLI_ghash_free(entry->modified_verts, NULL, NULL);
+ BLI_ghash_free(entry->modified_faces, NULL, NULL);
BLI_mempool_destroy(entry->pool_verts);
BLI_mempool_destroy(entry->pool_faces);
@@ -397,7 +421,7 @@ static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
GHASH_ITER (gh_iter, id_ghash) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_INT_FROM_POINTER(key);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
if (range_tree_uint_has(unused_ids, id)) {
range_tree_uint_take(unused_ids, id);
@@ -420,16 +444,16 @@ static int uint_compare(const void *a_v, const void *b_v)
* 10 -> 3
* 3 -> 1
*/
-static GHash *bm_log_compress_ids_to_indices(unsigned int *ids, int totid)
+static GHash *bm_log_compress_ids_to_indices(unsigned int *ids, unsigned int totid)
{
- GHash *map = BLI_ghash_int_new_ex(AT, totid);
- int i;
+ GHash *map = BLI_ghash_int_new_ex(__func__, totid);
+ unsigned int i;
qsort(ids, totid, sizeof(*ids), uint_compare);
for (i = 0; i < totid; i++) {
- void *key = SET_INT_IN_POINTER(ids[i]);
- void *val = SET_INT_IN_POINTER(i);
+ void *key = SET_UINT_IN_POINTER(ids[i]);
+ void *val = SET_UINT_IN_POINTER(i);
BLI_ghash_insert(map, key, val);
}
@@ -443,7 +467,7 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
GHASH_ITER (gh_iter, id_ghash) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_INT_FROM_POINTER(key);
+ unsigned int id = GET_UINT_FROM_POINTER(key);
range_tree_uint_release(log->unused_ids, id);
}
}
@@ -453,11 +477,11 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
/* Allocate, initialize, and assign a new BMLog */
BMLog *BM_log_create(BMesh *bm)
{
- BMLog *log = MEM_callocN(sizeof(*log), AT);
+ BMLog *log = MEM_callocN(sizeof(*log), __func__);
log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
- log->id_to_elem = BLI_ghash_ptr_new_ex(AT, bm->totvert + bm->totface);
- log->elem_to_id = BLI_ghash_ptr_new_ex(AT, bm->totvert + bm->totface);
+ log->id_to_elem = BLI_ghash_ptr_new_ex(__func__, (unsigned int)(bm->totvert + bm->totface));
+ log->elem_to_id = BLI_ghash_ptr_new_ex(__func__, (unsigned int)(bm->totvert + bm->totface));
/* Assign IDs to all existing vertices and faces */
bm_log_assign_ids(bm, log);
@@ -506,6 +530,7 @@ BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_faces);
}
return log;
@@ -555,37 +580,37 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
/* Put all vertex IDs into an array */
i = 0;
- varr = MEM_mallocN(sizeof(int) * bm->totvert, AT);
+ varr = MEM_mallocN(sizeof(int) * (size_t)bm->totvert, __func__);
BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v);
}
/* Put all face IDs into an array */
i = 0;
- farr = MEM_mallocN(sizeof(int) * bm->totface, AT);
+ farr = MEM_mallocN(sizeof(int) * (size_t)bm->totface, __func__);
BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f);
}
/* Create BMVert index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(varr, bm->totvert);
+ id_to_idx = bm_log_compress_ids_to_indices(varr, (unsigned int)bm->totvert);
i = 0;
BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
const unsigned id = bm_log_vert_id_get(log, v);
- const void *key = SET_INT_IN_POINTER(id);
+ const void *key = SET_UINT_IN_POINTER(id);
const void *val = BLI_ghash_lookup(id_to_idx, key);
- ((int *)varr)[i++] = GET_INT_FROM_POINTER(val);
+ ((unsigned int *)varr)[i++] = GET_UINT_FROM_POINTER(val);
}
BLI_ghash_free(id_to_idx, NULL, NULL);
/* Create BMFace index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(farr, bm->totface);
+ id_to_idx = bm_log_compress_ids_to_indices(farr, (unsigned int)bm->totface);
i = 0;
BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
const unsigned id = bm_log_face_id_get(log, f);
- const void *key = SET_INT_IN_POINTER(id);
+ const void *key = SET_UINT_IN_POINTER(id);
const void *val = BLI_ghash_lookup(id_to_idx, key);
- ((int *)farr)[i++] = GET_INT_FROM_POINTER(val);
+ ((unsigned int *)farr)[i++] = GET_UINT_FROM_POINTER(val);
}
BLI_ghash_free(id_to_idx, NULL, NULL);
@@ -701,6 +726,7 @@ void BM_log_undo(BMesh *bm, BMLog *log)
/* Restore vertex coordinates, mask, and hflag */
bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ bm_log_face_values_swap(log, entry->modified_faces);
}
}
@@ -737,6 +763,7 @@ void BM_log_redo(BMesh *bm, BMLog *log)
/* Restore vertex coordinates, mask, and hflag */
bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ bm_log_face_values_swap(log, entry->modified_faces);
}
}
@@ -763,40 +790,57 @@ void BM_log_redo(BMesh *bm, BMLog *log)
* state so that a subsequent redo operation will restore the newer
* vertex state.
*/
-void BM_log_vert_before_modified(BMesh *bm, BMLog *log, BMVert *v)
+void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogEntry *entry = log->current_entry;
BMLogVert *lv;
unsigned int v_id = bm_log_vert_id_get(log, v);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
/* Find or create the BMLogVert entry */
if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
- bm_log_vert_bmvert_copy(bm, lv, v);
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
}
else if (!BLI_ghash_haskey(entry->modified_verts, key)) {
- lv = bm_log_vert_alloc(bm, log, v);
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
BLI_ghash_insert(entry->modified_verts, key, lv);
}
}
+
/* Log a new vertex as added to the BMesh
*
* The new vertex gets a unique ID assigned. It is then added to a map
* of added vertices, with the key being its ID and the value
* containing everything needed to reconstruct that vertex.
*/
-void BM_log_vert_added(BMesh *bm, BMLog *log, BMVert *v)
+void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogVert *lv;
unsigned int v_id = range_tree_uint_take_any(log->unused_ids);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
bm_log_vert_id_set(log, v, v_id);
- lv = bm_log_vert_alloc(bm, log, v);
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
BLI_ghash_insert(log->current_entry->added_verts, key, lv);
}
+
+/* Log a face before it is modified
+ *
+ * This is intended to handle only header flags and we always
+ * assume face has been added before
+ */
+void BM_log_face_modified(BMLog *log, BMFace *f)
+{
+ BMLogFace *lf;
+ unsigned int f_id = bm_log_face_id_get(log, f);
+ void *key = SET_UINT_IN_POINTER(f_id);
+
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(log->current_entry->modified_faces, key, lf);
+}
+
/* Log a new face as added to the BMesh
*
* The new face gets a unique ID assigned. It is then added to a map
@@ -807,7 +851,7 @@ void BM_log_face_added(BMLog *log, BMFace *f)
{
BMLogFace *lf;
unsigned int f_id = range_tree_uint_take_any(log->unused_ids);
- void *key = SET_INT_IN_POINTER(f_id);
+ void *key = SET_UINT_IN_POINTER(f_id);
/* Only triangles are supported for now */
BLI_assert(f->len == 3);
@@ -833,11 +877,11 @@ void BM_log_face_added(BMLog *log, BMFace *f)
* If there's a move record for the vertex, that's used as the
* vertices original location, then the move record is deleted.
*/
-void BM_log_vert_removed(BMesh *bm, BMLog *log, BMVert *v)
+void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogEntry *entry = log->current_entry;
unsigned int v_id = bm_log_vert_id_get(log, v);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
/* if it has a key, it shouldn't be NULL */
BLI_assert(!!BLI_ghash_lookup(entry->added_verts, key) ==
@@ -849,7 +893,7 @@ void BM_log_vert_removed(BMesh *bm, BMLog *log, BMVert *v)
else {
BMLogVert *lv, *lv_mod;
- lv = bm_log_vert_alloc(bm, log, v);
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
BLI_ghash_insert(entry->deleted_verts, key, lv);
/* If the vertex was modified before deletion, ensure that the
@@ -878,7 +922,7 @@ void BM_log_face_removed(BMLog *log, BMFace *f)
{
BMLogEntry *entry = log->current_entry;
unsigned int f_id = bm_log_face_id_get(log, f);
- void *key = SET_INT_IN_POINTER(f_id);
+ void *key = SET_UINT_IN_POINTER(f_id);
/* if it has a key, it shouldn't be NULL */
BLI_assert(!!BLI_ghash_lookup(entry->added_faces, key) ==
@@ -898,13 +942,14 @@ void BM_log_face_removed(BMLog *log, BMFace *f)
/* Log all vertices/faces in the BMesh as added */
void BM_log_all_added(BMesh *bm, BMLog *log)
{
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
BMIter bm_iter;
BMVert *v;
BMFace *f;
/* Log all vertices as newly created */
BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
- BM_log_vert_added(bm, log, v);
+ BM_log_vert_added(log, v, cd_vert_mask_offset);
}
/* Log all faces as newly created */
@@ -916,6 +961,7 @@ void BM_log_all_added(BMesh *bm, BMLog *log)
/* Log all vertices/faces in the BMesh as removed */
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
{
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
BMIter bm_iter;
BMVert *v;
BMFace *f;
@@ -927,7 +973,7 @@ void BM_log_before_all_removed(BMesh *bm, BMLog *log)
/* Log deletion of all vertices */
BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
- BM_log_vert_removed(bm, log, v);
+ BM_log_vert_removed(log, v, cd_vert_mask_offset);
}
}
@@ -939,7 +985,7 @@ const float *BM_log_original_vert_co(BMLog *log, BMVert *v)
BMLogEntry *entry = log->current_entry;
const BMLogVert *lv;
unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
BLI_assert(entry);
@@ -957,7 +1003,7 @@ const short *BM_log_original_vert_no(BMLog *log, BMVert *v)
BMLogEntry *entry = log->current_entry;
const BMLogVert *lv;
unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
BLI_assert(entry);
@@ -975,7 +1021,7 @@ float BM_log_original_mask(BMLog *log, BMVert *v)
BMLogEntry *entry = log->current_entry;
const BMLogVert *lv;
unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = SET_INT_IN_POINTER(v_id);
+ void *key = SET_UINT_IN_POINTER(v_id);
BLI_assert(entry);
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
index 3cd2fd70081..7a26506439f 100644
--- a/source/blender/bmesh/intern/bmesh_log.h
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -61,16 +61,19 @@ void BM_log_undo(BMesh *bm, BMLog *log);
void BM_log_redo(BMesh *bm, BMLog *log);
/* Log a vertex before it is modified */
-void BM_log_vert_before_modified(BMesh *bm, BMLog *log, struct BMVert *v);
+void BM_log_vert_before_modified(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset);
/* Log a new vertex as added to the BMesh */
-void BM_log_vert_added(BMesh *bm, BMLog *log, struct BMVert *v);
+void BM_log_vert_added(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset);
+
+/* Log a face before it is modified */
+void BM_log_face_modified(BMLog *log, struct BMFace *f);
/* Log a new face as added to the BMesh */
void BM_log_face_added(BMLog *log, struct BMFace *f);
/* Log a vertex as removed from the BMesh */
-void BM_log_vert_removed(BMesh *bm, BMLog *log, struct BMVert *v);
+void BM_log_vert_removed(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset);
/* Log a face as removed from the BMesh */
void BM_log_face_removed(BMLog *log, struct BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 77505242002..eff3cf220f3 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -236,55 +236,30 @@ void BM_mesh_select_mode_flush(BMesh *bm)
*/
void BM_mesh_deselect_flush(BMesh *bm)
{
- BMEdge *e;
- BMLoop *l_iter;
- BMLoop *l_first;
- BMFace *f;
-
BMIter eiter;
- BMIter fiter;
-
- bool ok;
+ BMEdge *e;
- /* we can use 2 sections here because the second loop isnt checking edge selection */
-#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
- {
-#pragma omp section
- {
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ if (!BM_elem_flag_test(e->v1, BM_ELEM_SELECT) ||
+ !BM_elem_flag_test(e->v2, BM_ELEM_SELECT))
{
BM_elem_flag_disable(e, BM_ELEM_SELECT);
}
}
- }
-#pragma omp section
- {
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = true;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = false;
- }
+ if (e->l && !BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
- if (ok == false) {
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
- }
+ l_iter = l_first = e->l;
+ do {
+ BM_elem_flag_disable(l_iter->f, BM_ELEM_SELECT);
+ } while ((l_iter = l_iter->radial_next) != l_first);
}
}
}
- /* end sections */
/* Remove any deselected elements from the BMEditSelection */
BM_select_history_validate(bm);
@@ -925,7 +900,7 @@ bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
}
void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const char hflag_test)
+ const bool respecthide, const bool overwrite, const char hflag_test)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
@@ -933,6 +908,8 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
+ const char hflag_nosel = hflag & ~BM_ELEM_SELECT;
+
int i;
BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
@@ -971,17 +948,22 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
- if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
- continue;
+ if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
+ /* pass */
}
- if (hflag_test && !BM_elem_flag_test(ele, hflag_test)) {
- continue;
+ else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, false);
+ }
+ BM_elem_flag_disable(ele, hflag);
}
-
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, false);
+ else if (overwrite) {
+ /* no match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, true);
+ }
+ BM_elem_flag_enable(ele, hflag_nosel);
}
- BM_elem_flag_disable(ele, hflag);
}
}
}
@@ -989,7 +971,7 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
}
void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const char hflag_test)
+ const bool respecthide, const bool overwrite, const char hflag_test)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
@@ -1021,17 +1003,23 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
- if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
- continue;
+ if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
+ /* pass */
}
- if (hflag_test && !BM_elem_flag_test(ele, hflag_test)) {
- continue;
+ else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
+ /* match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, true);
+ }
+ BM_elem_flag_enable(ele, hflag_nosel);
}
-
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, true);
+ else if (overwrite) {
+ /* no match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, false);
+ }
+ BM_elem_flag_disable(ele, hflag);
}
- BM_elem_flag_enable(ele, hflag_nosel);
}
}
}
@@ -1041,14 +1029,14 @@ void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hfla
const bool respecthide)
{
/* call with 0 hflag_test */
- BM_mesh_elem_hflag_disable_test(bm, htype, hflag, respecthide, 0);
+ BM_mesh_elem_hflag_disable_test(bm, htype, hflag, respecthide, false, 0);
}
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag,
const bool respecthide)
{
/* call with 0 hflag_test */
- BM_mesh_elem_hflag_enable_test(bm, htype, hflag, respecthide, 0);
+ BM_mesh_elem_hflag_enable_test(bm, htype, hflag, respecthide, false, 0);
}
/***************** Mesh Hiding stuff *********** */
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index f23eac61278..99456ea2c98 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -44,9 +44,9 @@ void BM_face_hide_set(BMFace *f, const bool hide);
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select);
void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const char hflag_test);
+ const bool respecthide, const bool overwrite, const char hflag_test);
void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const char hflag_test);
+ const bool respecthide, const bool overwrite, const char hflag_test);
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag,
const bool respecthide);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 7a0c12793f3..e9d3c36eb1a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -31,6 +31,7 @@
#include "DNA_listBase.h"
#include "DNA_object_types.h"
+#include "BLI_linklist_stack.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -52,12 +53,12 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize)
bm->epool = BLI_mempool_create(sizeof(BMEdge), allocsize->totedge,
bm_mesh_chunksize_default.totedge, BLI_MEMPOOL_ALLOW_ITER);
bm->lpool = BLI_mempool_create(sizeof(BMLoop), allocsize->totloop,
- bm_mesh_chunksize_default.totloop, 0);
+ bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_NOP);
bm->fpool = BLI_mempool_create(sizeof(BMFace), allocsize->totface,
bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER);
#ifdef USE_BMESH_HOLES
- bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0);
+ bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, BLI_MEMPOOL_NOP);
#endif
}
@@ -67,9 +68,9 @@ void BM_mesh_elem_toolflags_ensure(BMesh *bm)
return;
}
- bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0);
- bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0);
- bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0);
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
{
@@ -431,6 +432,240 @@ void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*
MEM_freeN(edgevec);
}
+/**
+ * Helpers for #BM_mesh_loop_normals_update and #BM_loops_calc_normals_vnos
+ */
+static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float split_angle,
+ float (*r_lnos)[3])
+{
+ BMIter eiter;
+ BMEdge *e;
+ int i;
+
+ const bool check_angle = (split_angle < (float)M_PI);
+
+ if (check_angle) {
+ split_angle = cosf(split_angle);
+ }
+
+ {
+ char hflag = BM_LOOP;
+ if (vnos) {
+ hflag |= BM_VERT;
+ }
+ if (fnos) {
+ hflag |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, hflag);
+ }
+
+ /* This first loop checks which edges are actually smooth, and pre-populate lnos with vnos (as if they were
+ * all smooth).
+ */
+ BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
+ BMLoop *l_a, *l_b;
+
+ BM_elem_index_set(e, i); /* set_inline */
+ BM_elem_flag_disable(e, BM_ELEM_TAG); /* Clear tag (means edge is sharp). */
+
+ /* An edge with only two loops, might be smooth... */
+ if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+ bool is_angle_smooth = true;
+ if (check_angle) {
+ const float *no_a = fnos ? fnos[BM_elem_index_get(l_a->f)] : l_a->f->no;
+ const float *no_b = fnos ? fnos[BM_elem_index_get(l_b->f)] : l_b->f->no;
+ is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle);
+ }
+
+ /* We only tag edges that are *really* smooth... */
+ if (is_angle_smooth &&
+ BM_elem_flag_test_bool(e, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test_bool(l_a->f, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test_bool(l_b->f, BM_ELEM_SMOOTH))
+ {
+ const float *no;
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+
+ /* linked vertices might be fully smooth, copy their normals to loop ones. */
+ no = vnos ? vnos[BM_elem_index_get(l_a->v)] : l_a->v->no;
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_a)], no);
+ no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no;
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no);
+ }
+ }
+ }
+
+ bm->elem_index_dirty &= ~BM_EDGE;
+}
+
+/* BMesh version of BKE_mesh_normals_loop_split() in mesh_evaluate.c */
+static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3])
+{
+ BMIter fiter;
+ BMFace *f_curr;
+
+ /* Temp normal stack. */
+ BLI_SMALLSTACK_DECLARE(normal, float *);
+
+ {
+ char hflag = BM_LOOP;
+ if (vcos) {
+ hflag |= BM_VERT;
+ }
+ if (fnos) {
+ hflag |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, hflag);
+ }
+
+ /* We now know edges that can be smoothed (they are tagged), and edges that will be hard (they aren't).
+ * Now, time to generate the normals.
+ */
+ BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_curr, *l_first;
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
+ do {
+ if (BM_elem_flag_test_bool(l_curr->e, BM_ELEM_TAG)) {
+ /* A smooth edge.
+ * We skip it because it is either:
+ * - in the middle of a 'smooth fan' already computed (or that will be as soon as we hit
+ * one of its ends, i.e. one of its two sharp edges), or...
+ * - the related vertex is a "full smooth" one, in which case pre-populated normals from vertex
+ * are just fine!
+ */
+ }
+ else if (!BM_elem_flag_test_bool(l_curr->prev->e, BM_ELEM_TAG)) {
+ /* Simple case (both edges around that vertex are sharp in related polygon),
+ * this vertex just takes its poly normal.
+ */
+ const float *no = fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no;
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
+ }
+ else {
+ /* We have to fan around current vertex, until we find the other non-smooth edge,
+ * and accumulate face normals into the vertex!
+ * Note in case this vertex has only one sharp edge, this is a waste because the normal is the same as
+ * the vertex normal, but I do not see any easy way to detect that (would need to count number
+ * of sharp edges per vertex, I doubt the additional memory usage would be worth it, especially as
+ * it should not be a common case in real-life meshes anyway).
+ */
+ BMVert *v_pivot = l_curr->v;
+ BMEdge *e_next;
+ BMLoop *lfan_pivot, *lfan_pivot_next;
+ float lnor[3] = {0.0f, 0.0f, 0.0f};
+ float vec_curr[3], vec_next[3];
+
+ const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
+
+ lfan_pivot = l_curr;
+ e_next = lfan_pivot->e; /* Current edge here, actually! */
+
+ /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
+ {
+ const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_curr, co_2, co_pivot);
+ normalize_v3(vec_curr);
+ }
+
+ while (true) {
+ /* Much simpler than in sibling code with basic Mesh data! */
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
+ if (lfan_pivot_next) {
+ BLI_assert(lfan_pivot_next->v == v_pivot);
+ }
+ else {
+ /* next edge is non-manifold, we have to find it ourselves! */
+ e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
+ }
+
+ /* Compute edge vector.
+ * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing them
+ * twice (or more) here. However, time gained is not worth memory and time lost,
+ * given the fact that this code should not be called that much in real-life meshes...
+ */
+ {
+ const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_next, co_2, co_pivot);
+ normalize_v3(vec_next);
+ }
+
+ {
+ /* Code similar to accumulate_vertex_normals_poly. */
+ /* Calculate angle between the two poly edges incident on this vertex. */
+ const BMFace *f = lfan_pivot->f;
+ const float fac = saacos(dot_v3v3(vec_next, vec_curr));
+ const float *no = fnos ? fnos[BM_elem_index_get(f)] : f->no;
+ /* Accumulate */
+ madd_v3_v3fl(lnor, no, fac);
+ }
+
+ /* We store here a pointer to all loop-normals processed. */
+ BLI_SMALLSTACK_PUSH(normal, (float *)r_lnos[BM_elem_index_get(lfan_pivot)]);
+
+ if (!BM_elem_flag_test_bool(e_next, BM_ELEM_TAG)) {
+ /* Next edge is sharp, we have finished with this fan of faces around this vert! */
+ break;
+ }
+
+ /* Copy next edge vector to current one. */
+ copy_v3_v3(vec_curr, vec_next);
+ /* Next pivot loop to current one. */
+ lfan_pivot = lfan_pivot_next;
+ }
+
+ /* In case we get a zero normal here, just use vertex normal already set! */
+ if (LIKELY(normalize_v3(lnor) != 0.0f)) {
+ /* Copy back the final computed normal into all related loop-normals. */
+ float *nor;
+ while ((nor = BLI_SMALLSTACK_POP(normal))) {
+ copy_v3_v3(nor, lnor);
+ }
+ }
+ }
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+
+ BLI_SMALLSTACK_FREE(normal);
+}
+
+#if 0 /* Unused currently */
+/**
+ * \brief BMesh Compute Loop Normals
+ *
+ * Updates the loop normals of a mesh. Assumes vertex and face normals are valid (else call BM_mesh_normals_update()
+ * first)!
+ */
+void BM_mesh_loop_normals_update(BMesh *bm, const float split_angle, float (*r_lnos)[3])
+{
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth... */
+ bm_mesh_edges_sharp_tag(bm, NULL, NULL, split_angle, r_lnos);
+
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(bm, NULL, NULL, r_lnos);
+}
+#endif
+
+/**
+ * \brief BMesh Compute Loop Normals from/to external data.
+ *
+ * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
+ * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
+ */
+void BM_loops_calc_normal_vcos(BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3],
+ const float split_angle, float (*r_lnos)[3])
+{
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth... */
+ bm_mesh_edges_sharp_tag(bm, vnos, fnos, split_angle, r_lnos);
+
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos);
+}
+
static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to)
{
/* switch multires data out of tangent space */
@@ -585,19 +820,39 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag)
#pragma omp section
{
- if (hflag & BM_FACE) {
- if (bm->elem_index_dirty & BM_FACE) {
+ if (hflag & (BM_FACE | BM_LOOP)) {
+ if (bm->elem_index_dirty & (BM_FACE | BM_LOOP)) {
BMIter iter;
BMElem *ele;
+ const bool update_face = (hflag & BM_FACE) && (bm->elem_index_dirty & BM_FACE);
+ const bool update_loop = (hflag & BM_LOOP) && (bm->elem_index_dirty & BM_LOOP);
+
int index;
+ int index_loop = 0;
+
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) {
- BM_elem_index_set(ele, index); /* set_ok */
+ if (update_face) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+
+ if (update_loop) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)ele);
+ do {
+ BM_elem_index_set(l_iter, index_loop++); /* set_ok */
+ } while ((l_iter = l_iter->next) != l_first);
+ }
}
+
BLI_assert(index == bm->totface);
+ if (update_loop) {
+ BLI_assert(index_loop == bm->totloop);
+ }
}
else {
- // printf("%s: skipping face index calc!\n", __func__);
+ // printf("%s: skipping face/loop index calc!\n", __func__);
}
}
}
@@ -899,7 +1154,7 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
*
* WARNING: Be careful if you keep pointers to affected BM elements, or arrays, when using this func!
*/
-void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx)
+void BM_mesh_remap(BMesh *bm, unsigned int *vert_idx, unsigned int *edge_idx, unsigned int *face_idx)
{
/* Mapping old to new pointers. */
GHash *vptr_map = NULL, *eptr_map = NULL, *fptr_map = NULL;
@@ -916,7 +1171,7 @@ void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx)
if (vert_idx) {
BMVert **verts_pool, *verts_copy, **vep;
int i, totvert = bm->totvert;
- int *new_idx = NULL;
+ unsigned int *new_idx = NULL;
/* Init the old-to-new vert pointers mapping */
vptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap vert pointers mapping", bm->totvert);
@@ -950,7 +1205,7 @@ void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx)
if (edge_idx) {
BMEdge **edges_pool, *edges_copy, **edp;
int i, totedge = bm->totedge;
- int *new_idx = NULL;
+ unsigned int *new_idx = NULL;
/* Init the old-to-new vert pointers mapping */
eptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap edge pointers mapping", bm->totedge);
@@ -983,7 +1238,7 @@ void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx)
if (face_idx) {
BMFace **faces_pool, *faces_copy, **fap;
int i, totface = bm->totface;
- int *new_idx = NULL;
+ unsigned int *new_idx = NULL;
/* Init the old-to-new vert pointers mapping */
fptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap face pointers mapping", bm->totface);
@@ -1006,7 +1261,7 @@ void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx)
BLI_ghash_insert(fptr_map, (void *)*fap, (void *)new_fap);
}
- bm->elem_index_dirty |= BM_FACE;
+ bm->elem_index_dirty |= BM_FACE | BM_LOOP;
MEM_freeN(faces_pool);
MEM_freeN(faces_copy);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index cba4260eaea..3923c2515a3 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -39,6 +39,8 @@ void BM_mesh_clear(BMesh *bm);
void BM_mesh_normals_update(BMesh *bm);
void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]);
+void BM_loops_calc_normal_vcos(BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3],
+ const float split_angle, float (*r_lnos)[3]);
void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag);
void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag);
@@ -67,7 +69,7 @@ BMFace *BM_face_at_index_find(BMesh *bm, const int index);
int BM_mesh_elem_count(BMesh *bm, const char htype);
-void BM_mesh_remap(BMesh *bm, int *vert_idx, int *edge_idx, int *face_idx);
+void BM_mesh_remap(BMesh *bm, unsigned int *vert_idx, unsigned int *edge_idx, unsigned int *face_idx);
typedef struct BMAllocTemplate {
int totvert, totedge, totloop, totface;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index d92fe45afcd..b7be0cc0ae2 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -233,12 +233,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
BMEdge *e, **etable = NULL;
BMFace *f;
float (*keyco)[3] = NULL;
- int *keyi;
int totuv, i, j;
int cd_vert_bweight_offset;
int cd_edge_bweight_offset;
int cd_edge_crease_offset;
+ int cd_shape_keyindex_offset;
/* free custom data */
/* this isnt needed in most cases but do just incase */
@@ -325,6 +325,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+ cd_shape_keyindex_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1;
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
v = vtable[i] = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
@@ -348,10 +349,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
/* set shapekey data */
if (me->key) {
/* set shape key original index */
- keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
- if (keyi) {
- *keyi = i;
- }
+ if (cd_shape_keyindex_offset != -1) BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
for (block = me->key->block.first, j = 0; block; block = block->next, j++) {
float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, j);
@@ -441,6 +439,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
}
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
+ bm->elem_index_dirty |= BM_LOOP; /* did not set the loop indices */
if (me->mselect && me->totselect != 0) {
@@ -495,9 +494,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
*/
static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
{
+ const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
BMVert **vertMap = NULL;
BMVert *eve;
- int index;
int i = 0;
BMIter iter;
@@ -505,32 +504,22 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
BLI_assert(ototvert > 0);
vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
- if (CustomData_has_layer(&bm->vdata, CD_SHAPE_KEYINDEX)) {
- int *keyi;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
- if (keyi) {
- if (((index = *keyi) != ORIGINDEX_NONE) && (index < ototvert)) {
- vertMap[index] = eve;
- }
- }
- else {
- if (i < ototvert) {
- vertMap[i] = eve;
- }
+ if (cd_shape_keyindex_offset != -1) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+ if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert)) {
+ vertMap[keyi] = eve;
}
- i++;
}
}
else {
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
if (i < ototvert) {
vertMap[i] = eve;
}
else {
break;
}
- i++;
}
}
@@ -634,6 +623,7 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
* end up with 'me->totface' and me->mface == NULL which can crash [#28625]
*/
me->totface = 0;
+ me->act_face = -1;
CustomData_copy(&bm->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
CustomData_copy(&bm->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
@@ -823,6 +813,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
/* see comment below, this logic is in twice */
if (me->key) {
+ const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
+
KeyBlock *currkey;
KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
@@ -866,16 +858,17 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
}
}
- if (act_is_basis) { /* active key is a base */
+ /* active key is a base */
+ if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
float (*fp)[3] = actkey->data;
- int *keyi;
ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert, "currkey->data");
mvert = me->mvert;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
- if (keyi && *keyi != ORIGINDEX_NONE) {
- sub_v3_v3v3(ofs[i], mvert->co, fp[*keyi]);
+ const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+
+ if (keyi != ORIGINDEX_NONE) {
+ sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
}
else {
/* if there are new vertices in the mesh, we can't propagate the offset
@@ -892,12 +885,14 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
}
for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
- int apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative));
- int *keyi;
+ const bool apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative));
+ int cd_shape_offset;
+ int keyi;
float (*ofs_pt)[3] = ofs;
- float *newkey, *oldkey, *fp;
+ float *newkey, (*oldkey)[3], *fp;
j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
+ cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j);
fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data");
@@ -910,26 +905,29 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
copy_v3_v3(fp, eve->co);
if (actkey != me->key->refkey) { /* important see bug [#30771] */
- if (oldverts) {
- keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
- if (*keyi != ORIGINDEX_NONE && *keyi < currkey->totelem) { /* valid old vertex */
- copy_v3_v3(mvert->co, oldverts[*keyi].co);
+ if (cd_shape_keyindex_offset != -1) {
+ if (oldverts) {
+ keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+ if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */
+ copy_v3_v3(mvert->co, oldverts[keyi].co);
+ }
}
}
}
}
else if (j != -1) {
/* in most cases this runs */
- copy_v3_v3(fp, CustomData_bmesh_get_n(&bm->vdata, eve->head.data, CD_SHAPEKEY, j));
+ copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
}
- else if (oldkey &&
- (keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX)) &&
- (*keyi != ORIGINDEX_NONE && *keyi < currkey->totelem))
+ else if ((oldkey != NULL) &&
+ (cd_shape_keyindex_offset != -1) &&
+ ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
+ (keyi < currkey->totelem))
{
/* old method of reconstructing keys via vertice's original key indices,
* currently used if the new method above fails (which is theoretically
* possible in certain cases of undo) */
- copy_v3_v3(fp, &oldkey[3 * (*keyi)]);
+ copy_v3_v3(fp, oldkey[keyi]);
}
else {
/* fail! fill in with dummy value */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.c b/source/blender/bmesh/intern/bmesh_mesh_validate.c
index e6eee16e49c..3a7a4f85e99 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_validate.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_validate.c
@@ -33,6 +33,7 @@
#ifdef DEBUG
#include "BLI_utildefines.h"
+#include "BLI_edgehash.h"
#include "bmesh.h"
@@ -53,6 +54,7 @@
*/
bool BM_mesh_validate(BMesh *bm)
{
+ EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, bm->totedge);
int errtot;
BMIter iter;
@@ -84,8 +86,21 @@ bool BM_mesh_validate(BMesh *bm)
/* check edges */
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- if (e->v1 == e->v2)
- ERRMSG("edge %d: duplicate index: %d", i, BM_elem_index_get(e->v1));
+ BMEdge *e_other;
+
+ if (e->v1 == e->v2) {
+ ERRMSG("edge %d: duplicate index: %d", i, BM_elem_index_get(e->v1));
+ }
+
+
+ /* build edgehash at the same time */
+ e_other = BLI_edgehash_lookup(edge_hash, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));
+ if (e_other) {
+ ERRMSG("edge %d, %d: are duplicates", i, BM_elem_index_get(e_other));
+ }
+ else {
+ BLI_edgehash_insert(edge_hash, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2), e);
+ }
}
/* edge radial structure */
@@ -177,7 +192,7 @@ bool BM_mesh_validate(BMesh *bm)
}
}
-
+ BLI_edgehash_free(edge_hash, NULL);
ERRMSG("Finished - errors %d", errtot);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index a7e3c12e5d7..60de592f964 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -32,7 +32,6 @@
#include "BLI_math.h"
#include "BLI_array.h"
-#include "BLI_smallhash.h"
#include "BKE_customdata.h"
@@ -178,8 +177,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
e = v->e;
do {
f = NULL;
- len = bmesh_radial_length(e->l);
- if (len == 2 && (e != baseedge) && (e != keepedge)) {
+ if (BM_edge_is_manifold(e) && (e != baseedge) && (e != keepedge)) {
f = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true);
/* return if couldn't join faces in manifold
* conditions */
@@ -193,8 +191,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
done = false;
break;
}
- e = bmesh_disk_edge_next(e, v);
- } while (e != v->e);
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
}
/* collapse the vertex */
@@ -205,14 +202,16 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
return false;
}
- /* get remaining two faces */
- f = e->l->f;
- f2 = e->l->radial_next->f;
-
- if (f != f2) {
- /* join two remaining faces */
- if (!BM_faces_join_pair(bm, f, f2, e, true)) {
- return false;
+ if (e->l) {
+ /* get remaining two faces */
+ f = e->l->f;
+ f2 = e->l->radial_next->f;
+
+ if (f != f2) {
+ /* join two remaining faces */
+ if (!BM_faces_join_pair(bm, f, f2, e, true)) {
+ return false;
+ }
}
}
}
@@ -281,11 +280,12 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f,
BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
/* could be an assert */
- if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b))) {
- return NULL;
- }
-
- if (f != l_a->f || f != l_b->f) {
+ if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b)) ||
+ UNLIKELY((f != l_a->f || f != l_b->f)))
+ {
+ if (r_l) {
+ *r_l = NULL;
+ }
return NULL;
}
@@ -301,8 +301,6 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f,
#endif
if (f_new) {
- BM_elem_attrs_copy(bm, bm, f, f_new);
-
/* handle multires update */
if (has_mdisp) {
BMLoop *l_iter;
@@ -368,11 +366,12 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
BLI_assert(!((n == 0) && BM_loop_is_adjacent(l_a, l_b)));
/* could be an assert */
- if (UNLIKELY((n == 0) && BM_loop_is_adjacent(l_a, l_b))) {
- return NULL;
- }
-
- if (l_a->f != l_b->f) {
+ if (UNLIKELY((n == 0) && BM_loop_is_adjacent(l_a, l_b)) ||
+ UNLIKELY(l_a->f != l_b->f))
+ {
+ if (r_l) {
+ *r_l = NULL;
+ }
return NULL;
}
@@ -390,9 +389,6 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
* The radial_next is for f and goes from v_b to v_a */
if (f_new) {
- BM_elem_attrs_copy(bm, bm, f, f_new);
- copy_v3_v3(f_new->no, f->no);
-
e = (*r_l)->e;
for (i = 0; i < n; i++) {
v_new = bmesh_semv(bm, v_b, e, &e_new);
@@ -495,12 +491,13 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
if (BLI_array_count(faces) >= 2) {
BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true);
if (f2) {
- BMLoop *l_new = NULL;
BMLoop *l_a, *l_b;
if ((l_a = BM_face_vert_share_loop(f2, tv)) &&
(l_b = BM_face_vert_share_loop(f2, tv2)))
{
+ BMLoop *l_new;
+
if (BM_face_split(bm, f2, l_a, l_b, &l_new, NULL, false)) {
e_new = l_new->e;
}
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index b4697935da5..f8cca0a3707 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -49,7 +49,7 @@
* for output slots, for single-type geometry slots, use the type name plus "out",
* (e.g. verts.out), for double-type slots, use the two type names plus "out",
* (e.g. vertfaces.out), for three-type slots, use geom. note that you can also
- * use more esohteric names (e.g. geom_skirt.out) so long as the comment next to the
+ * use more esoteric names (e.g. geom_skirt.out) so long as the comment next to the
* slot definition tells you what types of elements are in it.
*
*/
@@ -875,6 +875,7 @@ static BMOpDefine bmo_connect_verts_def = {
"connect_verts",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"check_degenerate", BMO_OP_SLOT_BOOL}, /* prevent splits with overlaps & intersections */
{{'\0'}},
},
/* slots_out */
@@ -1022,6 +1023,24 @@ static BMOpDefine bmo_dissolve_limit_def = {
};
/*
+ * Degenerate Dissolve.
+ *
+ * Dissolve edges with no length, faces with no area.
+ */
+static BMOpDefine bmo_dissolve_degenerate_def = {
+ "dissolve_degenerate",
+ /* slots_in */
+ {{"dist", BMO_OP_SLOT_FLT}, /* minimum distance to consider degenerate */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{{'\0'}}},
+ bmo_dissolve_degenerate_exec,
+ BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
+};
+
+/*
* Triangulate.
*/
static BMOpDefine bmo_triangulate_def = {
@@ -1100,7 +1119,7 @@ static BMOpDefine bmo_subdivide_edges_def = {
/*
* Subdivide Edge-Ring.
*
- * Take an edge-ring, and supdivide with interpolation options.
+ * Take an edge-ring, and subdivide with interpolation options.
*/
static BMOpDefine bmo_subdivide_edgering_def = {
"subdivide_edgering",
@@ -1673,6 +1692,7 @@ static BMOpDefine bmo_inset_region_def = {
{"use_even_offset", BMO_OP_SLOT_BOOL},
{"use_interpolate", BMO_OP_SLOT_BOOL},
{"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"use_edge_rail", BMO_OP_SLOT_BOOL},
{"thickness", BMO_OP_SLOT_FLT},
{"depth", BMO_OP_SLOT_FLT},
{"use_outset", BMO_OP_SLOT_BOOL},
@@ -1827,8 +1847,9 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_delete_def,
&bmo_dissolve_edges_def,
&bmo_dissolve_faces_def,
- &bmo_dissolve_limit_def,
&bmo_dissolve_verts_def,
+ &bmo_dissolve_limit_def,
+ &bmo_dissolve_degenerate_def,
&bmo_duplicate_def,
&bmo_holes_fill_def,
&bmo_face_attribute_fill_def,
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 4dba28ab035..2a6b4d70419 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -347,13 +347,10 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n
}
}
else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
- GHashIterator it;
- for (BLI_ghashIterator_init(&it, slot_src->data.ghash);
- BLI_ghashIterator_done(&it) == false;
- BLI_ghashIterator_step(&it))
- {
- void *key = BLI_ghashIterator_getKey(&it);
- void *val = BLI_ghashIterator_getValue(&it);
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, slot_src->data.ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ void *val = BLI_ghashIterator_getValue(&gh_iter);
BLI_ghash_insert(slot_dst->data.ghash, key, val);
}
}
@@ -722,17 +719,15 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
void BMO_slot_map_to_flag(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- GHashIterator it;
+ GHashIterator gh_iter;
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BMElemF *ele_f;
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- for (BLI_ghashIterator_init(&it, slot->data.ghash);
- (ele_f = BLI_ghashIterator_getKey(&it));
- BLI_ghashIterator_step(&it))
- {
+ GHASH_ITER (gh_iter, slot->data.ghash) {
+ ele_f = BLI_ghashIterator_getKey(&gh_iter);
if (ele_f->head.htype & htype) {
BMO_elem_flag_enable(bm, ele_f, oflag);
}
@@ -1167,9 +1162,9 @@ static void bmo_flag_layer_alloc(BMesh *bm)
bm->totflags++;
- bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totvert), 512, 0);
- bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0);
- bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0);
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totface, 512, BLI_MEMPOOL_NOP);
#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
{
@@ -1248,9 +1243,9 @@ static void bmo_flag_layer_free(BMesh *bm)
/* de-increment the totflags first.. */
bm->totflags--;
- bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, 0);
- bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0);
- bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0);
+ bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, BLI_MEMPOOL_NOP);
#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
{
@@ -1314,13 +1309,10 @@ static void bmo_flag_layer_free(BMesh *bm)
static void bmo_flag_layer_clear(BMesh *bm)
{
- BMElemF *ele;
/* set the index values since we are looping over all data anyway,
* may save time later on */
- int i;
const BMFlagLayer zero_flag = {0};
- BMIter iter;
const int totflags_offset = bm->totflags - 1;
#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
@@ -1328,6 +1320,9 @@ static void bmo_flag_layer_clear(BMesh *bm)
/* now go through and memcpy all the flag */
#pragma omp section
{
+ BMIter iter;
+ BMElemF *ele;
+ int i;
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
ele->oflags[totflags_offset] = zero_flag;
BM_elem_index_set(ele, i); /* set_inline */
@@ -1335,6 +1330,9 @@ static void bmo_flag_layer_clear(BMesh *bm)
}
#pragma omp section
{
+ BMIter iter;
+ BMElemF *ele;
+ int i;
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
ele->oflags[totflags_offset] = zero_flag;
BM_elem_index_set(ele, i); /* set_inline */
@@ -1342,6 +1340,9 @@ static void bmo_flag_layer_clear(BMesh *bm)
}
#pragma omp section
{
+ BMIter iter;
+ BMElemF *ele;
+ int i;
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
ele->oflags[totflags_offset] = zero_flag;
BM_elem_index_set(ele, i); /* set_inline */
@@ -1418,10 +1419,19 @@ void *BMO_iter_step(BMOIter *iter)
return ele;
}
else if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
- void *ret = BLI_ghashIterator_getKey(&iter->giter);
- iter->val = BLI_ghashIterator_getValue_p(&iter->giter);
+ void *ret;
+
- BLI_ghashIterator_step(&iter->giter);
+ if (BLI_ghashIterator_done(&iter->giter) == false) {
+ ret = BLI_ghashIterator_getKey(&iter->giter);
+ iter->val = BLI_ghashIterator_getValue_p(&iter->giter);
+
+ BLI_ghashIterator_step(&iter->giter);
+ }
+ else {
+ ret = NULL;
+ iter->val = NULL;
+ }
return ret;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 517a2c4fa01..9c1b7085835 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -56,8 +56,9 @@ void bmo_create_vert_exec(BMesh *bm, BMOperator *op);
void bmo_delete_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op);
-void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op);
+void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op);
+void bmo_dissolve_degenerate_exec(BMesh *bm, BMOperator *op);
void bmo_duplicate_exec(BMesh *bm, BMOperator *op);
void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op);
void bmo_face_attribute_fill_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 797c21d21b6..3422656b50c 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -37,7 +37,6 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill2d.h"
-#include "BLI_listbase.h"
#include "bmesh.h"
#include "bmesh_tools.h"
@@ -70,40 +69,16 @@ static bool testedgesidef(const float v1[2], const float v2[2], const float v3[2
}
/**
- * \brief COMPUTE POLY NORMAL
- *
- * Computes the normal of a planar
- * polygon See Graphics Gems for
- * computing newell normal.
- */
-static void calc_poly_normal(float normal[3], float verts[][3], int nverts)
-{
- float const *v_prev = verts[nverts - 1];
- float const *v_curr = verts[0];
- float n[3] = {0.0f};
- int i;
-
- /* Newell's Method */
- for (i = 0; i < nverts; v_prev = v_curr, v_curr = verts[++i]) {
- add_newell_cross_v3_v3v3(n, v_prev, v_curr);
- }
-
- if (UNLIKELY(normalize_v3_v3(normal, n) == 0.0f)) {
- normal[2] = 1.0f; /* other axis set to 0.0 */
- }
-}
-
-/**
* \brief COMPUTE POLY NORMAL (BMFace)
*
- * Same as #calc_poly_normal but operates directly on a bmesh face.
+ * Same as #normal_poly_v3 but operates directly on a bmesh face.
*/
static void bm_face_calc_poly_normal(const BMFace *f, float n[3])
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
- float const *v_prev = l_first->prev->v->co;
- float const *v_curr = l_first->v->co;
+ const float *v_prev = l_first->prev->v->co;
+ const float *v_curr = l_first->v->co;
zero_v3(n);
@@ -133,8 +108,8 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float r_no[3],
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
- float const *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)];
- float const *v_curr = vertexCos[BM_elem_index_get(l_first->v)];
+ const float *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)];
+ const float *v_curr = vertexCos[BM_elem_index_get(l_first->v)];
zero_v3(r_no);
@@ -229,15 +204,15 @@ void BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (
*/
float BM_face_calc_area(BMFace *f)
{
- BMLoop *l;
- BMIter iter;
+ BMLoop *l_iter, *l_first;
float (*verts)[3] = BLI_array_alloca(verts, f->len);
float area;
- int i;
+ unsigned int i = 0;
- BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
- copy_v3_v3(verts[i], l->v->co);
- }
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ copy_v3_v3(verts[i++], l_iter->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
if (f->len == 3) {
area = area_tri_v3(verts[0], verts[1], verts[2]);
@@ -246,9 +221,7 @@ float BM_face_calc_area(BMFace *f)
area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
}
else {
- float normal[3];
- calc_poly_normal(normal, verts, f->len);
- area = area_poly_v3(f->len, verts, normal);
+ area = area_poly_v3((const float (*)[3])verts, f->len);
}
return area;
@@ -311,7 +284,7 @@ void BM_face_calc_plane(BMFace *f, float r_plane[3])
sub_v3_v3v3(vec_b, verts[1]->co, verts[2]->co);
add_v3_v3v3(vec, vec_a, vec_b);
/* use the biggest edge length */
- if (dot_v3v3(r_plane, r_plane) < dot_v3v3(vec, vec)) {
+ if (len_squared_v3(r_plane) < len_squared_v3(vec)) {
copy_v3_v3(r_plane, vec);
}
}
@@ -388,46 +361,6 @@ void BM_face_calc_center_mean_weighted(BMFace *f, float r_cent[3])
}
/**
- * COMPUTE POLY PLANE
- *
- * Projects a set polygon's vertices to
- * a plane defined by the average
- * of its edges cross products
- */
-void calc_poly_plane(float (*verts)[3], const int nverts)
-{
-
- float avgc[3], norm[3], mag, avgn[3];
- float *v1, *v2, *v3;
- int i;
-
- if (nverts < 3)
- return;
-
- zero_v3(avgn);
- zero_v3(avgc);
-
- for (i = 0; i < nverts; i++) {
- v1 = verts[i];
- v2 = verts[(i + 1) % nverts];
- v3 = verts[(i + 2) % nverts];
- normal_tri_v3(norm, v1, v2, v3);
-
- add_v3_v3(avgn, norm);
- }
-
- if (UNLIKELY(normalize_v3(avgn) == 0.0f)) {
- avgn[2] = 1.0f;
- }
-
- for (i = 0; i < nverts; i++) {
- v1 = verts[i];
- mag = dot_v3v3(v1, avgn);
- madd_v3_v3fl(v1, avgn, -mag);
- }
-}
-
-/**
* \brief BM LEGAL EDGES
*
* takes in a face and a list of edges, and sets to NULL any edge in
@@ -456,15 +389,18 @@ static void scale_edge_v2f(float v1[2], float v2[2], const float fac)
* Rotates a polygon so that it's
* normal is pointing towards the mesh Z axis
*/
-void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts)
+void poly_rotate_plane(const float normal[3], float (*verts)[3], const unsigned int nverts)
{
float mat[3][3];
+ float co[3];
+ unsigned int i;
- if (axis_dominant_v3_to_m3(mat, normal)) {
- int i;
- for (i = 0; i < nverts; i++) {
- mul_m3_v3(mat, verts[i]);
- }
+ co[2] = 0.0f;
+
+ axis_dominant_v3_to_m3(mat, normal);
+ for (i = 0; i < nverts; i++) {
+ mul_v2_m3v3(co, mat, verts[i]);
+ copy_v3_v3(verts[i], co);
}
}
@@ -723,7 +659,7 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3])
int crosses = 0;
float onepluseps = 1.0f + (float)FLT_EPSILON * 150.0f;
- if (dot_v3v3(f->no, f->no) <= FLT_EPSILON * 10)
+ if (is_zero_v3(f->no))
BM_face_normal_update(f);
/* find best projection of face XY, XZ or YZ: barycentric weights of
@@ -860,7 +796,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
}
}
- f_new = BM_face_split(bm, f, l_v1, l_v2, &l_new, NULL, false);
+ f_new = BM_face_split(bm, f, l_v1, l_v2, &l_new, NULL, true);
copy_v3_v3(f_new->no, f->no);
if (use_tag) {
@@ -1061,7 +997,14 @@ void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len)
for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
BM_elem_index_set(l, i); /* set_loop */
mul_v2_m3v3(projverts[i], axis_mat, l->v->co);
+ }
+ /* first test for completely convex face */
+ if (is_poly_convex_v2((const float (*)[2])projverts, f->len)) {
+ return;
+ }
+
+ for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
out[0] = max_ff(out[0], projverts[i][0]);
out[1] = max_ff(out[1], projverts[i][1]);
}
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index 7ec418b2253..cac4713c8b2 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -72,8 +72,7 @@ enum {
#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f))
#define BM_ELEM_API_FLAG_CLEAR(element) ((element)->head.api_flag = 0)
-void calc_poly_plane(float (*verts)[3], const int nverts);
-void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts);
+void poly_rotate_plane(const float normal[3], float (*verts)[3], unsigned const int nverts);
/* include the rest of our private declarations */
#include "bmesh_structure.h"
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index e66af07eeac..67f333215d9 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -1236,7 +1236,7 @@ float BM_vert_calc_shell_factor(BMVert *v)
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
+ accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle;
accum_angle += face_angle;
}
@@ -1260,7 +1260,7 @@ float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
+ accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle;
accum_angle += face_angle;
tot_sel++;
}
@@ -1441,8 +1441,8 @@ BMEdge *BM_edge_find_double(BMEdge *e)
bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
{
BMVert *v_search = varr[0]; /* we can search any of the verts in the array */
- BMIter viter;
- BMFace *f;
+ BMIter liter;
+ BMLoop *l_search;
#if 0
@@ -1470,8 +1470,8 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
int i;
- BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
- if (f->len == len) {
+ BM_ITER_ELEM (l_search, &liter, v_search, BM_LOOPS_OF_VERT) {
+ if (l_search->f->len == len) {
if (is_init == false) {
is_init = true;
for (i = 0; i < len; i++) {
@@ -1484,21 +1484,21 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
{
BMLoop *l_iter;
- BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ /* skip ourselves */
+ l_iter = l_search->next;
do {
if (!BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
is_found = false;
break;
}
- } while ((l_iter = l_iter->next) != l_first);
+ } while ((l_iter = l_iter->next) != l_search);
}
if (is_found) {
if (r_existface) {
- *r_existface = f;
+ *r_existface = l_search->f;
}
break;
}
@@ -1799,6 +1799,60 @@ bool BM_face_exists_overlap_subset(BMVert **varr, const int len)
return is_overlap;
}
+bool BM_vert_is_all_edge_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
+{
+ if (v->e) {
+ BMEdge *e_other;
+ BMIter eiter;
+
+ BM_ITER_ELEM (e_other, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
+ if (!respect_hide || !BM_elem_flag_test(e_other, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(e_other, hflag)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool BM_vert_is_all_face_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
+{
+ if (v->e) {
+ BMEdge *f_other;
+ BMIter fiter;
+
+ BM_ITER_ELEM (f_other, &fiter, (BMVert *)v, BM_FACES_OF_VERT) {
+ if (!respect_hide || !BM_elem_flag_test(f_other, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(f_other, hflag)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool BM_edge_is_all_face_flag_test(const BMEdge *e, const char hflag, const bool respect_hide)
+{
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = e->l;
+ do {
+ if (!respect_hide || !BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(l_iter->f, hflag)) {
+ return false;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+
+ return true;
+}
/* convenience functions for checking flags */
bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag)
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index d4b6cd0e061..36e67a73f1f 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -119,6 +119,10 @@ void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
void BM_edge_ordered_verts_ex(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
const BMLoop *edge_loop);
+bool BM_vert_is_all_edge_flag_test(const BMVert *v, const char hflag, const bool respect_hide);
+bool BM_vert_is_all_face_flag_test(const BMVert *v, const char hflag, const bool respect_hide);
+bool BM_edge_is_all_face_flag_test(const BMEdge *e, const char hflag, const bool respect_hide);
+
bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag);
bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag);
bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag);
diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c
index acb97d328cc..75513a48d98 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.c
+++ b/source/blender/bmesh/intern/bmesh_walkers.c
@@ -115,7 +115,7 @@ void BMW_init(BMWalker *walker, BMesh *bm, int type,
BLI_assert(mask_face == 0 || (walker->valid_mask & BM_FACE));
}
- walker->worklist = BLI_mempool_create(walker->structsize, 100, 100, BLI_MEMPOOL_SYSMALLOC);
+ walker->worklist = BLI_mempool_create(walker->structsize, 0, 128, BLI_MEMPOOL_NOP);
BLI_listbase_clear(&walker->states);
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers.h b/source/blender/bmesh/intern/bmesh_walkers.h
index ea1dbc61cc6..9b0c200adc5 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.h
+++ b/source/blender/bmesh/intern/bmesh_walkers.h
@@ -118,6 +118,7 @@ enum {
BMW_LOOP,
BMW_FACELOOP,
BMW_EDGERING,
+ BMW_EDGEBOUNDARY,
/* #define BMW_RING 2 */
/* walk over uv islands; takes a loop as input. restrict flag
* restricts the walking to loops whose vert has restrict flag set as a
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 4cf252e76e8..70b90238f96 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -42,6 +42,9 @@
BMW_state_remove(walker); \
} (void)0
+/** \name Mask Flag Checks
+ * \{ */
+
static bool bmw_mask_check_vert(BMWalker *walker, BMVert *v)
{
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
@@ -81,8 +84,11 @@ static bool bmw_mask_check_face(BMWalker *walker, BMFace *f)
}
}
-/**
- * Shell Walker:
+/** \} */
+
+
+/** \name Shell Walker
+ * \{
*
* Starts at a vertex on the mesh and walks over the 'shell' it belongs
* to via visiting connected edges.
@@ -205,15 +211,17 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
newState->curedge = curedge;
}
}
- curedge = bmesh_disk_edge_next(curedge, shellWalk.base);
- } while (curedge != shellWalk.curedge);
+ } while ((curedge = bmesh_disk_edge_next(curedge, shellWalk.base)) != shellWalk.curedge);
return shellWalk.curedge;
}
#endif
-/**
- * Connected Vertex Walker:
+/** \} */
+
+
+/** \name Connected Vertex Walker
+ * \{
*
* Similar to shell walker, but visits vertices instead of edges.
*/
@@ -270,8 +278,11 @@ static void *bmw_ConnectedVertexWalker_step(BMWalker *walker)
return v;
}
-/**
- * Island Boundary Walker:
+/** \} */
+
+
+/** \name Island Boundary Walker
+ * \{
*
* Starts at a edge on the mesh and walks over the boundary of an island it belongs to.
*
@@ -367,8 +378,8 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
}
-/**
- * Island Walker:
+/** \name Island Walker
+ * \{
*
* Starts at a tool flagged-face and walks over the face region
*
@@ -438,9 +449,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
return owalk.cur;
}
+/** \} */
-/**
- * Edge Loop Walker:
+
+/** \name Edge Loop Walker
+ * \{
*
* Starts at a tool-flagged edge and walks over the edge loop
*/
@@ -458,8 +471,10 @@ static void bmw_LoopWalker_begin(BMWalker *walker, void *data)
BMwLoopWalker *lwalk = NULL, owalk, *owalk_pt;
BMEdge *e = data;
BMVert *v;
- int vert_edge_count[2] = {BM_vert_edge_count_nonwire(e->v1),
- BM_vert_edge_count_nonwire(e->v2)};
+ const int vert_edge_count[2] = {
+ BM_vert_edge_count_nonwire(e->v1),
+ BM_vert_edge_count_nonwire(e->v2),
+ };
v = e->v1;
@@ -645,7 +660,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
(owalk.is_single == false && vert_edge_tot > 2) ||
/* initial edge was a boundary, so is this edge and vertex is only apart of this face
- * this lets us walk over the the boundary of an ngon which is handy */
+ * this lets us walk over the the boundary of an ngon which is handy */
(owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
{
/* find next boundary edge in the fan */
@@ -689,8 +704,11 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
return owalk.cur;
}
-/**
- * Face Loop Walker:
+/** \} */
+
+
+/** \name Face Loop Walker
+ * \{
*
* Starts at a tool-flagged face and walks over the face loop
* Conditions for starting and stepping the face loop have been
@@ -830,10 +848,13 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
return f;
}
+/** \} */
+
+
// #define BMW_EDGERING_NGON
-/**
- * Edge Ring Walker:
+/** \name Edge Ring Walker
+ * \{
*
* Starts at a tool-flagged edge and walks over the edge ring
* Conditions for starting and stepping the edge ring have been
@@ -970,6 +991,83 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
#undef EDGE_CHECK
}
+/** \} */
+
+
+/** \name Boundary Edge Walker
+ * \{ */
+
+static void bmw_EdgeboundaryWalker_begin(BMWalker *walker, void *data)
+{
+ BMwEdgeboundaryWalker *lwalk;
+ BMEdge *e = data;
+
+ BLI_assert(BM_edge_is_boundary(e));
+
+ if (BLI_gset_haskey(walker->visit_set, e))
+ return;
+
+ lwalk = BMW_state_add(walker);
+ lwalk->e = e;
+ BLI_gset_insert(walker->visit_set, e);
+}
+
+static void *bmw_EdgeboundaryWalker_yield(BMWalker *walker)
+{
+ BMwEdgeboundaryWalker *lwalk = BMW_current_state(walker);
+
+ if (!lwalk) {
+ return NULL;
+ }
+
+ return lwalk->e;
+}
+
+static void *bmw_EdgeboundaryWalker_step(BMWalker *walker)
+{
+ BMwEdgeboundaryWalker *lwalk, owalk;
+ BMEdge *e, *e_other;
+ BMVert *v;
+ BMIter eiter;
+ BMIter viter;
+
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
+
+ e = lwalk->e;
+
+ if (!bmw_mask_check_edge(walker, e)) {
+ return e;
+ }
+
+ BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
+ BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
+ if (e != e_other && BM_edge_is_boundary(e_other)) {
+ if (BLI_gset_haskey(walker->visit_set, e_other)) {
+ continue;
+ }
+
+ if (!bmw_mask_check_edge(walker, e_other)) {
+ continue;
+ }
+
+ lwalk = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, e_other);
+
+ lwalk->e = e_other;
+ }
+ }
+ }
+
+ return e;
+}
+
+/** \} */
+
+
+/** \name UV Edge Walker
+ * \{ */
+
static void bmw_UVEdgeWalker_begin(BMWalker *walker, void *data)
{
BMwUVEdgeWalker *lwalk;
@@ -1053,6 +1151,9 @@ static void *bmw_UVEdgeWalker_step(BMWalker *walker)
return l;
}
+/** \} */
+
+
static BMWalker bmw_ShellWalker_Type = {
bmw_ShellWalker_begin,
bmw_ShellWalker_step,
@@ -1104,7 +1205,16 @@ static BMWalker bmw_EdgeringWalker_Type = {
bmw_EdgeringWalker_yield,
sizeof(BMwEdgeringWalker),
BMW_DEPTH_FIRST,
- 0, /* valid restrict masks */ /* could add flags here but so far none are used */
+ BM_EDGE, /* valid restrict masks */
+};
+
+static BMWalker bmw_EdgeboundaryWalker_Type = {
+ bmw_EdgeboundaryWalker_begin,
+ bmw_EdgeboundaryWalker_step,
+ bmw_EdgeboundaryWalker_yield,
+ sizeof(BMwEdgeboundaryWalker),
+ BMW_DEPTH_FIRST,
+ 0,
};
static BMWalker bmw_UVEdgeWalker_Type = {
@@ -1130,6 +1240,7 @@ BMWalker *bm_walker_types[] = {
&bmw_LoopWalker_Type, /* BMW_LOOP */
&bmw_FaceLoopWalker_Type, /* BMW_FACELOOP */
&bmw_EdgeringWalker_Type, /* BMW_EDGERING */
+ &bmw_EdgeboundaryWalker_Type, /* BMW_EDGEBOUNDARY */
&bmw_UVEdgeWalker_Type, /* BMW_LOOPDATA_ISLAND */
&bmw_IslandboundWalker_Type, /* BMW_ISLANDBOUND */
&bmw_IslandWalker_Type, /* BMW_ISLAND */
diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h
index 09dd4f18d89..82d1e760db7 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_private.h
+++ b/source/blender/bmesh/intern/bmesh_walkers_private.h
@@ -78,6 +78,11 @@ typedef struct BMwEdgeringWalker {
BMEdge *wireedge;
} BMwEdgeringWalker;
+typedef struct BMwEdgeboundaryWalker {
+ BMwGenericWalker header;
+ BMEdge *e;
+} BMwEdgeboundaryWalker;
+
typedef struct BMwUVEdgeWalker {
BMwGenericWalker header;
BMLoop *l;
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 3d2c8c3d020..2e45cb9fec1 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -26,7 +26,6 @@
* Connect verts across faces (splits faces).
*/
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_linklist_stack.h"
@@ -39,7 +38,7 @@
#define EDGE_OUT 1
#define FACE_TAG 2
-static int bm_face_connect_verts(BMesh *bm, BMFace *f)
+static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenerate)
{
BMLoop *(*loops_split)[2] = BLI_array_alloca(loops_split, f->len);
STACK_DECLARE(loops_split);
@@ -48,7 +47,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
BMIter liter;
BMFace *f_new;
- BMLoop *l, *l_new;
+ BMLoop *l;
BMLoop *l_last;
unsigned int i;
@@ -82,7 +81,9 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
l_pair[1] = loops_split[0][0];
}
- BM_face_legal_splits(f, loops_split, STACK_SIZE(loops_split));
+ if (check_degenerate) {
+ BM_face_legal_splits(f, loops_split, STACK_SIZE(loops_split));
+ }
for (i = 0; i < STACK_SIZE(loops_split); i++) {
BMVert **v_pair;
@@ -96,6 +97,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
}
for (i = 0; i < STACK_SIZE(verts_pair); i++) {
+ BMLoop *l_new;
BMLoop *l_a, *l_b;
if ((l_a = BM_face_vert_share_loop(f, verts_pair[i][0])) &&
@@ -105,6 +107,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f)
}
else {
f_new = NULL;
+ l_new = NULL;
}
f = f_new;
@@ -126,6 +129,7 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
BMIter iter;
BMVert *v;
BMFace *f;
+ const bool check_degenerate = BMO_slot_bool_get(op->slots_in, "check_degenerate");
BLI_LINKSTACK_DECLARE(faces, BMFace *);
BLI_LINKSTACK_INIT(faces);
@@ -145,7 +149,7 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
/* connect faces */
while ((f = BLI_LINKSTACK_POP(faces))) {
- if (bm_face_connect_verts(bm, f) == -1) {
+ if (bm_face_connect_verts(bm, f, check_degenerate) == -1) {
BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL);
}
}
diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
index 334647fc68c..15447c97b5f 100644
--- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c
+++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
@@ -43,7 +43,7 @@
*/
static bool bm_face_subset_calc_normal(BMLoop *l_first, BMLoop *l_last, float r_no[3])
{
- float const *v_prev, *v_curr;
+ const float *v_prev, *v_curr;
/* Newell's Method */
BMLoop *l_iter = l_first;
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index 1b78a6b1dc7..b497ab2f693 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -387,7 +387,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
/* setup context */
{
BLI_listbase_clear(&pc.state_lb);
- pc.link_pool = BLI_mempool_create(sizeof(PathLink), 1, 512, BLI_MEMPOOL_SYSMALLOC);
+ pc.link_pool = BLI_mempool_create(sizeof(PathLink), 0, 512, BLI_MEMPOOL_NOP);
}
/* calculate matrix */
@@ -529,6 +529,8 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
#if 1
if (found_all) {
+ /* leave 'check_degenerate' off, if a user tries to cut with 2 verts,
+ * always connect even when resulting faces are degenerate [#39418] */
BMOperator op_sub;
BMO_op_initf(bm, &op_sub, 0,
"connect_verts verts=%fv", VERT_OUT);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 60b96e35057..334242f3100 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -474,3 +474,144 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "region.out", BM_FACE, FACE_NEW);
}
+
+
+#define EDGE_MARK 1
+#define EDGE_COLLAPSE 2
+
+static void bm_mesh_edge_collapse_flagged(BMesh *bm, const int flag, const short oflag)
+{
+ BMO_op_callf(bm, flag, "collapse edges=%fe", oflag);
+}
+
+void bmo_dissolve_degenerate_exec(BMesh *bm, BMOperator *op)
+{
+ const float dist = BMO_slot_float_get(op->slots_in, "dist");
+ const float dist_sq = dist * dist;
+
+ bool found;
+ BMIter eiter;
+ BMEdge *e;
+
+
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
+
+ /* collapse zero length edges, this accounts for zero area faces too */
+ found = false;
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
+ if (BM_edge_calc_length_squared(e) < dist_sq) {
+ BMO_elem_flag_enable(bm, e, EDGE_COLLAPSE);
+ found = true;
+ }
+ }
+
+ /* clear all loop tags (checked later) */
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+
+ if (found) {
+ bm_mesh_edge_collapse_flagged(bm, op->flag, EDGE_COLLAPSE);
+ }
+
+
+ /* clip degenerate ears from the face */
+ found = false;
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (e->l && BMO_elem_flag_test(bm, e, EDGE_MARK)) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (
+ /* check the loop hasn't already been tested (and flag not to test again) */
+ !BM_elem_flag_test(l_iter, BM_ELEM_TAG) &&
+ (BM_elem_flag_enable(l_iter, BM_ELEM_TAG),
+
+ /* check we're marked to tested (radial edge already tested) */
+ BMO_elem_flag_test(bm, l_iter->prev->e, EDGE_MARK) &&
+
+ /* check edges are not already going to be collapsed */
+ !BMO_elem_flag_test(bm, l_iter->e, EDGE_COLLAPSE) &&
+ !BMO_elem_flag_test(bm, l_iter->prev->e, EDGE_COLLAPSE)))
+ {
+ /* test if the faces loop (ear) is degenerate */
+ float dir_prev[3], len_prev;
+ float dir_next[3], len_next;
+
+
+ sub_v3_v3v3(dir_prev, l_iter->prev->v->co, l_iter->v->co);
+ sub_v3_v3v3(dir_next, l_iter->next->v->co, l_iter->v->co);
+
+ len_prev = normalize_v3(dir_prev);
+ len_next = normalize_v3(dir_next);
+
+ if ((len_v3v3(dir_prev, dir_next) * min_ff(len_prev, len_next)) <= dist) {
+ bool reset = false;
+
+ if (fabsf(len_prev - len_next) <= dist) {
+ /* both edges the same length */
+ if (l_iter->f->len == 3) {
+ /* ideally this would have been discovered with short edge test above */
+ BMO_elem_flag_enable(bm, l_iter->next->e, EDGE_COLLAPSE);
+ found = true;
+ }
+ else {
+ /* add a joining edge and tag for removal */
+ BMLoop *l_split;
+ if (BM_face_split(bm, l_iter->f, l_iter->prev, l_iter->next, &l_split, NULL, true)) {
+ BMO_elem_flag_enable(bm, l_split->e, EDGE_COLLAPSE);
+ found = true;
+ reset = true;
+ }
+ }
+ }
+ else if (len_prev < len_next) {
+ /* split 'l_iter->e', then join the vert with next */
+ BMVert *v_new;
+ BMEdge *e_new;
+ BMLoop *l_split;
+ v_new = BM_edge_split(bm, l_iter->e, l_iter->v, &e_new, len_prev / len_next);
+ BLI_assert(v_new == l_iter->next->v);
+ (void)v_new;
+ if (BM_face_split(bm, l_iter->f, l_iter->prev, l_iter->next, &l_split, NULL, true)) {
+ BMO_elem_flag_enable(bm, l_split->e, EDGE_COLLAPSE);
+ found = true;
+ }
+ reset = true;
+ }
+ else if (len_next < len_prev) {
+ /* split 'l_iter->prev->e', then join the vert with next */
+ BMVert *v_new;
+ BMEdge *e_new;
+ BMLoop *l_split;
+ v_new = BM_edge_split(bm, l_iter->prev->e, l_iter->v, &e_new, len_next / len_prev);
+ BLI_assert(v_new == l_iter->prev->v);
+ (void)v_new;
+ if (BM_face_split(bm, l_iter->f, l_iter->prev, l_iter->next, &l_split, NULL, true)) {
+ BMO_elem_flag_enable(bm, l_split->e, EDGE_COLLAPSE);
+ found = true;
+ }
+ reset = true;
+ }
+
+ if (reset) {
+ /* we can't easily track where we are on the radial edge, reset! */
+ l_first = l_iter;
+ }
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+
+ if (found) {
+ bm_mesh_edge_collapse_flagged(bm, op->flag, EDGE_COLLAPSE);
+ }
+
+}
diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c
index de41bc7937d..0c5de590ccf 100644
--- a/source/blender/bmesh/operators/bmo_edgenet.c
+++ b/source/blender/bmesh/operators/bmo_edgenet.c
@@ -114,7 +114,7 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(edges1);
BLI_array_declare(edges2);
BLI_array_declare(edges);
- int ok = 1;
+ bool ok = true;
int i, count;
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 90c514bfd02..f924d478f1a 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -602,7 +602,7 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
v = l->v;
index = BM_elem_index_get(v);
vert_accum[index] += face_angles[i];
- vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i];
+ vert_angles[index] += shell_v3v3_normalized_to_dist(v->no, f->no) * face_angles[i];
i++;
}
}
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 0a86a84d55b..26a4dbe1e1d 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -213,15 +213,15 @@ static HullFinalEdges *hull_final_edges(GSet *hull_triangles)
final_edges = MEM_callocN(sizeof(HullFinalEdges), "HullFinalEdges");
final_edges->edges = BLI_ghash_ptr_new("final edges ghash");
- final_edges->base_pool = BLI_mempool_create(sizeof(ListBase), 128, 128, 0);
- final_edges->link_pool = BLI_mempool_create(sizeof(LinkData), 128, 128, 0);
+ final_edges->base_pool = BLI_mempool_create(sizeof(ListBase), 0, 128, BLI_MEMPOOL_NOP);
+ final_edges->link_pool = BLI_mempool_create(sizeof(LinkData), 0, 128, BLI_MEMPOOL_NOP);
GSET_ITER (iter, hull_triangles) {
+ HullTriangle *t = BLI_gsetIterator_getKey(&iter);
LinkData *link;
int i;
-
+
for (i = 0; i < 3; i++) {
- HullTriangle *t = BLI_gsetIterator_getKey(&iter);
BMVert *v1 = t->v[i];
BMVert *v2 = t->v[(i + 1) % 3];
ListBase *adj;
@@ -574,7 +574,7 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, ele, HULL_FLAG_INTERIOR_ELE);
}
- hull_pool = BLI_mempool_create(sizeof(HullTriangle), 128, 128, 0);
+ hull_pool = BLI_mempool_create(sizeof(HullTriangle), 0, 128, BLI_MEMPOOL_NOP);
hull_triangles = BLI_gset_ptr_new("hull_triangles");
hull_from_bullet(bm, op, hull_triangles, hull_pool);
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index c79480d47dd..cb4255d337e 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -201,7 +201,7 @@ static void bmo_face_inset_individual(
copy_v3_v3(v_new_co, l_iter->v->co);
if (use_even_offset) {
- mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(eno_prev, eno_next) / 2.0f));
+ mul_v3_fl(tvec, shell_v3v3_mid_normalized_to_dist(eno_prev, eno_next));
}
/* Modify vertices and their normals */
@@ -390,6 +390,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
const bool use_even_boundry = use_even_offset; /* could make own option */
const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const bool use_edge_rail = BMO_slot_bool_get(op->slots_in, "use_edge_rail");
const bool use_interpolate = BMO_slot_bool_get(op->slots_in, "use_interpolate");
const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
const float depth = BMO_slot_float_get(op->slots_in, "depth");
@@ -406,6 +407,11 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
int iface_array_len;
MemArena *interp_arena = NULL;
+ /* BMVert original location storage */
+ const bool use_vert_coords_orig = use_edge_rail;
+ MemArena *vert_coords_orig = NULL;
+ GHash *vert_coords = NULL;
+
BMVert *v;
BMEdge *e;
BMFace *f;
@@ -470,6 +476,22 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
}
}
+
+ if (use_vert_coords_orig) {
+ vert_coords_orig = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ vert_coords = BLI_ghash_ptr_new(__func__);
+ }
+
+ /* util macros */
+#define VERT_ORIG_STORE(_v) { \
+ float *_co = BLI_memarena_alloc(vert_coords_orig, sizeof(float[3])); \
+ copy_v3_v3(_co, (_v)->co); \
+ BLI_ghash_insert(vert_coords, _v, _co); \
+ } (void)0
+#define VERT_ORIG_GET(_v) \
+ (const float *)BLI_ghash_lookup_default(vert_coords, (_v), (_v)->co)
+
+
for (i = 0, es = edge_info; i < edge_info_len; i++, es++) {
if ((es->l = bm_edge_is_mixed_face_tag(es->e_old->l))) {
/* do nothing */
@@ -563,6 +585,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
/* in some cases the edge doesn't split off */
if (r_vout_len == 1) {
+ if (use_vert_coords_orig) {
+ VERT_ORIG_STORE(vout[0]);
+ }
MEM_freeN(vout);
continue;
}
@@ -574,6 +599,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
int vert_edge_tag_tot = 0;
int vecpair[2];
+ if (use_vert_coords_orig) {
+ VERT_ORIG_STORE(v_split);
+ }
+
/* find adjacent */
BM_ITER_ELEM (e, &iter, v_split, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(e, BM_ELEM_TAG) &&
@@ -616,7 +645,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
* cross product between both face normals */
add_v3_v3v3(tvec, e_info_a->no, e_info_b->no);
- if (f_a != f_b) {
+ if (use_edge_rail == false) {
+ /* pass */
+ }
+ else if (f_a != f_b) {
/* these lookups are very quick */
BMLoop *l_other_a = BM_loop_other_vert_loop(e_info_a->l, v_split);
BMLoop *l_other_b = BM_loop_other_vert_loop(e_info_b->l, v_split);
@@ -624,9 +656,23 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
if (l_other_a->v == l_other_b->v) {
/* both edges faces are adjacent, but we don't need to know the shared edge
* having both verts is enough. */
- sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co);
+ const float *co_other;
+
+ /* note that we can't use 'l_other_a->v' directly since it
+ * may be inset and give a feedback loop. */
+ if (use_vert_coords_orig) {
+ co_other = VERT_ORIG_GET(l_other_a->v);
+ }
+ else {
+ co_other = l_other_a->v->co;
+ }
+
+ sub_v3_v3v3(tvec, co_other, v_split->co);
is_mid = false;
}
+
+ /* distable gives odd results at times, see [#39288] */
+#if 0
else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) {
/* epsilon increased to fix [#32329] */
@@ -641,20 +687,23 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
copy_v3_v3(tvec, tno);
is_mid = false;
}
+#endif
}
normalize_v3(tvec);
/* scale by edge angle */
if (use_even_offset) {
if (is_mid) {
- mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(e_info_a->no,
- e_info_b->no) / 2.0f));
+ mul_v3_fl(tvec, shell_v3v3_mid_normalized_to_dist(e_info_a->no,
+ e_info_b->no));
}
else {
- mul_v3_fl(tvec, shell_angle_to_dist(max_ff(angle_normalized_v3v3(tvec,
- e_info_a->no),
- angle_normalized_v3v3(tvec,
- e_info_b->no))));
+ /* use the largest angle */
+ mul_v3_fl(tvec,
+ shell_v3v3_normalized_to_dist(tvec,
+ len_squared_v3v3(tvec, e_info_a->no) >
+ len_squared_v3v3(tvec, e_info_b->no) ?
+ e_info_a->no : e_info_b->no));
}
}
@@ -725,7 +774,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
normalize_v3(tvec);
if (use_even_offset) {
- mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(e_no_a, tvec)));
+ mul_v3_fl(tvec, shell_v3v3_normalized_to_dist(e_no_a, tvec));
}
}
else {
@@ -777,6 +826,11 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
}
}
+ if (use_vert_coords_orig) {
+ BLI_memarena_free(vert_coords_orig);
+ BLI_ghash_free(vert_coords, NULL, NULL);
+ }
+
if (use_interpolate) {
for (i = 0; i < iface_array_len; i++) {
if (iface_array[i]) {
@@ -894,7 +948,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
zero_v3(es->e_new->v2->no);
}
for (i = 0, es = edge_info; i < edge_info_len; i++, es++) {
- float *no = es->l->f->no;
+ const float *no = es->l->f->no;
add_v3_v3(es->e_new->v1->no, no);
add_v3_v3(es->e_new->v2->no, no);
}
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index cef7c70d520..216d3410de8 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -219,7 +219,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
}
}
}
- bm->elem_index_dirty |= BM_FACE;
+ bm->elem_index_dirty |= BM_FACE | BM_LOOP;
/* faces get "modified" by creating new faces here, then at the
* end the old faces are deleted */
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index 2d6ceb23f37..f779828a00d 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -438,7 +438,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
case SIMEDGE_CREASE:
{
- float *c1, *c2;
+ const float *c1, *c2;
c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE);
@@ -453,7 +453,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
case SIMEDGE_BEVEL:
{
- float *c1, *c2;
+ const float *c1, *c2;
c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT);
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index e6321341950..af5f35f2a75 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -66,7 +66,6 @@ struct BLaplacianSystem {
};
typedef struct BLaplacianSystem LaplacianSystem;
-static float cotan_weight(float *v1, float *v2, float *v3);
static bool vert_is_boundary(BMVert *v);
static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
static void init_laplacian_matrix(LaplacianSystem *sys);
@@ -261,9 +260,9 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
v3 = vf[(j + 2) % 4]->co;
v4 = vf[(j + 3) % 4]->co;
- w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
- w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
- w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
+ w2 = cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3);
+ w4 = cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1);
sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f;
}
@@ -271,9 +270,9 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
else {
i = BM_elem_index_get(f);
- w1 = cotan_weight(v1, v2, v3);
- w2 = cotan_weight(v2, v3, v1);
- w3 = cotan_weight(v3, v1, v2);
+ w1 = cotangent_tri_weight_v3(v1, v2, v3);
+ w2 = cotangent_tri_weight_v3(v2, v3, v1);
+ w3 = cotangent_tri_weight_v3(v3, v1, v2);
sys->fweights[i][0] += w1;
sys->fweights[i][1] += w2;
@@ -325,9 +324,9 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
v3 = vf[(j + 2) % 4]->co;
v4 = vf[(j + 3) % 4]->co;
- w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
- w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
- w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
+ w2 = cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3);
+ w4 = cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1);
w2 = w2 / 4.0f;
w3 = w3 / 4.0f;
@@ -376,22 +375,6 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
}
}
-static float cotan_weight(float *v1, float *v2, float *v3)
-{
- float a[3], b[3], c[3], clen;
-
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
-
- clen = len_v3(c);
-
- if (clen == 0.0f)
- return 0.0f;
-
- return dot_v3v3(a, b) / clen;
-}
-
static bool vert_is_boundary(BMVert *v)
{
BMEdge *ed;
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 723595771a1..e0c86564db4 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -135,7 +135,6 @@ typedef struct SubDPattern {
* edge subdivision */
static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new)
{
- BMLoop *l_new;
BMLoop *l_a, *l_b;
BMFace *f;
@@ -146,6 +145,7 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace
if (f) {
BMFace *f_new;
+ BMLoop *l_new;
f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
@@ -1002,7 +1002,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
/* copy original-geometry displacements to current coordinates */
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
- float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
+ const float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
copy_v3_v3(v->co, co);
}
@@ -1147,7 +1147,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
/* copy original-geometry displacements to current coordinates */
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
- float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
+ const float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
copy_v3_v3(v->co, co);
}
diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c
index 4b5c8789227..90d26a775d3 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.c
+++ b/source/blender/bmesh/tools/bmesh_beautify.c
@@ -59,16 +59,14 @@ typedef struct EdRotState {
int f1, f2; /* face vert, small -> large */
} EdRotState;
+#if 0
+/* use BLI_ghashutil_inthash_v4 direct */
static unsigned int erot_gsetutil_hash(const void *ptr)
{
const EdRotState *e_state = (const EdRotState *)ptr;
- unsigned int
- hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v1));
- hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v2));
- hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f1));
- hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f2));
- return hash;
+ return BLI_ghashutil_inthash_v4(&e_state->v1);
}
+#endif
static int erot_gsetutil_cmp(const void *a, const void *b)
{
const EdRotState *e_state_a = (const EdRotState *)a;
@@ -86,7 +84,7 @@ static int erot_gsetutil_cmp(const void *a, const void *b)
static GSet *erot_gset_new(void)
{
- return BLI_gset_new(erot_gsetutil_hash, erot_gsetutil_cmp, __func__);
+ return BLI_gset_new(BLI_ghashutil_inthash_v4_p, erot_gsetutil_cmp, __func__);
}
/* ensure v0 is smaller */
@@ -135,10 +133,11 @@ static float bm_edge_calc_rotate_beauty__area(
/* not a loop (only to be able to break out) */
do {
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
+ bool is_zero_a, is_zero_b;
/* first get the 2d values */
{
- bool is_zero_a, is_zero_b;
+ float no_a[3], no_b[3];
float no[3];
float axis_mat[3][3];
@@ -148,23 +147,20 @@ static float bm_edge_calc_rotate_beauty__area(
(ELEM3(v3, v1, v2, v4) == false) &&
(ELEM3(v4, v1, v2, v3) == false));
- is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON;
- is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON;
+ is_zero_a = (normal_tri_v3(no_a, v2, v3, v4) <= FLT_EPSILON);
+ is_zero_b = (normal_tri_v3(no_b, v2, v4, v1) <= FLT_EPSILON);
if (LIKELY(is_zero_a == false && is_zero_b == false)) {
- float no_a[3], no_b[3];
- normal_tri_v3(no_a, v2, v3, v4); /* a */
- normal_tri_v3(no_b, v2, v4, v1); /* b */
add_v3_v3v3(no, no_a, no_b);
if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
break;
}
}
else if (is_zero_a == false) {
- normal_tri_v3(no, v2, v3, v4); /* a */
+ copy_v3_v3(no, no_a);
}
else if (is_zero_b == false) {
- normal_tri_v3(no, v2, v4, v1); /* b */
+ copy_v3_v3(no, no_b);
}
else {
/* both zero area, no useful normal can be calculated */
@@ -182,7 +178,32 @@ static float bm_edge_calc_rotate_beauty__area(
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
- if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
+ if (is_zero_a == false && is_zero_b == false) {
+ /* both tri's are valid, check we make a concave quad */
+ if (!is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
+ break;
+ }
+ }
+ else {
+ /* one of the tri's was degenerate, chech we're not rotating
+ * into a different degenerate shape or flipping the face */
+ float area_a, area_b;
+
+ area_a = area_tri_signed_v2(v1_xy, v2_xy, v3_xy);
+ area_b = area_tri_signed_v2(v1_xy, v3_xy, v4_xy);
+
+ if ((fabsf(area_a) <= FLT_EPSILON) || (fabsf(area_b) <= FLT_EPSILON)) {
+ /* one of the new rotations is degenerate */
+ break;
+ }
+
+ if ((area_a >= 0.0f) != (area_b >= 0.0f)) {
+ /* rotation would cause flipping */
+ break;
+ }
+ }
+
+ {
/* testing rule: the area divided by the perimeter,
* check if (1-3) beats the existing (2-4) edge rotation */
float area_a, area_b;
@@ -251,7 +272,8 @@ static float bm_edge_calc_rotate_beauty__angle(
}
float BM_verts_calc_rotate_beauty(
-const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4, const short flag, const short method)
+ const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4,
+ const short flag, const short method)
{
/* not a loop (only to be able to break out) */
do {
@@ -385,7 +407,7 @@ void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
GSet **edge_state_arr = MEM_callocN((size_t)edge_array_len * sizeof(GSet *), __func__);
- BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC);
+ BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 0, 512, BLI_MEMPOOL_NOP);
int i;
#ifdef DEBUG_TIME
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 13de07a2b7b..33ba4b9550e 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -380,7 +380,7 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv,
interp_f = facerep;
}
if (interp_f)
- BM_loop_interp_from_face(bm, l, interp_f, TRUE, TRUE);
+ BM_loop_interp_from_face(bm, l, interp_f, true, true);
i++;
}
}
@@ -504,7 +504,7 @@ static BMFace *bev_create_quad_straddle(BMesh *bm, BMVert *v1, BMVert *v2, BMVer
else
facerep = f2;
if (facerep)
- BM_loop_interp_from_face(bm, l, facerep, TRUE, TRUE);
+ BM_loop_interp_from_face(bm, l, facerep, true, true);
}
return f;
}
@@ -552,6 +552,15 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
madd_v3_v3fl(slideco, dir, -d);
}
+/* Is co not on the edge e? */
+static bool is_outside_edge(EdgeHalf *e, const float co[3])
+{
+ float d_squared;
+
+ d_squared = dist_squared_to_line_segment_v3(co, e->e->v1->co, e->e->v2->co);
+ return d_squared > 10000.0f * BEVEL_EPSILON_SQ;
+}
+
/*
* Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco.
* e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of
@@ -601,10 +610,12 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float
else {
/* Get normal to plane where meet point should be,
* using cross product instead of f->no in case f is non-planar.
- * If e1-v-e2 is a reflex angle (viewed from vertex normal side), need to flip*/
+ * If e1-v-e2 is a reflex angle (viewed from vertex normal side), need to flip.
+ * Use f->no to figure out which side to look at angle from, as even if
+ * f is non-planar, will be more accurate than vertex normal */
cross_v3_v3v3(norm_v, dir2, dir1);
normalize_v3(norm_v);
- if (dot_v3v3(norm_v, v->no) < 0.0f)
+ if (dot_v3v3(norm_v, f ? f->no : v->no) < 0.0f)
negate_v3(norm_v);
/* get vectors perp to each edge, perp to norm_v, and pointing into face */
@@ -631,6 +642,20 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float
if (fabsf(d - e2->offset_l) > BEVEL_EPSILON)
e2->offset_l = d;
}
+ else {
+ /* The lines intersect, but is it at a reasonable place?
+ * One problem to check: if one of the offsets is 0, then don't
+ * want an intersection that is outside that edge itself.
+ * This can happen if angle between them is > 180 degrees. */
+ if (e1->offset_r == 0.0f && is_outside_edge(e1, meetco)) {
+ copy_v3_v3(meetco, v->co);
+ e2->offset_l = 0.0f;
+ }
+ if (e2->offset_l == 0.0f && is_outside_edge(e2, meetco)) {
+ copy_v3_v3(meetco, v->co);
+ e1->offset_r = 0.0f;
+ }
+ }
}
}
@@ -806,10 +831,10 @@ static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, Ed
}
}
-/* Offset by e->offset in plane with normal plane_no, on left if left==TRUE,
+/* Offset by e->offset in plane with normal plane_no, on left if left==true,
* else on right. If no is NULL, choose an arbitrary plane different
* from eh's direction. */
-static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, float r[3])
+static void offset_in_plane(EdgeHalf *e, const float plane_no[3], bool left, float r[3])
{
float dir[3], no[3], fdir[3];
BMVert *v;
@@ -982,8 +1007,8 @@ static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
/* Fill matrix r_mat so that a point in the sheared parallelogram with corners
* va, vmid, vb (and the 4th that is implied by it being a parallelogram)
* is the result of transforming the unit square by multiplication with r_mat.
- * If it can't be done because the parallelogram is degenerate, return FALSE
- * else return TRUE.
+ * If it can't be done because the parallelogram is degenerate, return false
+ * else return true.
* Method:
* Find vo, the origin of the parallelogram with other three points va, vmid, vb.
* Also find vd, which is in direction normal to parallelogram and 1 unit away
@@ -999,8 +1024,8 @@ static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
* and B has the right side as columns - both extended into homogeneous coords.
* So M = B*(Ainverse). Doing Ainverse by hand gives the code below.
*/
-static int make_unit_square_map(const float va[3], const float vmid[3], const float vb[3],
- float r_mat[4][4])
+static bool make_unit_square_map(const float va[3], const float vmid[3], const float vb[3],
+ float r_mat[4][4])
{
float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3];
@@ -1027,10 +1052,10 @@ static int make_unit_square_map(const float va[3], const float vmid[3], const fl
sub_v3_v3(&r_mat[3][0], vmid);
r_mat[3][3] = 1.0f;
- return TRUE;
+ return true;
}
else
- return FALSE;
+ return false;
}
/* Like make_unit_square_map, but this one makes a matrix that transforms the
@@ -1162,7 +1187,7 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int n,
}
}
-/* Calculcate the actual coordinate values for bndv's profile.
+/* Calculate the actual coordinate values for bndv's profile.
* This is only needed if bp->seg > 1.
* Allocate the space for them if that hasn't been done already.
* If bp->seg is not a power of 2, also need to calculate
@@ -1172,7 +1197,7 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int n,
static void calculate_profile(BevelParams *bp, BoundVert *bndv)
{
int i, k, ns;
- float *uvals;
+ const float *uvals;
float co[3], co2[3], p[3], m[4][4];
float *prof_co, *prof_co_k;
float r;
@@ -1350,7 +1375,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
BevVert *bvother;
VMesh *vm;
float co[3];
- const float *no;
+ const float *no;
float lastd;
vm = bv->vmesh;
@@ -1381,7 +1406,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
if (bv->edgecount == 2 && bv->selcount == 1) {
/* special case: beveled edge meets non-beveled one at valence 2 vert */
no = e->fprev ? e->fprev->no : (e->fnext ? e->fnext->no : NULL);
- offset_in_plane(e, no, TRUE, co);
+ offset_in_plane(e, no, true, co);
if (construct) {
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = v->elast = v->ebev = e;
@@ -1391,7 +1416,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
adjust_bound_vert(e->leftv, co);
}
no = e->fnext ? e->fnext->no : (e->fprev ? e->fprev->no : NULL);
- offset_in_plane(e, no, FALSE, co);
+ offset_in_plane(e, no, false, co);
if (construct) {
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = v->elast = e;
@@ -1681,7 +1706,7 @@ static BoundVert *pipe_test(BevVert *bv)
for (e = &bv->edges[0]; e != &bv->edges[bv->edgecount]; e++) {
if (e->fnext) {
if (dot_v3v3(dir1, e->fnext->no) > BEVEL_EPSILON)
- return FALSE;
+ return NULL;
}
}
return v1;
@@ -2598,7 +2623,7 @@ static void bevel_build_trifan(BMesh *bm, BevVert *bv)
BMLoop *l_new;
BMFace *f_new;
BLI_assert(v_fan == l_fan->v);
- f_new = BM_face_split(bm, f, l_fan, l_fan->next->next, &l_new, NULL, FALSE);
+ f_new = BM_face_split(bm, f, l_fan, l_fan->next->next, &l_new, NULL, false);
if (f_new->len > f->len) {
f = f_new;
@@ -2643,7 +2668,7 @@ static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
l_b = l_b->next;
}
else {
- BM_face_split(bm, f, l_a, l_b, &l_new, NULL, FALSE);
+ BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
f = l_new->f;
/* walk around the new face to get the next verts to split */
@@ -2796,6 +2821,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
* Want edges to be ordered so that they share faces.
* There may be one or more chains of shared faces broken by
* gaps where there are no faces.
+ * TODO: Want to ignore wire edges completely for edge beveling.
* TODO: make following work when more than one gap.
*/
@@ -2813,7 +2839,6 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
first_bme = bme;
}
ntot++;
-
BM_BEVEL_EDGE_TAG_DISABLE(bme);
}
if (!first_bme)
@@ -2825,10 +2850,6 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
return NULL;
}
- /* avoid calling BM_vert_edge_count since we loop over edges already */
- // ntot = BM_vert_edge_count(v);
- // BLI_assert(ntot == BM_vert_edge_count(v));
-
bv = (BevVert *)BLI_memarena_alloc(bp->mem_arena, (sizeof(BevVert)));
bv->v = v;
bv->edgecount = ntot;
@@ -2893,11 +2914,11 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
bme = e->e;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
- e->is_bev = TRUE;
+ e->is_bev = true;
e->seg = bp->seg;
}
else {
- e->is_bev = FALSE;
+ e->is_bev = false;
e->seg = 0;
}
e->is_rev = (bme->v2 == v);
@@ -2913,6 +2934,11 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
}
+ /* now done with tag flag */
+ BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
+ BM_BEVEL_EDGE_TAG_DISABLE(bme);
+ }
+
/* if edge array doesn't go CCW around vertex from average normal side,
* reverse the array, being careful to reverse face pointers too */
if (ntot > 1) {
@@ -2991,7 +3017,6 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
e->offset_l = e->offset_l_spec;
e->offset_r = e->offset_r_spec;
- BM_BEVEL_EDGE_TAG_DISABLE(e->e);
if (e->fprev && e->fnext)
e->is_seam = !contig_ldata_across_edge(bm, e->e, e->fprev, e->fnext);
else
@@ -3058,7 +3083,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BLI_array_append(vv, v->nv.v);
}
- do_rebuild = TRUE;
+ do_rebuild = true;
}
else {
BLI_array_append(vv, l->v);
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 7a33dc40f8e..f4318933deb 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -136,16 +136,14 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
if ((STACK_SIZE(vert_split_arr) > 1) &&
(use_dirs[0] && use_dirs[2]))
{
- BMLoop *l_new;
-
if (LIKELY(STACK_SIZE(vert_split_arr) == 2)) {
+ BMLoop *l_new;
BMLoop *l_a, *l_b;
l_a = BM_face_vert_share_loop(f, vert_split_arr[0]);
l_b = BM_face_vert_share_loop(f, vert_split_arr[1]);
/* common case, just cut the face once */
- l_new = NULL;
BM_face_split(bm, f, l_a, l_b, &l_new, NULL, true);
if (l_new) {
if (oflag_center) {
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 00915d60428..f614c43193a 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -30,7 +30,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_quadric.h"
@@ -146,8 +145,8 @@ static bool bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
if (l->e != e && l->prev->e != e) {
- float *co_prev = l->prev->v->co;
- float *co_next = l->next->v->co;
+ const float *co_prev = l->prev->v->co;
+ const float *co_next = l->next->v->co;
float cross_exist[3];
float cross_optim[3];
@@ -1006,7 +1005,7 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, c
bm_decim_build_edge_cost(bm, vquadrics, vweights, eheap, eheap_table);
face_tot_target = bm->totface * factor;
- bm->elem_index_dirty |= BM_FACE | BM_EDGE | BM_VERT;
+ bm->elem_index_dirty |= BM_ALL;
#ifdef USE_CUSTOMDATA
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index 092a004aece..ffc680817a7 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -41,6 +41,8 @@ static bool bm_vert_dissolve_fan_test(BMVert *v)
BMIter iter;
BMEdge *e;
+ BMVert *varr[4];
+
unsigned int tot_edge = 0;
unsigned int tot_edge_boundary = 0;
unsigned int tot_edge_manifold = 0;
@@ -56,17 +58,25 @@ static bool bm_vert_dissolve_fan_test(BMVert *v)
else if (BM_edge_is_wire(e)) {
tot_edge_wire++;
}
+
+ /* bail out early */
+ if (tot_edge == 4) {
+ return false;
+ }
+
+ /* used to check overlapping faces */
+ varr[tot_edge] = BM_edge_other_vert(e, v);
+
tot_edge++;
}
- if ((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) {
- return true;
- }
- else if ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) {
- return true;
- }
- else if ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)) {
- return true;
+ if (((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) ||
+ ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) ||
+ ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)))
+ {
+ if (!BM_face_exists(varr, tot_edge, NULL)) {
+ return true;
+ }
}
else if ((tot_edge == 2) && (tot_edge_wire == 2)) {
return true;
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c
index 37a748c238e..ddf43949258 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.c
+++ b/source/blender/bmesh/tools/bmesh_edgenet.c
@@ -443,8 +443,8 @@ void BM_mesh_edgenet(BMesh *bm,
const bool use_edge_tag, const bool use_new_face_tag)
{
VertNetInfo *vnet_info = MEM_callocN(sizeof(*vnet_info) * (size_t)bm->totvert, __func__);
- BLI_mempool *edge_queue_pool = BLI_mempool_create(sizeof(LinkNode), 1, 512, 0);
- BLI_mempool *path_pool = BLI_mempool_create(sizeof(LinkNode), 1, 512, 0);
+ BLI_mempool *edge_queue_pool = BLI_mempool_create(sizeof(LinkNode), 0, 512, BLI_MEMPOOL_NOP);
+ BLI_mempool *path_pool = BLI_mempool_create(sizeof(LinkNode), 0, 512, BLI_MEMPOOL_NOP);
LinkNode *edge_queue = NULL;
BMEdge *e;
@@ -500,7 +500,7 @@ void BM_mesh_edgenet(BMesh *bm,
BLI_assert(BLI_mempool_count(path_pool) == 0);
}
- bm->elem_index_dirty |= BM_FACE;
+ bm->elem_index_dirty |= BM_FACE | BM_LOOP;
BLI_mempool_destroy(edge_queue_pool);
BLI_mempool_destroy(path_pool);
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 9fc1996e51a..060d0dd969b 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -193,6 +193,14 @@ static void edgetag_add_adjacent(Heap *heap, BMEdge *e1, BMEdge **edges_prev, fl
const int e1_index = BM_elem_index_get(e1);
BM_ITER_ELEM (v, &viter, e1, BM_VERTS_OF_EDGE) {
+
+ /* don't walk over previous vertex */
+ if ((edges_prev[e1_index]) &&
+ (BM_vert_in_edge(edges_prev[e1_index], v)))
+ {
+ continue;
+ }
+
BM_ITER_ELEM (e2, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e2, BM_ELEM_TAG)) {
/* we know 'e2' is not visited, check it out! */
diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c
index db4601d6134..b7d7a595dc9 100644
--- a/source/blender/bmesh/tools/bmesh_wireframe.c
+++ b/source/blender/bmesh/tools/bmesh_wireframe.c
@@ -227,16 +227,18 @@ void BM_mesh_wireframe(
cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
}
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
BM_ITER_MESH_INDEX (v_src, &iter, bm, BM_VERTS_OF_MESH, i) {
- BM_elem_flag_disable(v_src, BM_ELEM_TAG);
+ BM_elem_index_set(v_src, i); /* set_inline */
+
verts_src[i] = v_src;
+ BM_elem_flag_disable(v_src, BM_ELEM_TAG);
}
+ bm->elem_index_dirty &= ~BM_VERT;
/* setup tags, all faces and verts will be tagged which will be duplicated */
- BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH_INDEX (f_src, &iter, bm, BM_FACES_OF_MESH, i) {
+ BM_elem_index_set(f_src, i); /* set_inline */
if (use_tag) {
if (!BM_elem_flag_test(f_src, BM_ELEM_TAG)) {
@@ -256,6 +258,7 @@ void BM_mesh_wireframe(
BM_elem_flag_set(l->e, BM_ELEM_TAG, bm_loop_is_radial_boundary(l));
}
}
+ bm->elem_index_dirty &= ~BM_FACE;
/* duplicate tagged verts */
for (i = 0; i < totvert_orig; i++) {
@@ -529,8 +532,62 @@ void BM_mesh_wireframe(
}
if (use_replace) {
- for (i = 0; i < totvert_orig; i++) {
- BM_vert_kill(bm, verts_src[i]);
+
+ if (use_tag) {
+ /* only remove faces which are original and used to make wire,
+ * use 'verts_pos' and 'verts_neg' to avoid a feedback loop. */
+
+ /* vertex must be from 'verts_src' */
+#define VERT_DUPE_TEST_ORIG(v) (verts_neg[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_TEST(v) (verts_pos[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_CLEAR(v) { verts_pos[BM_elem_index_get(v)] = NULL; } (void)0
+
+ /* first ensure we keep all verts which are used in faces that weren't
+ * entirely made into wire. */
+ BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) {
+ int mix_flag = 0;
+ BMLoop *l_iter, *l_first;
+
+ /* skip new faces */
+ if (BM_elem_index_get(f_src) == -1) {
+ continue;
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ mix_flag |= (VERT_DUPE_TEST_ORIG(l_iter->v) ? 1 : 2);
+ if (mix_flag == (1 | 2)) {
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (mix_flag == (1 | 2)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ VERT_DUPE_CLEAR(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ /* now remove any verts which were made into wire by all faces */
+ for (i = 0; i < totvert_orig; i++) {
+ v_src = verts_src[i];
+ BLI_assert(i == BM_elem_index_get(v_src));
+ if (VERT_DUPE_TEST(v_src)) {
+ BM_vert_kill(bm, v_src);
+ }
+ }
+
+#undef VERT_DUPE_TEST_ORIG
+#undef VERT_DUPE_TEST
+#undef VERT_DUPE_CLEAR
+
+ }
+ else {
+ /* simple case, no tags - replace all */
+ for (i = 0; i < totvert_orig; i++) {
+ BM_vert_kill(bm, verts_src[i]);
+ }
}
}
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 61a675d4c8f..f2c057d32d8 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -187,7 +187,7 @@ void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<fl
for (con = (bConstraint *)conlist->first; con; con = con->next) {
ListBase targets = {NULL, NULL};
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (!validateConstraints(con)) continue;
@@ -999,7 +999,9 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
BIK_release_tree(scene, ob, ctime);
}
- enable_fcurves(ob->adt->action, NULL);
+ if (ob->adt) {
+ enable_fcurves(ob->adt->action, NULL);
+ }
source.finish();
@@ -1526,7 +1528,7 @@ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, i
bool AnimationExporter::validateConstraints(bConstraint *con)
{
bool valid = true;
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
/* these we can skip completely (invalid constraints...) */
if (cti == NULL) valid = false;
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) valid = false;
@@ -1545,7 +1547,7 @@ void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[
for (con = (bConstraint *)conlist->first; con; con = con->next) {
ListBase targets = {NULL, NULL};
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 6d4308be5b5..e2c36df564a 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -337,18 +337,23 @@ void ArmatureImporter::create_armature_bones( )
if (get_armature_for_joint(*ri) != NULL) continue;
Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
-
if (!ob_arm)
continue;
- ED_armature_to_edit((bArmature *)ob_arm->data);
+ bArmature * armature = (bArmature *)ob_arm->data;
+ if (!armature)
+ continue;
+
+ char * bone_name = (char *)bc_get_joint_name(*ri);
+ Bone *bone = BKE_armature_find_bone_name(armature, bone_name);
+ if (bone) {
+ fprintf(stderr, "Reuse of child bone [%s] as root bone in same Armature is not supported.\n", bone_name);
+ continue;
+ }
- /*
- * TODO:
- * check if bones have already been created for a given joint
- */
+ ED_armature_to_edit(armature);
- create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data);
+ create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
//leaf bone tails are derived from the matrix, so no need of this.
fix_leaf_bones();
@@ -356,12 +361,12 @@ void ArmatureImporter::create_armature_bones( )
// exit armature edit mode
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
- ED_armature_from_edit((bArmature *)ob_arm->data);
+ ED_armature_from_edit(armature);
//This serves no purpose, as pose is automatically reset later, in BKE_where_is_bone()
//set_pose(ob_arm, *ri, NULL, NULL);
- ED_armature_edit_free((bArmature *)ob_arm->data);
+ ED_armature_edit_free(armature);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
}
@@ -696,7 +701,7 @@ void ArmatureImporter::make_shape_keys()
KeyBlock *kb;
//insert basis key
- kb = BKE_keyblock_add_ctime(key, "Basis", FALSE);
+ kb = BKE_keyblock_add_ctime(key, "Basis", false);
BKE_key_convert_from_mesh(source_me, kb);
//insert other shape keys
@@ -710,7 +715,7 @@ void ArmatureImporter::make_shape_keys()
me->key = key;
std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name);
- kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), FALSE);
+ kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false);
BKE_key_convert_from_mesh(me, kb);
//apply weights
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index 17ac5478b22..c5443828f60 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -42,6 +42,7 @@ extern "C" {
#include "BKE_mesh.h"
#include "BKE_global.h"
#include "BKE_library.h"
+#include "BKE_idprop.h"
}
#include "ED_armature.h"
@@ -466,6 +467,84 @@ std::string ControllerExporter::add_joints_source(Object *ob_arm, ListBase *defb
return source_id;
}
+static float get_property(Bone *bone, const char *key, float def)
+{
+ float result = def;
+ if (bone->prop) {
+ IDProperty *property = IDP_GetPropertyFromGroup(bone->prop, key);
+ if (property) {
+ switch(property->type) {
+ case IDP_INT:
+ result = (float)(IDP_Int(property));
+ break;
+ case IDP_FLOAT:
+ result = (float)(IDP_Float(property));
+ break;
+ case IDP_DOUBLE:
+ result = (float)(IDP_Double(property));
+ break;
+ default:
+ result = def;
+ }
+ }
+ }
+ return result;
+}
+
+/**
+ * This function creates an arbitrary rest pose matrix from
+ * data provided as custom properties. This is a workaround
+ * for support of maya's restpose matrix which can be arbitrary
+ * in opposition to Blender where the Rest pose Matrix is always
+ * the Identity matrix.
+ *
+ * The custom properties are:
+ *
+ * restpose_scale_x
+ * restpose_scale_y
+ * restpose_scale_z
+ *
+ * restpose_rot_x
+ * restpose_rot_y
+ * restpose_rot_z
+ *
+ * restpose_loc_x
+ * restpose_loc_y
+ * restpose_loc_z
+ *
+ * The matrix is only setup if the scale AND the rot properties are defined.
+ * The presence of the loc properties is optional.
+ *
+ * This feature has been implemented to support Second Life "Fitted Mesh"
+ * TODO: Check if an arbitrary rest pose matrix makes sense within Blender.
+ * Eventually leverage the custom property data into an "official"
+ * Edit_bone Property
+ */
+static void create_restpose_mat(Bone *bone, float mat[4][4])
+{
+ const double PI = 3.1415926535897932384626433832795;
+
+ float loc[3] = {
+ get_property(bone, "restpose_loc_x", 0.0),
+ get_property(bone, "restpose_loc_y", 0.0),
+ get_property(bone, "restpose_loc_z", 0.0)
+ };
+
+ float rot[3] = {
+ PI * get_property(bone, "restpose_rot_x", 0.0) / 180.0,
+ PI * get_property(bone, "restpose_rot_y", 0.0) / 180.0,
+ PI * get_property(bone, "restpose_rot_z", 0.0) / 180.0
+ };
+
+ float scale[3] = {
+ get_property(bone, "restpose_scale_x", 1.0),
+ get_property(bone, "restpose_scale_y", 1.0),
+ get_property(bone, "restpose_scale_z", 1.0)
+ };
+
+ loc_eulO_size_to_mat4(mat, loc, rot, scale, 6);
+}
+
std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
{
std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
@@ -507,19 +586,27 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas
float world[4][4];
float inv_bind_mat[4][4];
- // OPEN_SIM_COMPATIBILITY
+
+ // SL/OPEN_SIM COMPATIBILITY
if (export_settings->open_sim) {
// Only translations, no rotation vs armature
float temp[4][4];
unit_m4(temp);
copy_v3_v3(temp[3], pchan->bone->arm_mat[3]);
mul_m4_m4m4(world, ob_arm->obmat, temp);
+
+ // Add Maya restpose matrix (if defined as properties)
+ float restpose_mat[4][4];
+ create_restpose_mat(pchan->bone, restpose_mat);
+ mul_m4_m4m4(world, world, restpose_mat);
+
}
else {
// make world-space matrix, arm_mat is armature-space
mul_m4_m4m4(world, ob_arm->obmat, pchan->bone->arm_mat);
}
+
invert_m4_m4(mat, world);
converter.mat4_to_dae(inv_bind_mat, mat);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index ea0f6cf0049..bbbbbf211c6 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -478,7 +478,7 @@ void DocumentImporter::create_constraints(ExtraTags *et, Object *ob)
std::string name;
short* type = 0;
et->setData("type", type);
- BKE_add_ob_constraint(ob, "Test_con", *type);
+ BKE_constraint_add_for_object(ob, "Test_con", *type);
}
}
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 3d5d79f55ea..1bf245c39e0 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -289,6 +289,12 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
}
+std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, char *layer_name)
+{
+ std::string result = getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + "-" + layer_name;
+ return result;
+}
+
// powerful because it handles both cases when there is material and when there's not
void GeometryExporter::createPolylist(short material_index,
bool has_uvs,
@@ -365,9 +371,20 @@ void GeometryExporter::createPolylist(short material_index,
}
}
- if (has_color) {
- COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2);
- til.push_back(input4);
+ int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
+ if (totlayer_mcol > 0) {
+ int map_index = 0;
+
+ for (int a = 0; a < totlayer_mcol; a++) {
+ char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
+ COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
+ makeUrl(makeVertexColorSourceId(geom_id, layer_name)),
+ (has_uvs) ? 3 : 2, // all color layers have same index order
+ map_index // set number equals color map index
+ );
+ til.push_back(input4);
+ map_index++;
+ }
}
// sets <vcount>
@@ -420,6 +437,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
ARRAY_ID_SUFFIX);
source.setAccessorCount(totverts);
source.setAccessorStride(3);
+
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("X");
param.push_back("Y");
@@ -437,40 +455,54 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
}
+
void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
{
- MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
- if (mloopcol == NULL)
+ /* Find number of vertex color layers */
+ int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
+ if (totlayer_mcol == 0)
return;
+ int map_index = 0;
+ for (int a = 0; a < totlayer_mcol; a++) {
- COLLADASW::FloatSourceF source(mSW);
- source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR));
- source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX);
- source.setAccessorCount(me->totloop);
- source.setAccessorStride(3);
+ map_index++;
+ MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, a);
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("R");
- param.push_back("G");
- param.push_back("B");
+ COLLADASW::FloatSourceF source(mSW);
- source.prepareToAppendValues();
+ char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
+ std::string layer_id = makeVertexColorSourceId(geom_id, layer_name);
+ source.setId(layer_id);
- MPoly *mpoly;
- int i;
- for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
- MLoopCol *mlc = mloopcol + mpoly->loopstart;
- for (int j = 0; j < mpoly->totloop; j++, mlc++) {
- source.appendValues(
- mlc->r / 255.0f,
- mlc->g / 255.0f,
- mlc->b / 255.0f
- );
+ source.setNodeName(layer_name);
+
+ source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(me->totloop);
+ source.setAccessorStride(3);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("R");
+ param.push_back("G");
+ param.push_back("B");
+
+ source.prepareToAppendValues();
+
+ MPoly *mpoly;
+ int i;
+ for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
+ MLoopCol *mlc = mloopcol + mpoly->loopstart;
+ for (int j = 0; j < mpoly->totloop; j++, mlc++) {
+ source.appendValues(
+ mlc->r / 255.0f,
+ mlc->g / 255.0f,
+ mlc->b / 255.0f
+ );
+ }
}
- }
- source.finish();
+ source.finish();
+ }
}
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 5b67f80e98d..4d54e79d796 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -100,7 +100,8 @@ public:
void create_normals(std::vector<Normal> &nor, std::vector<BCPolygonNormalsIndices> &ind, Mesh *me);
std::string getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
-
+ std::string makeVertexColorSourceId(std::string& geom_id, char *layer_name);
+
COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
COLLADASW::URI makeUrl(std::string id);
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index d631a43676f..211c34ed325 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -173,6 +173,42 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
}
}
+VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata){
+}
+
+void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
+{
+ int stride = mVData->getStride(0);
+ if (stride == 0) stride = 3;
+
+ switch (mVData->getType()) {
+ case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
+ {
+ COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
+ if (values->empty()) return;
+
+ mloopcol->r = FTOCHAR((*values)[v_index * stride]);
+ mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
+ mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
+ }
+ break;
+
+ case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
+ {
+ COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
+ if (values->empty()) return;
+
+ mloopcol->r = FTOCHAR((*values)[v_index * stride]);
+ mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
+ mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
+ }
+ break;
+ default:
+ fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n");
+ }
+
+}
+
MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
}
@@ -187,6 +223,17 @@ void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index,
}
}
+void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int loop_index, COLLADAFW::IndexList &index_list, int count)
+{
+ COLLADAFW::UIntValuesArray& indices =index_list.getIndices();
+ int index;
+ for(index = 0; index < count; index++,mlc++)
+ {
+ int v_index = indices[index+loop_index];
+ vob.get_vcol(v_index,mlc);
+ }
+}
+
void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs,
int start_index, COLLADAFW::IndexList& index_list, int count)
{
@@ -328,6 +375,17 @@ bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
return has_faces;
}
+
+static std::string extract_vcolname(const COLLADAFW::String &collada_id) {
+ std::string colname = collada_id;
+ int spos = colname.find("-mesh-colors-");
+ if (spos != std::string::npos) {
+ colname = colname.substr(spos+13);
+ }
+ return colname;
+}
+
+
// =================================================================
// Return the number of faces by summing up
// the facecounts of the parts.
@@ -337,8 +395,8 @@ bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
{
COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
- int total_poly_count = 0;
- int total_loop_count = 0;
+ int total_poly_count = 0;
+ int total_loop_count = 0;
// collect edge_count and face_count from all parts
for (int i = 0; i < prim_arr.getCount(); i++) {
@@ -360,6 +418,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
total_poly_count += prim_poly_count;
total_loop_count += prim_loop_count;
+
break;
}
default:
@@ -394,6 +453,17 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
me->mtpoly = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
}
+
+ int totcolset = collada_mesh->getColors().getInputInfosArray().getCount();
+ if (totcolset > 0) {
+ for (int i = 0; i < totcolset; i++) {
+ COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getColors().getInputInfosArray()[i];
+ COLLADAFW::String colname = extract_vcolname(info->mName);
+ CustomData_add_layer_named(&me->ldata,CD_MLOOPCOL,CD_DEFAULT,NULL,me->totloop, colname.c_str());
+ }
+ me->mloopcol = (MLoopCol *) CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0);
+ }
+
}
}
@@ -538,6 +608,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
allocate_poly_data(collada_mesh, me);
UVDataWrapper uvs(collada_mesh->getUVCoords());
+ VCOLDataWrapper vcol(collada_mesh->getColors());
MPoly *mpoly = me->mpoly;
MLoop *mloop = me->mloop;
@@ -553,9 +624,9 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
// faces
- size_t prim_totpoly = mp->getFaceCount();
- unsigned int *position_indices = mp->getPositionIndices().getData();
- unsigned int *normal_indices = mp->getNormalIndices().getData();
+ size_t prim_totpoly = mp->getFaceCount();
+ unsigned int *position_indices = mp->getPositionIndices().getData();
+ unsigned int *normal_indices = mp->getNormalIndices().getData();
bool mp_has_normals = primitive_has_useable_normals(mp);
bool mp_has_faces = primitive_has_faces(mp);
@@ -564,7 +635,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
// since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
Primitive prim = {mpoly, 0};
- COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
// If MeshPrimitive is TRIANGLE_FANS we split it into triangles
// The first trifan vertex will be the first vertex in every triangle
@@ -611,6 +681,9 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
unsigned int start_index = 0;
+ COLLADAFW::IndexListArray& index_list_array_uvcoord = mp->getUVCoordIndicesArray();
+ COLLADAFW::IndexListArray& index_list_array_vcolor = mp->getColorIndicesArray();
+
for (unsigned int j = 0; j < prim_totpoly; j++) {
// Vertices in polygon:
@@ -618,15 +691,15 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
- for (unsigned int uvset_index = 0; uvset_index < index_list_array.getCount(); uvset_index++) {
+ for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) {
// get mtface by face index and uv set index
- COLLADAFW::IndexList& index_list = *index_list_array[uvset_index];
+ COLLADAFW::IndexList& index_list = *index_list_array_uvcoord[uvset_index];
MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, index_list.getName().c_str());
if (mloopuv == NULL) {
- fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].", me->id.name, index_list.getName().c_str() );
+ fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", me->id.name, index_list.getName().c_str() );
}
else {
- set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[uvset_index], vcount);
+ set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array_uvcoord[uvset_index], vcount);
}
}
@@ -634,10 +707,23 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
if (!is_flat_face(normal_indices, nor, vcount))
mpoly->flag |= ME_SMOOTH;
}
-
+
+ for(unsigned int vcolor_index = 0 ; vcolor_index < index_list_array_vcolor.getCount();vcolor_index++)
+ {
+ COLLADAFW::IndexList& index_list = *index_list_array_vcolor[vcolor_index];
+ COLLADAFW::String colname = extract_vcolname(index_list.getName());
+ MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str());
+ if (mloopcol == NULL) {
+ fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, index_list.getName().c_str() );
+ }
+ else {
+ set_vcol(mloopcol+loop_index, vcol, start_index, *index_list_array_vcolor[vcolor_index], vcount);
+ }
+ }
+
mpoly++;
- mloop += vcount;
- loop_index += vcount;
+ mloop += vcount;
+ loop_index += vcount;
start_index += vcount;
prim.totpoly++;
@@ -654,6 +740,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
if (mp_has_faces)
mat_prim_map[mp->getMaterialId()].push_back(prim);
+
+
}
geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map;
@@ -1114,5 +1202,6 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
// read_lines() must be called after the face edges have been generated.
// Oterwise the loose edges will be silently deleted again.
read_lines(mesh, me);
+
return true;
}
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 5275420f4b5..9fc1d777f62 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -77,6 +77,14 @@ public:
void getUV(int uv_index, float *uv);
};
+class VCOLDataWrapper
+{
+ COLLADAFW::MeshVertexData *mVData;
+public:
+ VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata);
+ void get_vcol(int v_index, MLoopCol *mloopcol);
+};
+
class MeshImporter : public MeshImporterBase
{
private:
@@ -113,6 +121,12 @@ private:
COLLADAFW::IndexList& index_list,
int count);
+ void set_vcol(MLoopCol *mloopcol,
+ VCOLDataWrapper &vob,
+ int loop_index,
+ COLLADAFW::IndexList& index_list,
+ int count);
+
#ifdef COLLADA_DEBUG
void print_index_list(COLLADAFW::IndexList& index_list);
#endif
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index a3bb02520da..b50b8b0a302 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -193,8 +193,10 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
if (BLI_listbase_is_empty(&ob->constraints) == false) {
bConstraint *con = (bConstraint *) ob->constraints.first;
while (con) {
- std::string con_name(id_name(con));
+ std::string con_name(translate_id(con->name));
std::string con_tag = con_name + "_constraint";
+ printf("%s\n", con_name.c_str());
+ printf("%s\n\n", con_tag.c_str());
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"type",con->type);
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"enforce",con->enforce);
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"flag",con->flag);
@@ -208,7 +210,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
//not ideal: add the target object name as another parameter.
//No real mapping in the .dae
//Need support for multiple target objects also.
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index f5b81c6f6b0..d91689ff496 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -362,6 +362,6 @@ void bc_triangulate_mesh(Mesh *me)
BM_mesh_bm_from_me(bm, me, true, false, 0);
BM_mesh_triangulate(bm, quad_method, use_beauty, tag_only, NULL, NULL);
- BM_mesh_bm_to_me(bm, me, FALSE);
+ BM_mesh_bm_to_me(bm, me, false);
BM_mesh_free(bm);
}
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 11add975db5..a19433436f1 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -54,28 +54,22 @@ set(SRC
intern/COM_compositor.cpp
intern/COM_ExecutionSystem.cpp
intern/COM_ExecutionSystem.h
- intern/COM_ExecutionSystemHelper.cpp
- intern/COM_ExecutionSystemHelper.h
+ intern/COM_NodeConverter.cpp
+ intern/COM_NodeConverter.h
+ intern/COM_NodeOperationBuilder.cpp
+ intern/COM_NodeOperationBuilder.h
+ intern/COM_NodeGraph.cpp
+ intern/COM_NodeGraph.h
intern/COM_Converter.cpp
intern/COM_Converter.h
intern/COM_ExecutionGroup.cpp
intern/COM_ExecutionGroup.h
intern/COM_Node.cpp
intern/COM_Node.h
- intern/COM_NodeBase.cpp
- intern/COM_NodeBase.h
intern/COM_NodeOperation.cpp
intern/COM_NodeOperation.h
- intern/COM_Socket.cpp
- intern/COM_Socket.h
intern/COM_SocketReader.cpp
intern/COM_SocketReader.h
- intern/COM_InputSocket.cpp
- intern/COM_InputSocket.h
- intern/COM_OutputSocket.cpp
- intern/COM_OutputSocket.h
- intern/COM_SocketConnection.cpp
- intern/COM_SocketConnection.h
intern/COM_MemoryProxy.cpp
intern/COM_MemoryProxy.h
intern/COM_MemoryBuffer.cpp
@@ -98,8 +92,8 @@ set(SRC
intern/COM_CompositorContext.h
intern/COM_ChannelInfo.cpp
intern/COM_ChannelInfo.h
- intern/COM_SingleThreadedNodeOperation.cpp
- intern/COM_SingleThreadedNodeOperation.h
+ intern/COM_SingleThreadedOperation.cpp
+ intern/COM_SingleThreadedOperation.h
intern/COM_Debug.cpp
intern/COM_Debug.h
@@ -107,10 +101,6 @@ set(SRC
operations/COM_QualityStepHelper.cpp
# Internal nodes
- nodes/COM_MuteNode.cpp
- nodes/COM_MuteNode.h
- nodes/COM_GroupNode.cpp
- nodes/COM_GroupNode.h
nodes/COM_SocketProxyNode.cpp
nodes/COM_SocketProxyNode.h
@@ -185,6 +175,8 @@ set(SRC
nodes/COM_GlareNode.cpp
nodes/COM_GlareNode.h
+ nodes/COM_CornerPinNode.cpp
+ nodes/COM_CornerPinNode.h
nodes/COM_PlaneTrackDeformNode.cpp
nodes/COM_PlaneTrackDeformNode.h
@@ -243,22 +235,10 @@ set(SRC
# converter nodes
nodes/COM_IDMaskNode.cpp
nodes/COM_IDMaskNode.h
- nodes/COM_SeparateRGBANode.cpp
- nodes/COM_SeparateRGBANode.h
- nodes/COM_CombineRGBANode.cpp
- nodes/COM_CombineRGBANode.h
- nodes/COM_SeparateHSVANode.cpp
- nodes/COM_SeparateHSVANode.h
- nodes/COM_CombineHSVANode.cpp
- nodes/COM_CombineHSVANode.h
- nodes/COM_SeparateYUVANode.cpp
- nodes/COM_SeparateYUVANode.h
- nodes/COM_CombineYUVANode.cpp
- nodes/COM_CombineYUVANode.h
- nodes/COM_SeparateYCCANode.cpp
- nodes/COM_SeparateYCCANode.h
- nodes/COM_CombineYCCANode.cpp
- nodes/COM_CombineYCCANode.h
+ nodes/COM_SeparateColorNode.cpp
+ nodes/COM_SeparateColorNode.h
+ nodes/COM_CombineColorNode.cpp
+ nodes/COM_CombineColorNode.h
nodes/COM_NormalNode.cpp
nodes/COM_NormalNode.h
@@ -488,12 +468,12 @@ set(SRC
operations/COM_ProjectorLensDistortionOperation.h
operations/COM_ScreenLensDistortionOperation.cpp
operations/COM_ScreenLensDistortionOperation.h
- operations/COM_PlaneTrackCommonOperation.cpp
- operations/COM_PlaneTrackCommonOperation.h
- operations/COM_PlaneTrackMaskOperation.cpp
- operations/COM_PlaneTrackMaskOperation.h
- operations/COM_PlaneTrackWarpImageOperation.cpp
- operations/COM_PlaneTrackWarpImageOperation.h
+ operations/COM_PlaneDistortCommonOperation.cpp
+ operations/COM_PlaneDistortCommonOperation.h
+ operations/COM_PlaneTrackOperation.cpp
+ operations/COM_PlaneTrackOperation.h
+ operations/COM_PlaneCornerPinOperation.cpp
+ operations/COM_PlaneCornerPinOperation.h
#Filter operations
operations/COM_ConvolutionFilterOperation.h
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index b79c26aa236..2cf2c690d3e 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -213,8 +213,8 @@ extern "C" {
* (is called from [@ref ExecutionGroup.scheduleChunkWhenPossible])
* @see ExecutionGroup.scheduleChunk Schedule a chunk on the WorkScheduler
* @see NodeOperation.determineDependingAreaOfInterest Influence the area of interest of a chunk.
- * @see WriteBufferOperation NodeOperation to write to a MemoryProxy/MemoryBuffer
- * @see ReadBufferOperation NodeOperation to read from a MemoryProxy/MemoryBuffer
+ * @see WriteBufferOperation Operation to write to a MemoryProxy/MemoryBuffer
+ * @see ReadBufferOperation Operation to read from a MemoryProxy/MemoryBuffer
* @see MemoryProxy proxy for information about memory image (a image consist out of multiple chunks)
* @see MemoryBuffer Allocated memory for a single chunk
*
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index 3b0e9f239bb..d086f81d03c 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -24,7 +24,7 @@
#define __COM_DEFINES_H__
/**
- * @brief possible data types for SocketConnection
+ * @brief possible data types for sockets
* @ingroup Model
*/
typedef enum DataType {
@@ -109,4 +109,13 @@ typedef enum OrderOfChunks {
#define COM_BLUR_BOKEH_PIXELS 512
+/**
+ * The fast gaussien blur is not an accurate blur.
+ * This setting can be used to increase/decrease the
+ * amount of the input data. (dependent area of interest)
+ *
+ * Fix for: T39307
+ */
+#define COM_FAST_GAUSSIAN_MULTIPLIER 3
+
#endif /* __COM_DEFINES_H__ */
diff --git a/source/blender/compositor/intern/COM_CPUDevice.cpp b/source/blender/compositor/intern/COM_CPUDevice.cpp
index 7029aa032cc..c7c3f7769fe 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.cpp
+++ b/source/blender/compositor/intern/COM_CPUDevice.cpp
@@ -30,7 +30,7 @@ void CPUDevice::execute(WorkPackage *work)
executionGroup->determineChunkRect(&rect, chunkNumber);
- executionGroup->getOutputNodeOperation()->executeRegion(&rect, chunkNumber);
+ executionGroup->getOutputOperation()->executeRegion(&rect, chunkNumber);
executionGroup->finalizeChunkExecution(chunkNumber, NULL);
}
diff --git a/source/blender/compositor/intern/COM_ChannelInfo.h b/source/blender/compositor/intern/COM_ChannelInfo.h
index 44664442359..ec78e7e1cb1 100644
--- a/source/blender/compositor/intern/COM_ChannelInfo.h
+++ b/source/blender/compositor/intern/COM_ChannelInfo.h
@@ -49,8 +49,8 @@ typedef enum ChannelType {
/**
* @brief ChannelInfo holds information about a channel.
*
- * Channels are transported from node to node via a SocketConnection.
- * ChannelInfo holds specific setting of these channels in order that the to-node of the connection
+ * Channels are transported from node to node via a NodeLink.
+ * ChannelInfo holds specific setting of these channels in order that the to-node of the link
* Can handle specific logic per channel setting.
*
* @note currently this is not used, but a future place to implement color spacing and other things.
@@ -59,7 +59,7 @@ typedef enum ChannelType {
class ChannelInfo {
private:
/**
- * @brief the channel number, in the connection. [0-3]
+ * @brief the channel number, in the link. [0-3]
*/
int m_number;
@@ -87,12 +87,12 @@ public:
ChannelInfo();
/**
- * @brief set the index of this channel in the SocketConnection
+ * @brief set the index of this channel in the NodeLink
*/
void setNumber(const int number) { this->m_number = number; }
/**
- * @brief get the index of this channel in the SocketConnection
+ * @brief get the index of this channel in the NodeLink
*/
const int getNumber() const { return this->m_number; }
diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h
index 223f900b391..a398ae937a3 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.h
+++ b/source/blender/compositor/intern/COM_CompositorContext.h
@@ -181,11 +181,11 @@ public:
*/
void setHasActiveOpenCLDevices(bool hasAvtiveOpenCLDevices) { this->m_hasActiveOpenCLDevices = hasAvtiveOpenCLDevices; }
- int getChunksize() { return this->getbNodeTree()->chunksize; }
+ int getChunksize() const { return this->getbNodeTree()->chunksize; }
void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;}
- bool isFastCalculation() {return this->m_fastCalculation;}
- inline bool isGroupnodeBufferEnabled() {return this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER;}
+ bool isFastCalculation() const { return this->m_fastCalculation; }
+ bool isGroupnodeBufferEnabled() const { return this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER; }
};
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 384cfbe47fa..9251e161839 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -22,7 +22,14 @@
#include <string.h>
+extern "C" {
+#include "DNA_node_types.h"
+
#include "BKE_node.h"
+}
+
+#include "COM_NodeOperationBuilder.h"
+#include "COM_NodeOperation.h"
#include "COM_AlphaOverNode.h"
#include "COM_BilateralBlurNode.h"
@@ -41,14 +48,12 @@
#include "COM_ColorRampNode.h"
#include "COM_ColorSpillNode.h"
#include "COM_ColorToBWNode.h"
-#include "COM_CombineHSVANode.h"
-#include "COM_CombineRGBANode.h"
-#include "COM_CombineYCCANode.h"
-#include "COM_CombineYUVANode.h"
+#include "COM_CombineColorNode.h"
#include "COM_CompositorNode.h"
#include "COM_ConvertAlphaNode.h"
#include "COM_ConvertOperation.h"
#include "COM_Converter.h"
+#include "COM_CornerPinNode.h"
#include "COM_CropNode.h"
#include "COM_DefocusNode.h"
#include "COM_DespeckleNode.h"
@@ -60,12 +65,10 @@
#include "COM_DoubleEdgeMaskNode.h"
#include "COM_EllipseMaskNode.h"
#include "COM_ExecutionSystem.h"
-#include "COM_ExecutionSystemHelper.h"
#include "COM_FilterNode.h"
#include "COM_FlipNode.h"
#include "COM_GammaNode.h"
#include "COM_GlareNode.h"
-#include "COM_GroupNode.h"
#include "COM_HueSaturationValueCorrectNode.h"
#include "COM_HueSaturationValueNode.h"
#include "COM_IDMaskNode.h"
@@ -84,7 +87,6 @@
#include "COM_MixNode.h"
#include "COM_MovieClipNode.h"
#include "COM_MovieDistortionNode.h"
-#include "COM_MuteNode.h"
#include "COM_NormalNode.h"
#include "COM_NormalizeNode.h"
#include "COM_OutputFileNode.h"
@@ -92,13 +94,9 @@
#include "COM_RotateNode.h"
#include "COM_ScaleNode.h"
#include "COM_ScaleOperation.h"
-#include "COM_SeparateHSVANode.h"
-#include "COM_SeparateRGBANode.h"
-#include "COM_SeparateYCCANode.h"
-#include "COM_SeparateYUVANode.h"
+#include "COM_SeparateColorNode.h"
#include "COM_SetAlphaNode.h"
#include "COM_SetValueOperation.h"
-#include "COM_SocketConnection.h"
#include "COM_SplitViewerNode.h"
#include "COM_Stabilize2dNode.h"
#include "COM_SwitchNode.h"
@@ -118,30 +116,24 @@
#include "COM_PixelateNode.h"
#include "COM_PlaneTrackDeformNode.h"
-Node *Converter::convert(bNode *b_node, bool fast)
+bool Converter::is_fast_node(bNode *b_node)
{
- Node *node = NULL;
+ return !(b_node->type == CMP_NODE_BLUR ||
+ b_node->type == CMP_NODE_VECBLUR ||
+ b_node->type == CMP_NODE_BILATERALBLUR ||
+ b_node->type == CMP_NODE_DEFOCUS ||
+ b_node->type == CMP_NODE_BOKEHBLUR ||
+ b_node->type == CMP_NODE_GLARE ||
+ b_node->type == CMP_NODE_DBLUR ||
+ b_node->type == CMP_NODE_MOVIEDISTORTION ||
+ b_node->type == CMP_NODE_LENSDIST ||
+ b_node->type == CMP_NODE_DOUBLEEDGEMASK ||
+ b_node->type == CMP_NODE_DILATEERODE);
+}
- if (b_node->flag & NODE_MUTED) {
- node = new MuteNode(b_node);
- return node;
- }
- if (fast) {
- if (b_node->type == CMP_NODE_BLUR ||
- b_node->type == CMP_NODE_VECBLUR ||
- b_node->type == CMP_NODE_BILATERALBLUR ||
- b_node->type == CMP_NODE_DEFOCUS ||
- b_node->type == CMP_NODE_BOKEHBLUR ||
- b_node->type == CMP_NODE_GLARE ||
- b_node->type == CMP_NODE_DBLUR ||
- b_node->type == CMP_NODE_MOVIEDISTORTION ||
- b_node->type == CMP_NODE_LENSDIST ||
- b_node->type == CMP_NODE_DOUBLEEDGEMASK ||
- b_node->type == CMP_NODE_DILATEERODE)
- {
- return new MuteNode(b_node);
- }
- }
+Node *Converter::convert(bNode *b_node)
+{
+ Node *node = NULL;
switch (b_node->type) {
case CMP_NODE_COMPOSITE:
@@ -220,11 +212,9 @@ Node *Converter::convert(bNode *b_node, bool fast)
node = new InvertNode(b_node);
break;
case NODE_GROUP:
- node = new GroupNode(b_node);
- break;
case NODE_GROUP_INPUT:
case NODE_GROUP_OUTPUT:
- /* handled in GroupNode::ungroup */
+ /* handled in NodeCompiler */
break;
case CMP_NODE_NORMAL:
node = new NormalNode(b_node);
@@ -401,52 +391,48 @@ Node *Converter::convert(bNode *b_node, bool fast)
case CMP_NODE_PLANETRACKDEFORM:
node = new PlaneTrackDeformNode(b_node);
break;
- default:
- node = new MuteNode(b_node);
+ case CMP_NODE_CORNERPIN:
+ node = new CornerPinNode(b_node);
break;
}
return node;
}
-void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *system)
+
+NodeOperation *Converter::convertDataType(NodeOperationOutput *from, NodeOperationInput *to)
{
- OutputSocket *outputSocket = connection->getFromSocket();
- InputSocket *inputSocket = connection->getToSocket();
- DataType fromDatatype = outputSocket->getDataType();
- DataType toDatatype = inputSocket->getDataType();
- NodeOperation *converter = NULL;
+ DataType fromDatatype = from->getDataType();
+ DataType toDatatype = to->getDataType();
+
if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
- converter = new ConvertValueToColorOperation();
+ return new ConvertValueToColorOperation();
}
else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
- converter = new ConvertValueToVectorOperation();
+ return new ConvertValueToVectorOperation();
}
else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
- converter = new ConvertColorToValueOperation();
+ return new ConvertColorToValueOperation();
}
else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
- converter = new ConvertColorToVectorOperation();
+ return new ConvertColorToVectorOperation();
}
else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
- converter = new ConvertVectorToValueOperation();
+ return new ConvertVectorToValueOperation();
}
else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
- converter = new ConvertVectorToColorOperation();
- }
- if (converter != NULL) {
- inputSocket->relinkConnections(converter->getInputSocket(0));
- ExecutionSystemHelper::addLink(system->getConnections(), converter->getOutputSocket(), inputSocket);
- system->addOperation(converter);
+ return new ConvertVectorToColorOperation();
}
+
+ return NULL;
}
-void Converter::convertResolution(SocketConnection *connection, ExecutionSystem *system)
+void Converter::convertResolution(NodeOperationBuilder &builder, NodeOperationOutput *fromSocket, NodeOperationInput *toSocket)
{
- InputSocketResizeMode mode = connection->getToSocket()->getResizeMode();
+ InputResizeMode mode = toSocket->getResizeMode();
- NodeOperation *toOperation = (NodeOperation *)connection->getToNode();
+ NodeOperation *toOperation = &toSocket->getOperation();
const float toWidth = toOperation->getWidth();
const float toHeight = toOperation->getHeight();
- NodeOperation *fromOperation = (NodeOperation *)connection->getFromNode();
+ NodeOperation *fromOperation = &fromSocket->getOperation();
const float fromWidth = fromOperation->getWidth();
const float fromHeight = fromOperation->getHeight();
bool doCenter = false;
@@ -495,62 +481,59 @@ void Converter::convertResolution(SocketConnection *connection, ExecutionSystem
if (doCenter) {
NodeOperation *first = NULL;
- SocketConnection *c;
ScaleOperation *scaleOperation = NULL;
if (doScale) {
scaleOperation = new ScaleOperation();
+ scaleOperation->getInputSocket(1)->setResizeMode(COM_SC_NO_RESIZE);
+ scaleOperation->getInputSocket(2)->setResizeMode(COM_SC_NO_RESIZE);
first = scaleOperation;
SetValueOperation *sxop = new SetValueOperation();
sxop->setValue(scaleX);
- c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
- c->setIgnoreResizeCheck(true);
+ builder.addLink(sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
SetValueOperation *syop = new SetValueOperation();
syop->setValue(scaleY);
- c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2));
- c->setIgnoreResizeCheck(true);
- system->addOperation(sxop);
- system->addOperation(syop);
+ builder.addLink(syop->getOutputSocket(), scaleOperation->getInputSocket(2));
+ builder.addOperation(sxop);
+ builder.addOperation(syop);
unsigned int resolution[2] = {fromOperation->getWidth(),
fromOperation->getHeight()};
scaleOperation->setResolution(resolution);
sxop->setResolution(resolution);
syop->setResolution(resolution);
- system->addOperation(scaleOperation);
-
- c->setIgnoreResizeCheck(true);
+ builder.addOperation(scaleOperation);
}
TranslateOperation *translateOperation = new TranslateOperation();
+ translateOperation->getInputSocket(1)->setResizeMode(COM_SC_NO_RESIZE);
+ translateOperation->getInputSocket(2)->setResizeMode(COM_SC_NO_RESIZE);
if (!first) first = translateOperation;
SetValueOperation *xop = new SetValueOperation();
xop->setValue(addX);
- c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1));
- c->setIgnoreResizeCheck(true);
+ builder.addLink(xop->getOutputSocket(), translateOperation->getInputSocket(1));
SetValueOperation *yop = new SetValueOperation();
yop->setValue(addY);
- c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2));
- c->setIgnoreResizeCheck(true);
- system->addOperation(xop);
- system->addOperation(yop);
+ builder.addLink(yop->getOutputSocket(), translateOperation->getInputSocket(2));
+ builder.addOperation(xop);
+ builder.addOperation(yop);
unsigned int resolution[2] = {toOperation->getWidth(),
toOperation->getHeight()};
translateOperation->setResolution(resolution);
xop->setResolution(resolution);
yop->setResolution(resolution);
- system->addOperation(translateOperation);
+ builder.addOperation(translateOperation);
if (doScale) {
- c = ExecutionSystemHelper::addLink(system->getConnections(), scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
- c->setIgnoreResizeCheck(true);
+ translateOperation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
+ builder.addLink(scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
}
- InputSocket *inputSocket = connection->getToSocket();
- inputSocket->relinkConnections(first->getInputSocket(0));
- c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket);
- c->setIgnoreResizeCheck(true);
+ /* remove previous link and replace */
+ builder.removeInputLink(toSocket);
+ first->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
+ toSocket->setResizeMode(COM_SC_NO_RESIZE);
+ builder.addLink(fromSocket, first->getInputSocket(0));
+ builder.addLink(translateOperation->getOutputSocket(), toSocket);
}
-
- connection->setIgnoreResizeCheck(true);
}
diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h
index 15bda0839fa..311cec35644 100644
--- a/source/blender/compositor/intern/COM_Converter.h
+++ b/source/blender/compositor/intern/COM_Converter.h
@@ -23,8 +23,17 @@
#ifndef _COM_Converter_h
#define _COM_Converter_h
-#include "DNA_node_types.h"
-#include "COM_Node.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
+struct bNode;
+
+class Node;
+class NodeOperation;
+class NodeOperationInput;
+class NodeOperationOutput;
+class NodeOperationBuilder;
/**
* @brief Conversion methods for the compositor
@@ -35,37 +44,42 @@ public:
* @brief Convert/wraps a bNode in its Node instance.
*
* For all nodetypes a wrapper class is created.
- * Muted nodes are wrapped with MuteNode.
*
* @note When adding a new node to blender, this method needs to be changed to return the correct Node instance.
*
* @see Node
- * @see MuteNode
*/
- static Node *convert(bNode *b_node, bool fast);
+ static Node *convert(bNode *b_node);
+
+ /**
+ * @brief True if the node is considered 'fast'.
+ *
+ * Slow nodes will be skipped if fast execution is required.
+ */
+ static bool is_fast_node(bNode *b_node);
/**
* @brief This method will add a datetype conversion rule when the to-socket does not support the from-socket actual data type.
*
* @note this method is called when conversion is needed.
*
- * @param connection the SocketConnection what needs conversion
+ * @param link the NodeLink what needs conversion
* @param system the ExecutionSystem to add the conversion to.
- * @see SocketConnection - a link between two sockets
+ * @see NodeLink - a link between two sockets
*/
- static void convertDataType(SocketConnection *connection, ExecutionSystem *system);
+ static NodeOperation *convertDataType(NodeOperationOutput *from, NodeOperationInput *to);
/**
- * @brief This method will add a resolution rule based on the settings of the InputSocket.
+ * @brief This method will add a resolution rule based on the settings of the NodeInput.
*
* @note Conversion logic is implemented in this method
* @see InputSocketResizeMode for the possible conversions.
*
- * @param connection the SocketConnection what needs conversion
+ * @param link the NodeLink what needs conversion
* @param system the ExecutionSystem to add the conversion to.
- * @see SocketConnection - a link between two sockets
+ * @see NodeLink - a link between two sockets
*/
- static void convertResolution(SocketConnection *connection, ExecutionSystem *system);
+ static void convertResolution(NodeOperationBuilder &builder, NodeOperationOutput *fromSocket, NodeOperationInput *toSocket);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:Converter")
diff --git a/source/blender/compositor/intern/COM_Debug.cpp b/source/blender/compositor/intern/COM_Debug.cpp
index f5e3cca976c..a453af5ad13 100644
--- a/source/blender/compositor/intern/COM_Debug.cpp
+++ b/source/blender/compositor/intern/COM_Debug.cpp
@@ -46,10 +46,12 @@ extern "C" {
int DebugInfo::m_file_index = 0;
DebugInfo::NodeNameMap DebugInfo::m_node_names;
+DebugInfo::OpNameMap DebugInfo::m_op_names;
std::string DebugInfo::m_current_node_name;
+std::string DebugInfo::m_current_op_name;
DebugInfo::GroupStateMap DebugInfo::m_group_states;
-std::string DebugInfo::node_name(NodeBase *node)
+std::string DebugInfo::node_name(const Node *node)
{
NodeNameMap::const_iterator it = m_node_names.find(node);
if (it != m_node_names.end())
@@ -58,56 +60,65 @@ std::string DebugInfo::node_name(NodeBase *node)
return "";
}
+std::string DebugInfo::operation_name(const NodeOperation *op)
+{
+ OpNameMap::const_iterator it = m_op_names.find(op);
+ if (it != m_op_names.end())
+ return it->second;
+ else
+ return "";
+}
+
void DebugInfo::convert_started()
{
- m_node_names.clear();
+ m_op_names.clear();
}
-void DebugInfo::execute_started(ExecutionSystem *system)
+void DebugInfo::execute_started(const ExecutionSystem *system)
{
m_file_index = 1;
m_group_states.clear();
- for (int i = 0; i < system->getExecutionGroups().size(); ++i)
- m_group_states[system->getExecutionGroups()[i]] = EG_WAIT;
+ for (ExecutionSystem::Groups::const_iterator it = system->m_groups.begin(); it != system->m_groups.end(); ++it)
+ m_group_states[*it] = EG_WAIT;
}
-void DebugInfo::node_added(Node *node)
+void DebugInfo::node_added(const Node *node)
{
m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : "");
}
-void DebugInfo::node_to_operations(Node *node)
+void DebugInfo::node_to_operations(const Node *node)
{
m_current_node_name = m_node_names[node];
}
-void DebugInfo::operation_added(NodeOperation *operation)
+void DebugInfo::operation_added(const NodeOperation *operation)
{
- m_node_names[operation] = m_current_node_name;
+ m_op_names[operation] = m_current_node_name;
}
-void DebugInfo::operation_read_write_buffer(NodeOperation *operation)
+void DebugInfo::operation_read_write_buffer(const NodeOperation *operation)
{
- m_current_node_name = m_node_names[operation];
+ m_current_op_name = m_op_names[operation];
}
-void DebugInfo::execution_group_started(ExecutionGroup *group)
+void DebugInfo::execution_group_started(const ExecutionGroup *group)
{
m_group_states[group] = EG_RUNNING;
}
-void DebugInfo::execution_group_finished(ExecutionGroup *group)
+void DebugInfo::execution_group_finished(const ExecutionGroup *group)
{
m_group_states[group] = EG_FINISHED;
}
-int DebugInfo::graphviz_operation(ExecutionSystem *system, NodeOperation *operation, ExecutionGroup *group, char *str, int maxlen)
+int DebugInfo::graphviz_operation(const ExecutionSystem *system, const NodeOperation *operation, const ExecutionGroup *group, char *str, int maxlen)
{
int len = 0;
std::string fillcolor = "gainsboro";
if (operation->isViewerOperation()) {
- ViewerOperation *viewer = (ViewerOperation *)operation;
+ const ViewerOperation *viewer = (const ViewerOperation *)operation;
if (viewer->isActiveViewerOutput()) {
fillcolor = "lightskyblue1";
}
@@ -139,7 +150,7 @@ int DebugInfo::graphviz_operation(ExecutionSystem *system, NodeOperation *operat
if (totinputs != 0) {
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{");
for (int k = 0; k < totinputs; k++) {
- InputSocket *socket = operation->getInputSocket(k);
+ NodeOperationInput *socket = operation->getInputSocket(k);
if (k != 0) {
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
}
@@ -160,7 +171,7 @@ int DebugInfo::graphviz_operation(ExecutionSystem *system, NodeOperation *operat
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
}
- len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "%s\\n(%s)", m_node_names[operation].c_str(), typeid(*operation).name());
+ len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "%s\\n(%s)", m_op_names[operation].c_str(), typeid(*operation).name());
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, " (%d,%d)", operation->getWidth(), operation->getHeight());
@@ -169,7 +180,7 @@ int DebugInfo::graphviz_operation(ExecutionSystem *system, NodeOperation *operat
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{");
for (int k = 0; k < totoutputs; k++) {
- OutputSocket *socket = operation->getOutputSocket(k);
+ NodeOperationOutput *socket = operation->getOutputSocket(k);
if (k != 0) {
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
}
@@ -227,7 +238,7 @@ int DebugInfo::graphviz_legend(char *str, int maxlen)
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\r\n");
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>\r\n");
- len += graphviz_legend_color("Operation", "gainsboro", str + len, maxlen > len ? maxlen - len : 0);
+ len += graphviz_legend_color("NodeOperation", "gainsboro", str + len, maxlen > len ? maxlen - len : 0);
len += graphviz_legend_color("Output", "dodgerblue1", str + len, maxlen > len ? maxlen - len : 0);
len += graphviz_legend_color("Viewer", "lightskyblue3", str + len, maxlen > len ? maxlen - len : 0);
len += graphviz_legend_color("Active Viewer", "lightskyblue1", str + len, maxlen > len ? maxlen - len : 0);
@@ -248,26 +259,29 @@ int DebugInfo::graphviz_legend(char *str, int maxlen)
return len;
}
-bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
+bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int maxlen)
{
char strbuf[64];
int len = 0;
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "digraph compositorexecution {\r\n");
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "ranksep=1.5\r\n");
+ len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "rankdir=LR\r\n");
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "splines=false\r\n");
- int totnodes = system->getNodes().size();
- for (int i = 0; i < totnodes; i++) {
- Node *node = system->getNodes()[i];
- len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// NODE: %s\r\n", node->getbNode()->typeinfo->ui_name);
+#if 0
+ for (ExecutionSystem::Operations::const_iterator it = system->m_operations.begin();
+ it != system->m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+ len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// OPERATION: %s\r\n", node->getbNode()->typeinfo->ui_name);
}
+#endif
- int totgroups = system->getExecutionGroups().size();
- int totops = system->getOperations().size();
+ int totops = system->m_operations.size();
+ int totgroups = system->m_groups.size();
std::map<NodeOperation *, std::vector<std::string> > op_groups;
for (int i = 0; i < totgroups; ++i) {
- ExecutionGroup *group = system->getExecutionGroups()[i];
+ const ExecutionGroup *group = system->m_groups[i];
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// GROUP: %d\r\n", i);
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "subgraph cluster_%d{\r\n", i);
@@ -286,10 +300,8 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "fillcolor=chartreuse4\r\n");
}
- for (int j = 0; j < totops; ++j) {
- NodeOperation *operation = system->getOperations()[j];
- if (!group->containsOperation(operation))
- continue;
+ for (ExecutionGroup::Operations::const_iterator it = group->m_operations.begin(); it != group->m_operations.end(); ++it) {
+ NodeOperation *operation = *it;
sprintf(strbuf, "_%p", group);
op_groups[operation].push_back(std::string(strbuf));
@@ -297,14 +309,14 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
len += graphviz_operation(system, operation, group, str + len, maxlen > len ? maxlen - len : 0);
}
-// len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "// OUTPUTOPERATION: %p\r\n", group->getOutputNodeOperation());
-// len += snprintf(str+len, maxlen>len ? maxlen-len : 0, " O_%p\r\n", group->getOutputNodeOperation());
+// len += snprintf(str+len, maxlen>len ? maxlen-len : 0, "// OUTPUTOPERATION: %p\r\n", group->getOutputOperation());
+// len += snprintf(str+len, maxlen>len ? maxlen-len : 0, " O_%p\r\n", group->getOutputOperation());
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n");
}
/* operations not included in any group */
for (int j = 0; j < totops; ++j) {
- NodeOperation *operation = system->getOperations()[j];
+ NodeOperation *operation = system->m_operations[j];
if (op_groups.find(operation) != op_groups.end())
continue;
@@ -314,7 +326,7 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
}
for (int i = 0; i < totops; i++) {
- NodeOperation *operation = system->getOperations()[i];
+ NodeOperation *operation = system->m_operations[i];
if (operation->isReadBufferOperation()) {
ReadBufferOperation *read = (ReadBufferOperation *)operation;
@@ -330,16 +342,18 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
}
}
- int totcon = system->getConnections().size();
- for (int i = 0; i < totcon; i++) {
- SocketConnection *connection = system->getConnections()[i];
+ for (int i = 0; i < totops; i++) {
+ NodeOperation *op = system->m_operations[i];
- std::string color;
- if (!connection->isValid()) {
- color = "red";
- }
- else {
- switch (connection->getFromSocket()->getDataType()) {
+ for (NodeOperation::Inputs::const_iterator it = op->m_inputs.begin(); it != op->m_inputs.end(); ++it) {
+ NodeOperationInput *to = *it;
+ NodeOperationOutput *from = to->getLink();
+
+ if (!from)
+ continue;
+
+ std::string color;
+ switch (from->getDataType()) {
case COM_DT_VALUE:
color = "grey";
break;
@@ -350,22 +364,18 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
color = "orange";
break;
}
- }
-
- NodeBase *from_node = connection->getFromNode();
- NodeBase *to_node = connection->getToNode();
- OutputSocket *from_sock = connection->getFromSocket();
- InputSocket *to_sock = connection->getToSocket();
- if (from_node->isOperation() && to_node->isOperation()) {
- NodeOperation *from_op = (NodeOperation *)from_node;
- NodeOperation *to_op = (NodeOperation *)to_node;
+
+ NodeOperation *to_op = &to->getOperation();
+ NodeOperation *from_op = &from->getOperation();
std::vector<std::string> &from_groups = op_groups[from_op];
std::vector<std::string> &to_groups = op_groups[to_op];
- len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// CONNECTION: %p.%p -> %p.%p\r\n", from_op, from_sock, to_op, to_sock);
+ len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// CONNECTION: %p.%p -> %p.%p\r\n",
+ from_op, from, to_op, to);
for (int k = 0; k < from_groups.size(); ++k) {
for (int l = 0; l < to_groups.size(); ++l) {
- len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\"O_%p%s\":\"OUT_%p\":s -> \"O_%p%s\":\"IN_%p\":n", from_op, from_groups[k].c_str(), from_sock, to_op, to_groups[l].c_str(), to_sock);
+ len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\"O_%p%s\":\"OUT_%p\":e -> \"O_%p%s\":\"IN_%p\":w",
+ from_op, from_groups[k].c_str(), from, to_op, to_groups[l].c_str(), to);
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, " [color=%s]", color.c_str());
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n");
}
@@ -380,7 +390,7 @@ bool DebugInfo::graphviz_system(ExecutionSystem *system, char *str, int maxlen)
return (len < maxlen);
}
-void DebugInfo::graphviz(ExecutionSystem *system)
+void DebugInfo::graphviz(const ExecutionSystem *system)
{
char str[1000000];
if (graphviz_system(system, str, sizeof(str) - 1)) {
@@ -399,15 +409,16 @@ void DebugInfo::graphviz(ExecutionSystem *system)
#else
-std::string DebugInfo::node_name(NodeBase * /*node*/) { return ""; }
+std::string DebugInfo::node_name(const Node * /*node*/) { return ""; }
+std::string DebugInfo::operation_name(const NodeOperation * /*op*/) { return ""; }
void DebugInfo::convert_started() {}
-void DebugInfo::execute_started(ExecutionSystem * /*system*/) {}
-void DebugInfo::node_added(Node * /*node*/) {}
-void DebugInfo::node_to_operations(Node * /*node*/) {}
-void DebugInfo::operation_added(NodeOperation * /*operation*/) {}
-void DebugInfo::operation_read_write_buffer(NodeOperation * /*operation*/) {}
-void DebugInfo::execution_group_started(ExecutionGroup * /*group*/) {}
-void DebugInfo::execution_group_finished(ExecutionGroup * /*group*/) {}
-void DebugInfo::graphviz(ExecutionSystem * /*system*/) {}
+void DebugInfo::execute_started(const ExecutionSystem * /*system*/) {}
+void DebugInfo::node_added(const Node * /*node*/) {}
+void DebugInfo::node_to_operations(const Node * /*node*/) {}
+void DebugInfo::operation_added(const NodeOperation * /*operation*/) {}
+void DebugInfo::operation_read_write_buffer(const NodeOperation * /*operation*/) {}
+void DebugInfo::execution_group_started(const ExecutionGroup * /*group*/) {}
+void DebugInfo::execution_group_finished(const ExecutionGroup * /*group*/) {}
+void DebugInfo::graphviz(const ExecutionSystem * /*system*/) {}
#endif
diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h
index cc108157769..204e7e4f57c 100644
--- a/source/blender/compositor/intern/COM_Debug.h
+++ b/source/blender/compositor/intern/COM_Debug.h
@@ -27,7 +27,6 @@
#include "COM_defines.h"
-class NodeBase;
class Node;
class NodeOperation;
class ExecutionSystem;
@@ -41,37 +40,41 @@ public:
EG_FINISHED
} GroupState;
- typedef std::map<NodeBase *, std::string> NodeNameMap;
- typedef std::map<ExecutionGroup *, GroupState> GroupStateMap;
+ typedef std::map<const Node *, std::string> NodeNameMap;
+ typedef std::map<const NodeOperation *, std::string> OpNameMap;
+ typedef std::map<const ExecutionGroup *, GroupState> GroupStateMap;
- static std::string node_name(NodeBase *node);
+ static std::string node_name(const Node *node);
+ static std::string operation_name(const NodeOperation *op);
static void convert_started();
- static void execute_started(ExecutionSystem *system);
+ static void execute_started(const ExecutionSystem *system);
- static void node_added(Node *node);
- static void node_to_operations(Node *node);
- static void operation_added(NodeOperation *operation);
- static void operation_read_write_buffer(NodeOperation *operation);
+ static void node_added(const Node *node);
+ static void node_to_operations(const Node *node);
+ static void operation_added(const NodeOperation *operation);
+ static void operation_read_write_buffer(const NodeOperation *operation);
- static void execution_group_started(ExecutionGroup *group);
- static void execution_group_finished(ExecutionGroup *group);
+ static void execution_group_started(const ExecutionGroup *group);
+ static void execution_group_finished(const ExecutionGroup *group);
- static void graphviz(ExecutionSystem *system);
+ static void graphviz(const ExecutionSystem *system);
#ifdef COM_DEBUG
protected:
- static int graphviz_operation(ExecutionSystem *system, NodeOperation *operation, ExecutionGroup *group, char *str, int maxlen);
+ static int graphviz_operation(const ExecutionSystem *system, const NodeOperation *operation, const ExecutionGroup *group, char *str, int maxlen);
static int graphviz_legend_color(const char *name, const char *color, char *str, int maxlen);
static int graphviz_legend_line(const char *name, const char *color, const char *style, char *str, int maxlen);
static int graphviz_legend_group(const char *name, const char *color, const char *style, char *str, int maxlen);
static int graphviz_legend(char *str, int maxlen);
- static bool graphviz_system(ExecutionSystem *system, char *str, int maxlen);
+ static bool graphviz_system(const ExecutionSystem *system, char *str, int maxlen);
private:
static int m_file_index;
static NodeNameMap m_node_names; /**< map nodes to usable names for debug output */
+ static OpNameMap m_op_names; /**< map operations to usable names for debug output */
static std::string m_current_node_name; /**< base name for all operations added by a node */
+ static std::string m_current_op_name; /**< base name for automatic sub-operations */
static GroupStateMap m_group_states; /**< for visualizing group states */
#endif
};
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index a2e4e809a3d..366c97b50c6 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -26,8 +26,6 @@
#include <stdlib.h>
#include "COM_ExecutionGroup.h"
-#include "COM_InputSocket.h"
-#include "COM_SocketConnection.h"
#include "COM_defines.h"
#include "COM_ExecutionSystem.h"
#include "COM_ReadBufferOperation.h"
@@ -36,7 +34,6 @@
#include "COM_WorkScheduler.h"
#include "COM_ViewerOperation.h"
#include "COM_ChunkOrder.h"
-#include "COM_ExecutionSystemHelper.h"
#include "COM_Debug.h"
#include "MEM_guardedalloc.h"
@@ -69,84 +66,43 @@ ExecutionGroup::ExecutionGroup()
CompositorPriority ExecutionGroup::getRenderPriotrity()
{
- return this->getOutputNodeOperation()->getRenderPriority();
-}
-
-bool ExecutionGroup::containsOperation(NodeOperation *operation)
-{
- for (vector<NodeOperation *>::const_iterator iterator = this->m_operations.begin(); iterator != this->m_operations.end(); ++iterator) {
- NodeOperation *inListOperation = *iterator;
- if (inListOperation == operation) {
- return true;
- }
- }
- return false;
-}
-
-const bool ExecutionGroup::isComplex() const
-{
- return this->m_complex;
+ return this->getOutputOperation()->getRenderPriority();
}
bool ExecutionGroup::canContainOperation(NodeOperation *operation)
{
if (!this->m_initialized) { return true; }
+
if (operation->isReadBufferOperation()) { return true; }
if (operation->isWriteBufferOperation()) { return false; }
if (operation->isSetOperation()) { return true; }
-
- if (!this->isComplex()) {
- return (!operation->isComplex());
- }
- else {
- return false;
- }
+
+ /* complex groups don't allow further ops (except read buffer and values, see above) */
+ if (m_complex) { return false; }
+ /* complex ops can't be added to other groups (except their own, which they initialize, see above) */
+ if (operation->isComplex()) { return false; }
+
+ return true;
}
-void ExecutionGroup::addOperation(ExecutionSystem *system, NodeOperation *operation)
+bool ExecutionGroup::addOperation(NodeOperation *operation)
{
- /* should never happen but in rare cases it can - it causes confusing crashes */
- BLI_assert(operation->isOperation() == true);
-
- if (containsOperation(operation)) return;
- if (canContainOperation(operation)) {
- if (!operation->isBufferOperation()) {
- this->m_complex = operation->isComplex();
- this->m_openCL = operation->isOpenCL();
- this->m_singleThreaded = operation->isSingleThreaded();
- this->m_initialized = true;
- }
- this->m_operations.push_back(operation);
- if (operation->isReadBufferOperation()) {
- ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
- WriteBufferOperation *writeOperation = readOperation->getMemoryProxy()->getWriteBufferOperation();
- this->addOperation(system, writeOperation);
- }
- else {
- unsigned int index;
- for (index = 0; index < operation->getNumberOfInputSockets(); index++) {
- InputSocket *inputSocket = operation->getInputSocket(index);
- if (inputSocket->isConnected()) {
- NodeOperation *node = (NodeOperation *)inputSocket->getConnection()->getFromNode();
- this->addOperation(system, node);
- }
- }
- }
- }
- else {
- if (operation->isWriteBufferOperation()) {
- WriteBufferOperation *writeoperation = (WriteBufferOperation *)operation;
- if (writeoperation->getMemoryProxy()->getExecutor() == NULL) {
- ExecutionGroup *newGroup = new ExecutionGroup();
- writeoperation->getMemoryProxy()->setExecutor(newGroup);
- newGroup->addOperation(system, operation);
- ExecutionSystemHelper::addExecutionGroup(system->getExecutionGroups(), newGroup);
- }
- }
+ if (!canContainOperation(operation))
+ return false;
+
+ if (!operation->isReadBufferOperation() && !operation->isWriteBufferOperation()) {
+ m_complex = operation->isComplex();
+ m_openCL = operation->isOpenCL();
+ m_singleThreaded = operation->isSingleThreaded();
+ m_initialized = true;
}
+
+ m_operations.push_back(operation);
+
+ return true;
}
-NodeOperation *ExecutionGroup::getOutputNodeOperation() const
+NodeOperation *ExecutionGroup::getOutputOperation() const
{
return this->m_operations[0]; // the first operation of the group is always the output operation.
}
@@ -197,7 +153,7 @@ void ExecutionGroup::deinitExecution()
}
void ExecutionGroup::determineResolution(unsigned int resolution[2])
{
- NodeOperation *operation = this->getOutputNodeOperation();
+ NodeOperation *operation = this->getOutputOperation();
resolution[0] = operation->getWidth();
resolution[1] = operation->getHeight();
this->setResolution(resolution);
@@ -226,7 +182,7 @@ void ExecutionGroup::determineNumberOfChunks()
*/
void ExecutionGroup::execute(ExecutionSystem *graph)
{
- CompositorContext &context = graph->getContext();
+ const CompositorContext &context = graph->getContext();
const bNodeTree *bTree = context.getbNodeTree();
if (this->m_width == 0 || this->m_height == 0) {return; } /// @note: break out... no pixels to calculate.
if (bTree->test_break && bTree->test_break(bTree->tbh)) {return; } /// @note: early break out for blur and preview nodes
@@ -243,7 +199,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
for (chunkNumber = 0; chunkNumber < this->m_numberOfChunks; chunkNumber++) {
chunkOrder[chunkNumber] = chunkNumber;
}
- NodeOperation *operation = this->getOutputNodeOperation();
+ NodeOperation *operation = this->getOutputOperation();
float centerX = 0.5;
float centerY = 0.5;
OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
@@ -443,7 +399,7 @@ void ExecutionGroup::printBackgroundStats(void)
BLI_timestr(execution_time, timestr, sizeof(timestr));
printf("| Elapsed %s ", timestr);
- printf("| Tree %s, Tile %d-%d ", this->m_bTree->id.name + 2,
+ printf("| Tree %s, Tile %u-%u ", this->m_bTree->id.name + 2,
this->m_chunksFinished, this->m_numberOfChunks);
fputc('\n', stdout);
@@ -506,7 +462,7 @@ void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int chunkNumb
MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect)
{
// we asume that this method is only called from complex execution groups.
- NodeOperation *operation = this->getOutputNodeOperation();
+ NodeOperation *operation = this->getOutputOperation();
if (operation->isWriteBufferOperation()) {
WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect);
@@ -615,7 +571,7 @@ bool ExecutionGroup::scheduleChunkWhenPossible(ExecutionSystem *graph, int xChun
void ExecutionGroup::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- this->getOutputNodeOperation()->determineDependingAreaOfInterest(input, readOperation, output);
+ this->getOutputOperation()->determineDependingAreaOfInterest(input, readOperation, output);
}
void ExecutionGroup::determineDependingMemoryProxies(vector<MemoryProxy *> *memoryProxies)
@@ -634,7 +590,7 @@ bool ExecutionGroup::isOpenCL()
void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax)
{
- NodeOperation *operation = this->getOutputNodeOperation();
+ NodeOperation *operation = this->getOutputOperation();
if (operation->isViewerOperation() || operation->isPreviewOperation()) {
BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width,
@@ -644,7 +600,7 @@ void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float y
void ExecutionGroup::setRenderBorder(float xmin, float xmax, float ymin, float ymax)
{
- NodeOperation *operation = this->getOutputNodeOperation();
+ NodeOperation *operation = this->getOutputOperation();
if (operation->isOutputOperation(true)) {
/* Basically, setting border need to happen for only operations
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index 47f8447015d..4b6f51c72c0 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -31,6 +31,12 @@
#include "COM_Device.h"
#include "COM_CompositorContext.h"
+using std::vector;
+
+class ExecutionSystem;
+class MemoryProxy;
+class ReadBufferOperation;
+class Device;
/**
* @brief the execution state of a chunk in an ExecutionGroup
@@ -51,23 +57,22 @@ typedef enum ChunkExecutionState {
COM_ES_EXECUTED = 2
} ChunkExecutionState;
-class MemoryProxy;
-class ReadBufferOperation;
-class Device;
-
/**
- * @brief Class ExecutionGroup is a group of NodeOperations that are executed as one.
+ * @brief Class ExecutionGroup is a group of Operations that are executed as one.
* This grouping is used to combine Operations that can be executed as one whole when multi-processing.
* @ingroup Execution
*/
class ExecutionGroup {
+public:
+ typedef std::vector<NodeOperation*> Operations;
+
private:
// fields
/**
* @brief list of operations in this ExecutionGroup
*/
- vector<NodeOperation *> m_operations;
+ Operations m_operations;
/**
* @brief is this ExecutionGroup an input ExecutionGroup
@@ -130,7 +135,7 @@ private:
/**
* @brief a cached vector of all read operations in the execution group.
*/
- vector<NodeOperation *> m_cachedReadOperations;
+ Operations m_cachedReadOperations;
/**
* @brief reference to the original bNodeTree, this field is only set for the 'top' execution group.
@@ -152,8 +157,8 @@ private:
ChunkExecutionState *m_chunkExecutionStates;
/**
- * @brief indicator when this ExecutionGroup has valid NodeOperations in its vector for Execution
- * @note When building the ExecutionGroup NodeOperations are added via recursion. First a WriteBufferOperations is added, then the
+ * @brief indicator when this ExecutionGroup has valid Operations in its vector for Execution
+ * @note When building the ExecutionGroup Operations are added via recursion. First a WriteBufferOperations is added, then the
* @note Operation containing the settings that is important for the ExecutiongGroup is added,
* @note When this occurs, these settings are copied over from the node to the ExecutionGroup
* @note and the Initialized flag is set to true.
@@ -245,23 +250,17 @@ private:
public:
// constructors
ExecutionGroup();
-
- // methods
- /**
- * @brief check to see if a NodeOperation is already inside this execution group
- * @param operation the NodeOperation to check
- * @return [true,false]
- */
- bool containsOperation(NodeOperation *operation);
+ // methods
/**
* @brief add an operation to this ExecutionGroup
* @note this method will add input of the operations recursively
* @note this method can create multiple ExecutionGroup's
* @param system
* @param operation
+ * @return True if the operation was successfully added
*/
- void addOperation(ExecutionSystem *system, NodeOperation *operation);
+ bool addOperation(NodeOperation *operation);
/**
* @brief is this ExecutionGroup an output ExecutionGroup
@@ -292,24 +291,24 @@ public:
/**
* @brief get the width of this execution group
*/
- const unsigned int getWidth() { return this->m_width; }
+ unsigned int getWidth() const { return m_width; }
/**
* @brief get the height of this execution group
*/
- const unsigned int getHeight() { return this->m_height; }
+ unsigned int getHeight() const { return m_height; }
/**
* @brief does this ExecutionGroup contains a complex NodeOperation
*/
- const bool isComplex() const;
+ bool isComplex() const { return m_complex; }
/**
* @brief get the output operation of this ExecutionGroup
* @return NodeOperation *output operation
*/
- NodeOperation *getOutputNodeOperation() const;
+ NodeOperation *getOutputOperation() const;
/**
* @brief compose multiple chunks into a single chunk
@@ -419,12 +418,12 @@ public:
void setRenderBorder(float xmin, float xmax, float ymin, float ymax);
+ /* allow the DebugInfo class to look at internals */
+ friend class DebugInfo;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup")
#endif
-
- /* allow the DebugInfo class to peek inside without having to add getters for everything */
- friend class DebugInfo;
};
#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
index 6a208001f46..7c08188db90 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
@@ -29,15 +29,11 @@ extern "C" {
}
#include "COM_Converter.h"
+#include "COM_NodeOperationBuilder.h"
#include "COM_NodeOperation.h"
#include "COM_ExecutionGroup.h"
-#include "COM_NodeBase.h"
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
-#include "COM_GroupNode.h"
-#include "COM_WriteBufferOperation.h"
-#include "COM_ReadBufferOperation.h"
-#include "COM_ExecutionSystemHelper.h"
#include "COM_Debug.h"
#include "BKE_global.h"
@@ -63,14 +59,15 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin
this->m_context.setRendering(rendering);
this->m_context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL));
- ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NODE_INSTANCE_KEY_BASE);
-
this->m_context.setRenderData(rd);
this->m_context.setViewSettings(viewSettings);
this->m_context.setDisplaySettings(displaySettings);
- this->convertToOperations();
- this->groupOperations(); /* group operations in ExecutionGroups */
+ {
+ NodeOperationBuilder builder(&m_context, editingtree);
+ builder.convertToOperations(this);
+ }
+
unsigned int index;
unsigned int resolution[2];
@@ -107,16 +104,6 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin
ExecutionSystem::~ExecutionSystem()
{
unsigned int index;
- for (index = 0; index < this->m_connections.size(); index++) {
- SocketConnection *connection = this->m_connections[index];
- delete connection;
- }
- this->m_connections.clear();
- for (index = 0; index < this->m_nodes.size(); index++) {
- Node *node = this->m_nodes[index];
- delete node;
- }
- this->m_nodes.clear();
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
delete operation;
@@ -129,14 +116,19 @@ ExecutionSystem::~ExecutionSystem()
this->m_groups.clear();
}
+void ExecutionSystem::set_operations(const Operations &operations, const Groups &groups)
+{
+ m_operations = operations;
+ m_groups = groups;
+}
+
void ExecutionSystem::execute()
{
DebugInfo::execute_started(this);
unsigned int order = 0;
for (vector<NodeOperation *>::iterator iter = this->m_operations.begin(); iter != this->m_operations.end(); ++iter) {
- NodeBase *node = *iter;
- NodeOperation *operation = (NodeOperation *) node;
+ NodeOperation *operation = *iter;
if (operation->isReadBufferOperation()) {
ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
readOperation->setOffset(order);
@@ -196,182 +188,6 @@ void ExecutionSystem::executeGroups(CompositorPriority priority)
}
}
-void ExecutionSystem::addOperation(NodeOperation *operation)
-{
- ExecutionSystemHelper::addOperation(this->m_operations, operation);
- DebugInfo::operation_added(operation);
-}
-
-void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation)
-{
- DebugInfo::operation_read_write_buffer(operation);
-
- // for every input add write and read operation if input is not a read operation
- // only add read operation to other links when they are attached to buffered operations.
- unsigned int index;
- for (index = 0; index < operation->getNumberOfInputSockets(); index++) {
- InputSocket *inputsocket = operation->getInputSocket(index);
- if (inputsocket->isConnected()) {
- SocketConnection *connection = inputsocket->getConnection();
- NodeOperation *otherEnd = (NodeOperation *)connection->getFromNode();
- if (!otherEnd->isReadBufferOperation()) {
- // check of other end already has write operation
- OutputSocket *fromsocket = connection->getFromSocket();
- WriteBufferOperation *writeoperation = fromsocket->findAttachedWriteBufferOperation();
- if (writeoperation == NULL) {
- writeoperation = new WriteBufferOperation();
- writeoperation->setbNodeTree(this->getContext().getbNodeTree());
- this->addOperation(writeoperation);
- ExecutionSystemHelper::addLink(this->getConnections(), fromsocket, writeoperation->getInputSocket(0));
- writeoperation->readResolutionFromInputSocket();
- }
- ReadBufferOperation *readoperation = new ReadBufferOperation();
- readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
- connection->setFromSocket(readoperation->getOutputSocket());
- readoperation->getOutputSocket()->addConnection(connection);
- readoperation->readResolutionFromWriteBuffer();
- this->addOperation(readoperation);
- }
- }
- }
- /*
- * link the outputsocket to a write operation
- * link the writeoperation to a read operation
- * link the read operation to the next node.
- */
- OutputSocket *outputsocket = operation->getOutputSocket();
- if (outputsocket->isConnected()) {
- WriteBufferOperation *writeOperation;
- writeOperation = new WriteBufferOperation();
- writeOperation->setbNodeTree(this->getContext().getbNodeTree());
- this->addOperation(writeOperation);
- ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0));
- writeOperation->readResolutionFromInputSocket();
- for (index = 0; index < outputsocket->getNumberOfConnections() - 1; index++) {
- SocketConnection *connection = outputsocket->getConnection(index);
- ReadBufferOperation *readoperation = new ReadBufferOperation();
- readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
- connection->setFromSocket(readoperation->getOutputSocket());
- readoperation->getOutputSocket()->addConnection(connection);
- readoperation->readResolutionFromWriteBuffer();
- this->addOperation(readoperation);
- }
- }
-}
-
-#ifndef NDEBUG
-/* if this fails, there are still connection to/from this node,
- * which have not been properly relinked to operations!
- */
-static void debug_check_node_connections(Node *node)
-{
- /* note: connected inputs are not checked here,
- * it would break quite a lot and such inputs are ignored later anyway
- */
-#if 0
- for (int i = 0; i < node->getNumberOfInputSockets(); ++i) {
- BLI_assert(!node->getInputSocket(i)->isConnected());
- }
-#endif
- for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) {
- BLI_assert(!node->getOutputSocket(i)->isConnected());
- }
-}
-#else
-/* stub */
-#define debug_check_node_connections(node)
-#endif
-
-void ExecutionSystem::convertToOperations()
-{
- unsigned int index;
-
- for (index = 0; index < this->m_nodes.size(); index++) {
- Node *node = (Node *)this->m_nodes[index];
- DebugInfo::node_to_operations(node);
- node->convertToOperations(this, &this->m_context);
-
- debug_check_node_connections(node);
- }
-
- for (index = 0; index < this->m_connections.size(); index++) {
- SocketConnection *connection = this->m_connections[index];
- if (connection->isValid()) {
- if (connection->getFromSocket()->getDataType() != connection->getToSocket()->getDataType()) {
- Converter::convertDataType(connection, this);
- }
- }
- }
-
- // determine all resolutions of the operations (Width/Height)
- for (index = 0; index < this->m_operations.size(); index++) {
- NodeOperation *operation = this->m_operations[index];
- if (operation->isOutputOperation(this->m_context.isRendering()) && !operation->isPreviewOperation()) {
- unsigned int resolution[2] = {0, 0};
- unsigned int preferredResolution[2] = {0, 0};
- operation->determineResolution(resolution, preferredResolution);
- operation->setResolution(resolution);
- }
- }
- for (index = 0; index < this->m_operations.size(); index++) {
- NodeOperation *operation = this->m_operations[index];
- if (operation->isOutputOperation(this->m_context.isRendering()) && operation->isPreviewOperation()) {
- unsigned int resolution[2] = {0, 0};
- unsigned int preferredResolution[2] = {0, 0};
- operation->determineResolution(resolution, preferredResolution);
- operation->setResolution(resolution);
- }
- }
-
- // add convert resolution operations when needed.
- for (index = 0; index < this->m_connections.size(); index++) {
- SocketConnection *connection = this->m_connections[index];
- if (connection->isValid()) {
- if (connection->needsResolutionConversion()) {
- Converter::convertResolution(connection, this);
- }
- }
- }
-}
-
-void ExecutionSystem::groupOperations()
-{
- vector<NodeOperation *> outputOperations;
- NodeOperation *operation;
- unsigned int index;
- // surround complex operations with ReadBufferOperation and WriteBufferOperation
- for (index = 0; index < this->m_operations.size(); index++) {
- operation = this->m_operations[index];
- if (operation->isComplex()) {
- this->addReadWriteBufferOperations(operation);
- }
- }
- ExecutionSystemHelper::findOutputNodeOperations(&outputOperations, this->getOperations(), this->m_context.isRendering());
- for (vector<NodeOperation *>::iterator iter = outputOperations.begin(); iter != outputOperations.end(); ++iter) {
- operation = *iter;
- ExecutionGroup *group = new ExecutionGroup();
- group->addOperation(this, operation);
- group->setOutputExecutionGroup(true);
- ExecutionSystemHelper::addExecutionGroup(this->getExecutionGroups(), group);
- }
-}
-
-void ExecutionSystem::addSocketConnection(SocketConnection *connection)
-{
- this->m_connections.push_back(connection);
-}
-
-void ExecutionSystem::removeSocketConnection(SocketConnection *connection)
-{
- for (vector<SocketConnection *>::iterator it = m_connections.begin(); it != m_connections.end(); ++it) {
- if (*it == connection) {
- this->m_connections.erase(it);
- return;
- }
- }
-}
-
-
void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const
{
unsigned int index;
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h
index 7402ff90fb5..ab903206f0a 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.h
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.h
@@ -29,7 +29,6 @@ class ExecutionGroup;
#include "DNA_node_types.h"
#include <vector>
#include "COM_Node.h"
-#include "COM_SocketConnection.h"
#include "BKE_text.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeOperation.h"
@@ -73,7 +72,7 @@ using namespace std;
* As values are ordered differently than colors a conversion happens.
*
* - Image size conversions: the system can automatically convert when resolutions do not match.
- * An InputSocket has a resize mode. This can be any of the following settings.
+ * An NodeInput has a resize mode. This can be any of the following settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
@@ -115,6 +114,10 @@ using namespace std;
* @brief the ExecutionSystem contains the whole compositor tree.
*/
class ExecutionSystem {
+public:
+ typedef std::vector<NodeOperation*> Operations;
+ typedef std::vector<ExecutionGroup*> Groups;
+
private:
/**
* @brief the context used during execution
@@ -122,34 +125,17 @@ private:
CompositorContext m_context;
/**
- * @brief vector of nodes
- */
- vector<Node *> m_nodes;
-
- /**
* @brief vector of operations
*/
- vector<NodeOperation *> m_operations;
+ Operations m_operations;
/**
* @brief vector of groups
*/
- vector<ExecutionGroup *> m_groups;
-
- /**
- * @brief vector of connections
- */
- vector<SocketConnection *> m_connections;
+ Groups m_groups;
private: //methods
/**
- * @brief add ReadBufferOperation and WriteBufferOperation around an operation
- * @param operation the operation to add the bufferoperations around.
- */
- void addReadWriteBufferOperations(NodeOperation *operation);
-
-
- /**
* find all execution group with output nodes
*/
void findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const;
@@ -175,6 +161,7 @@ public:
*/
~ExecutionSystem();
+ void set_operations(const Operations &operations, const Groups &groups);
/**
* @brief execute this system
@@ -185,70 +172,16 @@ public:
void execute();
/**
- * @brief Add an operation to the operation list
- *
- * @param operation the operation to add
- */
- void addOperation(NodeOperation *operation);
-
- /**
- * Add an editor link to the system. convert it to an socketconnection (CPP-representative)
- * this converted socket is returned.
- */
- SocketConnection *addNodeLink(bNodeLink *bNodeLink);
- void addSocketConnection(SocketConnection *connection);
-
- /**
- * Remove a socket connection from the system.
- */
- void removeSocketConnection(SocketConnection *connection);
-
- /**
- * @brief Convert all nodes to operations
- */
- void convertToOperations();
-
- /**
- * @brief group operations in ExecutionGroup's
- * @see ExecutionGroup
- */
- void groupOperations();
-
- /**
* @brief get the reference to the compositor context
*/
- CompositorContext &getContext() { return this->m_context; }
-
- /**
- * @brief get the reference to the compositor nodes
- */
- vector<Node *> &getNodes() { return this->m_nodes; }
-
- /**
- * @brief get the reference to the compositor connections
- */
- vector<SocketConnection *>& getConnections() { return this->m_connections; }
-
- /**
- * @brief get the reference to the list of execution groups
- */
- vector<ExecutionGroup *>& getExecutionGroups() { return this->m_groups; }
-
- /**
- * @brief get the reference to the list of operations
- */
- vector<NodeOperation *>& getOperations() { return this->m_operations; }
+ const CompositorContext &getContext() const { return this->m_context; }
private:
-
- /**
- * @brief determine the actual data types of all sockets
- * @param nodes list of nodes or operations to do the data type determination
- */
- void determineActualSocketDataTypes(vector<NodeBase *> &nodes);
-
void executeGroups(CompositorPriority priority);
+ /* allow the DebugInfo class to look at internals */
+ friend class DebugInfo;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionSystem")
#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
deleted file mode 100644
index 7def96d426e..00000000000
--- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_ExecutionSystemHelper.h"
-
-#include "PIL_time.h"
-
-#include "COM_Converter.h"
-#include "COM_NodeOperation.h"
-#include "COM_ExecutionGroup.h"
-#include "COM_NodeBase.h"
-#include "COM_WorkScheduler.h"
-#include "COM_ReadBufferOperation.h"
-#include "COM_GroupNode.h"
-#include "COM_WriteBufferOperation.h"
-#include "COM_ReadBufferOperation.h"
-#include "COM_ViewerOperation.h"
-#include "COM_Debug.h"
-
-extern "C" {
-#include "BKE_node.h"
-}
-
-void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key)
-{
- vector<Node *>& nodes = system.getNodes();
- vector<SocketConnection *>& links = system.getConnections();
-
- const bNodeTree *basetree = system.getContext().getbNodeTree();
- /* update viewers in the active edittree as well the base tree (for backdrop) */
- bool is_active_group = ((parent_key.value == basetree->active_viewer_key.value) ||
- (tree == basetree));
-
- /* add all nodes of the tree to the node list */
- bNode *node = (bNode *)tree->nodes.first;
- while (node != NULL) {
- Node *nnode = addNode(nodes, node, is_active_group, system.getContext().isFastCalculation());
- if (nnode) {
- nnode->setbNodeTree(tree);
- nnode->setInstanceKey(BKE_node_instance_key(parent_key, tree, node));
- }
- node = node->next;
- }
-
- NodeRange node_range(nodes.begin() + nodes_start, nodes.end());
-
- /* add all nodelinks of the tree to the link list */
- bNodeLink *nodelink = (bNodeLink *)tree->links.first;
- while (nodelink != NULL) {
- addNodeLink(node_range, links, nodelink);
- nodelink = nodelink->next;
- }
-
- /* Expand group nodes
- * Only go up to nodes_end, to avoid ungrouping nested node groups repeatedly.
- */
- int nodes_end = nodes.size();
- for (unsigned int i = nodes_start; i < nodes_end; ++i) {
- Node *execnode = nodes[i];
- if (execnode->isGroupNode()) {
- GroupNode *groupNode = (GroupNode *)execnode;
- groupNode->ungroup(system);
- }
- }
-}
-
-void ExecutionSystemHelper::addNode(vector<Node *>& nodes, Node *node)
-{
- nodes.push_back(node);
-}
-
-Node *ExecutionSystemHelper::addNode(vector<Node *>& nodes, bNode *b_node, bool inActiveGroup, bool fast)
-{
- Node *node = Converter::convert(b_node, fast);
- if (node) {
- node->setIsInActiveGroup(inActiveGroup);
- addNode(nodes, node);
-
- DebugInfo::node_added(node);
- }
- return node;
-}
-void ExecutionSystemHelper::addOperation(vector<NodeOperation *>& operations, NodeOperation *operation)
-{
- operations.push_back(operation);
-}
-
-void ExecutionSystemHelper::addExecutionGroup(vector<ExecutionGroup *>& executionGroups, ExecutionGroup *executionGroup)
-{
- executionGroups.push_back(executionGroup);
-}
-
-void ExecutionSystemHelper::findOutputNodeOperations(vector<NodeOperation *> *result, vector<NodeOperation *>& operations, bool rendering)
-{
- unsigned int index;
-
- for (index = 0; index < operations.size(); index++) {
- NodeOperation *operation = operations[index];
- if (operation->isOutputOperation(rendering)) {
- result->push_back(operation);
- }
- }
-}
-
-static InputSocket *find_input(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket)
-{
- for (NodeIterator it = node_range.first; it != node_range.second; ++it) {
- Node *node = *it;
- InputSocket *input = node->findInputSocketBybNodeSocket(bsocket);
- if (input)
- return input;
- }
- return NULL;
-}
-static OutputSocket *find_output(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket)
-{
- for (NodeIterator it = node_range.first; it != node_range.second; ++it) {
- Node *node = *it;
- OutputSocket *output = node->findOutputSocketBybNodeSocket(bsocket);
- if (output)
- return output;
- }
- return NULL;
-}
-SocketConnection *ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vector<SocketConnection *>& links, bNodeLink *b_nodelink)
-{
- /// @note: ignore invalid links
- if (!(b_nodelink->flag & NODE_LINK_VALID))
- return NULL;
-
- InputSocket *inputSocket = find_input(node_range, b_nodelink->tonode, b_nodelink->tosock);
- OutputSocket *outputSocket = find_output(node_range, b_nodelink->fromnode, b_nodelink->fromsock);
- if (inputSocket == NULL || outputSocket == NULL) {
- return NULL;
- }
- if (inputSocket->isConnected()) {
- return NULL;
- }
- SocketConnection *connection = addLink(links, outputSocket, inputSocket);
- return connection;
-}
-
-SocketConnection *ExecutionSystemHelper::addLink(vector<SocketConnection *>& links, OutputSocket *fromSocket, InputSocket *toSocket)
-{
- SocketConnection *newconnection = new SocketConnection();
- newconnection->setFromSocket(fromSocket);
- newconnection->setToSocket(toSocket);
- fromSocket->addConnection(newconnection);
- toSocket->setConnection(newconnection);
- links.push_back(newconnection);
- return newconnection;
-}
diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h
deleted file mode 100644
index 002423c195c..00000000000
--- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-class ExecutionGroup;
-
-#ifndef _COM_ExecutionSystemHelper_h
-#define _COM_ExecutionSystemHelper_h
-
-#include "DNA_node_types.h"
-#include <vector>
-#include "COM_Node.h"
-#include "COM_SocketConnection.h"
-#include "BKE_text.h"
-#include "COM_ExecutionGroup.h"
-
-using namespace std;
-
-/**
- *
- */
-class ExecutionSystemHelper {
-
-public:
-
- /**
- * @brief add an bNodeTree to the nodes list and connections
- * @param system Execution system
- * @param nodes_start Starting index in the system's nodes list for nodes in this tree.
- * @param tree bNodeTree to add
- * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added
- */
- static void addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key);
-
- /**
- * @brief add an editor node to the system.
- * this node is converted to a Node instance.
- * and the converted node is returned
- *
- * @param b_node node to add
- * @return Node that represents the bNode or null when not able to convert.
- */
- static Node *addNode(vector<Node *>& nodes, bNode *b_node, bool isInActiveGroup, bool fast);
-
- /**
- * @brief Add a Node to a list
- *
- * @param nodes the list where the node needs to be added to
- * @param node the node to be added
- */
- static void addNode(vector<Node *>& nodes, Node *node);
-
- /**
- * @brief Add an operation to the operation list
- *
- * The id of the operation is updated.
- *
- * @param operations the list where the operation need to be added to
- * @param operation the operation to add
- */
- static void addOperation(vector<NodeOperation *> &operations, NodeOperation *operation);
-
- /**
- * @brief Add an ExecutionGroup to a list
- *
- * The id of the ExecutionGroup is updated.
- *
- * @param executionGroups the list where the executionGroup need to be added to
- * @param executionGroup the ExecutionGroup to add
- */
- static void addExecutionGroup(vector<ExecutionGroup *>& executionGroups, ExecutionGroup *executionGroup);
-
- /**
- * Find all Node Operations that needs to be executed.
- * @param rendering
- * the rendering parameter will tell what type of execution we are doing
- * FALSE is editing, TRUE is rendering
- */
- static void findOutputNodeOperations(vector<NodeOperation *> *result, vector<NodeOperation *>& operations, bool rendering);
-
- /**
- * @brief add a bNodeLink to the list of links
- * the bNodeLink will be wrapped in a SocketConnection
- *
- * @note Cyclic links will be ignored
- *
- * @param node_range list of possible nodes for lookup.
- * @param links list of links to add the bNodeLink to
- * @param bNodeLink the link to be added
- * @return the created SocketConnection or NULL
- */
- static SocketConnection *addNodeLink(NodeRange &node_range, vector<SocketConnection *>& links, bNodeLink *bNodeLink);
-
- /**
- * @brief create a new SocketConnection and add to a vector of links
- * @param links the vector of links
- * @param fromSocket the startpoint of the connection
- * @param toSocket the endpoint of the connection
- * @return the new created SocketConnection
- */
- static SocketConnection *addLink(vector<SocketConnection *>& links, OutputSocket *fromSocket, InputSocket *toSocket);
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionSystemHelper")
-#endif
-};
-
-#endif /* _COM_ExecutionSystemHelper_h */
diff --git a/source/blender/compositor/intern/COM_InputSocket.cpp b/source/blender/compositor/intern/COM_InputSocket.cpp
deleted file mode 100644
index 6868745d631..00000000000
--- a/source/blender/compositor/intern/COM_InputSocket.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_Socket.h"
-#include "COM_Node.h"
-#include "COM_SocketConnection.h"
-#include "COM_ExecutionSystem.h"
-
-InputSocket::InputSocket(DataType datatype) : Socket(datatype)
-{
- this->m_connection = NULL;
- this->m_resizeMode = COM_SC_CENTER;
-}
-InputSocket::InputSocket(DataType datatype, InputSocketResizeMode resizeMode) : Socket(datatype)
-{
- this->m_connection = NULL;
- this->m_resizeMode = resizeMode;
-}
-
-InputSocket::InputSocket(InputSocket *from) : Socket(from->getDataType())
-{
- this->m_connection = NULL;
- this->m_resizeMode = from->getResizeMode();
-}
-
-int InputSocket::isInputSocket() const { return true; }
-const int InputSocket::isConnected() const { return this->m_connection != NULL; }
-
-void InputSocket::setConnection(SocketConnection *connection)
-{
- this->m_connection = connection;
-}
-SocketConnection *InputSocket::getConnection()
-{
- return this->m_connection;
-}
-
-void InputSocket::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
-{
- if (this->isConnected()) {
- this->m_connection->getFromSocket()->determineResolution(resolution, preferredResolution);
- }
- else {
- return;
- }
-}
-
-void InputSocket::relinkConnections(InputSocket *relinkToSocket)
-{
- if (!isConnected()) {
- return;
- }
- SocketConnection *connection = this->getConnection();
- connection->setToSocket(relinkToSocket);
- relinkToSocket->setConnection(connection);
- this->setConnection(NULL);
-}
-
-void InputSocket::relinkConnectionsDuplicate(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *graph)
-{
- if (!this->isConnected()) {
- Node *node = (Node *)this->getNode();
- switch (this->getDataType()) {
- case COM_DT_COLOR:
- node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- case COM_DT_VECTOR:
- node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- case COM_DT_VALUE:
- node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- }
- return;
- }
- SocketConnection *newConnection = new SocketConnection();
- OutputSocket *fromSocket = this->getConnection()->getFromSocket();
- newConnection->setToSocket(relinkToSocket);
- newConnection->setFromSocket(fromSocket);
- relinkToSocket->setConnection(newConnection);
- fromSocket->addConnection(newConnection);
- graph->addSocketConnection(newConnection);
-}
-
-void InputSocket::relinkConnections(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *graph)
-{
- if (isConnected()) {
- relinkConnections(relinkToSocket);
- }
- else {
- Node *node = (Node *)this->getNode();
- switch (this->getDataType()) {
- case COM_DT_COLOR:
- node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- case COM_DT_VECTOR:
- node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- case COM_DT_VALUE:
- node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
- break;
- }
- }
-}
-
-void InputSocket::unlinkConnections(ExecutionSystem *system)
-{
- SocketConnection *connection = getConnection();
- if (connection) {
- system->removeSocketConnection(connection);
- connection->getFromSocket()->removeConnection(connection);
- setConnection(NULL);
- delete connection;
- }
-}
-
-bool InputSocket::isStatic()
-{
- if (isConnected()) {
- NodeBase *node = this->getConnection()->getFromNode();
- if (node) {
- return node->isStatic();
- }
- }
- return true;
-}
-SocketReader *InputSocket::getReader()
-{
- return this->getOperation();
-}
-
-NodeOperation *InputSocket::getOperation() const
-{
- if (isConnected()) {
- return (NodeOperation *)this->m_connection->getFromSocket()->getNode();
- }
- else {
- return NULL;
- }
-}
diff --git a/source/blender/compositor/intern/COM_InputSocket.h b/source/blender/compositor/intern/COM_InputSocket.h
deleted file mode 100644
index 23490b66bba..00000000000
--- a/source/blender/compositor/intern/COM_InputSocket.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_InputSocket_h
-#define _COM_InputSocket_h
-
-#include <vector>
-#include "COM_Socket.h"
-#include "COM_SocketReader.h"
-
-using namespace std;
-class SocketConnection;
-class Node;
-class ExecutionSystem;
-class OutputSocket;
-class ChannelInfo;
-class NodeOperation;
-
-/**
- * @brief Resize modes of inputsockets
- * How are the input and working resolutions matched
- * @ingroup Model
- */
-typedef enum InputSocketResizeMode {
- /** @brief Center the input image to the center of the working area of the node, no resizing occurs */
- COM_SC_CENTER = NS_CR_CENTER,
- /** @brief The bottom left of the input image is the bottom left of the working area of the node, no resizing occurs */
- COM_SC_NO_RESIZE = NS_CR_NONE,
- /** @brief Fit the width of the input image to the width of the working area of the node */
- COM_SC_FIT_WIDTH = NS_CR_FIT_WIDTH,
- /** @brief Fit the height of the input image to the height of the working area of the node */
- COM_SC_FIT_HEIGHT = NS_CR_FIT_HEIGHT,
- /** @brief Fit the width or the height of the input image to the width or height of the working area of the node, image will be larger than the working area */
- COM_SC_FIT = NS_CR_FIT,
- /** @brief Fit the width and the height of the input image to the width and height of the working area of the node, image will be equally larger than the working area */
- COM_SC_STRETCH = NS_CR_STRETCH
-} InputSocketResizeMode;
-
-/**
- * @brief InputSocket are sockets that can receive data/input
- * @ingroup Model
- */
-class InputSocket : public Socket {
-private:
- /**
- * @brief connection connected to this InputSocket.
- * An input socket can only have a single connection
- */
- SocketConnection *m_connection;
-
- /**
- * @brief resize mode of this socket
- */
- InputSocketResizeMode m_resizeMode;
-
-
-public:
- InputSocket(DataType datatype);
- InputSocket(DataType datatype, InputSocketResizeMode resizeMode);
- InputSocket(InputSocket *from);
-
- void setConnection(SocketConnection *connection);
- SocketConnection *getConnection();
-
- const int isConnected() const;
- int isInputSocket() const;
-
- /**
- * @brief determine the resolution of this data going through this socket
- * @param resolution the result of this operation
- * @param preferredResolution the preferable resolution as no resolution could be determined
- */
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
-
- /**
- * @brief move all connections of this input socket to another socket
- * only use this method when already checked the availability of a SocketConnection
- * @param relinkToSocket the socket to move to connections to
- */
- void relinkConnections(InputSocket *relinkToSocket);
-
- /**
- * @brief move all connections of this input socket to another socket
- * @param relinkToSocket the socket to move to connections to
- * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection)
- * @param system ExecutionSystem to update to
- */
- void relinkConnections(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system);
-
- /**
- * @brief add a connection of this input socket to another socket
- * @warning make sure to remove the original connection with \a unlinkConnections afterward.
- * @param relinkToSocket the socket to move to connections to
- * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection)
- * @param system ExecutionSystem to update to
- */
- void relinkConnectionsDuplicate(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system);
-
- /**
- * @brief remove all connections of this input socket.
- * @warning \a relinkConnectionsDuplicate should be used to ensure this socket is still connected.
- * @param system ExecutionSystem to update to
- */
- void unlinkConnections(ExecutionSystem *system);
-
- /**
- * @brief set the resize mode
- * @param resizeMode the new resize mode.
- */
- void setResizeMode(InputSocketResizeMode resizeMode) {
- this->m_resizeMode = resizeMode;
- }
-
- /**
- * @brief get the resize mode of this socket
- * @return InputSocketResizeMode
- */
- InputSocketResizeMode getResizeMode() const {
- return this->m_resizeMode;
- }
-
- const ChannelInfo *getChannelInfo(const int channelnumber);
-
- bool isStatic();
-
- SocketReader *getReader();
- NodeOperation *getOperation() const;
-};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
index 7d8511540f7..04828bfe3f8 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
@@ -21,8 +21,11 @@
*/
#include "COM_MemoryBuffer.h"
+
#include "MEM_guardedalloc.h"
-//#include "BKE_global.h"
+
+using std::min;
+using std::max;
unsigned int MemoryBuffer::determineBufferSize()
{
@@ -218,8 +221,8 @@ static void ellipse_bounds(float A, float B, float C, float F, float &xmax, floa
{
float denom = 4.0f * A * C - B * B;
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
- xmax = sqrt(F) / (2.0f * A) * (sqrt(F * (4.0f * A - B * B / C)) + B * B * sqrt(F / (C * denom)));
- ymax = sqrt(F) / (2.0f * C) * (sqrt(F * (4.0f * C - B * B / A)) + B * B * sqrt(F / (A * denom)));
+ xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
+ ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
}
else {
xmax = 0.0f;
@@ -272,7 +275,7 @@ void MemoryBuffer::readEWA(float result[4], const float uv[2], const float deriv
int U0 = (int)u;
int V0 = (int)v;
/* pixel offset for interpolation */
- float ufac = u - floor(u), vfac = v - floor(v);
+ float ufac = u - floorf(u), vfac = v - floorf(v);
/* filter size */
int u1 = (int)(u - ue);
int u2 = (int)(u + ue);
@@ -288,6 +291,20 @@ void MemoryBuffer::readEWA(float result[4], const float uv[2], const float deriv
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
+ /* Early output check for cases the whole region is outside of the buffer. */
+ if ((u2 < m_rect.xmin || u1 >= m_rect.xmax) ||
+ (v2 < m_rect.ymin || v1 >= m_rect.ymax))
+ {
+ zero_v4(result);
+ return;
+ }
+
+ /* Clamp sampling rectagle to the buffer dimensions. */
+ u1 = max_ii(u1, m_rect.xmin);
+ u2 = min_ii(u2, m_rect.xmax);
+ v1 = max_ii(v1, m_rect.ymin);
+ v2 = min_ii(v2, m_rect.ymax);
+
float DDQ = 2.0f * A;
float U = u1 - U0;
float ac1 = A * (2.0f * U + 1.0f);
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index 521e3c6231e..d6ef9cd673e 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -27,6 +27,7 @@ class MemoryBuffer;
#include "COM_ExecutionGroup.h"
#include "COM_MemoryProxy.h"
+#include "COM_SocketReader.h"
extern "C" {
# include "BLI_math.h"
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h
index 696c843e7c4..233b035a2d7 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.h
+++ b/source/blender/compositor/intern/COM_MemoryProxy.h
@@ -28,6 +28,7 @@ class MemoryProxy;
#include "COM_ExecutionGroup.h"
class ExecutionGroup;
+class WriteBufferOperation;
/**
* @brief A MemoryProxy is a unique identifier for a memory buffer.
diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp
index b62e2d08d9a..67f4d2523f3 100644
--- a/source/blender/compositor/intern/COM_Node.cpp
+++ b/source/blender/compositor/intern/COM_Node.cpp
@@ -22,27 +22,32 @@
#include <string.h>
+extern "C" {
#include "BKE_node.h"
-#include "COM_Node.h"
-#include "COM_NodeOperation.h"
-#include "COM_SetValueOperation.h"
-#include "COM_SetVectorOperation.h"
-#include "COM_SetColorOperation.h"
-#include "COM_SocketConnection.h"
+#include "RNA_access.h"
+}
+
#include "COM_ExecutionSystem.h"
-#include "COM_PreviewOperation.h"
+#include "COM_NodeOperation.h"
#include "COM_TranslateOperation.h"
#include "COM_SocketProxyNode.h"
-//#include <stdio.h>
#include "COM_defines.h"
-Node::Node(bNode *editorNode, bool create_sockets) : NodeBase()
+#include "COM_Node.h" /* own include */
+
+/**************
+ **** Node ****
+ **************/
+
+Node::Node(bNode *editorNode, bool create_sockets) :
+ m_editorNodeTree(NULL),
+ m_editorNode(editorNode),
+ m_inActiveGroup(false),
+ m_instanceKey(NODE_INSTANCE_KEY_NONE)
{
- setbNode(editorNode);
-
if (create_sockets) {
bNodeSocket *input = (bNodeSocket *)editorNode->inputs.first;
while (input != NULL) {
@@ -50,7 +55,7 @@ Node::Node(bNode *editorNode, bool create_sockets) : NodeBase()
if (input->type == SOCK_RGBA) dt = COM_DT_COLOR;
if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
- this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input);
+ this->addInputSocket(dt, input);
input = input->next;
}
bNodeSocket *output = (bNodeSocket *)editorNode->outputs.first;
@@ -65,102 +70,50 @@ Node::Node(bNode *editorNode, bool create_sockets) : NodeBase()
}
}
-void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex)
+Node::~Node()
{
- InputSocket *input = getInputSocket(editorNodeInputSocketIndex);
- SetValueOperation *operation = new SetValueOperation();
- operation->setValue(input->getEditorValueFloat());
- this->addLink(graph, operation->getOutputSocket(), inputsocket);
- graph->addOperation(operation);
+ while (!this->m_outputsockets.empty()) {
+ delete (this->m_outputsockets.back());
+ this->m_outputsockets.pop_back();
+ }
+ while (!this->m_inputsockets.empty()) {
+ delete (this->m_inputsockets.back());
+ this->m_inputsockets.pop_back();
+ }
}
-void Node::addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket)
+void Node::addInputSocket(DataType datatype)
{
- if (this->isInActiveGroup()) {
- if (!(this->getbNode()->flag & NODE_HIDDEN)) { // do not calculate previews of hidden nodes.
- bNodeInstanceHash *previews = context->getPreviewHash();
- if (previews && (this->getbNode()->flag & NODE_PREVIEW)) {
- PreviewOperation *operation = new PreviewOperation(context->getViewSettings(), context->getDisplaySettings());
- system->addOperation(operation);
- operation->setbNode(this->getbNode());
- operation->setbNodeTree(system->getContext().getbNodeTree());
- operation->verifyPreview(previews, this->getInstanceKey());
- this->addLink(system, outputSocket, operation->getInputSocket(0));
- }
- }
- }
+ this->addInputSocket(datatype, NULL);
}
-void Node::addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket)
+void Node::addInputSocket(DataType datatype, bNodeSocket *bSocket)
{
- if (inputSocket->isConnected() && this->isInActiveGroup()) {
- OutputSocket *outputsocket = inputSocket->getConnection()->getFromSocket();
- this->addPreviewOperation(system, context, outputsocket);
- }
+ NodeInput *socket = new NodeInput(this, bSocket, datatype);
+ this->m_inputsockets.push_back(socket);
}
-SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSocket, InputSocket *inputsocket)
+void Node::addOutputSocket(DataType datatype)
{
- if (inputsocket->isConnected()) {
- return NULL;
- }
- SocketConnection *connection = new SocketConnection();
- connection->setFromSocket(outputSocket);
- outputSocket->addConnection(connection);
- connection->setToSocket(inputsocket);
- inputsocket->setConnection(connection);
- graph->addSocketConnection(connection);
- return connection;
-}
-
-void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex)
-{
- InputSocket *input = getInputSocket(editorNodeInputSocketIndex);
- SetColorOperation *operation = new SetColorOperation();
- float col[4];
- input->getEditorValueColor(col);
- operation->setChannel1(col[0]);
- operation->setChannel2(col[1]);
- operation->setChannel3(col[2]);
- operation->setChannel4(col[3]);
- this->addLink(graph, operation->getOutputSocket(), inputsocket);
- graph->addOperation(operation);
-}
-
-void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex)
-{
- InputSocket *input = getInputSocket(editorNodeInputSocketIndex);
- SetVectorOperation *operation = new SetVectorOperation();
- float vec[3];
- input->getEditorValueVector(vec);
- operation->setX(vec[0]);
- operation->setY(vec[1]);
- operation->setZ(vec[2]);
- this->addLink(graph, operation->getOutputSocket(), inputsocket);
- graph->addOperation(operation);
-}
-
-NodeOperation *Node::convertToOperations_invalid_index(ExecutionSystem *graph, int index)
-{
- const float warning_color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
- SetColorOperation *operation = new SetColorOperation();
- operation->setChannels(warning_color);
-
- /* link the operation */
- this->getOutputSocket(index)->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
- return operation;
-}
-
-/* when a node has no valid data (missing image / group pointer, or missing renderlayer from EXR) */
-void Node::convertToOperations_invalid(ExecutionSystem *graph, CompositorContext *context)
-{
- /* this is a really bad situation - bring on the pink! - so artists know this is bad */
- int index;
- vector<OutputSocket *> &outputsockets = this->getOutputSockets();
- for (index = 0; index < outputsockets.size(); index++) {
- convertToOperations_invalid_index(graph, index);
- }
+ this->addOutputSocket(datatype, NULL);
+
+}
+void Node::addOutputSocket(DataType datatype, bNodeSocket *bSocket)
+{
+ NodeOutput *socket = new NodeOutput(this, bSocket, datatype);
+ this->m_outputsockets.push_back(socket);
+}
+
+NodeOutput *Node::getOutputSocket(unsigned int index) const
+{
+ BLI_assert(index < this->m_outputsockets.size());
+ return this->m_outputsockets[index];
+}
+
+NodeInput *Node::getInputSocket(unsigned int index) const
+{
+ BLI_assert(index < this->m_inputsockets.size());
+ return this->m_inputsockets[index];
}
bNodeSocket *Node::getEditorInputSocket(int editorNodeInputSocketIndex)
@@ -190,28 +143,74 @@ bNodeSocket *Node::getEditorOutputSocket(int editorNodeInputSocketIndex)
return NULL;
}
-InputSocket *Node::findInputSocketBybNodeSocket(bNodeSocket *socket)
+
+/*******************
+ **** NodeInput ****
+ *******************/
+
+NodeInput::NodeInput(Node *node, bNodeSocket *b_socket, DataType datatype) :
+ m_node(node),
+ m_editorSocket(b_socket),
+ m_datatype(datatype),
+ m_link(NULL)
{
- vector<InputSocket *> &inputsockets = this->getInputSockets();
- unsigned int index;
- for (index = 0; index < inputsockets.size(); index++) {
- InputSocket *input = inputsockets[index];
- if (input->getbNodeSocket() == socket) {
- return input;
- }
- }
- return NULL;
}
-OutputSocket *Node::findOutputSocketBybNodeSocket(bNodeSocket *socket)
+void NodeInput::setLink(NodeOutput *link)
{
- vector<OutputSocket *> &outputsockets = this->getOutputSockets();
- unsigned int index;
- for (index = 0; index < outputsockets.size(); index++) {
- OutputSocket *output = outputsockets[index];
- if (output->getbNodeSocket() == socket) {
- return output;
- }
- }
- return NULL;
+ m_link = link;
+}
+
+float NodeInput::getEditorValueFloat()
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get(&ptr, "default_value");
+}
+
+void NodeInput::getEditorValueColor(float *value)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get_array(&ptr, "default_value", value);
+}
+
+void NodeInput::getEditorValueVector(float *value)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get_array(&ptr, "default_value", value);
+}
+
+
+/********************
+ **** NodeOutput ****
+ ********************/
+
+NodeOutput::NodeOutput(Node *node, bNodeSocket *b_socket, DataType datatype) :
+ m_node(node),
+ m_editorSocket(b_socket),
+ m_datatype(datatype)
+{
+}
+
+float NodeOutput::getEditorValueFloat()
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get(&ptr, "default_value");
+}
+
+void NodeOutput::getEditorValueColor(float *value)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get_array(&ptr, "default_value", value);
+}
+
+void NodeOutput::getEditorValueVector(float *value)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
+ return RNA_float_get_array(&ptr, "default_value", value);
}
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index c14a1973da5..6046af24c55 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -23,32 +23,50 @@
#ifndef __COM_NODE_H__
#define __COM_NODE_H__
-#include "COM_NodeBase.h"
-#include "COM_InputSocket.h"
-#include "COM_OutputSocket.h"
-#include "COM_CompositorContext.h"
#include "DNA_node_types.h"
#include "BKE_text.h"
-#include "COM_ExecutionSystem.h"
#include <vector>
#include <string>
#include <algorithm>
-using namespace std;
+/* common node includes
+ * added here so node files don't have to include themselves
+ */
+#include "COM_CompositorContext.h"
+#include "COM_NodeConverter.h"
class Node;
class NodeOperation;
-class ExecutionSystem;
-
-typedef vector<Node *> NodeList;
-typedef NodeList::iterator NodeIterator;
-typedef pair<NodeIterator, NodeIterator> NodeRange;
+class NodeConverter;
/**
* My node documentation.
*/
-class Node : public NodeBase {
+class Node {
+public:
+ typedef std::vector<NodeInput *> Inputs;
+ typedef std::vector<NodeOutput *> Outputs;
+
private:
+ /**
+ * @brief stores the reference to the SDNA bNode struct
+ */
+ bNodeTree *m_editorNodeTree;
+
+ /**
+ * @brief stores the reference to the SDNA bNode struct
+ */
+ bNode *m_editorNode;
+
+ /**
+ * @brief the list of actual inputsockets @see NodeInput
+ */
+ Inputs m_inputsockets;
+
+ /**
+ * @brief the list of actual outputsockets @see NodeOutput
+ */
+ Outputs m_outputsockets;
/**
* @brief Is this node part of the active group
@@ -60,10 +78,81 @@ private:
*/
bNodeInstanceKey m_instanceKey;
+protected:
+ /**
+ * @brief get access to the vector of input sockets
+ */
+ const Inputs &getInputSockets() const { return this->m_inputsockets; }
+
+ /**
+ * @brief get access to the vector of input sockets
+ */
+ const Outputs &getOutputSockets() const { return this->m_outputsockets; }
+
public:
Node(bNode *editorNode, bool create_sockets = true);
+ virtual ~Node();
+
+ /**
+ * @brief get the reference to the SDNA bNode struct
+ */
+ bNode *getbNode() const {return m_editorNode;}
/**
+ * @brief get the reference to the SDNA bNodeTree struct
+ */
+ bNodeTree *getbNodeTree() const {return m_editorNodeTree;}
+
+ /**
+ * @brief set the reference to the bNode
+ * @note used in Node instances to receive the storage/settings and complex node for highlight during execution
+ * @param bNode
+ */
+ void setbNode(bNode *node) {this->m_editorNode = node;}
+
+ /**
+ * @brief set the reference to the bNodeTree
+ * @param bNodeTree
+ */
+ void setbNodeTree(bNodeTree *nodetree) {this->m_editorNodeTree = nodetree;}
+
+ /**
+ * @brief Return the number of input sockets of this node.
+ */
+ const unsigned int getNumberOfInputSockets() const { return this->m_inputsockets.size(); }
+
+ /**
+ * @brief Return the number of output sockets of this node.
+ */
+ const unsigned int getNumberOfOutputSockets() const { return this->m_outputsockets.size(); }
+
+ /**
+ * get the reference to a certain outputsocket
+ * @param index
+ * the index of the needed outputsocket
+ */
+ NodeOutput *getOutputSocket(const unsigned int index) const;
+
+ /**
+ * get the reference to the first outputsocket
+ * @param index
+ * the index of the needed outputsocket
+ */
+ inline NodeOutput *getOutputSocket() const { return getOutputSocket(0); }
+
+ /**
+ * get the reference to a certain inputsocket
+ * @param index
+ * the index of the needed inputsocket
+ */
+ NodeInput *getInputSocket(const unsigned int index) const;
+
+ /** Check if this is an input node
+ * An input node is a node that only has output sockets and no input sockets
+ */
+ bool isInputNode() const { return m_inputsockets.empty(); }
+
+ /**
* @brief Is this node in the active group (the group that is being edited)
* @param isInActiveGroup
*/
@@ -75,7 +164,7 @@ public:
* the active group will be the main tree (all nodes that are not part of a group will be active)
* @return bool [false:true]
*/
- inline bool isInActiveGroup() { return this->m_inActiveGroup; }
+ inline bool isInActiveGroup() const { return this->m_inActiveGroup; }
/**
* @brief convert node to operation
@@ -85,76 +174,99 @@ public:
* @param system the ExecutionSystem where the operations need to be added
* @param context reference to the CompositorContext
*/
- virtual void convertToOperations(ExecutionSystem *system, CompositorContext *context) = 0;
-
- /**
- * this method adds a SetValueOperation as input of the input socket.
- * This can only be used from the convertToOperation method. all other usages are not allowed
- */
- void addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex);
-
- /**
- * this method adds a SetColorOperation as input of the input socket.
- * This can only be used from the convertToOperation method. all other usages are not allowed
- */
- void addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex);
-
- /**
- * this method adds a SetVectorOperation as input of the input socket.
- * This can only be used from the convertToOperation method. all other usages are not allowed
- */
- void addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex);
+ virtual void convertToOperations(NodeConverter &converter, const CompositorContext &context) const = 0;
/**
* Create dummy warning operation, use when we can't get the source data.
*/
- NodeOperation *convertToOperations_invalid_index(ExecutionSystem *graph, int index);
+ NodeOperation *convertToOperations_invalid_index(NodeConverter *compiler, int index) const;
/**
* when a node has no valid data (missing image or a group nodes ID pointer is NULL)
* call this function from #convertToOperations, this way the node sockets are converted
* into valid outputs, without this the compositor system gets confused and crashes, see [#32490]
*/
- void convertToOperations_invalid(ExecutionSystem *graph, CompositorContext *context);
-
- /**
- * Creates a new link between an outputSocket and inputSocket and registrates the link to the graph
- * @return the new created link
- */
- SocketConnection *addLink(ExecutionSystem *graph, OutputSocket *outputSocket, InputSocket *inputsocket);
+ void convertToOperations_invalid(NodeConverter *compiler) const;
+ void setInstanceKey(bNodeInstanceKey instance_key) { m_instanceKey = instance_key; }
+ bNodeInstanceKey getInstanceKey() const { return m_instanceKey; }
+
+protected:
/**
- * is this node a group node.
- */
- virtual bool isGroupNode() const { return false; }
- /**
- * is this node a proxy node.
+ * @brief add an NodeInput to the collection of inputsockets
+ * @note may only be called in an constructor
+ * @param socket the NodeInput to add
*/
- virtual bool isProxyNode() const { return false; }
+ void addInputSocket(DataType datatype);
+ void addInputSocket(DataType datatype, bNodeSocket *socket);
/**
- * @brief find the InputSocket by bNodeSocket
- *
- * @param socket
+ * @brief add an NodeOutput to the collection of outputsockets
+ * @note may only be called in an constructor
+ * @param socket the NodeOutput to add
*/
- InputSocket *findInputSocketBybNodeSocket(bNodeSocket *socket);
+ void addOutputSocket(DataType datatype);
+ void addOutputSocket(DataType datatype, bNodeSocket *socket);
+
+ bNodeSocket *getEditorInputSocket(int editorNodeInputSocketIndex);
+ bNodeSocket *getEditorOutputSocket(int editorNodeOutputSocketIndex);
+};
+
+
+/**
+ * @brief NodeInput are sockets that can receive data/input
+ * @ingroup Model
+ */
+class NodeInput {
+private:
+ Node *m_node;
+ bNodeSocket *m_editorSocket;
+
+ DataType m_datatype;
/**
- * @brief find the OutputSocket by bNodeSocket
- *
- * @param socket
+ * @brief link connected to this NodeInput.
+ * An input socket can only have a single link
*/
- OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket);
+ NodeOutput *m_link;
- void setInstanceKey(bNodeInstanceKey instance_key) { m_instanceKey = instance_key; }
- bNodeInstanceKey getInstanceKey() const { return m_instanceKey; }
+public:
+ NodeInput(Node *node, bNodeSocket *b_socket, DataType datatype);
-protected:
- void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket);
- void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket);
+ Node *getNode() const { return this->m_node; }
+ DataType getDataType() const { return m_datatype; }
+ bNodeSocket *getbNodeSocket() const { return this->m_editorSocket; }
- bNodeSocket *getEditorInputSocket(int editorNodeInputSocketIndex);
- bNodeSocket *getEditorOutputSocket(int editorNodeOutputSocketIndex);
+ void setLink(NodeOutput *link);
+ bool isLinked() const { return m_link; }
+ NodeOutput *getLink() { return m_link; }
+
+ float getEditorValueFloat();
+ void getEditorValueColor(float *value);
+ void getEditorValueVector(float *value);
+};
+
+
+/**
+ * @brief NodeOutput are sockets that can send data/input
+ * @ingroup Model
+ */
+class NodeOutput {
private:
+ Node *m_node;
+ bNodeSocket *m_editorSocket;
+
+ DataType m_datatype;
+
+public:
+ NodeOutput(Node *node, bNodeSocket *b_socket, DataType datatype);
+
+ Node *getNode() const { return this->m_node; }
+ DataType getDataType() const { return m_datatype; }
+ bNodeSocket *getbNodeSocket() const { return this->m_editorSocket; }
+
+ float getEditorValueFloat();
+ void getEditorValueColor(float *value);
+ void getEditorValueVector(float *value);
};
#endif /* __COM_NODE_H__ */
diff --git a/source/blender/compositor/intern/COM_NodeBase.cpp b/source/blender/compositor/intern/COM_NodeBase.cpp
deleted file mode 100644
index 5c2ce37bdea..00000000000
--- a/source/blender/compositor/intern/COM_NodeBase.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include <string.h>
-
-#include "BKE_node.h"
-
-#include "COM_NodeBase.h"
-#include "COM_NodeOperation.h"
-#include "COM_SetValueOperation.h"
-#include "COM_SetColorOperation.h"
-#include "COM_SocketConnection.h"
-#include "COM_ExecutionSystem.h"
-
-NodeBase::NodeBase()
-{
- this->m_editorNode = NULL;
-}
-
-
-NodeBase::~NodeBase()
-{
- while (!this->m_outputsockets.empty()) {
- delete (this->m_outputsockets.back());
- this->m_outputsockets.pop_back();
- }
- while (!this->m_inputsockets.empty()) {
- delete (this->m_inputsockets.back());
- this->m_inputsockets.pop_back();
- }
-}
-
-void NodeBase::addInputSocket(DataType datatype)
-{
- this->addInputSocket(datatype, COM_SC_CENTER, NULL);
-}
-
-void NodeBase::addInputSocket(DataType datatype, InputSocketResizeMode resizeMode)
-{
- this->addInputSocket(datatype, resizeMode, NULL);
-}
-void NodeBase::addInputSocket(DataType datatype, InputSocketResizeMode resizeMode, bNodeSocket *bSocket)
-{
- InputSocket *socket = new InputSocket(datatype, resizeMode);
- socket->setEditorSocket(bSocket);
- socket->setNode(this);
- this->m_inputsockets.push_back(socket);
-}
-
-void NodeBase::addOutputSocket(DataType datatype)
-{
- this->addOutputSocket(datatype, NULL);
-
-}
-void NodeBase::addOutputSocket(DataType datatype, bNodeSocket *bSocket)
-{
- OutputSocket *socket = new OutputSocket(datatype);
- socket->setEditorSocket(bSocket);
- socket->setNode(this);
- this->m_outputsockets.push_back(socket);
-}
-const bool NodeBase::isInputNode() const
-{
- return this->m_inputsockets.size() == 0;
-}
-
-OutputSocket *NodeBase::getOutputSocket(unsigned int index)
-{
- BLI_assert(index < this->m_outputsockets.size());
- return this->m_outputsockets[index];
-}
-
-InputSocket *NodeBase::getInputSocket(unsigned int index)
-{
- BLI_assert(index < this->m_inputsockets.size());
- return this->m_inputsockets[index];
-}
diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h
deleted file mode 100644
index e2072575509..00000000000
--- a/source/blender/compositor/intern/COM_NodeBase.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef __COM_NODEBASE_H__
-#define __COM_NODEBASE_H__
-
-#include "COM_InputSocket.h"
-#include "COM_OutputSocket.h"
-#include "DNA_node_types.h"
-#include "BKE_text.h"
-#include <vector>
-#include <string>
-
-using namespace std;
-
-
-class NodeOperation;
-class ExecutionSystem;
-
-/**
- * @brief The NodeBase class is the super-class of all node related objects like @see Node @see NodeOperation
- * the reason for the existence of this class is to support graph-nodes when using ExecutionSystem
- * the NodeBase also contains the reference to InputSocket and OutputSocket.
- * @ingroup Model
- */
-class NodeBase {
-private:
- /**
- * @brief the list of actual inputsockets @see InputSocket
- */
- vector<InputSocket *> m_inputsockets;
-
- /**
- * @brief the list of actual outputsockets @see OutputSocket
- */
- vector<OutputSocket *> m_outputsockets;
-
- /**
- * @brief stores the reference to the SDNA bNode struct
- */
- bNode *m_editorNode;
-
- /**
- * @brief stores the reference to the SDNA bNode struct
- */
- bNodeTree *m_editorNodeTree;
-
-protected:
- /**
- * @brief get access to the vector of input sockets
- */
- inline vector<InputSocket *>& getInputSockets() { return this->m_inputsockets; }
-
- /**
- * @brief get access to the vector of input sockets
- */
- inline vector<OutputSocket *>& getOutputSockets() { return this->m_outputsockets; }
-
-
-protected:
- /**
- * @brief destructor
- * clean up memory related to this NodeBase.
- */
- virtual ~NodeBase();
-
-public:
- /**
- * @brief get the reference to the SDNA bNode struct
- */
- bNode *getbNode() const {return m_editorNode;}
-
- /**
- * @brief get the reference to the SDNA bNodeTree struct
- */
- bNodeTree *getbNodeTree() const {return m_editorNodeTree;}
-
- /**
- * @brief set the reference to the bNode
- * @note used in Node instances to receive the storage/settings and complex node for highlight during execution
- * @param bNode
- */
- void setbNode(bNode *node) {this->m_editorNode = node;}
-
- /**
- * @brief set the reference to the bNodeTree
- * @param bNodeTree
- */
- void setbNodeTree(bNodeTree *nodetree) {this->m_editorNodeTree = nodetree;}
-
- /**
- * @brief is this node an operation?
- * This is true when the instance is of the subclass NodeOperation.
- * @return [true:false]
- * @see NodeOperation
- */
- virtual const bool isOperation() const { return false; }
-
- /**
- * @brief check if this is an input node
- * An input node is a node that only has output sockets and no input sockets
- * @return [false..true]
- */
- const bool isInputNode() const;
-
- /**
- * @brief Return the number of input sockets of this node.
- */
- const unsigned int getNumberOfInputSockets() const { return this->m_inputsockets.size(); }
-
- /**
- * @brief Return the number of output sockets of this node.
- */
- const unsigned int getNumberOfOutputSockets() const { return this->m_outputsockets.size(); }
-
- /**
- * get the reference to a certain outputsocket
- * @param index
- * the index of the needed outputsocket
- */
- OutputSocket *getOutputSocket(const unsigned int index);
-
- /**
- * get the reference to the first outputsocket
- * @param index
- * the index of the needed outputsocket
- */
- inline OutputSocket *getOutputSocket() { return getOutputSocket(0); }
-
- /**
- * get the reference to a certain inputsocket
- * @param index
- * the index of the needed inputsocket
- */
- InputSocket *getInputSocket(const unsigned int index);
-
- virtual bool isStatic() const { return false; }
- void getStaticValues(float *result) const { }
-
-protected:
- NodeBase();
-
- /**
- * @brief add an InputSocket to the collection of inputsockets
- * @note may only be called in an constructor
- * @param socket the InputSocket to add
- */
- void addInputSocket(DataType datatype);
- void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode);
- void addInputSocket(DataType datatype, InputSocketResizeMode resizeMode, bNodeSocket *socket);
-
- /**
- * @brief add an OutputSocket to the collection of outputsockets
- * @note may only be called in an constructor
- * @param socket the OutputSocket to add
- */
- void addOutputSocket(DataType datatype);
- void addOutputSocket(DataType datatype, bNodeSocket *socket);
-
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeBase")
-#endif
-};
-
-#endif /* __COM_NODEBASE_H__ */
diff --git a/source/blender/compositor/intern/COM_NodeConverter.cpp b/source/blender/compositor/intern/COM_NodeConverter.cpp
new file mode 100644
index 00000000000..5965eade389
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeConverter.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+extern "C" {
+#include "BLI_utildefines.h"
+}
+
+#include "COM_Debug.h"
+
+#include "COM_NodeOperationBuilder.h"
+#include "COM_NodeOperation.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
+#include "COM_SocketProxyOperation.h"
+
+#include "COM_NodeConverter.h" /* own include */
+
+NodeConverter::NodeConverter(NodeOperationBuilder *builder) :
+ m_builder(builder)
+{
+}
+
+void NodeConverter::addOperation(NodeOperation *operation)
+{
+ m_builder->addOperation(operation);
+}
+
+void NodeConverter::mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket)
+{
+ m_builder->mapInputSocket(node_socket, operation_socket);
+}
+
+void NodeConverter::mapOutputSocket(NodeOutput *node_socket, NodeOperationOutput *operation_socket)
+{
+ m_builder->mapOutputSocket(node_socket, operation_socket);
+}
+
+void NodeConverter::addLink(NodeOperationOutput *from, NodeOperationInput *to)
+{
+ m_builder->addLink(from, to);
+}
+
+void NodeConverter::addPreview(NodeOperationOutput *output)
+{
+ m_builder->addPreview(output);
+}
+
+void NodeConverter::addNodeInputPreview(NodeInput *input)
+{
+ m_builder->addNodeInputPreview(input);
+}
+
+NodeOperation *NodeConverter::setInvalidOutput(NodeOutput *output)
+{
+ /* this is a really bad situation - bring on the pink! - so artists know this is bad */
+ const float warning_color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
+
+ SetColorOperation *operation = new SetColorOperation();
+ operation->setChannels(warning_color);
+
+ m_builder->addOperation(operation);
+ m_builder->mapOutputSocket(output, operation->getOutputSocket());
+
+ return operation;
+}
+
+NodeOperationOutput *NodeConverter::addInputProxy(NodeInput *input)
+{
+ SocketProxyOperation *proxy = new SocketProxyOperation(input->getDataType());
+ m_builder->addOperation(proxy);
+
+ m_builder->mapInputSocket(input, proxy->getInputSocket(0));
+
+ return proxy->getOutputSocket();
+}
+
+NodeOperationInput *NodeConverter::addOutputProxy(NodeOutput *output)
+{
+ SocketProxyOperation *proxy = new SocketProxyOperation(output->getDataType());
+ m_builder->addOperation(proxy);
+
+ m_builder->mapOutputSocket(output, proxy->getOutputSocket());
+
+ return proxy->getInputSocket(0);
+}
+
+void NodeConverter::addInputValue(NodeOperationInput *input, float value)
+{
+ SetValueOperation *operation = new SetValueOperation();
+ operation->setValue(value);
+
+ m_builder->addOperation(operation);
+ m_builder->addLink(operation->getOutputSocket(), input);
+}
+
+void NodeConverter::addInputColor(NodeOperationInput *input, const float value[4])
+{
+ SetColorOperation *operation = new SetColorOperation();
+ operation->setChannels(value);
+
+ m_builder->addOperation(operation);
+ m_builder->addLink(operation->getOutputSocket(), input);
+}
+
+void NodeConverter::addInputVector(NodeOperationInput *input, const float value[3])
+{
+ SetVectorOperation *operation = new SetVectorOperation();
+ operation->setVector(value);
+
+ m_builder->addOperation(operation);
+ m_builder->addLink(operation->getOutputSocket(), input);
+}
+
+void NodeConverter::addOutputValue(NodeOutput *output, float value)
+{
+ SetValueOperation *operation = new SetValueOperation();
+ operation->setValue(value);
+
+ m_builder->addOperation(operation);
+ m_builder->mapOutputSocket(output, operation->getOutputSocket());
+}
+
+void NodeConverter::addOutputColor(NodeOutput *output, const float value[4])
+{
+ SetColorOperation *operation = new SetColorOperation();
+ operation->setChannels(value);
+
+ m_builder->addOperation(operation);
+ m_builder->mapOutputSocket(output, operation->getOutputSocket());
+}
+
+void NodeConverter::addOutputVector(NodeOutput *output, const float value[3])
+{
+ SetVectorOperation *operation = new SetVectorOperation();
+ operation->setVector(value);
+
+ m_builder->addOperation(operation);
+ m_builder->mapOutputSocket(output, operation->getOutputSocket());
+}
diff --git a/source/blender/compositor/intern/COM_NodeConverter.h b/source/blender/compositor/intern/COM_NodeConverter.h
new file mode 100644
index 00000000000..cad8408a2bf
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeConverter.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#ifndef _COM_NodeCompiler_h
+#define _COM_NodeCompiler_h
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
+class NodeInput;
+class NodeOutput;
+
+class NodeOperation;
+class NodeOperationInput;
+class NodeOperationOutput;
+class NodeOperationBuilder;
+
+/** Interface type for converting a \a Node into \a NodeOperation.
+ * This is passed to \a Node::convertToOperation methods and allows them
+ * to register any number of operations, create links between them,
+ * and map original node sockets to their inputs or outputs.
+ */
+class NodeConverter {
+public:
+ NodeConverter(NodeOperationBuilder *builder);
+
+ /** Insert a new operation into the operations graph.
+ * The operation must be created by the node.
+ */
+ void addOperation(NodeOperation *operation);
+
+ /** Map input socket of the node to an operation socket.
+ * Links between nodes will then generate equivalent links between
+ * the mapped operation sockets.
+ *
+ * \note A \a Node input can be mapped to multiple \a NodeOperation inputs.
+ */
+ void mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket);
+ /** Map output socket of the node to an operation socket.
+ * Links between nodes will then generate equivalent links between
+ * the mapped operation sockets.
+ *
+ * \note A \a Node output can only be mapped to one \a NodeOperation output.
+ * Any existing operation output mapping will be replaced.
+ */
+ void mapOutputSocket(NodeOutput *node_socket, NodeOperationOutput *operation_socket);
+
+ /** Create a proxy operation for a node input.
+ * This operation will be removed later and replaced
+ * by direct links between the connected operations.
+ */
+ NodeOperationOutput *addInputProxy(NodeInput *input);
+ /** Create a proxy operation for a node output.
+ * This operation will be removed later and replaced
+ * by direct links between the connected operations.
+ */
+ NodeOperationInput *addOutputProxy(NodeOutput *output);
+
+ /** Define a constant input value. */
+ void addInputValue(NodeOperationInput *input, float value);
+ /** Define a constant input color. */
+ void addInputColor(NodeOperationInput *input, const float value[4]);
+ /** Define a constant input vector. */
+ void addInputVector(NodeOperationInput *input, const float value[3]);
+
+ /** Define a constant output value. */
+ void addOutputValue(NodeOutput *output, float value);
+ /** Define a constant output color. */
+ void addOutputColor(NodeOutput *output, const float value[4]);
+ /** Define a constant output vector. */
+ void addOutputVector(NodeOutput *output, const float value[3]);
+
+ /** Add an explicit link between two operations. */
+ void addLink(NodeOperationOutput *from, NodeOperationInput *to);
+
+ /** Add a preview operation for a operation output. */
+ void addPreview(NodeOperationOutput *output);
+ /** Add a preview operation for a node input. */
+ void addNodeInputPreview(NodeInput *input);
+
+ /** When a node has no valid data
+ * @note missing image / group pointer, or missing renderlayer from EXR
+ */
+ NodeOperation *setInvalidOutput(NodeOutput *output);
+
+private:
+ /** The internal builder for storing the results of the graph construction. */
+ NodeOperationBuilder *m_builder;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompiler")
+#endif
+};
+
+#endif /* _COM_NodeCompiler_h */
diff --git a/source/blender/compositor/intern/COM_NodeGraph.cpp b/source/blender/compositor/intern/COM_NodeGraph.cpp
new file mode 100644
index 00000000000..5c3de84f13c
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeGraph.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#include <cstring>
+
+extern "C" {
+#include "BLI_listbase.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_node_types.h"
+
+#include "BKE_node.h"
+}
+
+#include "COM_CompositorContext.h"
+#include "COM_Converter.h"
+#include "COM_Debug.h"
+#include "COM_Node.h"
+#include "COM_SocketProxyNode.h"
+
+#include "COM_NodeGraph.h" /* own include */
+
+/*******************
+ **** NodeGraph ****
+ *******************/
+
+NodeGraph::NodeGraph()
+{
+}
+
+NodeGraph::~NodeGraph()
+{
+ for (int index = 0; index < this->m_nodes.size(); index++) {
+ Node *node = this->m_nodes[index];
+ delete node;
+ }
+}
+
+void NodeGraph::from_bNodeTree(const CompositorContext &context, bNodeTree *tree)
+{
+ add_bNodeTree(context, 0, tree, NODE_INSTANCE_KEY_BASE);
+}
+
+bNodeSocket *NodeGraph::find_b_node_input(bNode *b_group_node, const char *identifier)
+{
+ for (bNodeSocket *b_sock = (bNodeSocket *)b_group_node->inputs.first; b_sock; b_sock = b_sock->next) {
+ if (STREQ(b_sock->identifier, identifier))
+ return b_sock;
+ }
+ return NULL;
+}
+
+bNodeSocket *NodeGraph::find_b_node_output(bNode *b_group_node, const char *identifier)
+{
+ for (bNodeSocket *b_sock = (bNodeSocket *)b_group_node->outputs.first; b_sock; b_sock = b_sock->next) {
+ if (STREQ(b_sock->identifier, identifier))
+ return b_sock;
+ }
+ return NULL;
+}
+
+void NodeGraph::add_node(Node *node, bNodeTree *b_ntree, bNodeInstanceKey key, bool is_active_group)
+{
+ node->setbNodeTree(b_ntree);
+ node->setInstanceKey(key);
+ node->setIsInActiveGroup(is_active_group);
+
+ m_nodes.push_back(node);
+
+ DebugInfo::node_added(node);
+}
+
+void NodeGraph::add_link(NodeOutput *fromSocket, NodeInput *toSocket)
+{
+ m_links.push_back(Link(fromSocket, toSocket));
+
+ /* register with the input */
+ toSocket->setLink(fromSocket);
+}
+
+void NodeGraph::add_bNodeTree(const CompositorContext &context, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key)
+{
+ const bNodeTree *basetree = context.getbNodeTree();
+
+ /* update viewers in the active edittree as well the base tree (for backdrop) */
+ bool is_active_group = ((parent_key.value == basetree->active_viewer_key.value) ||
+ (tree == basetree));
+
+ /* add all nodes of the tree to the node list */
+ for (bNode *node = (bNode *)tree->nodes.first; node; node = node->next) {
+ bNodeInstanceKey key = BKE_node_instance_key(parent_key, tree, node);
+ add_bNode(context, tree, node, key, is_active_group);
+ }
+
+ NodeRange node_range(m_nodes.begin() + nodes_start, m_nodes.end());
+ /* add all nodelinks of the tree to the link list */
+ for (bNodeLink *nodelink = (bNodeLink *)tree->links.first; nodelink; nodelink = nodelink->next) {
+ add_bNodeLink(node_range, nodelink);
+ }
+}
+
+void NodeGraph::add_bNode(const CompositorContext &context, bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group)
+{
+ /* replace muted nodes by proxies for internal links */
+ if (b_node->flag & NODE_MUTED) {
+ add_proxies_mute(b_ntree, b_node, key, is_active_group);
+ return;
+ }
+
+ /* replace slow nodes with proxies for fast execution */
+ if (context.isFastCalculation() && !Converter::is_fast_node(b_node)) {
+ add_proxies_skip(b_ntree, b_node, key, is_active_group);
+ return;
+ }
+
+ /* special node types */
+ if (b_node->type == NODE_GROUP) {
+ add_proxies_group(context, b_node, key);
+ }
+ else if (b_node->type == NODE_REROUTE) {
+ add_proxies_reroute(b_ntree, b_node, key, is_active_group);
+ }
+ else {
+ /* regular nodes, handled in Converter */
+ Node *node = Converter::convert(b_node);
+ if (node)
+ add_node(node, b_ntree, key, is_active_group);
+ }
+}
+
+NodeInput *NodeGraph::find_input(const NodeRange &node_range, bNodeSocket *b_socket)
+{
+ for (NodeGraph::NodeIterator it = node_range.first; it != node_range.second; ++it) {
+ Node *node = *it;
+ for (int index = 0; index < node->getNumberOfInputSockets(); index++) {
+ NodeInput *input = node->getInputSocket(index);
+ if (input->getbNodeSocket() == b_socket)
+ return input;
+ }
+ }
+ return NULL;
+}
+
+NodeOutput *NodeGraph::find_output(const NodeRange &node_range, bNodeSocket *b_socket)
+{
+ for (NodeGraph::NodeIterator it = node_range.first; it != node_range.second; ++it) {
+ Node *node = *it;
+ for (int index = 0; index < node->getNumberOfOutputSockets(); index++) {
+ NodeOutput *output = node->getOutputSocket(index);
+ if (output->getbNodeSocket() == b_socket)
+ return output;
+ }
+ }
+ return NULL;
+}
+
+void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink)
+{
+ /// @note: ignore invalid links
+ if (!(b_nodelink->flag & NODE_LINK_VALID))
+ return;
+
+ NodeInput *input = find_input(node_range, b_nodelink->tosock);
+ NodeOutput *output = find_output(node_range, b_nodelink->fromsock);
+ if (!input || !output)
+ return;
+ if (input->isLinked())
+ return;
+
+ add_link(output, input);
+}
+
+/* **** Special proxy node type conversions **** */
+
+void NodeGraph::add_proxies_mute(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group)
+{
+ for (bNodeLink *b_link = (bNodeLink *)b_node->internal_links.first; b_link; b_link = b_link->next) {
+ SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link->fromsock, b_link->tosock);
+ add_node(proxy, b_ntree, key, is_active_group);
+ }
+}
+
+void NodeGraph::add_proxies_skip(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group)
+{
+ for (bNodeSocket *output = (bNodeSocket *)b_node->outputs.first; output; output = output->next) {
+ bNodeSocket *input;
+
+ /* look for first input with matching datatype for each output */
+ for (input = (bNodeSocket *)b_node->inputs.first; input; input = input->next) {
+ if (input->type == output->type)
+ break;
+ }
+
+ if (input) {
+ SocketProxyNode *proxy = new SocketProxyNode(b_node, input, output);
+ add_node(proxy, b_ntree, key, is_active_group);
+ }
+ }
+}
+
+void NodeGraph::add_proxies_group_inputs(bNode *b_node, bNode *b_node_io)
+{
+ bNodeTree *b_group_tree = (bNodeTree *)b_node->id;
+ BLI_assert(b_group_tree); /* should have been checked in advance */
+
+ /* not important for proxies */
+ bNodeInstanceKey key = NODE_INSTANCE_KEY_BASE;
+ bool is_active_group = false;
+
+ for (bNodeSocket *b_sock_io = (bNodeSocket *)b_node_io->outputs.first; b_sock_io; b_sock_io = b_sock_io->next) {
+ bNodeSocket *b_sock_group = find_b_node_input(b_node, b_sock_io->identifier);
+ if (b_sock_group) {
+ SocketProxyNode *proxy = new SocketProxyNode(b_node_io, b_sock_group, b_sock_io);
+ add_node(proxy, b_group_tree, key, is_active_group);
+ }
+ }
+}
+
+void NodeGraph::add_proxies_group_outputs(bNode *b_node, bNode *b_node_io, bool use_buffer)
+{
+ bNodeTree *b_group_tree = (bNodeTree *)b_node->id;
+ BLI_assert(b_group_tree); /* should have been checked in advance */
+
+ /* not important for proxies */
+ bNodeInstanceKey key = NODE_INSTANCE_KEY_BASE;
+ bool is_active_group = false;
+
+ for (bNodeSocket *b_sock_io = (bNodeSocket *)b_node_io->inputs.first; b_sock_io; b_sock_io = b_sock_io->next) {
+ bNodeSocket *b_sock_group = find_b_node_output(b_node, b_sock_io->identifier);
+ if (b_sock_group) {
+ if (use_buffer) {
+ SocketBufferNode *buffer = new SocketBufferNode(b_node_io, b_sock_io, b_sock_group);
+ add_node(buffer, b_group_tree, key, is_active_group);
+ }
+ else {
+ SocketProxyNode *proxy = new SocketProxyNode(b_node_io, b_sock_io, b_sock_group);
+ add_node(proxy, b_group_tree, key, is_active_group);
+ }
+ }
+ }
+}
+
+void NodeGraph::add_proxies_group(const CompositorContext &context, bNode *b_node, bNodeInstanceKey key)
+{
+ bNodeTree *b_group_tree = (bNodeTree *)b_node->id;
+
+ /* missing node group datablock can happen with library linking */
+ if (!b_group_tree) {
+ /* this error case its handled in convertToOperations() so we don't get un-convertred sockets */
+ return;
+ }
+
+ /* use node list size before adding proxies, so they can be connected in add_bNodeTree */
+ int nodes_start = m_nodes.size();
+
+ /* create proxy nodes for group input/output nodes */
+ for (bNode *b_node_io = (bNode *)b_group_tree->nodes.first; b_node_io; b_node_io = b_node_io->next) {
+ if (b_node_io->type == NODE_GROUP_INPUT)
+ add_proxies_group_inputs(b_node, b_node_io);
+
+ if (b_node_io->type == NODE_GROUP_OUTPUT && (b_node_io->flag & NODE_DO_OUTPUT))
+ add_proxies_group_outputs(b_node, b_node_io, context.isGroupnodeBufferEnabled());
+ }
+
+ add_bNodeTree(context, nodes_start, b_group_tree, key);
+}
+
+void NodeGraph::add_proxies_reroute(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group)
+{
+ SocketProxyNode *proxy = new SocketProxyNode(b_node, (bNodeSocket *)b_node->inputs.first, (bNodeSocket *)b_node->outputs.first);
+ add_node(proxy, b_ntree, key, is_active_group);
+}
diff --git a/source/blender/compositor/intern/COM_NodeGraph.h b/source/blender/compositor/intern/COM_NodeGraph.h
new file mode 100644
index 00000000000..81799d76e1d
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeGraph.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#ifndef _COM_NodeGraph_h
+#define _COM_NodeGraph_h
+
+#include <map>
+#include <set>
+#include <vector>
+
+extern "C" {
+#include "DNA_node_types.h"
+}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
+class CompositorContext;
+class Node;
+class NodeInput;
+class NodeOutput;
+
+/** Internal representation of DNA node data.
+ * This structure is converted into operations by \a NodeCompiler.
+ */
+class NodeGraph {
+public:
+ class Link {
+ private:
+ NodeOutput *m_from;
+ NodeInput *m_to;
+
+ public:
+ Link(NodeOutput *from, NodeInput *to) :
+ m_from(from),
+ m_to(to)
+ {}
+
+ NodeOutput *getFromSocket() const { return m_from; }
+ NodeInput *getToSocket() const { return m_to; }
+ };
+
+ typedef std::vector<Node *> Nodes;
+ typedef Nodes::iterator NodeIterator;
+ typedef std::vector<Link> Links;
+
+private:
+ Nodes m_nodes;
+ Links m_links;
+
+public:
+ NodeGraph();
+ ~NodeGraph();
+
+ const Nodes &nodes() const { return m_nodes; }
+ const Links &links() const { return m_links; }
+
+ void from_bNodeTree(const CompositorContext &context, bNodeTree *tree);
+
+protected:
+ typedef std::pair<NodeIterator, NodeIterator> NodeRange;
+
+ static bNodeSocket *find_b_node_input(bNode *b_node, const char *identifier);
+ static bNodeSocket *find_b_node_output(bNode *b_node, const char *identifier);
+
+ void add_node(Node *node, bNodeTree *b_ntree, bNodeInstanceKey key, bool is_active_group);
+ void add_link(NodeOutput *fromSocket, NodeInput *toSocket);
+
+ void add_bNodeTree(const CompositorContext &context, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key);
+
+ void add_bNode(const CompositorContext &context, bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group);
+
+ NodeInput *find_input(const NodeRange &node_range, bNodeSocket *b_socket);
+ NodeOutput *find_output(const NodeRange &node_range, bNodeSocket *b_socket);
+ void add_bNodeLink(const NodeRange &node_range, bNodeLink *bNodeLink);
+
+ /* **** Special proxy node type conversions **** */
+ /* These nodes are not represented in the node graph themselves,
+ * but converted into a number of proxy links
+ */
+
+ void add_proxies_mute(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group);
+ void add_proxies_skip(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group);
+
+ void add_proxies_group_inputs(bNode *b_node, bNode *b_node_io);
+ void add_proxies_group_outputs(bNode *b_node, bNode *b_node_io, bool use_buffer);
+ void add_proxies_group(const CompositorContext &context, bNode *b_node, bNodeInstanceKey key);
+
+ void add_proxies_reroute(bNodeTree *b_ntree, bNode *b_node, bNodeInstanceKey key, bool is_active_group);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeGraph")
+#endif
+};
+
+#endif /* _COM_NodeGraph_h */
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp
index d33b8085022..f780c609dce 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperation.cpp
@@ -23,12 +23,16 @@
#include <typeinfo>
#include <stdio.h>
-#include "COM_NodeOperation.h"
-#include "COM_InputSocket.h"
-#include "COM_SocketConnection.h"
#include "COM_defines.h"
+#include "COM_ExecutionSystem.h"
-NodeOperation::NodeOperation() : NodeBase()
+#include "COM_NodeOperation.h" /* own include */
+
+/*******************
+ **** NodeOperation ****
+ *******************/
+
+NodeOperation::NodeOperation()
{
this->m_resolutionInputSocketIndex = 0;
this->m_complex = false;
@@ -39,28 +43,63 @@ NodeOperation::NodeOperation() : NodeBase()
this->m_btree = NULL;
}
+NodeOperation::~NodeOperation()
+{
+ while (!this->m_outputs.empty()) {
+ delete (this->m_outputs.back());
+ this->m_outputs.pop_back();
+ }
+ while (!this->m_inputs.empty()) {
+ delete (this->m_inputs.back());
+ this->m_inputs.pop_back();
+ }
+}
+
+NodeOperationOutput *NodeOperation::getOutputSocket(unsigned int index) const
+{
+ BLI_assert(index < m_outputs.size());
+ return m_outputs[index];
+}
+
+NodeOperationInput *NodeOperation::getInputSocket(unsigned int index) const
+{
+ BLI_assert(index < m_inputs.size());
+ return m_inputs[index];
+}
+
+void NodeOperation::addInputSocket(DataType datatype, InputResizeMode resize_mode)
+{
+ NodeOperationInput *socket = new NodeOperationInput(this, datatype, resize_mode);
+ m_inputs.push_back(socket);
+}
+
+void NodeOperation::addOutputSocket(DataType datatype)
+{
+ NodeOperationOutput *socket = new NodeOperationOutput(this, datatype);
+ m_outputs.push_back(socket);
+}
+
void NodeOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
unsigned int temp[2];
unsigned int temp2[2];
- vector<InputSocket *> &inputsockets = this->getInputSockets();
- for (unsigned int index = 0; index < inputsockets.size(); index++) {
- InputSocket *inputSocket = inputsockets[index];
- if (inputSocket->isConnected()) {
+ for (unsigned int index = 0; index < m_inputs.size(); index++) {
+ NodeOperationInput *input = m_inputs[index];
+ if (input->isConnected()) {
if (index == this->m_resolutionInputSocketIndex) {
- inputSocket->determineResolution(resolution, preferredResolution);
+ input->determineResolution(resolution, preferredResolution);
temp2[0] = resolution[0];
temp2[1] = resolution[1];
break;
}
}
}
- for (unsigned int index = 0; index < inputsockets.size(); index++) {
- InputSocket *inputSocket = inputsockets[index];
- if (inputSocket->isConnected()) {
+ for (unsigned int index = 0; index < m_inputs.size(); index++) {
+ NodeOperationInput *input = m_inputs[index];
+ if (input->isConnected()) {
if (index != this->m_resolutionInputSocketIndex) {
- inputSocket->determineResolution(temp, temp2);
+ input->determineResolution(temp, temp2);
}
}
}
@@ -102,25 +141,29 @@ SocketReader *NodeOperation::getInputSocketReader(unsigned int inputSocketIndex)
{
return this->getInputSocket(inputSocketIndex)->getReader();
}
+
NodeOperation *NodeOperation::getInputOperation(unsigned int inputSocketIndex)
{
- return this->getInputSocket(inputSocketIndex)->getOperation();
+ NodeOperationInput *input = getInputSocket(inputSocketIndex);
+ if (input && input->isConnected())
+ return &input->getLink()->getOperation();
+ else
+ return NULL;
}
-void NodeOperation::getConnectedInputSockets(vector<InputSocket *> *sockets)
+void NodeOperation::getConnectedInputSockets(Inputs *sockets)
{
- vector<InputSocket *> &inputsockets = this->getInputSockets();
- for (vector<InputSocket *>::iterator iterator = inputsockets.begin(); iterator != inputsockets.end(); iterator++) {
- InputSocket *socket = *iterator;
- if (socket->isConnected()) {
- sockets->push_back(socket);
+ for (Inputs::const_iterator it = m_inputs.begin(); it != m_inputs.end(); ++it) {
+ NodeOperationInput *input = *it;
+ if (input->isConnected()) {
+ sockets->push_back(input);
}
}
}
bool NodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- if (this->isInputNode()) {
+ if (isInputOperation()) {
BLI_rcti_init(output, input->xmin, input->xmax, input->ymin, input->ymax);
return false;
}
@@ -148,3 +191,56 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOper
return !first;
}
}
+
+
+/*****************
+ **** OpInput ****
+ *****************/
+
+NodeOperationInput::NodeOperationInput(NodeOperation *op, DataType datatype, InputResizeMode resizeMode) :
+ m_operation(op),
+ m_datatype(datatype),
+ m_resizeMode(resizeMode),
+ m_link(NULL)
+{
+}
+
+SocketReader *NodeOperationInput::getReader()
+{
+ if (isConnected()) {
+ return &m_link->getOperation();
+ }
+ else {
+ return NULL;
+ }
+}
+
+void NodeOperationInput::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+{
+ if (m_link)
+ m_link->determineResolution(resolution, preferredResolution);
+}
+
+
+/******************
+ **** OpOutput ****
+ ******************/
+
+NodeOperationOutput::NodeOperationOutput(NodeOperation *op, DataType datatype) :
+ m_operation(op),
+ m_datatype(datatype)
+{
+}
+
+void NodeOperationOutput::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+{
+ NodeOperation &operation = getOperation();
+ if (operation.isResolutionSet()) {
+ resolution[0] = operation.getWidth();
+ resolution[1] = operation.getHeight();
+ }
+ else {
+ operation.determineResolution(resolution, preferredResolution);
+ operation.setResolution(resolution);
+ }
+}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index 160e493073e..3f636dff63c 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -20,32 +20,72 @@
* Monique Dewanchand
*/
-#ifndef _COM_NodeOperation_h
-#define _COM_NodeOperation_h
-class OpenCLDevice;
-#include "COM_Node.h"
+#ifndef _COM_Operation_h
+#define _COM_Operation_h
+
+#include <list>
#include <string>
#include <sstream>
+
+extern "C" {
+#include "BLI_math_color.h"
+#include "BLI_math_vector.h"
+#include "BLI_threads.h"
+}
+
+#include "COM_Node.h"
#include "COM_MemoryBuffer.h"
#include "COM_MemoryProxy.h"
#include "COM_SocketReader.h"
+
#include "OCL_opencl.h"
-#include "list"
-#include "BLI_threads.h"
-#include "BLI_math_color.h"
-#include "BLI_math_vector.h"
+using std::list;
+using std::min;
+using std::max;
+class OpenCLDevice;
class ReadBufferOperation;
+class WriteBufferOperation;
+
+class NodeOperationInput;
+class NodeOperationOutput;
+
+/**
+ * @brief Resize modes of inputsockets
+ * How are the input and working resolutions matched
+ * @ingroup Model
+ */
+typedef enum InputResizeMode {
+ /** @brief Center the input image to the center of the working area of the node, no resizing occurs */
+ COM_SC_CENTER = NS_CR_CENTER,
+ /** @brief The bottom left of the input image is the bottom left of the working area of the node, no resizing occurs */
+ COM_SC_NO_RESIZE = NS_CR_NONE,
+ /** @brief Fit the width of the input image to the width of the working area of the node */
+ COM_SC_FIT_WIDTH = NS_CR_FIT_WIDTH,
+ /** @brief Fit the height of the input image to the height of the working area of the node */
+ COM_SC_FIT_HEIGHT = NS_CR_FIT_HEIGHT,
+ /** @brief Fit the width or the height of the input image to the width or height of the working area of the node, image will be larger than the working area */
+ COM_SC_FIT = NS_CR_FIT,
+ /** @brief Fit the width and the height of the input image to the width and height of the working area of the node, image will be equally larger than the working area */
+ COM_SC_STRETCH = NS_CR_STRETCH
+} InputResizeMode;
/**
- * @brief NodeOperation are contains calculation logic
+ * @brief NodeOperation contains calculation logic
*
* Subclasses needs to implement the execution method (defined in SocketReader) to implement logic.
* @ingroup Model
*/
-class NodeOperation : public NodeBase, public SocketReader {
+class NodeOperation : public SocketReader {
+public:
+ typedef std::vector<NodeOperationInput*> Inputs;
+ typedef std::vector<NodeOperationOutput*> Outputs;
+
private:
+ Inputs m_inputs;
+ Outputs m_outputs;
+
/**
* @brief the index of the input socket that will be used to determine the resolution
*/
@@ -85,15 +125,21 @@ private:
* @brief set to truth when resolution for this operation is set
*/
bool m_isResolutionSet;
+
public:
- /**
- * @brief is this node an operation?
- * This is true when the instance is of the subclass NodeOperation.
- * @return [true:false]
- * @see NodeBase
+ virtual ~NodeOperation();
+
+ unsigned int getNumberOfInputSockets() const { return m_inputs.size(); }
+ unsigned int getNumberOfOutputSockets() const { return m_outputs.size(); }
+ NodeOperationOutput *getOutputSocket(unsigned int index) const;
+ NodeOperationOutput *getOutputSocket() const { return getOutputSocket(0); }
+ NodeOperationInput *getInputSocket(unsigned int index) const;
+
+ /** Check if this is an input operation
+ * An input operation is an operation that only has output sockets and no input sockets
*/
- const bool isOperation() const { return true; }
-
+ bool isInputOperation() const { return m_inputs.empty(); }
+
/**
* @brief determine the resolution of this node
* @note this method will not set the resolution, this is the responsibility of the caller
@@ -117,15 +163,6 @@ public:
*/
virtual bool isOutputOperation(bool rendering) const { return false; }
- /**
- * isBufferOperation returns if this is an operation that work directly on buffers.
- *
- * there are only 2 implementation where this is true:
- * @see ReadBufferOperation
- * @see WriteBufferOperation
- * for all other operations this will result in false.
- */
- virtual int isBufferOperation() { return false; }
virtual int isSingleThreaded() { return false; }
void setbNodeTree(const bNodeTree *tree) { this->m_btree = tree; }
@@ -190,7 +227,7 @@ public:
}
- void getConnectedInputSockets(vector<InputSocket *> *sockets);
+ void getConnectedInputSockets(Inputs *sockets);
/**
* @brief is this operation complex
@@ -244,13 +281,14 @@ public:
* @see WorkScheduler.schedule
* @see ExecutionGroup.addOperation
*/
- bool isOpenCL() { return this->m_openCL; }
+ bool isOpenCL() const { return this->m_openCL; }
- virtual bool isViewerOperation() { return false; }
- virtual bool isPreviewOperation() { return false; }
- virtual bool isFileOutputOperation() { return false; }
+ virtual bool isViewerOperation() const { return false; }
+ virtual bool isPreviewOperation() const { return false; }
+ virtual bool isFileOutputOperation() const { return false; }
+ virtual bool isProxyOperation() const { return false; }
- inline bool isBreaked() {
+ inline bool isBreaked() const {
return this->m_btree->test_break(this->m_btree->tbh);
}
@@ -261,6 +299,9 @@ public:
protected:
NodeOperation();
+ void addInputSocket(DataType datatype, InputResizeMode resize_mode = COM_SC_CENTER);
+ void addOutputSocket(DataType datatype);
+
void setWidth(unsigned int width) { this->m_width = width; this->m_isResolutionSet = true; }
void setHeight(unsigned int height) { this->m_height = height; this->m_isResolutionSet = true; }
SocketReader *getInputSocketReader(unsigned int inputSocketindex);
@@ -271,7 +312,6 @@ protected:
void lockMutex();
void unlockMutex();
-
/**
* @brief set whether this operation is complex
*
@@ -285,6 +325,75 @@ protected:
*/
void setOpenCL(bool openCL) { this->m_openCL = openCL; }
+ /* allow the DebugInfo class to look at internals */
+ friend class DebugInfo;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
+#endif
+};
+
+
+class NodeOperationInput {
+private:
+ NodeOperation *m_operation;
+
+ /** Datatype of this socket. Is used for automatically data transformation.
+ * @section data-conversion
+ */
+ DataType m_datatype;
+
+ /** Resize mode of this socket */
+ InputResizeMode m_resizeMode;
+
+ /** Connected output */
+ NodeOperationOutput *m_link;
+
+public:
+ NodeOperationInput(NodeOperation *op, DataType datatype, InputResizeMode resizeMode = COM_SC_CENTER);
+
+ NodeOperation &getOperation() const { return *m_operation; }
+ DataType getDataType() const { return m_datatype; }
+
+ void setLink(NodeOperationOutput *link) { m_link = link; }
+ NodeOperationOutput *getLink() const { return m_link; }
+ bool isConnected() const { return m_link; }
+
+ void setResizeMode(InputResizeMode resizeMode) { this->m_resizeMode = resizeMode; }
+ InputResizeMode getResizeMode() const { return this->m_resizeMode; }
+
+ SocketReader *getReader();
+
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
+#endif
+};
+
+
+class NodeOperationOutput {
+private:
+ NodeOperation *m_operation;
+
+ /** Datatype of this socket. Is used for automatically data transformation.
+ * @section data-conversion
+ */
+ DataType m_datatype;
+
+public:
+ NodeOperationOutput(NodeOperation *op, DataType datatype);
+
+ NodeOperation &getOperation() const { return *m_operation; }
+ DataType getDataType() const { return m_datatype; }
+
+ /**
+ * @brief determine the resolution of this data going through this socket
+ * @param resolution the result of this operation
+ * @param preferredResolution the preferable resolution as no resolution could be determined
+ */
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
#endif
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
new file mode 100644
index 00000000000..a90bac847c0
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
@@ -0,0 +1,666 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+extern "C" {
+#include "BLI_utildefines.h"
+}
+
+#include "COM_NodeConverter.h"
+#include "COM_Converter.h"
+#include "COM_Debug.h"
+#include "COM_ExecutionSystem.h"
+#include "COM_Node.h"
+#include "COM_SocketProxyNode.h"
+
+#include "COM_NodeOperation.h"
+#include "COM_PreviewOperation.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
+#include "COM_SocketProxyOperation.h"
+#include "COM_ReadBufferOperation.h"
+#include "COM_WriteBufferOperation.h"
+
+#include "COM_NodeOperationBuilder.h" /* own include */
+
+NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree) :
+ m_context(context),
+ m_current_node(NULL)
+{
+ m_graph.from_bNodeTree(*context, b_nodetree);
+}
+
+NodeOperationBuilder::~NodeOperationBuilder()
+{
+}
+
+void NodeOperationBuilder::convertToOperations(ExecutionSystem *system)
+{
+ /* interface handle for nodes */
+ NodeConverter converter(this);
+
+ for (int index = 0; index < m_graph.nodes().size(); index++) {
+ Node *node = (Node *)m_graph.nodes()[index];
+
+ m_current_node = node;
+
+ DebugInfo::node_to_operations(node);
+ node->convertToOperations(converter, *m_context);
+ }
+
+ m_current_node = NULL;
+
+ /* The input map constructed by nodes maps operation inputs to node inputs.
+ * Inverting yields a map of node inputs to all connected operation inputs,
+ * so multiple operations can use the same node input.
+ */
+ OpInputInverseMap inverse_input_map;
+ for (InputSocketMap::const_iterator it = m_input_map.begin(); it != m_input_map.end(); ++it)
+ inverse_input_map[it->second].push_back(it->first);
+
+ for (NodeGraph::Links::const_iterator it = m_graph.links().begin(); it != m_graph.links().end(); ++it) {
+ const NodeGraph::Link &link = *it;
+ NodeOutput *from = link.getFromSocket();
+ NodeInput *to = link.getToSocket();
+
+ NodeOperationOutput *op_from = find_operation_output(m_output_map, from);
+ const OpInputs &op_to_list = find_operation_inputs(inverse_input_map, to);
+ if (!op_from || op_to_list.empty()) {
+ /* XXX allow this? error/debug message? */
+ //BLI_assert(false);
+ /* XXX note: this can happen with certain nodes (e.g. OutputFile)
+ * which only generate operations in certain circumstances (rendering)
+ * just let this pass silently for now ...
+ */
+ continue;
+ }
+
+ for (OpInputs::const_iterator it = op_to_list.begin(); it != op_to_list.end(); ++it) {
+ NodeOperationInput *op_to = *it;
+ addLink(op_from, op_to);
+ }
+ }
+
+ add_datatype_conversions();
+
+ add_operation_input_constants();
+
+ resolve_proxies();
+
+ determineResolutions();
+
+ /* surround complex ops with read/write buffer */
+ add_complex_operation_buffers();
+
+ /* links not available from here on */
+ /* XXX make m_links a local variable to avoid confusion! */
+ m_links.clear();
+
+ prune_operations();
+
+ /* ensure topological (link-based) order of nodes */
+ /*sort_operations();*/ /* not needed yet */
+
+ /* create execution groups */
+ group_operations();
+
+ /* transfer resulting operations to the system */
+ system->set_operations(m_operations, m_groups);
+}
+
+void NodeOperationBuilder::addOperation(NodeOperation *operation)
+{
+ m_operations.push_back(operation);
+}
+
+void NodeOperationBuilder::mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket)
+{
+ BLI_assert(m_current_node);
+ BLI_assert(node_socket->getNode() == m_current_node);
+
+ /* note: this maps operation sockets to node sockets.
+ * for resolving links the map will be inverted first in convertToOperations,
+ * to get a list of links for each node input socket.
+ */
+ m_input_map[operation_socket] = node_socket;
+}
+
+void NodeOperationBuilder::mapOutputSocket(NodeOutput *node_socket, NodeOperationOutput *operation_socket)
+{
+ BLI_assert(m_current_node);
+ BLI_assert(node_socket->getNode() == m_current_node);
+
+ m_output_map[node_socket] = operation_socket;
+}
+
+void NodeOperationBuilder::addLink(NodeOperationOutput *from, NodeOperationInput *to)
+{
+ if (to->isConnected())
+ return;
+
+ m_links.push_back(Link(from, to));
+
+ /* register with the input */
+ to->setLink(from);
+}
+
+void NodeOperationBuilder::removeInputLink(NodeOperationInput *to)
+{
+ for (Links::iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ Link &link = *it;
+ if (link.to() == to) {
+ /* unregister with the input */
+ to->setLink(NULL);
+
+ m_links.erase(it);
+ return;
+ }
+ }
+}
+
+NodeInput *NodeOperationBuilder::find_node_input(const InputSocketMap &map, NodeOperationInput *op_input)
+{
+ InputSocketMap::const_iterator it = map.find(op_input);
+ return (it != map.end() ? it->second : NULL);
+}
+
+const NodeOperationBuilder::OpInputs &NodeOperationBuilder::find_operation_inputs(const OpInputInverseMap &map, NodeInput *node_input)
+{
+ static const OpInputs empty_list;
+ OpInputInverseMap::const_iterator it = map.find(node_input);
+ return (it != map.end() ? it->second : empty_list);
+}
+
+NodeOperationOutput *NodeOperationBuilder::find_operation_output(const OutputSocketMap &map, NodeOutput *node_output)
+{
+ OutputSocketMap::const_iterator it = map.find(node_output);
+ return (it != map.end() ? it->second : NULL);
+}
+
+PreviewOperation *NodeOperationBuilder::make_preview_operation() const
+{
+ BLI_assert(m_current_node);
+
+ if (!(m_current_node->getbNode()->flag & NODE_PREVIEW))
+ return NULL;
+ /* previews only in the active group */
+ if (!m_current_node->isInActiveGroup())
+ return NULL;
+ /* do not calculate previews of hidden nodes */
+ if (m_current_node->getbNode()->flag & NODE_HIDDEN)
+ return NULL;
+
+ bNodeInstanceHash *previews = m_context->getPreviewHash();
+ if (previews) {
+ PreviewOperation *operation = new PreviewOperation(m_context->getViewSettings(), m_context->getDisplaySettings());
+ operation->setbNodeTree(m_context->getbNodeTree());
+ operation->verifyPreview(previews, m_current_node->getInstanceKey());
+ return operation;
+ }
+
+ return NULL;
+}
+
+void NodeOperationBuilder::addPreview(NodeOperationOutput *output)
+{
+ PreviewOperation *operation = make_preview_operation();
+ if (operation) {
+ addOperation(operation);
+
+ addLink(output, operation->getInputSocket(0));
+ }
+}
+
+void NodeOperationBuilder::addNodeInputPreview(NodeInput *input)
+{
+ PreviewOperation *operation = make_preview_operation();
+ if (operation) {
+ addOperation(operation);
+
+ mapInputSocket(input, operation->getInputSocket(0));
+ }
+}
+
+/****************************
+ **** Optimization Steps ****
+ ****************************/
+
+void NodeOperationBuilder::add_datatype_conversions()
+{
+ Links convert_links;
+ for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ const Link &link = *it;
+ if (link.from()->getDataType() != link.to()->getDataType())
+ convert_links.push_back(link);
+ }
+ for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) {
+ const Link &link = *it;
+ NodeOperation *converter = Converter::convertDataType(link.from(), link.to());
+ if (converter) {
+ addOperation(converter);
+
+ removeInputLink(link.to());
+ addLink(link.from(), converter->getInputSocket(0));
+ addLink(converter->getOutputSocket(0), link.to());
+ }
+ }
+}
+
+void NodeOperationBuilder::add_operation_input_constants()
+{
+ /* Note: unconnected inputs cached first to avoid modifying
+ * m_operations while iterating over it
+ */
+ typedef std::vector<NodeOperationInput*> Inputs;
+ Inputs pending_inputs;
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+ for (int k = 0; k < op->getNumberOfInputSockets(); ++k) {
+ NodeOperationInput *input = op->getInputSocket(k);
+ if (!input->isConnected())
+ pending_inputs.push_back(input);
+ }
+ }
+ for (Inputs::const_iterator it = pending_inputs.begin(); it != pending_inputs.end(); ++it) {
+ NodeOperationInput *input = *it;
+ add_input_constant_value(input, find_node_input(m_input_map, input));
+ }
+}
+
+void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, NodeInput *node_input)
+{
+ switch (input->getDataType()) {
+ case COM_DT_VALUE: {
+ float value;
+ if (node_input && node_input->getbNodeSocket())
+ value = node_input->getEditorValueFloat();
+ else
+ value = 0.0f;
+
+ SetValueOperation *op = new SetValueOperation();
+ op->setValue(value);
+ addOperation(op);
+ addLink(op->getOutputSocket(), input);
+ break;
+ }
+ case COM_DT_COLOR: {
+ float value[4];
+ if (node_input && node_input->getbNodeSocket())
+ node_input->getEditorValueColor(value);
+ else
+ zero_v4(value);
+
+ SetColorOperation *op = new SetColorOperation();
+ op->setChannels(value);
+ addOperation(op);
+ addLink(op->getOutputSocket(), input);
+ break;
+ }
+ case COM_DT_VECTOR: {
+ float value[3];
+ if (node_input && node_input->getbNodeSocket())
+ node_input->getEditorValueVector(value);
+ else
+ zero_v3(value);
+
+ SetVectorOperation *op = new SetVectorOperation();
+ op->setVector(value);
+ addOperation(op);
+ addLink(op->getOutputSocket(), input);
+ break;
+ }
+ }
+}
+
+void NodeOperationBuilder::resolve_proxies()
+{
+ Links proxy_links;
+ for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ const Link &link = *it;
+ /* don't replace links from proxy to proxy, since we may need them for replacing others! */
+ if (link.from()->getOperation().isProxyOperation() &&
+ !link.to()->getOperation().isProxyOperation())
+ {
+ proxy_links.push_back(link);
+ }
+ }
+
+ for (Links::const_iterator it = proxy_links.begin(); it != proxy_links.end(); ++it) {
+ const Link &link = *it;
+
+ NodeOperationInput *to = link.to();
+ NodeOperationOutput *from = link.from();
+ do {
+ /* walk upstream bypassing the proxy operation */
+ from = from->getOperation().getInputSocket(0)->getLink();
+ } while (from && from->getOperation().isProxyOperation());
+
+ removeInputLink(to);
+ /* we may not have a final proxy input link,
+ * in that case it just gets dropped
+ */
+ if (from)
+ addLink(from, to);
+ }
+}
+
+void NodeOperationBuilder::determineResolutions()
+{
+ /* determine all resolutions of the operations (Width/Height) */
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+
+ if (op->isOutputOperation(m_context->isRendering()) && !op->isPreviewOperation()) {
+ unsigned int resolution[2] = {0, 0};
+ unsigned int preferredResolution[2] = {0, 0};
+ op->determineResolution(resolution, preferredResolution);
+ op->setResolution(resolution);
+ }
+ }
+
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+
+ if (op->isOutputOperation(m_context->isRendering()) && op->isPreviewOperation()) {
+ unsigned int resolution[2] = {0, 0};
+ unsigned int preferredResolution[2] = {0, 0};
+ op->determineResolution(resolution, preferredResolution);
+ op->setResolution(resolution);
+ }
+ }
+
+ /* add convert resolution operations when needed */
+ {
+ Links convert_links;
+ for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ const Link &link = *it;
+
+ if (link.to()->getResizeMode() != COM_SC_NO_RESIZE) {
+ NodeOperation &from_op = link.from()->getOperation();
+ NodeOperation &to_op = link.to()->getOperation();
+ if (from_op.getWidth() != to_op.getWidth() || from_op.getHeight() != to_op.getHeight())
+ convert_links.push_back(link);
+ }
+ }
+ for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) {
+ const Link &link = *it;
+ Converter::convertResolution(*this, link.from(), link.to());
+ }
+ }
+}
+
+NodeOperationBuilder::OpInputs NodeOperationBuilder::cache_output_links(NodeOperationOutput *output) const
+{
+ OpInputs inputs;
+ for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ const Link &link = *it;
+ if (link.from() == output)
+ inputs.push_back(link.to());
+ }
+ return inputs;
+}
+
+WriteBufferOperation *NodeOperationBuilder::find_attached_write_buffer_operation(NodeOperationOutput *output) const
+{
+ for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) {
+ const Link &link = *it;
+ if (link.from() == output) {
+ NodeOperation &op = link.to()->getOperation();
+ if (op.isWriteBufferOperation())
+ return (WriteBufferOperation *)(&op);
+ }
+ }
+ return NULL;
+}
+
+void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOperationInput *input)
+{
+ if (!input->isConnected())
+ return;
+
+ NodeOperationOutput *output = input->getLink();
+ if (output->getOperation().isReadBufferOperation()) {
+ /* input is already buffered, no need to add another */
+ return;
+ }
+
+ /* this link will be replaced below */
+ removeInputLink(input);
+
+ /* check of other end already has write operation, otherwise add a new one */
+ WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
+ if (!writeoperation) {
+ writeoperation = new WriteBufferOperation();
+ writeoperation->setbNodeTree(m_context->getbNodeTree());
+ addOperation(writeoperation);
+
+ addLink(output, writeoperation->getInputSocket(0));
+
+ writeoperation->readResolutionFromInputSocket();
+ }
+
+ /* add readbuffer op for the input */
+ ReadBufferOperation *readoperation = new ReadBufferOperation();
+ readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
+ this->addOperation(readoperation);
+
+ addLink(readoperation->getOutputSocket(), input);
+
+ readoperation->readResolutionFromWriteBuffer();
+}
+
+void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOperationOutput *output)
+{
+ /* cache connected sockets, so we can safely remove links first before replacing them */
+ OpInputs targets = cache_output_links(output);
+ if (targets.empty())
+ return;
+
+ WriteBufferOperation *writeOperation = NULL;
+ for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ NodeOperationInput *target = *it;
+
+ /* try to find existing write buffer operation */
+ if (target->getOperation().isWriteBufferOperation()) {
+ BLI_assert(writeOperation == NULL); /* there should only be one write op connected */
+ writeOperation = (WriteBufferOperation *)(&target->getOperation());
+ }
+ else {
+ /* remove all links to other nodes */
+ removeInputLink(target);
+ }
+ }
+
+ /* if no write buffer operation exists yet, create a new one */
+ if (!writeOperation) {
+ writeOperation = new WriteBufferOperation();
+ writeOperation->setbNodeTree(m_context->getbNodeTree());
+ addOperation(writeOperation);
+
+ addLink(output, writeOperation->getInputSocket(0));
+ }
+
+ writeOperation->readResolutionFromInputSocket();
+
+ /* add readbuffer op for every former connected input */
+ for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ NodeOperationInput *target = *it;
+ if (&target->getOperation() == writeOperation)
+ continue; /* skip existing write op links */
+
+ ReadBufferOperation *readoperation = new ReadBufferOperation();
+ readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
+ addOperation(readoperation);
+
+ addLink(readoperation->getOutputSocket(), target);
+
+ readoperation->readResolutionFromWriteBuffer();
+ }
+}
+
+void NodeOperationBuilder::add_complex_operation_buffers()
+{
+ /* note: complex ops and get cached here first, since adding operations
+ * will invalidate iterators over the main m_operations
+ */
+ Operations complex_ops;
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it)
+ if ((*it)->isComplex())
+ complex_ops.push_back(*it);
+
+ for (Operations::const_iterator it = complex_ops.begin(); it != complex_ops.end(); ++it) {
+ NodeOperation *op = *it;
+
+ DebugInfo::operation_read_write_buffer(op);
+
+ for (int index = 0; index < op->getNumberOfInputSockets(); index++)
+ add_input_buffers(op, op->getInputSocket(index));
+
+ for (int index = 0; index < op->getNumberOfOutputSockets(); index++)
+ add_output_buffers(op, op->getOutputSocket(index));
+ }
+}
+
+typedef std::set<NodeOperation*> Tags;
+
+static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op)
+{
+ if (reachable.find(op) != reachable.end())
+ return;
+ reachable.insert(op);
+
+ for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
+ NodeOperationInput *input = op->getInputSocket(i);
+ if (input->isConnected())
+ find_reachable_operations_recursive(reachable, &input->getLink()->getOperation());
+ }
+
+ /* associated write-buffer operations are executed as well */
+ if (op->isReadBufferOperation()) {
+ ReadBufferOperation *read_op = (ReadBufferOperation *)op;
+ MemoryProxy *memproxy = read_op->getMemoryProxy();
+ find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation());
+ }
+}
+
+void NodeOperationBuilder::prune_operations()
+{
+ Tags reachable;
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+
+ /* output operations are primary executed operations */
+ if (op->isOutputOperation(m_context->isRendering()))
+ find_reachable_operations_recursive(reachable, op);
+ }
+
+ /* delete unreachable operations */
+ Operations reachable_ops;
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+
+ if (reachable.find(op) != reachable.end())
+ reachable_ops.push_back(op);
+ else
+ delete op;
+ }
+ /* finally replace the operations list with the pruned list */
+ m_operations = reachable_ops;
+}
+
+/* topological (depth-first) sorting of operations */
+static void sort_operations_recursive(NodeOperationBuilder::Operations &sorted, Tags &visited, NodeOperation *op)
+{
+ if (visited.find(op) != visited.end())
+ return;
+ visited.insert(op);
+
+ for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
+ NodeOperationInput *input = op->getInputSocket(i);
+ if (input->isConnected())
+ sort_operations_recursive(sorted, visited, &input->getLink()->getOperation());
+ }
+
+ sorted.push_back(op);
+}
+
+void NodeOperationBuilder::sort_operations()
+{
+ Operations sorted;
+ sorted.reserve(m_operations.size());
+ Tags visited;
+
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it)
+ sort_operations_recursive(sorted, visited, *it);
+
+ m_operations = sorted;
+}
+
+static void add_group_operations_recursive(Tags &visited, NodeOperation *op, ExecutionGroup *group)
+{
+ if (visited.find(op) != visited.end())
+ return;
+ visited.insert(op);
+
+ if (!group->addOperation(op))
+ return;
+
+ /* add all eligible input ops to the group */
+ for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
+ NodeOperationInput *input = op->getInputSocket(i);
+ if (input->isConnected())
+ add_group_operations_recursive(visited, &input->getLink()->getOperation(), group);
+ }
+}
+
+ExecutionGroup *NodeOperationBuilder::make_group(NodeOperation *op)
+{
+ ExecutionGroup *group = new ExecutionGroup();
+ m_groups.push_back(group);
+
+ Tags visited;
+ add_group_operations_recursive(visited, op, group);
+
+ return group;
+}
+
+void NodeOperationBuilder::group_operations()
+{
+ for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
+ NodeOperation *op = *it;
+
+ if (op->isOutputOperation(m_context->isRendering())) {
+ ExecutionGroup *group = make_group(op);
+ group->setOutputExecutionGroup(true);
+ }
+
+ /* add new groups for associated memory proxies where needed */
+ if (op->isReadBufferOperation()) {
+ ReadBufferOperation *read_op = (ReadBufferOperation *)op;
+ MemoryProxy *memproxy = read_op->getMemoryProxy();
+
+ if (memproxy->getExecutor() == NULL) {
+ ExecutionGroup *group = make_group(memproxy->getWriteBufferOperation());
+ memproxy->setExecutor(group);
+ }
+ }
+ }
+}
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
new file mode 100644
index 00000000000..ab890282bab
--- /dev/null
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2013, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#ifndef _COM_NodeCompilerImpl_h
+#define _COM_NodeCompilerImpl_h
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "COM_NodeGraph.h"
+
+using std::vector;
+
+class CompositorContext;
+
+class Node;
+class NodeInput;
+class NodeOutput;
+
+class ExecutionSystem;
+class ExecutionGroup;
+class NodeOperation;
+class NodeOperationInput;
+class NodeOperationOutput;
+
+class PreviewOperation;
+class WriteBufferOperation;
+
+class NodeOperationBuilder {
+public:
+ class Link {
+ private:
+ NodeOperationOutput *m_from;
+ NodeOperationInput *m_to;
+
+ public:
+ Link(NodeOperationOutput *from, NodeOperationInput *to) :
+ m_from(from),
+ m_to(to)
+ {}
+
+ NodeOperationOutput *from() const { return m_from; }
+ NodeOperationInput *to() const { return m_to; }
+ };
+
+ typedef std::vector<NodeOperation *> Operations;
+ typedef std::vector<Link> Links;
+ typedef std::vector<ExecutionGroup *> Groups;
+
+ typedef std::map<NodeOperationInput *, NodeInput *> InputSocketMap;
+ typedef std::map<NodeOutput *, NodeOperationOutput *> OutputSocketMap;
+
+ typedef std::vector<NodeOperationInput *> OpInputs;
+ typedef std::map<NodeInput *, OpInputs> OpInputInverseMap;
+
+private:
+ const CompositorContext *m_context;
+ NodeGraph m_graph;
+
+ Operations m_operations;
+ Links m_links;
+ Groups m_groups;
+
+ /** Maps operation inputs to node inputs */
+ InputSocketMap m_input_map;
+ /** Maps node outputs to operation outputs */
+ OutputSocketMap m_output_map;
+
+ Node *m_current_node;
+
+public:
+ NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree);
+ ~NodeOperationBuilder();
+
+ const CompositorContext &context() const { return *m_context; }
+
+ void convertToOperations(ExecutionSystem *system);
+
+ void addOperation(NodeOperation *operation);
+
+ /** Map input socket of the current node to an operation socket */
+ void mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket);
+ /** Map output socket of the current node to an operation socket */
+ void mapOutputSocket(NodeOutput *node_socket, NodeOperationOutput *operation_socket);
+
+ void addLink(NodeOperationOutput *from, NodeOperationInput *to);
+ void removeInputLink(NodeOperationInput *to);
+
+ /** Add a preview operation for a operation output */
+ void addPreview(NodeOperationOutput *output);
+ /** Add a preview operation for a node input */
+ void addNodeInputPreview(NodeInput *input);
+
+protected:
+ static NodeInput *find_node_input(const InputSocketMap &map, NodeOperationInput *op_input);
+ static const OpInputs &find_operation_inputs(const OpInputInverseMap &map, NodeInput *node_input);
+ static NodeOperationOutput *find_operation_output(const OutputSocketMap &map, NodeOutput *node_output);
+
+ /** Add datatype conversion where needed */
+ void add_datatype_conversions();
+
+ /** Construct a constant value operation for every unconnected input */
+ void add_operation_input_constants();
+ void add_input_constant_value(NodeOperationInput *input, NodeInput *node_input);
+
+ /** Replace proxy operations with direct links */
+ void resolve_proxies();
+
+ /** Calculate resolution for each operation */
+ void determineResolutions();
+
+ /** Helper function to store connected inputs for replacement */
+ OpInputs cache_output_links(NodeOperationOutput *output) const;
+ /** Find a connected write buffer operation to an OpOutput */
+ WriteBufferOperation *find_attached_write_buffer_operation(NodeOperationOutput *output) const;
+ /** Add read/write buffer operations around complex operations */
+ void add_complex_operation_buffers();
+ void add_input_buffers(NodeOperation *operation, NodeOperationInput *input);
+ void add_output_buffers(NodeOperation *operation, NodeOperationOutput *output);
+
+ /** Remove unreachable operations */
+ void prune_operations();
+
+ /** Sort operations by link dependencies */
+ void sort_operations();
+
+ /** Create execution groups */
+ void group_operations();
+ ExecutionGroup *make_group(NodeOperation *op);
+
+private:
+ PreviewOperation *make_preview_operation() const;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompilerImpl")
+#endif
+};
+
+#endif /* _COM_NodeCompilerImpl_h */
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
index bb60a629812..2cfc10cff29 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
@@ -58,7 +58,7 @@ void OpenCLDevice::execute(WorkPackage *work)
MemoryBuffer **inputBuffers = executionGroup->getInputBuffersOpenCL(chunkNumber);
MemoryBuffer *outputBuffer = executionGroup->allocateOutputBuffer(chunkNumber, &rect);
- executionGroup->getOutputNodeOperation()->executeOpenCLRegion(this, &rect,
+ executionGroup->getOutputOperation()->executeOpenCLRegion(this, &rect,
chunkNumber, inputBuffers, outputBuffer);
delete outputBuffer;
@@ -85,7 +85,7 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
CL_FLOAT
};
- cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, result->getWidth(),
+ cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(),
result->getHeight(), 0, result->getBuffer(), &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h
index 2021cacabcc..50cc6f25f70 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.h
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.h
@@ -30,6 +30,8 @@ class OpenCLDevice;
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
+using std::list;
+
/**
* @brief device representing an GPU OpenCL device.
* an instance of this class represents a single cl_device
diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp
deleted file mode 100644
index 50e9b75b072..00000000000
--- a/source/blender/compositor/intern/COM_OutputSocket.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_Socket.h"
-#include "COM_Node.h"
-#include "COM_SocketConnection.h"
-#include "COM_NodeOperation.h"
-
-OutputSocket::OutputSocket(DataType datatype) : Socket(datatype)
-{
- /* pass */
-}
-
-int OutputSocket::isOutputSocket() const { return true; }
-const int OutputSocket::isConnected() const { return this->m_connections.size() != 0; }
-
-void OutputSocket::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
-{
- NodeBase *node = this->getNode();
- if (node->isOperation()) {
- NodeOperation *operation = (NodeOperation *)node;
- if (operation->isResolutionSet()) {
- resolution[0] = operation->getWidth();
- resolution[1] = operation->getHeight();
- }
- else {
- operation->determineResolution(resolution, preferredResolution);
- operation->setResolution(resolution);
- }
- }
-}
-
-void OutputSocket::addConnection(SocketConnection *connection)
-{
- this->m_connections.push_back(connection);
-}
-
-void OutputSocket::removeConnection(SocketConnection *connection)
-{
- for (vector<SocketConnection *>::iterator it = m_connections.begin(); it != m_connections.end(); ++it) {
- if (*it == connection) {
- m_connections.erase(it);
- return;
- }
- }
-}
-
-void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single)
-{
- if (isConnected()) {
- if (single) {
- SocketConnection *connection = this->m_connections[0];
- connection->setFromSocket(relinkToSocket);
- relinkToSocket->addConnection(connection);
- this->m_connections.erase(this->m_connections.begin());
- }
- else {
- unsigned int index;
- for (index = 0; index < this->m_connections.size(); index++) {
- SocketConnection *connection = this->m_connections[index];
- connection->setFromSocket(relinkToSocket);
- relinkToSocket->addConnection(connection);
- }
- this->m_connections.clear();
- }
- }
-}
-void OutputSocket::removeFirstConnection()
-{
- SocketConnection *connection = this->m_connections[0];
- InputSocket *inputSocket = connection->getToSocket();
- if (inputSocket != NULL) {
- inputSocket->setConnection(NULL);
- }
- this->m_connections.erase(this->m_connections.begin());
-}
-
-void OutputSocket::clearConnections()
-{
- while (this->isConnected()) {
- removeFirstConnection();
- }
-}
-
-WriteBufferOperation *OutputSocket::findAttachedWriteBufferOperation() const
-{
- unsigned int index;
- for (index = 0; index < this->m_connections.size(); index++) {
- SocketConnection *connection = this->m_connections[index];
- NodeBase *node = connection->getToNode();
- if (node->isOperation()) {
- NodeOperation *operation = (NodeOperation *)node;
- if (operation->isWriteBufferOperation()) {
- return (WriteBufferOperation *)operation;
- }
- }
- }
- return NULL;
-}
-
diff --git a/source/blender/compositor/intern/COM_OutputSocket.h b/source/blender/compositor/intern/COM_OutputSocket.h
deleted file mode 100644
index 709005a6de0..00000000000
--- a/source/blender/compositor/intern/COM_OutputSocket.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_OutputSocket_h
-#define _COM_OutputSocket_h
-
-#include <vector>
-#include "COM_Socket.h"
-#include "COM_ChannelInfo.h"
-
-using namespace std;
-class SocketConnection;
-class Node;
-class InputSocket;
-class WriteBufferOperation;
-
-//#define COM_ST_INPUT 0
-//#define COM_ST_OUTPUT 1
-
-/**
- * @brief OutputSocket are sockets that can send data/input
- * @ingroup Model
- */
-class OutputSocket : public Socket {
-private:
- vector<SocketConnection *> m_connections;
-
- void removeFirstConnection();
-public:
- OutputSocket(DataType datatype);
- OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex);
- OutputSocket(OutputSocket *from);
- void addConnection(SocketConnection *connection);
- void removeConnection(SocketConnection *connection);
- SocketConnection *getConnection(unsigned int index) { return this->m_connections[index]; }
- const int isConnected() const;
- int isOutputSocket() const;
-
- /**
- * @brief determine the resolution of this socket
- * @param resolution the result of this operation
- * @param preferredResolution the preferable resolution as no resolution could be determined
- */
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
-
- /**
- * @brief determine the actual data type and channel info.
- */
- void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }
- void relinkConnections(OutputSocket *relinkToSocket, bool single);
- const int getNumberOfConnections() { return this->m_connections.size(); }
-
- void clearConnections();
-
- /**
- * @brief find a connected write buffer operation to this OutputSocket
- * @return WriteBufferOperation or NULL
- */
- WriteBufferOperation *findAttachedWriteBufferOperation() const;
- ChannelInfo *getChannelInfo(const int channelnumber);
-
-private:
-
-};
-#endif
diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp
index 7d1184cb356..c300a85bfa3 100644
--- a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp
@@ -20,25 +20,25 @@
* Monique Dewanchand
*/
-#include "COM_SingleThreadedNodeOperation.h"
+#include "COM_SingleThreadedOperation.h"
-SingleThreadedNodeOperation::SingleThreadedNodeOperation() : NodeOperation()
+SingleThreadedOperation::SingleThreadedOperation() : NodeOperation()
{
this->m_cachedInstance = NULL;
setComplex(true);
}
-void SingleThreadedNodeOperation::initExecution()
+void SingleThreadedOperation::initExecution()
{
initMutex();
}
-void SingleThreadedNodeOperation::executePixel(float output[4], int x, int y, void *data)
+void SingleThreadedOperation::executePixel(float output[4], int x, int y, void *data)
{
this->m_cachedInstance->readNoCheck(output, x, y);
}
-void SingleThreadedNodeOperation::deinitExecution()
+void SingleThreadedOperation::deinitExecution()
{
deinitMutex();
if (this->m_cachedInstance) {
@@ -46,7 +46,7 @@ void SingleThreadedNodeOperation::deinitExecution()
this->m_cachedInstance = NULL;
}
}
-void *SingleThreadedNodeOperation::initializeTileData(rcti *rect)
+void *SingleThreadedOperation::initializeTileData(rcti *rect)
{
if (this->m_cachedInstance) return this->m_cachedInstance;
diff --git a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h b/source/blender/compositor/intern/COM_SingleThreadedOperation.h
index 45325be18a9..a6b2f777cb5 100644
--- a/source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h
+++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.h
@@ -20,11 +20,11 @@
* Monique Dewanchand
*/
-#ifndef _COM_SingleThreadedNodeOperation_h
-#define _COM_SingleThreadedNodeOperation_h
+#ifndef _COM_SingleThreadedOperation_h
+#define _COM_SingleThreadedOperation_h
#include "COM_NodeOperation.h"
-class SingleThreadedNodeOperation : public NodeOperation {
+class SingleThreadedOperation : public NodeOperation {
private:
MemoryBuffer *m_cachedInstance;
@@ -34,7 +34,7 @@ protected:
}
public:
- SingleThreadedNodeOperation();
+ SingleThreadedOperation();
/**
* the inner loop of this program
diff --git a/source/blender/compositor/intern/COM_Socket.cpp b/source/blender/compositor/intern/COM_Socket.cpp
deleted file mode 100644
index 3465fa6f56d..00000000000
--- a/source/blender/compositor/intern/COM_Socket.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_Socket.h"
-#include "COM_Node.h"
-#include "COM_SocketConnection.h"
-
-extern "C" {
-#include "RNA_access.h"
-}
-
-Socket::Socket(DataType datatype)
-{
- this->m_datatype = datatype;
- this->m_editorSocket = NULL;
- this->m_node = NULL;
-}
-
-DataType Socket::getDataType() const
-{
- return this->m_datatype;
-}
-
-int Socket::isInputSocket() const { return false; }
-int Socket::isOutputSocket() const { return false; }
-const int Socket::isConnected() const { return false; }
-void Socket::setNode(NodeBase *node) { this->m_node = node; }
-NodeBase *Socket::getNode() const { return this->m_node; }
-
-float Socket::getEditorValueFloat()
-{
- PointerRNA ptr;
- RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
- return RNA_float_get(&ptr, "default_value");
-}
-
-void Socket::getEditorValueColor(float *value)
-{
- PointerRNA ptr;
- RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
- return RNA_float_get_array(&ptr, "default_value", value);
-}
-
-void Socket::getEditorValueVector(float *value)
-{
- PointerRNA ptr;
- RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr);
- return RNA_float_get_array(&ptr, "default_value", value);
-}
diff --git a/source/blender/compositor/intern/COM_Socket.h b/source/blender/compositor/intern/COM_Socket.h
deleted file mode 100644
index 6532864a4d9..00000000000
--- a/source/blender/compositor/intern/COM_Socket.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_Socket_h
-#define _COM_Socket_h
-
-#include <vector>
-#include "BKE_text.h"
-#include <string>
-#include "DNA_node_types.h"
-#include "COM_defines.h"
-
-#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
-#endif
-
-using namespace std;
-class SocketConnection;
-class NodeBase;
-struct PointerRNA;
-
-/**
- * @brief Base class for InputSocket and OutputSocket.
- *
- * A socket are the points on an node where the user can make a connection between.
- * Sockets are always part of a node or an operation.
- *
- * @see InputSocket
- * @see OutputSocket
- * @see SocketConnection - a connection between an InputSocket and an OutputSocket
- * @ingroup Model
- */
-class Socket {
-private:
- /**
- * Reference to the node where this Socket belongs to
- */
- NodeBase *m_node;
-
- /**
- * the datatype of this socket. Is used for automatically data transformation.
- * @section data-conversion
- */
- DataType m_datatype;
-
- bNodeSocket *m_editorSocket;
-
-protected:
- /**
- * @brief Declaration of the virtual destructor
- * @note resolve warning gcc 4.7
- */
- virtual ~Socket() {}
-
-public:
- Socket(DataType datatype);
-
- DataType getDataType() const;
- void setNode(NodeBase *node);
- NodeBase *getNode() const;
-
-
- const virtual int isConnected() const;
- int isInputSocket() const;
- int isOutputSocket() const;
- virtual void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) {}
-
- void setEditorSocket(bNodeSocket *editorSocket) { this->m_editorSocket = editorSocket; }
- bNodeSocket *getbNodeSocket() const { return this->m_editorSocket; }
-
- float getEditorValueFloat();
- void getEditorValueColor(float *value);
- void getEditorValueVector(float *value);
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("COM:Socket")
-#endif
-};
-
-
-#endif
diff --git a/source/blender/compositor/intern/COM_SocketConnection.cpp b/source/blender/compositor/intern/COM_SocketConnection.cpp
deleted file mode 100644
index 1f2cba72dc0..00000000000
--- a/source/blender/compositor/intern/COM_SocketConnection.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_SocketConnection.h"
-#include "COM_NodeOperation.h"
-
-SocketConnection::SocketConnection()
-{
- this->m_fromSocket = NULL;
- this->m_toSocket = NULL;
- this->setIgnoreResizeCheck(false);
-}
-
-void SocketConnection::setFromSocket(OutputSocket *fromsocket)
-{
- if (fromsocket == NULL) {
- throw "ERROR";
- }
- this->m_fromSocket = fromsocket;
-}
-
-OutputSocket *SocketConnection::getFromSocket() const { return this->m_fromSocket; }
-void SocketConnection::setToSocket(InputSocket *tosocket)
-{
- if (tosocket == NULL) {
- throw "ERROR";
- }
- this->m_toSocket = tosocket;
-}
-
-InputSocket *SocketConnection::getToSocket() const { return this->m_toSocket; }
-
-NodeBase *SocketConnection::getFromNode() const
-{
- if (this->getFromSocket() == NULL) {
- return NULL;
- }
- else {
- return this->getFromSocket()->getNode();
- }
-}
-NodeBase *SocketConnection::getToNode() const
-{
- if (this->getToSocket() == NULL) {
- return NULL;
- }
- else {
- return this->getToSocket()->getNode();
- }
-}
-bool SocketConnection::isValid() const
-{
- if ((this->getToSocket() != NULL && this->getFromSocket() != NULL)) {
- if (this->getFromNode()->isOperation() && this->getToNode()->isOperation()) {
- return true;
- }
- }
- return false;
-}
-
-bool SocketConnection::needsResolutionConversion() const
-{
- if (this->m_ignoreResizeCheck) { return false; }
- NodeOperation *fromOperation = (NodeOperation *)this->getFromNode();
- NodeOperation *toOperation = (NodeOperation *)this->getToNode();
- if (this->m_toSocket->getResizeMode() == COM_SC_NO_RESIZE) { return false; }
- const unsigned int fromWidth = fromOperation->getWidth();
- const unsigned int fromHeight = fromOperation->getHeight();
- const unsigned int toWidth = toOperation->getWidth();
- const unsigned int toHeight = toOperation->getHeight();
-
- if (fromWidth == toWidth && fromHeight == toHeight) {
- return false;
- }
- return true;
-}
diff --git a/source/blender/compositor/intern/COM_SocketConnection.h b/source/blender/compositor/intern/COM_SocketConnection.h
deleted file mode 100644
index 9777bd45be2..00000000000
--- a/source/blender/compositor/intern/COM_SocketConnection.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_SocketConnection_h
-#define _COM_SocketConnection_h
-
-#include "DNA_node_types.h"
-#include "COM_Node.h"
-#include "COM_Socket.h"
-#include "COM_ChannelInfo.h"
-
-/**
- * @brief An SocketConnection is an connection between an InputSocket and an OutputSocket.
- *
- * <pre>
- * +----------+ To InputSocket +----------+
- * | From | SocketConnection \| To Node |
- * | Node *====================* |
- * | |\ | |
- * | | From OutputSocket +----------+
- * +----------+
- * </pre>
- * @ingroup Model
- * @see InputSocket
- * @see OutputSocket
- */
-class SocketConnection {
-private:
- /**
- * @brief Startpoint of the connection
- */
- OutputSocket *m_fromSocket;
-
- /**
- * @brief Endpoint of the connection
- */
- InputSocket *m_toSocket;
-
- /**
- * @brief has the resize already been done for this connection
- */
- bool m_ignoreResizeCheck;
-public:
- SocketConnection();
-
- /**
- * @brief set the startpoint of the connection
- * @param fromsocket
- */
- void setFromSocket(OutputSocket *fromsocket);
-
- /**
- * @brief get the startpoint of the connection
- * @return from OutputSocket
- */
- OutputSocket *getFromSocket() const;
-
- /**
- * @brief set the endpoint of the connection
- * @param tosocket
- */
- void setToSocket(InputSocket *tosocket);
-
- /**
- * @brief get the endpoint of the connection
- * @return to InputSocket
- */
- InputSocket *getToSocket() const;
-
- /**
- * @brief check if this connection is valid
- */
- bool isValid() const;
-
- /**
- * @brief return the Node where this connection is connected from
- */
- NodeBase *getFromNode() const;
-
- /**
- * @brief return the Node where this connection is connected to
- */
- NodeBase *getToNode() const;
-
- /**
- * @brief set, whether the resize has already been done for this SocketConnection
- */
- void setIgnoreResizeCheck(bool check) { this->m_ignoreResizeCheck = check; }
-
- /**
- * @brief has the resize already been done for this SocketConnection
- */
- bool isIgnoreResizeCheck() const { return this->m_ignoreResizeCheck; }
-
- /**
- * @brief does this SocketConnection need resolution conversion
- * @note PreviewOperation's will be ignored
- * @note Already converted SocketConnection's will be ignored
- * @return needs conversion [true:false]
- */
- bool needsResolutionConversion() const;
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("COM:SocketConnection")
-#endif
-};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 76a3d92eb6c..d60f9cb7f10 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -81,12 +81,17 @@ static int g_highlightIndex;
static void **g_highlightedNodes;
static void **g_highlightedNodesRead;
+/* XXX highlighting disabled for now
+ * This requires pointers back to DNA data (bNodeTree/bNode) in operations, which is bad!
+ * Instead IF we want to keep this feature it should use a weak reference such as bNodeInstanceKey
+ */
+#if 0
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#define HIGHLIGHT(wp) \
{ \
ExecutionGroup *group = wp->getExecutionGroup(); \
if (group->isComplex()) { \
- NodeOperation *operation = group->getOutputNodeOperation(); \
+ NodeOperation *operation = group->getOutputOperation(); \
if (operation->isWriteBufferOperation()) { \
WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation; \
NodeOperation *complexOperation = writeOperation->getInput(); \
@@ -105,6 +110,9 @@ static void **g_highlightedNodesRead;
} \
}
#endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */
+#else
+#define HIGHLIGHT(wp) {}
+#endif
void COM_startReadHighlights()
{
@@ -327,7 +335,7 @@ void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads)
error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
if (error == -1001) { } /* GPU not supported */
else if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
- if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
+ if (G.f & G_DEBUG) printf("%u number of platforms\n", numberOfPlatforms);
cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
unsigned int indexPlatform;
diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp
index 1c1dcf1c37d..99655c67a3f 100644
--- a/source/blender/compositor/intern/COM_compositor.cpp
+++ b/source/blender/compositor/intern/COM_compositor.cpp
@@ -36,7 +36,7 @@ extern "C" {
#include "COM_MovieDistortionOperation.h"
static ThreadMutex s_compositorMutex;
-static bool is_compositorMutex_init = FALSE;
+static bool is_compositorMutex_init = false;
static void intern_freeCompositorCaches()
{
@@ -50,9 +50,9 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
/* initialize mutex, TODO this mutex init is actually not thread safe and
* should be done somewhere as part of blender startup, all the other
* initializations can be done lazily */
- if (is_compositorMutex_init == FALSE) {
+ if (is_compositorMutex_init == false) {
BLI_mutex_init(&s_compositorMutex);
- is_compositorMutex_init = TRUE;
+ is_compositorMutex_init = true;
}
BLI_mutex_lock(&s_compositorMutex);
@@ -69,7 +69,7 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
* Reserved preview size is determined by render output for now.
*/
float aspect = rd->xsch > 0 ? (float)rd->ysch / (float)rd->xsch : 1.0f;
- BKE_node_preview_init_tree(editingtree, COM_PREVIEW_SIZE, (int)(COM_PREVIEW_SIZE * aspect), FALSE);
+ BKE_node_preview_init_tree(editingtree, COM_PREVIEW_SIZE, (int)(COM_PREVIEW_SIZE * aspect), false);
/* initialize workscheduler, will check if already done. TODO deinitialize somewhere */
bool use_opencl = (editingtree->flag & NTREE_COM_OPENCL) != 0;
@@ -116,7 +116,7 @@ void COM_deinitialize()
BLI_mutex_lock(&s_compositorMutex);
intern_freeCompositorCaches();
WorkScheduler::deinitialize();
- is_compositorMutex_init = FALSE;
+ is_compositorMutex_init = false;
BLI_mutex_unlock(&s_compositorMutex);
BLI_mutex_end(&s_compositorMutex);
}
diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp
index bf081cae097..0306d636c8b 100644
--- a/source/blender/compositor/nodes/COM_AlphaOverNode.cpp
+++ b/source/blender/compositor/nodes/COM_AlphaOverNode.cpp
@@ -27,16 +27,13 @@
#include "COM_AlphaOverMixedOperation.h"
#include "COM_AlphaOverPremultiplyOperation.h"
-#include "COM_ExecutionSystem.h"
#include "COM_SetValueOperation.h"
#include "DNA_material_types.h" // the ramp types
-void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void AlphaOverNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *valueSocket = this->getInputSocket(0);
- InputSocket *color1Socket = this->getInputSocket(1);
- InputSocket *color2Socket = this->getInputSocket(2);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *color1Socket = this->getInputSocket(1);
+ NodeInput *color2Socket = this->getInputSocket(2);
bNode *editorNode = this->getbNode();
MixBaseOperation *convertProg;
@@ -55,18 +52,19 @@ void AlphaOverNode::convertToOperations(ExecutionSystem *graph, CompositorContex
}
convertProg->setUseValueAlphaMultiply(false);
- if (color1Socket->isConnected()) {
+ if (color1Socket->isLinked()) {
convertProg->setResolutionInputSocketIndex(1);
}
- else if (color2Socket->isConnected()) {
+ else if (color2Socket->isLinked()) {
convertProg->setResolutionInputSocketIndex(2);
}
else {
convertProg->setResolutionInputSocketIndex(0);
}
- valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
- color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
- color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph);
- outputSocket->relinkConnections(convertProg->getOutputSocket(0));
- graph->addOperation(convertProg);
+
+ converter.addOperation(convertProg);
+ converter.mapInputSocket(getInputSocket(0), convertProg->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), convertProg->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), convertProg->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(0), convertProg->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h
index e25e9e11975..45febd62683 100644
--- a/source/blender/compositor/nodes/COM_AlphaOverNode.h
+++ b/source/blender/compositor/nodes/COM_AlphaOverNode.h
@@ -32,7 +32,7 @@
class AlphaOverNode : public Node {
public:
AlphaOverNode(bNode *editorNode) : Node(editorNode) {}
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp
index 399d2adf0be..90ff4ecf235 100644
--- a/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.cpp
@@ -30,15 +30,15 @@ BilateralBlurNode::BilateralBlurNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BilateralBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BilateralBlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeBilateralBlurData *data = (NodeBilateralBlurData *)this->getbNode()->storage;
BilateralBlurOperation *operation = new BilateralBlurOperation();
- operation->setbNode(this->getbNode());
- operation->setQuality(context->getQuality());
+ operation->setQuality(context.getQuality());
operation->setData(data);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h
index e6f9242fa32..dfd7361dabe 100644
--- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h
+++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.h
@@ -32,7 +32,7 @@
class BilateralBlurNode : public Node {
public:
BilateralBlurNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp
index a8de2aed526..b8421dcb102 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BlurNode.cpp
@@ -38,84 +38,85 @@ BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
NodeBlurData *data = (NodeBlurData *)editorNode->storage;
- InputSocket *inputSizeSocket = this->getInputSocket(1);
- bool connectedSizeSocket = inputSizeSocket->isConnected();
+ NodeInput *inputSizeSocket = this->getInputSocket(1);
+ bool connectedSizeSocket = inputSizeSocket->isLinked();
const float size = this->getInputSocket(1)->getEditorValueFloat();
- CompositorQuality quality = context->getQuality();
+ CompositorQuality quality = context.getQuality();
NodeOperation *input_operation = NULL, *output_operation = NULL;
if (data->filtertype == R_FILTER_FAST_GAUSS) {
FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
operationfgb->setData(data);
- operationfgb->setChunksize(context->getChunksize());
- operationfgb->setbNode(editorNode);
- this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph);
- graph->addOperation(operationfgb);
-
+ operationfgb->setChunksize(context.getChunksize());
+ converter.addOperation(operationfgb);
+
+ converter.mapInputSocket(getInputSocket(1), operationfgb->getInputSocket(1));
+
input_operation = operationfgb;
output_operation = operationfgb;
}
else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) {
MathAddOperation *clamp = new MathAddOperation();
SetValueOperation *zero = new SetValueOperation();
- addLink(graph, zero->getOutputSocket(), clamp->getInputSocket(1));
- this->getInputSocket(1)->relinkConnections(clamp->getInputSocket(0), 1, graph);
zero->setValue(0.0f);
clamp->setUseClamp(true);
- graph->addOperation(clamp);
- graph->addOperation(zero);
-
+
+ converter.addOperation(clamp);
+ converter.addOperation(zero);
+ converter.mapInputSocket(getInputSocket(1), clamp->getInputSocket(0));
+ converter.addLink(zero->getOutputSocket(), clamp->getInputSocket(1));
+
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
operationx->setData(data);
- operationx->setbNode(editorNode);
operationx->setQuality(quality);
operationx->setSize(1.0f);
operationx->setFalloff(PROP_SMOOTH);
operationx->setSubtract(false);
- addLink(graph, clamp->getOutputSocket(), operationx->getInputSocket(0));
- graph->addOperation(operationx);
-
+
+ converter.addOperation(operationx);
+ converter.addLink(clamp->getOutputSocket(), operationx->getInputSocket(0));
+
GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
operationy->setData(data);
- operationy->setbNode(editorNode);
operationy->setQuality(quality);
operationy->setSize(1.0f);
operationy->setFalloff(PROP_SMOOTH);
operationy->setSubtract(false);
- addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
- graph->addOperation(operationy);
-
+
+ converter.addOperation(operationy);
+ converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
+
GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
operation->setData(data);
- operation->setbNode(editorNode);
operation->setQuality(quality);
- addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
- graph->addOperation(operation);
-
+
+ converter.addOperation(operation);
+ converter.addLink(operationy->getOutputSocket(), operation->getInputSocket(1));
+
output_operation = operation;
input_operation = operation;
}
else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
- operationx->setbNode(editorNode);
operationx->setQuality(quality);
- this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph);
- graph->addOperation(operationx);
+
+ converter.addOperation(operationx);
+ converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1));
+
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
operationy->setData(data);
- operationy->setbNode(editorNode);
operationy->setQuality(quality);
- graph->addOperation(operationy);
- addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
- addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1));
+ converter.addOperation(operationy);
+ converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1));
+ converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
if (!connectedSizeSocket) {
operationx->setSize(size);
@@ -128,10 +129,10 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
else {
GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation();
operation->setData(data);
- operation->setbNode(editorNode);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
operation->setQuality(quality);
- graph->addOperation(operation);
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
if (!connectedSizeSocket) {
operation->setSize(size);
@@ -144,19 +145,20 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
if (data->gamma) {
GammaCorrectOperation *correct = new GammaCorrectOperation();
GammaUncorrectOperation *inverse = new GammaUncorrectOperation();
-
- this->getInputSocket(0)->relinkConnections(correct->getInputSocket(0), 0, graph);
- addLink(graph, correct->getOutputSocket(), input_operation->getInputSocket(0));
- addLink(graph, output_operation->getOutputSocket(), inverse->getInputSocket(0));
- this->getOutputSocket()->relinkConnections(inverse->getOutputSocket());
- graph->addOperation(correct);
- graph->addOperation(inverse);
-
- addPreviewOperation(graph, context, inverse->getOutputSocket());
+ converter.addOperation(correct);
+ converter.addOperation(inverse);
+
+ converter.mapInputSocket(getInputSocket(0), correct->getInputSocket(0));
+ converter.addLink(correct->getOutputSocket(), input_operation->getInputSocket(0));
+ converter.addLink(output_operation->getOutputSocket(), inverse->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), inverse->getOutputSocket());
+
+ converter.addPreview(inverse->getOutputSocket());
}
else {
- this->getInputSocket(0)->relinkConnections(input_operation->getInputSocket(0), 0, graph);
- this->getOutputSocket()->relinkConnections(output_operation->getOutputSocket());
- addPreviewOperation(graph, context, output_operation->getOutputSocket());
+ converter.mapInputSocket(getInputSocket(0), input_operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), output_operation->getOutputSocket());
+
+ converter.addPreview(output_operation->getOutputSocket());
}
}
diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h
index 95b0516dae0..68844ca3d78 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.h
+++ b/source/blender/compositor/nodes/COM_BlurNode.h
@@ -32,7 +32,7 @@
class BlurNode : public Node {
public:
BlurNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
index 5725bc6cb32..636660bc96c 100644
--- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
@@ -34,40 +34,37 @@ BokehBlurNode::BokehBlurNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BokehBlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *b_node = this->getbNode();
- InputSocket *inputSizeSocket = this->getInputSocket(2);
+ NodeInput *inputSizeSocket = this->getInputSocket(2);
- bool connectedSizeSocket = inputSizeSocket->isConnected();
+ bool connectedSizeSocket = inputSizeSocket->isLinked();
if ((b_node->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) && connectedSizeSocket) {
VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
- operation->setQuality(context->getQuality());
- operation->setbNode(this->getbNode());
- graph->addOperation(operation);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
+ operation->setQuality(context.getQuality());
operation->setThreshold(0.0f);
operation->setMaxBlur(b_node->custom4);
operation->setDoScaleSize(true);
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
else {
BokehBlurOperation *operation = new BokehBlurOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(3), 2, graph);
- this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), 3, graph);
- operation->setQuality(context->getQuality());
- operation->setbNode(this->getbNode());
- graph->addOperation(operation);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
+ operation->setQuality(context.getQuality());
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
if (!connectedSizeSocket) {
operation->setSize(this->getInputSocket(2)->getEditorValueFloat());
diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h
index c2bc7552ac0..60ba79bed78 100644
--- a/source/blender/compositor/nodes/COM_BokehBlurNode.h
+++ b/source/blender/compositor/nodes/COM_BokehBlurNode.h
@@ -32,7 +32,7 @@
class BokehBlurNode : public Node {
public:
BokehBlurNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cpp b/source/blender/compositor/nodes/COM_BokehImageNode.cpp
index a89ed9e0c64..c75e9b16336 100644
--- a/source/blender/compositor/nodes/COM_BokehImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_BokehImageNode.cpp
@@ -29,11 +29,13 @@ BokehImageNode::BokehImageNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BokehImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BokehImageNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
BokehImageOperation *operation = new BokehImageOperation();
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
operation->setData((NodeBokehImage *)this->getbNode()->storage);
- addPreviewOperation(graph, context, operation->getOutputSocket(0));
+
+ converter.addOperation(operation);
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
+
+ converter.addPreview(operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h
index a4bfe2bedc0..6768bf0e88f 100644
--- a/source/blender/compositor/nodes/COM_BokehImageNode.h
+++ b/source/blender/compositor/nodes/COM_BokehImageNode.h
@@ -32,7 +32,7 @@
class BokehImageNode : public Node {
public:
BokehImageNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp
index e3fb6ecc704..b8bf23b8549 100644
--- a/source/blender/compositor/nodes/COM_BoxMaskNode.cpp
+++ b/source/blender/compositor/nodes/COM_BoxMaskNode.cpp
@@ -32,47 +32,43 @@ BoxMaskNode::BoxMaskNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BoxMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BoxMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
BoxMaskOperation *operation;
operation = new BoxMaskOperation();
operation->setData((NodeBoxMask *)this->getbNode()->storage);
-
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
- if (inputSocket->isConnected()) {
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket());
+ operation->setMaskType(this->getbNode()->custom1);
+ converter.addOperation(operation);
+
+ if (inputSocket->isLinked()) {
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
}
else {
/* Value operation to produce original transparent image */
SetValueOperation *valueOperation = new SetValueOperation();
valueOperation->setValue(0.0f);
- graph->addOperation(valueOperation);
+ converter.addOperation(valueOperation);
/* Scale that image up to render resolution */
- const RenderData *rd = context->getRenderData();
+ const RenderData *rd = context.getRenderData();
ScaleFixedSizeOperation *scaleOperation = new ScaleFixedSizeOperation();
scaleOperation->setIsAspect(false);
scaleOperation->setIsCrop(false);
scaleOperation->setOffset(0.0f, 0.0f);
-
scaleOperation->setNewWidth(rd->xsch * rd->size / 100.0f);
scaleOperation->setNewHeight(rd->ysch * rd->size / 100.0f);
+ scaleOperation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
+ converter.addOperation(scaleOperation);
- addLink(graph, valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
- addLink(graph, scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
- outputSocket->relinkConnections(operation->getOutputSocket(0));
-
- scaleOperation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true);
-
- graph->addOperation(scaleOperation);
+ converter.addLink(valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
+ converter.addLink(scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- operation->setMaskType(this->getbNode()->custom1);
-
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
}
diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h
index 9ebe2cc755a..3f466ef798e 100644
--- a/source/blender/compositor/nodes/COM_BoxMaskNode.h
+++ b/source/blender/compositor/nodes/COM_BoxMaskNode.h
@@ -32,7 +32,7 @@
class BoxMaskNode : public Node {
public:
BoxMaskNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cpp b/source/blender/compositor/nodes/COM_BrightnessNode.cpp
index cd230a23a5c..e684b569945 100644
--- a/source/blender/compositor/nodes/COM_BrightnessNode.cpp
+++ b/source/blender/compositor/nodes/COM_BrightnessNode.cpp
@@ -29,12 +29,13 @@ BrightnessNode::BrightnessNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void BrightnessNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void BrightnessNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
BrightnessOperation *operation = new BrightnessOperation();
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h
index a10372049f0..bd414b84e95 100644
--- a/source/blender/compositor/nodes/COM_BrightnessNode.h
+++ b/source/blender/compositor/nodes/COM_BrightnessNode.h
@@ -32,7 +32,7 @@
class BrightnessNode : public Node {
public:
BrightnessNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp
index 4c136583936..f356c74cd49 100644
--- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.cpp
@@ -30,15 +30,15 @@ ChannelMatteNode::ChannelMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ChannelMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocketImage = this->getInputSocket(0);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
-
- NodeOperation *convert = NULL;
bNode *node = this->getbNode();
-
+
+ NodeInput *inputSocketImage = this->getInputSocket(0);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
+
+ NodeOperation *convert = NULL;
/* colorspace */
switch (node->custom1) {
case CMP_NODE_CHANNEL_MATTE_CS_RGB:
@@ -56,35 +56,31 @@ void ChannelMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCon
default:
break;
}
-
+
ChannelMatteOperation *operation = new ChannelMatteOperation();
/* pass the ui properties to the operation */
operation->setSettings((NodeChroma *)node->storage, node->custom2);
-
+ converter.addOperation(operation);
+
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
-
+ converter.addOperation(operationAlpha);
+
if (convert) {
- inputSocketImage->relinkConnections(convert->getInputSocket(0), 0, graph);
- addLink(graph, convert->getOutputSocket(), operation->getInputSocket(0));
- addLink(graph, convert->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
- graph->addOperation(convert);
+ converter.addOperation(convert);
+
+ converter.mapInputSocket(inputSocketImage, convert->getInputSocket(0));
+ converter.addLink(convert->getOutputSocket(), operation->getInputSocket(0));
+ converter.addLink(convert->getOutputSocket(), operationAlpha->getInputSocket(0));
}
else {
- inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph);
- addLink(graph, operation->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
- }
-
- if (outputSocketMatte->isConnected()) {
- outputSocketMatte->relinkConnections(operation->getOutputSocket(0));
- }
-
- graph->addOperation(operation);
- graph->addOperation(operationAlpha);
-
- addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
- addPreviewOperation(graph, context, operationAlpha->getOutputSocket());
-
- if (outputSocketImage->isConnected()) {
- outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
+ converter.mapInputSocket(inputSocketImage, operation->getInputSocket(0));
+ converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0));
}
+
+ converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket(0));
+
+ converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket());
+
+ converter.addPreview(operationAlpha->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h
index 29c6000a245..f528578e6dd 100644
--- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h
@@ -31,7 +31,7 @@
class ChannelMatteNode : public Node {
public:
ChannelMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ChannelMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp
index c23f242ca5c..90de9358587 100644
--- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.cpp
@@ -30,44 +30,38 @@ ChromaMatteNode::ChromaMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ChromaMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocketImage = this->getInputSocket(0);
- InputSocket *inputSocketKey = this->getInputSocket(1);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
-
+ bNode *editorsnode = getbNode();
+
+ NodeInput *inputSocketImage = this->getInputSocket(0);
+ NodeInput *inputSocketKey = this->getInputSocket(1);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
+
ConvertRGBToYCCOperation *operationRGBToYCC_Image = new ConvertRGBToYCCOperation();
ConvertRGBToYCCOperation *operationRGBToYCC_Key = new ConvertRGBToYCCOperation();
operationRGBToYCC_Image->setMode(0); /* BLI_YCC_ITU_BT601 */
operationRGBToYCC_Key->setMode(0); /* BLI_YCC_ITU_BT601 */
-
+ converter.addOperation(operationRGBToYCC_Image);
+ converter.addOperation(operationRGBToYCC_Key);
+
ChromaMatteOperation *operation = new ChromaMatteOperation();
- bNode *editorsnode = getbNode();
operation->setSettings((NodeChroma *)editorsnode->storage);
-
- inputSocketImage->relinkConnections(operationRGBToYCC_Image->getInputSocket(0), 0, graph);
- inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 1, graph);
-
- addLink(graph, operationRGBToYCC_Image->getOutputSocket(), operation->getInputSocket(0));
- addLink(graph, operationRGBToYCC_Key->getOutputSocket(), operation->getInputSocket(1));
-
- graph->addOperation(operationRGBToYCC_Image);
- graph->addOperation(operationRGBToYCC_Key);
- graph->addOperation(operation);
-
- if (outputSocketMatte->isConnected()) {
- outputSocketMatte->relinkConnections(operation->getOutputSocket());
- }
-
+ converter.addOperation(operation);
+
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
- addLink(graph, operationRGBToYCC_Image->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
-
- graph->addOperation(operationAlpha);
- addPreviewOperation(graph, context, operationAlpha->getOutputSocket());
-
- if (outputSocketImage->isConnected()) {
- outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
- }
+ converter.addOperation(operationAlpha);
+
+ converter.mapInputSocket(inputSocketImage, operationRGBToYCC_Image->getInputSocket(0));
+ converter.mapInputSocket(inputSocketKey, operationRGBToYCC_Key->getInputSocket(0));
+ converter.addLink(operationRGBToYCC_Image->getOutputSocket(), operation->getInputSocket(0));
+ converter.addLink(operationRGBToYCC_Key->getOutputSocket(), operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket());
+
+ converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0));
+ converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket());
+
+ converter.addPreview(operationAlpha->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h
index bf5302ccdbb..d1eb3a907ef 100644
--- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h
@@ -31,7 +31,7 @@
class ChromaMatteNode : public Node {
public:
ChromaMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ChromaMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp
index 2b396fb9861..fc0df046e86 100644
--- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp
@@ -32,14 +32,15 @@ ColorBalanceNode::ColorBalanceNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorBalanceNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputImageSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
bNode *node = this->getbNode();
NodeColorBalance *n = (NodeColorBalance *)node->storage;
+
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputImageSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
NodeOperation *operation;
if (node->custom1 == 0) {
ColorBalanceLGGOperation *operationLGG = new ColorBalanceLGGOperation();
@@ -62,9 +63,9 @@ void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorCon
operationCDL->setSlope(n->slope);
operation = operationCDL;
}
+ converter.addOperation(operation);
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputImageSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputImageSocket, operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h
index 30d22ef2e63..f0b9694ec77 100644
--- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h
+++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h
@@ -32,7 +32,7 @@
class ColorBalanceNode : public Node {
public:
ColorBalanceNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ColorBalanceNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
index a05abaf17d3..728b51b8dc1 100644
--- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
@@ -29,16 +29,18 @@ ColorCorrectionNode::ColorCorrectionNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorCorrectionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorCorrectionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- ColorCorrectionOperation *operation = new ColorCorrectionOperation();
bNode *editorNode = getbNode();
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
+
+ ColorCorrectionOperation *operation = new ColorCorrectionOperation();
operation->setData((NodeColorCorrection *)editorNode->storage);
operation->setRedChannelEnabled((editorNode->custom1 & 1) > 0);
operation->setGreenChannelEnabled((editorNode->custom1 & 2) > 0);
operation->setBlueChannelEnabled((editorNode->custom1 & 4) > 0);
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
index f1b0f69bec5..aa2c475734d 100644
--- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
+++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
@@ -32,7 +32,7 @@
class ColorCorrectionNode : public Node {
public:
ColorCorrectionNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp
index 103fbf26c7d..6dc936302f4 100644
--- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp
@@ -29,36 +29,32 @@ ColorCurveNode::ColorCurveNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- if (this->getInputSocket(2)->isConnected() || this->getInputSocket(3)->isConnected()) {
+ if (this->getInputSocket(2)->isLinked() || this->getInputSocket(3)->isLinked()) {
ColorCurveOperation *operation = new ColorCurveOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
- this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, graph);
-
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
+
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
else {
ConstantLevelColorCurveOperation *operation = new ConstantLevelColorCurveOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
float col[4];
this->getInputSocket(2)->getEditorValueColor(col);
operation->setBlackLevel(col);
this->getInputSocket(3)->getEditorValueColor(col);
operation->setWhiteLevel(col);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
}
diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h
index ecfae1f86f8..5420058ea64 100644
--- a/source/blender/compositor/nodes/COM_ColorCurveNode.h
+++ b/source/blender/compositor/nodes/COM_ColorCurveNode.h
@@ -32,7 +32,7 @@
class ColorCurveNode : public Node {
public:
ColorCurveNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp
index 8ab93a58a1d..def3b18e0fe 100644
--- a/source/blender/compositor/nodes/COM_ColorMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorMatteNode.cpp
@@ -30,41 +30,36 @@ ColorMatteNode::ColorMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocketImage = this->getInputSocket(0);
- InputSocket *inputSocketKey = this->getInputSocket(1);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
-
+ bNode *editorsnode = getbNode();
+
+ NodeInput *inputSocketImage = this->getInputSocket(0);
+ NodeInput *inputSocketKey = this->getInputSocket(1);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
+
ConvertRGBToHSVOperation *operationRGBToHSV_Image = new ConvertRGBToHSVOperation();
ConvertRGBToHSVOperation *operationRGBToHSV_Key = new ConvertRGBToHSVOperation();
-
+ converter.addOperation(operationRGBToHSV_Image);
+ converter.addOperation(operationRGBToHSV_Key);
+
ColorMatteOperation *operation = new ColorMatteOperation();
- bNode *editorsnode = getbNode();
operation->setSettings((NodeChroma *)editorsnode->storage);
-
- inputSocketImage->relinkConnections(operationRGBToHSV_Image->getInputSocket(0), 0, graph);
- inputSocketKey->relinkConnections(operationRGBToHSV_Key->getInputSocket(0), 1, graph);
-
- addLink(graph, operationRGBToHSV_Image->getOutputSocket(), operation->getInputSocket(0));
- addLink(graph, operationRGBToHSV_Key->getOutputSocket(), operation->getInputSocket(1));
-
- if (outputSocketMatte->isConnected()) {
- outputSocketMatte->relinkConnections(operation->getOutputSocket(0));
- }
-
- graph->addOperation(operationRGBToHSV_Image);
- graph->addOperation(operationRGBToHSV_Key);
- graph->addOperation(operation);
-
+ converter.addOperation(operation);
+
SetAlphaOperation *operationAlpha = new SetAlphaOperation();
- addLink(graph, operationRGBToHSV_Image->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
- graph->addOperation(operationAlpha);
- addPreviewOperation(graph, context, operationAlpha->getOutputSocket());
-
- if (outputSocketImage->isConnected()) {
- outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
- }
+ converter.addOperation(operationAlpha);
+
+ converter.mapInputSocket(inputSocketImage, operationRGBToHSV_Image->getInputSocket(0));
+ converter.mapInputSocket(inputSocketKey, operationRGBToHSV_Key->getInputSocket(0));
+ converter.addLink(operationRGBToHSV_Image->getOutputSocket(), operation->getInputSocket(0));
+ converter.addLink(operationRGBToHSV_Key->getOutputSocket(), operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket(0));
+
+ converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0));
+ converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket());
+
+ converter.addPreview(operationAlpha->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h
index 3386476bc85..c17d3eb6c4e 100644
--- a/source/blender/compositor/nodes/COM_ColorMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h
@@ -31,7 +31,7 @@
class ColorMatteNode : public Node {
public:
ColorMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ColorMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorNode.cpp b/source/blender/compositor/nodes/COM_ColorNode.cpp
index fc2566e5a47..4106cb64798 100644
--- a/source/blender/compositor/nodes/COM_ColorNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorNode.cpp
@@ -29,13 +29,14 @@ ColorNode::ColorNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
SetColorOperation *operation = new SetColorOperation();
- OutputSocket *output = this->getOutputSocket(0);
- output->relinkConnections(operation->getOutputSocket());
+ NodeOutput *output = this->getOutputSocket(0);
float col[4];
output->getEditorValueColor(col);
operation->setChannels(col);
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapOutputSocket(output, operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h
index 3e3df63e90a..ac8c6c221b9 100644
--- a/source/blender/compositor/nodes/COM_ColorNode.h
+++ b/source/blender/compositor/nodes/COM_ColorNode.h
@@ -32,7 +32,7 @@
class ColorNode : public Node {
public:
ColorNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.cpp b/source/blender/compositor/nodes/COM_ColorRampNode.cpp
index 6f715a8f278..a61ddffbf35 100644
--- a/source/blender/compositor/nodes/COM_ColorRampNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorRampNode.cpp
@@ -32,23 +32,24 @@ ColorRampNode::ColorRampNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorRampNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorRampNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
- OutputSocket *outputSocketAlpha = this->getOutputSocket(1);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+ NodeOutput *outputSocketAlpha = this->getOutputSocket(1);
bNode *editorNode = this->getbNode();
ColorRampOperation *operation = new ColorRampOperation();
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- if (outputSocketAlpha->isConnected()) {
- SeparateChannelOperation *operation2 = new SeparateChannelOperation();
- outputSocketAlpha->relinkConnections(operation2->getOutputSocket());
- addLink(graph, operation->getOutputSocket(), operation2->getInputSocket(0));
- operation2->setChannel(3);
- graph->addOperation(operation2);
- }
operation->setColorBand((ColorBand *)editorNode->storage);
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
+
+ SeparateChannelOperation *operation2 = new SeparateChannelOperation();
+ operation2->setChannel(3);
+ converter.addOperation(operation2);
+
+ converter.addLink(operation->getOutputSocket(), operation2->getInputSocket(0));
+ converter.mapOutputSocket(outputSocketAlpha, operation2->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h
index 3f00e1c2190..d303616a417 100644
--- a/source/blender/compositor/nodes/COM_ColorRampNode.h
+++ b/source/blender/compositor/nodes/COM_ColorRampNode.h
@@ -32,7 +32,7 @@
class ColorRampNode : public Node {
public:
ColorRampNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ColorRampNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp
index 0e586955ff8..82454ba7979 100644
--- a/source/blender/compositor/nodes/COM_ColorSpillNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorSpillNode.cpp
@@ -29,14 +29,13 @@ ColorSpillNode::ColorSpillNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorSpillNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorSpillNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocketImage = this->getInputSocket(0);
- InputSocket *inputSocketFac = this->getInputSocket(1);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
-
bNode *editorsnode = getbNode();
-
+
+ NodeInput *inputSocketImage = this->getInputSocket(0);
+ NodeInput *inputSocketFac = this->getInputSocket(1);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
ColorSpillOperation *operation;
if (editorsnode->custom2 == 0) {
@@ -49,11 +48,9 @@ void ColorSpillNode::convertToOperations(ExecutionSystem *graph, CompositorConte
}
operation->setSettings((NodeColorspill *)editorsnode->storage);
operation->setSpillChannel(editorsnode->custom1 - 1); // Channel for spilling
+ converter.addOperation(operation);
-
- inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputSocketFac->relinkConnections(operation->getInputSocket(1), 1, graph);
-
- outputSocketImage->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+ converter.mapInputSocket(inputSocketImage, operation->getInputSocket(0));
+ converter.mapInputSocket(inputSocketFac, operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h
index 01722fac826..7442d2b0261 100644
--- a/source/blender/compositor/nodes/COM_ColorSpillNode.h
+++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h
@@ -32,7 +32,7 @@
class ColorSpillNode : public Node {
public:
ColorSpillNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_ColorSpillNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp
index 07be93dab86..a1616a61b4b 100644
--- a/source/blender/compositor/nodes/COM_ColorToBWNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorToBWNode.cpp
@@ -30,13 +30,14 @@ ColorToBWNode::ColorToBWNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ColorToBWNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ColorToBWNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *colorSocket = this->getInputSocket(0);
- OutputSocket *valueSocket = this->getOutputSocket(0);
+ NodeInput *colorSocket = this->getInputSocket(0);
+ NodeOutput *valueSocket = this->getOutputSocket(0);
ConvertColorToBWOperation *convertProg = new ConvertColorToBWOperation();
- colorSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
- valueSocket->relinkConnections(convertProg->getOutputSocket(0));
- graph->addOperation(convertProg);
+ converter.addOperation(convertProg);
+
+ converter.mapInputSocket(colorSocket, convertProg->getInputSocket(0));
+ converter.mapOutputSocket(valueSocket, convertProg->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h
index f21c6ecef52..6932c153c0c 100644
--- a/source/blender/compositor/nodes/COM_ColorToBWNode.h
+++ b/source/blender/compositor/nodes/COM_ColorToBWNode.h
@@ -32,6 +32,6 @@
class ColorToBWNode : public Node {
public:
ColorToBWNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cpp b/source/blender/compositor/nodes/COM_CombineColorNode.cpp
new file mode 100644
index 00000000000..c7a3baf809d
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_CombineColorNode.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Lukas Toenne
+ */
+
+#include "COM_CombineColorNode.h"
+
+#include "COM_ConvertOperation.h"
+
+
+CombineColorNode::CombineColorNode(bNode *editorNode) :
+ Node(editorNode)
+{
+}
+
+void CombineColorNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
+{
+ NodeInput *inputRSocket = this->getInputSocket(0);
+ NodeInput *inputGSocket = this->getInputSocket(1);
+ NodeInput *inputBSocket = this->getInputSocket(2);
+ NodeInput *inputASocket = this->getInputSocket(3);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
+ CombineChannelsOperation *operation = new CombineChannelsOperation();
+ if (inputRSocket->isLinked()) {
+ operation->setResolutionInputSocketIndex(0);
+ }
+ else if (inputGSocket->isLinked()) {
+ operation->setResolutionInputSocketIndex(1);
+ }
+ else if (inputBSocket->isLinked()) {
+ operation->setResolutionInputSocketIndex(2);
+ }
+ else {
+ operation->setResolutionInputSocketIndex(3);
+ }
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputRSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputGSocket, operation->getInputSocket(1));
+ converter.mapInputSocket(inputBSocket, operation->getInputSocket(2));
+ converter.mapInputSocket(inputASocket, operation->getInputSocket(3));
+
+ NodeOperation *color_conv = getColorConverter(context);
+ if (color_conv) {
+ converter.addOperation(color_conv);
+
+ converter.addLink(operation->getOutputSocket(), color_conv->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, color_conv->getOutputSocket());
+ }
+ else {
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+ }
+}
+
+
+NodeOperation *CombineRGBANode::getColorConverter(const CompositorContext &context) const
+{
+ return NULL; /* no conversion needed */
+}
+
+NodeOperation *CombineHSVANode::getColorConverter(const CompositorContext &context) const
+{
+ return new ConvertHSVToRGBOperation();
+}
+
+NodeOperation *CombineYCCANode::getColorConverter(const CompositorContext &context) const
+{
+ ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation();
+ bNode *editorNode = this->getbNode();
+ operation->setMode(editorNode->custom1);
+ return operation;
+}
+
+NodeOperation *CombineYUVANode::getColorConverter(const CompositorContext &context) const
+{
+ return new ConvertYUVToRGBOperation();
+}
diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.h b/source/blender/compositor/nodes/COM_CombineColorNode.h
new file mode 100644
index 00000000000..2eff1a28f20
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_CombineColorNode.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Lukas Toenne
+ */
+
+#ifndef _COM_CombineColorNode_h_
+#define _COM_CombineColorNode_h_
+
+#include "COM_Node.h"
+
+class CombineColorNode : public Node {
+public:
+ CombineColorNode(bNode *editorNode);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
+
+protected:
+ virtual NodeOperation *getColorConverter(const CompositorContext &context) const = 0;
+};
+
+class CombineRGBANode : public CombineColorNode {
+public:
+ CombineRGBANode(bNode *editorNode) :
+ CombineColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class CombineHSVANode : public CombineColorNode {
+public:
+ CombineHSVANode(bNode *editorNode) :
+ CombineColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class CombineYCCANode : public CombineColorNode {
+public:
+ CombineYCCANode(bNode *editorNode) :
+ CombineColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class CombineYUVANode : public CombineColorNode {
+public:
+ CombineYUVANode(bNode *editorNode) :
+ CombineColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+#endif
diff --git a/source/blender/compositor/nodes/COM_CombineHSVANode.cpp b/source/blender/compositor/nodes/COM_CombineHSVANode.cpp
deleted file mode 100644
index 9f6614ed8c3..00000000000
--- a/source/blender/compositor/nodes/COM_CombineHSVANode.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_CombineHSVANode.h"
-
-#include "COM_ConvertOperation.h"
-
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "COM_ConvertOperation.h"
-
-CombineHSVANode::CombineHSVANode(bNode *editorNode) : CombineRGBANode(editorNode)
-{
- /* pass */
-}
-
-void CombineHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertHSVToRGBOperation *operation = new ConvertHSVToRGBOperation();
- OutputSocket *outputSocket = this->getOutputSocket(0);
- if (outputSocket->isConnected()) {
- outputSocket->relinkConnections(operation->getOutputSocket());
- addLink(graph, outputSocket, operation->getInputSocket(0));
- }
- graph->addOperation(operation);
- CombineRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_CombineHSVANode.h b/source/blender/compositor/nodes/COM_CombineHSVANode.h
deleted file mode 100644
index 95d3cf9ecdd..00000000000
--- a/source/blender/compositor/nodes/COM_CombineHSVANode.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_CombineHSVANode_h_
-#define _COM_CombineHSVANode_h_
-
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-#include "COM_CombineRGBANode.h"
-/**
- * @brief CombineHSVANode
- * @ingroup Node
- */
-class CombineHSVANode : public CombineRGBANode {
-public:
- CombineHSVANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
diff --git a/source/blender/compositor/nodes/COM_CombineRGBANode.cpp b/source/blender/compositor/nodes/COM_CombineRGBANode.cpp
deleted file mode 100644
index 8dfded049e5..00000000000
--- a/source/blender/compositor/nodes/COM_CombineRGBANode.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_CombineRGBANode.h"
-
-#include "COM_ConvertOperation.h"
-
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "DNA_material_types.h" // the ramp types
-
-
-CombineRGBANode::CombineRGBANode(bNode *editorNode) : Node(editorNode)
-{
- /* pass */
-}
-
-void CombineRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- InputSocket *inputRSocket = this->getInputSocket(0);
- InputSocket *inputGSocket = this->getInputSocket(1);
- InputSocket *inputBSocket = this->getInputSocket(2);
- InputSocket *inputASocket = this->getInputSocket(3);
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
- CombineChannelsOperation *operation = new CombineChannelsOperation();
- if (inputRSocket->isConnected()) {
- operation->setResolutionInputSocketIndex(0);
- }
- else if (inputGSocket->isConnected()) {
- operation->setResolutionInputSocketIndex(1);
- }
- else if (inputBSocket->isConnected()) {
- operation->setResolutionInputSocketIndex(2);
- }
- else {
- operation->setResolutionInputSocketIndex(3);
- }
- inputRSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputGSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- inputBSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
- inputASocket->relinkConnections(operation->getInputSocket(3), 3, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
-}
diff --git a/source/blender/compositor/nodes/COM_CombineYCCANode.cpp b/source/blender/compositor/nodes/COM_CombineYCCANode.cpp
deleted file mode 100644
index ee787a4f9c1..00000000000
--- a/source/blender/compositor/nodes/COM_CombineYCCANode.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#include "COM_CombineYCCANode.h"
-#include "COM_ConvertOperation.h"
-
-CombineYCCANode::CombineYCCANode(bNode *editorNode) : CombineRGBANode(editorNode)
-{
- /* pass */
-}
-
-void CombineYCCANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation();
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
- bNode *node = this->getbNode();
- operation->setMode(node->custom1);
-
- if (outputSocket->isConnected()) {
- outputSocket->relinkConnections(operation->getOutputSocket());
- addLink(graph, outputSocket, operation->getInputSocket(0));
- }
-
- graph->addOperation(operation);
- CombineRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_CombineYCCANode.h b/source/blender/compositor/nodes/COM_CombineYCCANode.h
deleted file mode 100644
index 6ff2938c161..00000000000
--- a/source/blender/compositor/nodes/COM_CombineYCCANode.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#ifndef _COM_CombineYCCANode_h_
-#define _COM_CombineYCCANode_h_
-
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-#include "COM_CombineRGBANode.h"
-/**
- * @brief CombineYCCANode
- * @ingroup Node
- */
-class CombineYCCANode : public CombineRGBANode {
-public:
- CombineYCCANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
diff --git a/source/blender/compositor/nodes/COM_CombineYUVANode.cpp b/source/blender/compositor/nodes/COM_CombineYUVANode.cpp
deleted file mode 100644
index feee443cf05..00000000000
--- a/source/blender/compositor/nodes/COM_CombineYUVANode.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#include "COM_CombineYUVANode.h"
-#include "COM_ConvertOperation.h"
-
-CombineYUVANode::CombineYUVANode(bNode *editorNode) : CombineRGBANode(editorNode)
-{
- /* pass */
-}
-
-void CombineYUVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertYUVToRGBOperation *operation = new ConvertYUVToRGBOperation();
- OutputSocket *outputSocket = this->getOutputSocket(0);
- if (outputSocket->isConnected()) {
- outputSocket->relinkConnections(operation->getOutputSocket());
- addLink(graph, outputSocket, operation->getInputSocket(0));
- }
- graph->addOperation(operation);
- CombineRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp
index 7e192af0cd9..3d79eb693ea 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.cpp
+++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp
@@ -29,26 +29,33 @@ CompositorNode::CompositorNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void CompositorNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC) ||
- context->isRendering();
+ context.isRendering();
+ bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA;
- InputSocket *imageSocket = this->getInputSocket(0);
- InputSocket *alphaSocket = this->getInputSocket(1);
- InputSocket *depthSocket = this->getInputSocket(2);
+ NodeInput *imageSocket = this->getInputSocket(0);
+ NodeInput *alphaSocket = this->getInputSocket(1);
+ NodeInput *depthSocket = this->getInputSocket(2);
CompositorOperation *compositorOperation = new CompositorOperation();
- compositorOperation->setSceneName(context->getScene()->id.name);
- compositorOperation->setRenderData(context->getRenderData());
- compositorOperation->setbNodeTree(context->getbNodeTree());
- compositorOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
+ compositorOperation->setSceneName(context.getScene()->id.name);
+ compositorOperation->setRenderData(context.getRenderData());
+ compositorOperation->setbNodeTree(context.getbNodeTree());
+ /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */
+ compositorOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked());
compositorOperation->setActive(is_active);
- imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph);
- alphaSocket->relinkConnections(compositorOperation->getInputSocket(1));
- depthSocket->relinkConnections(compositorOperation->getInputSocket(2));
- graph->addOperation(compositorOperation);
-
- addPreviewOperation(graph, context, compositorOperation->getInputSocket(0));
+
+ converter.addOperation(compositorOperation);
+ converter.mapInputSocket(imageSocket, compositorOperation->getInputSocket(0));
+ /* only use alpha link if "use alpha" is enabled */
+ if (ignore_alpha)
+ converter.addInputValue(compositorOperation->getInputSocket(1), 1.0f);
+ else
+ converter.mapInputSocket(alphaSocket, compositorOperation->getInputSocket(1));
+ converter.mapInputSocket(depthSocket, compositorOperation->getInputSocket(2));
+
+ converter.addNodeInputPreview(imageSocket);
}
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h
index 54d52d7db9e..aa9a4cdd8bb 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.h
+++ b/source/blender/compositor/nodes/COM_CompositorNode.h
@@ -32,6 +32,6 @@
class CompositorNode : public Node {
public:
CompositorNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
index 72f3ed07fd5..ba31ed6e89c 100644
--- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
+++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
@@ -23,7 +23,7 @@
#include "COM_ConvertOperation.h"
#include "COM_ExecutionSystem.h"
-void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ConvertAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeOperation *operation = NULL;
bNode *node = this->getbNode();
@@ -35,9 +35,9 @@ void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorCon
else {
operation = new ConvertStraightToPremulOperation();
}
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
- graph->addOperation(operation);
+
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
index a80f8de1607..5bc5169b6d9 100644
--- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
+++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
@@ -31,7 +31,7 @@
class ConvertAlphaNode : public Node {
public:
ConvertAlphaNode(bNode *editorNode) : Node(editorNode) {}
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.cpp b/source/blender/compositor/nodes/COM_CornerPinNode.cpp
new file mode 100644
index 00000000000..ea9f22f2840
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_CornerPinNode.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#include "COM_CornerPinNode.h"
+#include "COM_ExecutionSystem.h"
+
+#include "COM_PlaneCornerPinOperation.h"
+
+CornerPinNode::CornerPinNode(bNode *editorNode) : Node(editorNode)
+{
+}
+
+void CornerPinNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
+{
+ NodeInput *input_image = this->getInputSocket(0);
+ /* note: socket order differs between UI node and operations:
+ * bNode uses intuitive order following top-down layout:
+ * upper-left, upper-right, lower-left, lower-right
+ * Operations use same order as the tracking blenkernel functions expect:
+ * lower-left, lower-right, upper-right, upper-left
+ */
+ const int node_corner_index[4] = { 3, 4, 2, 1 };
+
+ NodeOutput *output_warped_image = this->getOutputSocket(0);
+ NodeOutput *output_plane = this->getOutputSocket(1);
+
+ PlaneCornerPinWarpImageOperation *warp_image_operation = new PlaneCornerPinWarpImageOperation();
+ converter.addOperation(warp_image_operation);
+ PlaneCornerPinMaskOperation *plane_mask_operation = new PlaneCornerPinMaskOperation();
+ converter.addOperation(plane_mask_operation);
+
+ converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
+ for (int i = 0; i < 4; ++i) {
+ NodeInput *corner_input = getInputSocket(node_corner_index[i]);
+ converter.mapInputSocket(corner_input, warp_image_operation->getInputSocket(i + 1));
+ converter.mapInputSocket(corner_input, plane_mask_operation->getInputSocket(i));
+ }
+ converter.mapOutputSocket(output_warped_image, warp_image_operation->getOutputSocket());
+ converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
+}
diff --git a/source/blender/compositor/nodes/COM_CombineYUVANode.h b/source/blender/compositor/nodes/COM_CornerPinNode.h
index e3d8f36a5dd..70e48e41d6b 100644
--- a/source/blender/compositor/nodes/COM_CombineYUVANode.h
+++ b/source/blender/compositor/nodes/COM_CornerPinNode.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Blender Foundation.
+ * Copyright 2014, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -16,22 +16,26 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
- * Dalai Felinto
+ * Lukas Toenne
*/
-#ifndef _COM_CombineYUVANode_h_
-#define _COM_CombineYUVANode_h_
+#ifndef _COM_CornerPinNode_h
+#define _COM_CornerPinNode_h
#include "COM_Node.h"
+
+extern "C" {
#include "DNA_node_types.h"
-#include "COM_CombineRGBANode.h"
+}
+
/**
- * @brief CombineYUVANode
+ * @brief CornerPinNode
* @ingroup Node
*/
-class CombineYUVANode : public CombineRGBANode {
+class CornerPinNode : public Node {
public:
- CombineYUVANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ CornerPinNode(bNode *editorNode);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
+
+#endif /* _COM_CornerPinNode_h */
diff --git a/source/blender/compositor/nodes/COM_CropNode.cpp b/source/blender/compositor/nodes/COM_CropNode.cpp
index f09bb7e1c26..6c3dc93481b 100644
--- a/source/blender/compositor/nodes/COM_CropNode.cpp
+++ b/source/blender/compositor/nodes/COM_CropNode.cpp
@@ -29,7 +29,7 @@ CropNode::CropNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void CropNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void CropNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *node = getbNode();
NodeTwoXYs *cropSettings = (NodeTwoXYs *)node->storage;
@@ -44,7 +44,8 @@ void CropNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
}
operation->setCropSettings(cropSettings);
operation->setRelative(relative);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket()->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h
index 1003728a9d4..c1b84247ba2 100644
--- a/source/blender/compositor/nodes/COM_CropNode.h
+++ b/source/blender/compositor/nodes/COM_CropNode.h
@@ -32,7 +32,7 @@
class CropNode : public Node {
public:
CropNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cpp b/source/blender/compositor/nodes/COM_DefocusNode.cpp
index c2d25bbccd8..d2ea385fde0 100644
--- a/source/blender/compositor/nodes/COM_DefocusNode.cpp
+++ b/source/blender/compositor/nodes/COM_DefocusNode.cpp
@@ -39,11 +39,11 @@ DefocusNode::DefocusNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DefocusNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *node = this->getbNode();
NodeDefocus *data = (NodeDefocus *)node->storage;
- Scene *scene = node->id ? (Scene *)node->id : context->getScene();
+ Scene *scene = node->id ? (Scene *)node->id : context.getScene();
Object *camob = scene ? scene->camera : NULL;
NodeOperation *radiusOperation;
@@ -54,36 +54,39 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext
SetValueOperation *maxRadius = new SetValueOperation();
maxRadius->setValue(data->maxblur);
MathMinimumOperation *minimize = new MathMinimumOperation();
- this->getInputSocket(1)->relinkConnections(multiply->getInputSocket(0), 1, graph);
- addLink(graph, multiplier->getOutputSocket(), multiply->getInputSocket(1));
- addLink(graph, maxRadius->getOutputSocket(), minimize->getInputSocket(1));
- addLink(graph, multiply->getOutputSocket(), minimize->getInputSocket(0));
- graph->addOperation(multiply);
- graph->addOperation(multiplier);
- graph->addOperation(maxRadius);
- graph->addOperation(minimize);
+ converter.addOperation(multiply);
+ converter.addOperation(multiplier);
+ converter.addOperation(maxRadius);
+ converter.addOperation(minimize);
+
+ converter.mapInputSocket(getInputSocket(1), multiply->getInputSocket(0));
+ converter.addLink(multiplier->getOutputSocket(), multiply->getInputSocket(1));
+ converter.addLink(multiply->getOutputSocket(), minimize->getInputSocket(0));
+ converter.addLink(maxRadius->getOutputSocket(), minimize->getInputSocket(1));
+
radiusOperation = minimize;
}
else {
- ConvertDepthToRadiusOperation *converter = new ConvertDepthToRadiusOperation();
- converter->setCameraObject(camob);
- converter->setfStop(data->fstop);
- converter->setMaxRadius(data->maxblur);
- this->getInputSocket(1)->relinkConnections(converter->getInputSocket(0), 1, graph);
- graph->addOperation(converter);
+ ConvertDepthToRadiusOperation *radius_op = new ConvertDepthToRadiusOperation();
+ radius_op->setCameraObject(camob);
+ radius_op->setfStop(data->fstop);
+ radius_op->setMaxRadius(data->maxblur);
+ converter.addOperation(radius_op);
+
+ converter.mapInputSocket(getInputSocket(1), radius_op->getInputSocket(0));
FastGaussianBlurValueOperation *blur = new FastGaussianBlurValueOperation();
- addLink(graph, converter->getOutputSocket(0), blur->getInputSocket(0));
- graph->addOperation(blur);
- radiusOperation = blur;
- converter->setPostBlur(blur);
-
/* maintain close pixels so far Z values don't bleed into the foreground */
blur->setOverlay(FAST_GAUSS_OVERLAY_MIN);
+ converter.addOperation(blur);
+
+ converter.addLink(radius_op->getOutputSocket(0), blur->getInputSocket(0));
+ radius_op->setPostBlur(blur);
+
+ radiusOperation = blur;
}
- BokehImageOperation *bokeh = new BokehImageOperation();
NodeBokehImage *bokehdata = new NodeBokehImage();
bokehdata->angle = data->rotation;
bokehdata->rounding = 0.0f;
@@ -95,44 +98,47 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext
bokehdata->catadioptric = 0.0f;
bokehdata->lensshift = 0.0f;
+ BokehImageOperation *bokeh = new BokehImageOperation();
bokeh->setData(bokehdata);
bokeh->deleteDataOnFinish();
- graph->addOperation(bokeh);
-
-#ifdef COM_DEFOCUS_SEARCH
+ converter.addOperation(bokeh);
+
+#ifdef COM_DEFOCUS_SEARCH
InverseSearchRadiusOperation *search = new InverseSearchRadiusOperation();
- addLink(graph, radiusOperation->getOutputSocket(0), search->getInputSocket(0));
search->setMaxBlur(data->maxblur);
- graph->addOperation(search);
+ converter.addOperation(search);
+
+ converter.addLink(radiusOperation->getOutputSocket(0), search->getInputSocket(0));
#endif
+
VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
- if (data->preview) {
+ if (data->preview)
operation->setQuality(COM_QUALITY_LOW);
- }
- else {
- operation->setQuality(context->getQuality());
- }
+ else
+ operation->setQuality(context.getQuality());
operation->setMaxBlur(data->maxblur);
- operation->setbNode(node);
operation->setThreshold(data->bthresh);
- addLink(graph, bokeh->getOutputSocket(), operation->getInputSocket(1));
- addLink(graph, radiusOperation->getOutputSocket(), operation->getInputSocket(2));
+ converter.addOperation(operation);
+
+ converter.addLink(bokeh->getOutputSocket(), operation->getInputSocket(1));
+ converter.addLink(radiusOperation->getOutputSocket(), operation->getInputSocket(2));
#ifdef COM_DEFOCUS_SEARCH
- addLink(graph, search->getOutputSocket(), operation->getInputSocket(3));
+ converter.addLink(search->getOutputSocket(), operation->getInputSocket(3));
#endif
+
if (data->gamco) {
GammaCorrectOperation *correct = new GammaCorrectOperation();
+ converter.addOperation(correct);
GammaUncorrectOperation *inverse = new GammaUncorrectOperation();
- this->getInputSocket(0)->relinkConnections(correct->getInputSocket(0), 0, graph);
- addLink(graph, correct->getOutputSocket(), operation->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), inverse->getInputSocket(0));
- this->getOutputSocket()->relinkConnections(inverse->getOutputSocket());
- graph->addOperation(correct);
- graph->addOperation(inverse);
+ converter.addOperation(inverse);
+
+ converter.mapInputSocket(getInputSocket(0), correct->getInputSocket(0));
+ converter.addLink(correct->getOutputSocket(), operation->getInputSocket(0));
+ converter.addLink(operation->getOutputSocket(), inverse->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), inverse->getOutputSocket());
}
else {
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket()->relinkConnections(operation->getOutputSocket());
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), operation->getOutputSocket());
}
- graph->addOperation(operation);
}
diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h
index 7d69b6413bb..8c607f0737e 100644
--- a/source/blender/compositor/nodes/COM_DefocusNode.h
+++ b/source/blender/compositor/nodes/COM_DefocusNode.h
@@ -32,7 +32,7 @@
class DefocusNode : public Node {
public:
DefocusNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.cpp b/source/blender/compositor/nodes/COM_DespeckleNode.cpp
index 9894dc7b9ac..bac6337374f 100644
--- a/source/blender/compositor/nodes/COM_DespeckleNode.cpp
+++ b/source/blender/compositor/nodes/COM_DespeckleNode.cpp
@@ -29,22 +29,21 @@ DespeckleNode::DespeckleNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DespeckleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DespeckleNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputImageSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputImageSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
DespeckleOperation *operation = new DespeckleOperation();
-
- operation->setbNode(editorNode);
operation->setThreshold(editorNode->custom3);
operation->setThresholdNeighbor(editorNode->custom4);
-
- inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph);
- inputSocket->relinkConnections(operation->getInputSocket(1), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket());
- addPreviewOperation(graph, context, operation->getOutputSocket(0));
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputImageSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+
+ converter.addPreview(operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.h b/source/blender/compositor/nodes/COM_DespeckleNode.h
index 2b8ab9d0226..64d99db7ded 100644
--- a/source/blender/compositor/nodes/COM_DespeckleNode.h
+++ b/source/blender/compositor/nodes/COM_DespeckleNode.h
@@ -30,7 +30,7 @@
class DespeckleNode : public Node {
public:
DespeckleNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp
index b5ad07be319..8870badab09 100644
--- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cpp
@@ -30,26 +30,28 @@ DifferenceMatteNode::DifferenceMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DifferenceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DifferenceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputSocket2 = this->getInputSocket(1);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputSocket2 = this->getInputSocket(1);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
bNode *editorNode = this->getbNode();
DifferenceMatteOperation *operationSet = new DifferenceMatteOperation();
operationSet->setSettings((NodeChroma *)editorNode->storage);
- inputSocket->relinkConnections(operationSet->getInputSocket(0), 0, graph);
- inputSocket2->relinkConnections(operationSet->getInputSocket(1), 1, graph);
-
- outputSocketMatte->relinkConnections(operationSet->getOutputSocket(0));
- graph->addOperation(operationSet);
+ converter.addOperation(operationSet);
+
+ converter.mapInputSocket(inputSocket, operationSet->getInputSocket(0));
+ converter.mapInputSocket(inputSocket2, operationSet->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketMatte, operationSet->getOutputSocket(0));
SetAlphaOperation *operation = new SetAlphaOperation();
- addLink(graph, operationSet->getInputSocket(0)->getConnection()->getFromSocket(), operation->getInputSocket(0));
- addLink(graph, operationSet->getOutputSocket(), operation->getInputSocket(1));
- outputSocketImage->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
- addPreviewOperation(graph, context, operation->getOutputSocket());
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.addLink(operationSet->getOutputSocket(), operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operation->getOutputSocket());
+
+ converter.addPreview(operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
index 0b571889571..e221d43180b 100644
--- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
@@ -32,7 +32,7 @@
class DifferenceMatteNode : public Node {
public:
DifferenceMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_DifferenceMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
index 0fb7ea7d264..933cb8365f9 100644
--- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
+++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp
@@ -30,85 +30,84 @@
DilateErodeNode::DilateErodeNode(bNode *editorNode) : Node(editorNode)
{
- /* pass */
+ /* initialize node data */
+ NodeBlurData *data = &m_alpha_blur;
+ memset(data, 0, sizeof(NodeBlurData));
+ data->filtertype = R_FILTER_GAUSS;
+
+ if (editorNode->custom2 > 0) {
+ data->sizex = data->sizey = editorNode->custom2;
+ }
+ else {
+ data->sizex = data->sizey = -editorNode->custom2;
+ }
}
-void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DilateErodeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_THRESH) {
DilateErodeThresholdOperation *operation = new DilateErodeThresholdOperation();
- operation->setbNode(editorNode);
operation->setDistance(editorNode->custom2);
operation->setInset(editorNode->custom3);
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
if (editorNode->custom3 < 2.0f) {
AntiAliasOperation *antiAlias = new AntiAliasOperation();
- addLink(graph, operation->getOutputSocket(), antiAlias->getInputSocket(0));
- this->getOutputSocket(0)->relinkConnections(antiAlias->getOutputSocket(0));
- graph->addOperation(antiAlias);
+ converter.addOperation(antiAlias);
+
+ converter.addLink(operation->getOutputSocket(), antiAlias->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), antiAlias->getOutputSocket(0));
}
else {
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
- graph->addOperation(operation);
}
else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) {
if (editorNode->custom2 > 0) {
DilateDistanceOperation *operation = new DilateDistanceOperation();
- operation->setbNode(editorNode);
operation->setDistance(editorNode->custom2);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
ErodeDistanceOperation *operation = new ErodeDistanceOperation();
- operation->setbNode(editorNode);
operation->setDistance(-editorNode->custom2);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
}
else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_FEATHER) {
/* this uses a modified gaussian blur function otherwise its far too slow */
- CompositorQuality quality = context->getQuality();
-
- /* initialize node data */
- NodeBlurData *data = &this->m_alpha_blur;
- memset(data, 0, sizeof(*data));
- data->filtertype = R_FILTER_GAUSS;
-
- if (editorNode->custom2 > 0) {
- data->sizex = data->sizey = editorNode->custom2;
- }
- else {
- data->sizex = data->sizey = -editorNode->custom2;
-
- }
+ CompositorQuality quality = context.getQuality();
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
- operationx->setbNode(editorNode);
- operationx->setData(data);
+ operationx->setData(&m_alpha_blur);
operationx->setQuality(quality);
operationx->setFalloff(PROP_SMOOTH);
- this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph);
- // this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); // no size input yet
- graph->addOperation(operationx);
+ converter.addOperation(operationx);
+
+ converter.mapInputSocket(getInputSocket(0), operationx->getInputSocket(0));
+ // converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1)); // no size input yet
+
GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
- operationy->setbNode(editorNode);
- operationy->setData(data);
+ operationy->setData(&m_alpha_blur);
operationy->setQuality(quality);
operationy->setFalloff(PROP_SMOOTH);
- this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
- graph->addOperation(operationy);
- addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
- // addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1)); // no size input yet
- addPreviewOperation(graph, context, operationy->getOutputSocket());
+ converter.addOperation(operationy);
+
+ converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
+ // converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1)); // no size input yet
+ converter.mapOutputSocket(getOutputSocket(0), operationy->getOutputSocket());
+
+ converter.addPreview(operationy->getOutputSocket());
/* TODO? */
/* see gaussian blue node for original usage */
@@ -133,19 +132,19 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont
else {
if (editorNode->custom2 > 0) {
DilateStepOperation *operation = new DilateStepOperation();
- operation->setbNode(editorNode);
operation->setIterations(editorNode->custom2);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
ErodeStepOperation *operation = new ErodeStepOperation();
- operation->setbNode(editorNode);
operation->setIterations(-editorNode->custom2);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
}
}
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h
index 4b02042ffc9..b69592f7fc1 100644
--- a/source/blender/compositor/nodes/COM_DilateErodeNode.h
+++ b/source/blender/compositor/nodes/COM_DilateErodeNode.h
@@ -33,7 +33,7 @@ class DilateErodeNode : public Node {
NodeBlurData m_alpha_blur; /* only used for blurring alpha, since the dilate/erode node doesnt have this */
public:
DilateErodeNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp
index eb30f6952ba..3d95a462117 100644
--- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp
@@ -30,14 +30,14 @@ DirectionalBlurNode::DirectionalBlurNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DirectionalBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DirectionalBlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeDBlurData *data = (NodeDBlurData *)this->getbNode()->storage;
DirectionalBlurOperation *operation = new DirectionalBlurOperation();
- operation->setQuality(context->getQuality());
+ operation->setQuality(context.getQuality());
operation->setData(data);
- operation->setbNode(this->getbNode());
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
index d387ecf81dc..8c806aa5437 100644
--- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
+++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
@@ -32,7 +32,7 @@
class DirectionalBlurNode : public Node {
public:
DirectionalBlurNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.cpp b/source/blender/compositor/nodes/COM_DisplaceNode.cpp
index 41fbfd61981..ffbb85882d5 100644
--- a/source/blender/compositor/nodes/COM_DisplaceNode.cpp
+++ b/source/blender/compositor/nodes/COM_DisplaceNode.cpp
@@ -29,19 +29,18 @@ DisplaceNode::DisplaceNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DisplaceNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DisplaceNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeOperation *operation;
- if (context->getQuality() == COM_QUALITY_LOW)
+ if (context.getQuality() == COM_QUALITY_LOW)
operation = new DisplaceSimpleOperation();
else
operation = new DisplaceOperation();
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
- this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h
index af6afc25366..6eb894077fc 100644
--- a/source/blender/compositor/nodes/COM_DisplaceNode.h
+++ b/source/blender/compositor/nodes/COM_DisplaceNode.h
@@ -31,6 +31,6 @@
class DisplaceNode : public Node {
public:
DisplaceNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp
index 3c532fe0b1d..704c704c500 100644
--- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp
@@ -31,55 +31,58 @@ DistanceMatteNode::DistanceMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DistanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void DistanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocketImage = this->getInputSocket(0);
- InputSocket *inputSocketKey = this->getInputSocket(1);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
-
- NodeOperation *operation;
bNode *editorsnode = getbNode();
NodeChroma *storage = (NodeChroma *)editorsnode->storage;
-
+
+ NodeInput *inputSocketImage = this->getInputSocket(0);
+ NodeInput *inputSocketKey = this->getInputSocket(1);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
+
+ SetAlphaOperation *operationAlpha = new SetAlphaOperation();
+ converter.addOperation(operationAlpha);
+
/* work in RGB color space */
+ NodeOperation *operation;
if (storage->channel == 1) {
- operation = new DistanceRGBMatteOperation();
- ((DistanceRGBMatteOperation *) operation)->setSettings(storage);
-
- inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputSocketKey->relinkConnections(operation->getInputSocket(1), 1, graph);
+ DistanceRGBMatteOperation *matte = new DistanceRGBMatteOperation();
+ matte->setSettings(storage);
+ converter.addOperation(matte);
+
+ converter.mapInputSocket(inputSocketImage, matte->getInputSocket(0));
+ converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0));
+
+ converter.mapInputSocket(inputSocketKey, matte->getInputSocket(1));
+
+ operation = matte;
}
/* work in YCbCr color space */
else {
- operation = new DistanceYCCMatteOperation();
- ((DistanceYCCMatteOperation *) operation)->setSettings(storage);
-
+ DistanceYCCMatteOperation *matte = new DistanceYCCMatteOperation();
+ matte->setSettings(storage);
+ converter.addOperation(matte);
+
ConvertRGBToYCCOperation *operationYCCImage = new ConvertRGBToYCCOperation();
- inputSocketImage->relinkConnections(operationYCCImage->getInputSocket(0), 0, graph);
- addLink(graph, operationYCCImage->getOutputSocket(), operation->getInputSocket(0));
- graph->addOperation(operationYCCImage);
-
ConvertRGBToYCCOperation *operationYCCMatte = new ConvertRGBToYCCOperation();
- inputSocketKey->relinkConnections(operationYCCMatte->getInputSocket(0), 1, graph);
- addLink(graph, operationYCCMatte->getOutputSocket(), operation->getInputSocket(1));
- graph->addOperation(operationYCCMatte);
- }
-
- if (outputSocketMatte->isConnected()) {
- outputSocketMatte->relinkConnections(operation->getOutputSocket());
- }
-
- graph->addOperation(operation);
-
- SetAlphaOperation *operationAlpha = new SetAlphaOperation();
- addLink(graph, operation->getInputSocket(0)->getConnection()->getFromSocket(), operationAlpha->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), operationAlpha->getInputSocket(1));
-
- graph->addOperation(operationAlpha);
- addPreviewOperation(graph, context, operationAlpha->getOutputSocket());
-
- if (outputSocketImage->isConnected()) {
- outputSocketImage->relinkConnections(operationAlpha->getOutputSocket());
+ converter.addOperation(operationYCCImage);
+ converter.addOperation(operationYCCMatte);
+
+ converter.mapInputSocket(inputSocketImage, operationYCCImage->getInputSocket(0));
+ converter.addLink(operationYCCImage->getOutputSocket(), matte->getInputSocket(0));
+ converter.addLink(operationYCCImage->getOutputSocket(), operationAlpha->getInputSocket(0));
+
+ converter.mapInputSocket(inputSocketKey, operationYCCMatte->getInputSocket(0));
+ converter.addLink(operationYCCMatte->getOutputSocket(), matte->getInputSocket(1));
+
+ operation = matte;
}
+
+ converter.addLink(operation->getOutputSocket(), operationAlpha->getInputSocket(1));
+
+ converter.mapOutputSocket(outputSocketMatte, operation->getOutputSocket());
+ converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket());
+
+ converter.addPreview(operationAlpha->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h
index 46ceae7c4f4..e7a514b79c4 100644
--- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h
@@ -31,7 +31,7 @@
class DistanceMatteNode : public Node {
public:
DistanceMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_DistanceMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp
index 40a9d1fa275..1f80eeadf83 100644
--- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp
+++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp
@@ -29,18 +29,17 @@ DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void DoubleEdgeMaskNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void DoubleEdgeMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
DoubleEdgeMaskOperation *operation;
bNode *bnode = this->getbNode();
operation = new DoubleEdgeMaskOperation();
- operation->setbNode(bnode);
operation->setAdjecentOnly(bnode->custom1);
operation->setKeepInside(bnode->custom2);
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- system->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
index ebcddc06b05..8e5f81e5ba5 100644
--- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
+++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
@@ -32,7 +32,7 @@
class DoubleEdgeMaskNode : public Node {
public:
DoubleEdgeMaskNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp
index fe0c85c173a..b0a45c4e2fc 100644
--- a/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp
+++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.cpp
@@ -32,48 +32,42 @@ EllipseMaskNode::EllipseMaskNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void EllipseMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void EllipseMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
EllipseMaskOperation *operation;
-
operation = new EllipseMaskOperation();
operation->setData((NodeEllipseMask *)this->getbNode()->storage);
-
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
- if (inputSocket->isConnected()) {
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket());
+ operation->setMaskType(this->getbNode()->custom1);
+ converter.addOperation(operation);
+
+ if (inputSocket->isLinked()) {
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
}
else {
/* Value operation to produce original transparent image */
SetValueOperation *valueOperation = new SetValueOperation();
valueOperation->setValue(0.0f);
- graph->addOperation(valueOperation);
+ converter.addOperation(valueOperation);
/* Scale that image up to render resolution */
- const RenderData *rd = context->getRenderData();
+ const RenderData *rd = context.getRenderData();
ScaleFixedSizeOperation *scaleOperation = new ScaleFixedSizeOperation();
-
scaleOperation->setIsAspect(false);
scaleOperation->setIsCrop(false);
scaleOperation->setOffset(0.0f, 0.0f);
-
scaleOperation->setNewWidth(rd->xsch * rd->size / 100.0f);
scaleOperation->setNewHeight(rd->ysch * rd->size / 100.0f);
+ scaleOperation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
+ converter.addOperation(scaleOperation);
- addLink(graph, valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
- addLink(graph, scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
- outputSocket->relinkConnections(operation->getOutputSocket(0));
-
- scaleOperation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true);
-
- graph->addOperation(scaleOperation);
+ converter.addLink(valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
+ converter.addLink(scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
-
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- operation->setMaskType(this->getbNode()->custom1);
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
}
diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h
index 3e534451b13..370f28f1ec2 100644
--- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h
+++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.h
@@ -32,7 +32,7 @@
class EllipseMaskNode : public Node {
public:
EllipseMaskNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_FilterNode.cpp b/source/blender/compositor/nodes/COM_FilterNode.cpp
index 3b75e3e0a1a..9f3a7ae795c 100644
--- a/source/blender/compositor/nodes/COM_FilterNode.cpp
+++ b/source/blender/compositor/nodes/COM_FilterNode.cpp
@@ -32,11 +32,11 @@ FilterNode::FilterNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void FilterNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputImageSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputImageSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
ConvolutionFilterOperation *operation = NULL;
switch (this->getbNode()->custom1) {
@@ -73,11 +73,11 @@ void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
operation->set3x3Filter(0, 0, 0, 0, 1, 0, 0, 0, 0);
break;
}
- operation->setbNode(this->getbNode());
- inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph);
- inputSocket->relinkConnections(operation->getInputSocket(1), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket());
- addPreviewOperation(graph, context, operation->getOutputSocket(0));
+ converter.addOperation(operation);
- graph->addOperation(operation);
+ converter.mapInputSocket(inputImageSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+
+ converter.addPreview(operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h
index 9be3bb02494..ef228c770de 100644
--- a/source/blender/compositor/nodes/COM_FilterNode.h
+++ b/source/blender/compositor/nodes/COM_FilterNode.h
@@ -32,7 +32,7 @@
class FilterNode : public Node {
public:
FilterNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_FILTERNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_FlipNode.cpp b/source/blender/compositor/nodes/COM_FlipNode.cpp
index a50297aae1a..1dbcc97143e 100644
--- a/source/blender/compositor/nodes/COM_FlipNode.cpp
+++ b/source/blender/compositor/nodes/COM_FlipNode.cpp
@@ -30,10 +30,10 @@ FlipNode::FlipNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void FlipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void FlipNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
FlipOperation *operation = new FlipOperation();
switch (this->getbNode()->custom1) {
case 0: /// @TODO: I didn't find any constants in the old implementation, should I introduce them.
@@ -50,7 +50,7 @@ void FlipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
break;
}
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h
index 1e372a80b57..3e7b2de4812 100644
--- a/source/blender/compositor/nodes/COM_FlipNode.h
+++ b/source/blender/compositor/nodes/COM_FlipNode.h
@@ -32,7 +32,7 @@
class FlipNode : public Node {
public:
FlipNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_GammaNode.cpp b/source/blender/compositor/nodes/COM_GammaNode.cpp
index 33a5cb282a1..046cd9e9a0d 100644
--- a/source/blender/compositor/nodes/COM_GammaNode.cpp
+++ b/source/blender/compositor/nodes/COM_GammaNode.cpp
@@ -29,12 +29,12 @@ GammaNode::GammaNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void GammaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void GammaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
GammaOperation *operation = new GammaOperation();
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h
index d4e1f0abd5a..858d21cad9e 100644
--- a/source/blender/compositor/nodes/COM_GammaNode.h
+++ b/source/blender/compositor/nodes/COM_GammaNode.h
@@ -32,7 +32,7 @@
class GammaNode : public Node {
public:
GammaNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp
index a6a83846623..0429a1a80cf 100644
--- a/source/blender/compositor/nodes/COM_GlareNode.cpp
+++ b/source/blender/compositor/nodes/COM_GlareNode.cpp
@@ -36,15 +36,13 @@ GlareNode::GlareNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) \
- {
+void GlareNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
+{
bNode *node = this->getbNode();
NodeGlare *glare = (NodeGlare *)node->storage;
GlareBaseOperation *glareoperation = NULL;
-
switch (glare->type) {
-
default:
case 3:
glareoperation = new GlareGhostOperation();
@@ -59,28 +57,30 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext *
glareoperation = new GlareSimpleStarOperation();
break;
}
+ BLI_assert(glareoperation);
+ glareoperation->setGlareSettings(glare);
+
GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation();
- SetValueOperation *mixvalueoperation = new SetValueOperation();
- MixGlareOperation *mixoperation = new MixGlareOperation();
- mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT);
- thresholdOperation->setbNode(node);
- glareoperation->setbNode(node);
-
- this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system);
- addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0));
- addLink(system, mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0));
- addLink(system, glareoperation->getOutputSocket(), mixoperation->getInputSocket(2));
- addLink(system, thresholdOperation->getInputSocket(0)->getConnection()->getFromSocket(), mixoperation->getInputSocket(1));
- this->getOutputSocket()->relinkConnections(mixoperation->getOutputSocket());
-
thresholdOperation->setGlareSettings(glare);
- glareoperation->setGlareSettings(glare);
+
+ SetValueOperation *mixvalueoperation = new SetValueOperation();
mixvalueoperation->setValue(0.5f + glare->mix * 0.5f);
+
+ MixGlareOperation *mixoperation = new MixGlareOperation();
mixoperation->setResolutionInputSocketIndex(1);
+ mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT);
+
+ converter.addOperation(glareoperation);
+ converter.addOperation(thresholdOperation);
+ converter.addOperation(mixvalueoperation);
+ converter.addOperation(mixoperation);
- system->addOperation(glareoperation);
- system->addOperation(thresholdOperation);
- system->addOperation(mixvalueoperation);
- system->addOperation(mixoperation);
+ converter.mapInputSocket(getInputSocket(0), thresholdOperation->getInputSocket(0));
+ converter.addLink(thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0));
- }
+ converter.addLink(mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(0), mixoperation->getInputSocket(1));
+ converter.addLink(glareoperation->getOutputSocket(), mixoperation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(), mixoperation->getOutputSocket());
+
+}
diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h
index beb01db733a..1e19cc5510e 100644
--- a/source/blender/compositor/nodes/COM_GlareNode.h
+++ b/source/blender/compositor/nodes/COM_GlareNode.h
@@ -32,7 +32,7 @@
class GlareNode : public Node {
public:
GlareNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp
deleted file mode 100644
index 7c0499dc04e..00000000000
--- a/source/blender/compositor/nodes/COM_GroupNode.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "BKE_node.h"
-
-#include "COM_GroupNode.h"
-#include "COM_SocketProxyNode.h"
-#include "COM_SetColorOperation.h"
-#include "COM_ExecutionSystemHelper.h"
-#include "COM_SetValueOperation.h"
-#include "COM_SetVectorOperation.h"
-#include "COM_SetColorOperation.h"
-
-extern "C" {
-#include "RNA_access.h"
-}
-
-GroupNode::GroupNode(bNode *editorNode) : Node(editorNode)
-{
- /* pass */
-}
-
-void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- if (this->getbNode()->id == NULL) {
- convertToOperations_invalid(graph, context);
- }
-}
-
-static int find_group_input(GroupNode *gnode, const char *identifier, InputSocket **r_sock)
-{
- int index;
- for (index = 0; index < gnode->getNumberOfInputSockets(); ++index) {
- InputSocket *sock = gnode->getInputSocket(index);
- if (STREQ(sock->getbNodeSocket()->identifier, identifier)) {
- *r_sock = sock;
- return index;
- }
- }
- *r_sock = NULL;
- return -1;
-}
-
-static int find_group_output(GroupNode *gnode, const char *identifier, OutputSocket **r_sock)
-{
- int index;
- for (index = 0; index < gnode->getNumberOfOutputSockets(); ++index) {
- OutputSocket *sock = gnode->getOutputSocket(index);
- if (STREQ(sock->getbNodeSocket()->identifier, identifier)) {
- *r_sock = sock;
- return index;
- }
- }
- *r_sock = NULL;
- return -1;
-}
-
-void GroupNode::ungroup(ExecutionSystem &system)
-{
- bNode *bnode = this->getbNode();
- bNodeTree *subtree = (bNodeTree *)bnode->id;
-
- /* get the node list size _before_ adding proxy nodes, so they are available for linking */
- int nodes_start = system.getNodes().size();
-
- /* missing node group datablock can happen with library linking */
- if (!subtree) {
- /* this error case its handled in convertToOperations() so we don't get un-convertred sockets */
- return;
- }
-
- const bool groupnodeBuffering = system.getContext().isGroupnodeBufferEnabled();
-
- bool has_output = false;
- /* create proxy nodes for group input/output nodes */
- for (bNode *bionode = (bNode *)subtree->nodes.first; bionode; bionode = bionode->next) {
- if (bionode->type == NODE_GROUP_INPUT) {
- for (bNodeSocket *bsock = (bNodeSocket *)bionode->outputs.first; bsock; bsock = bsock->next) {
- InputSocket *gsock;
- int gsock_index = find_group_input(this, bsock->identifier, &gsock);
- /* ignore virtual sockets */
- if (gsock) {
- SocketProxyNode *proxy = new SocketProxyNode(bionode, gsock->getbNodeSocket(), bsock, false);
- ExecutionSystemHelper::addNode(system.getNodes(), proxy);
-
- gsock->relinkConnectionsDuplicate(proxy->getInputSocket(0), gsock_index, &system);
- }
- }
- }
-
- if (bionode->type == NODE_GROUP_OUTPUT && (bionode->flag & NODE_DO_OUTPUT)) {
- has_output = true;
- for (bNodeSocket *bsock = (bNodeSocket *)bionode->inputs.first; bsock; bsock = bsock->next) {
- OutputSocket *gsock;
- find_group_output(this, bsock->identifier, &gsock);
- /* ignore virtual sockets */
- if (gsock) {
- SocketProxyNode *proxy = new SocketProxyNode(bionode, bsock, gsock->getbNodeSocket(), groupnodeBuffering);
- ExecutionSystemHelper::addNode(system.getNodes(), proxy);
-
- gsock->relinkConnections(proxy->getOutputSocket(0));
- }
- }
- }
- }
-
- /* in case no output node exists, add input value operations using defaults */
- if (!has_output) {
- for (int index = 0; index < getNumberOfOutputSockets(); ++index) {
- OutputSocket *output = getOutputSocket(index);
- addDefaultOutputOperation(system, output);
- }
- }
-
- /* unlink the group node itself, input links have been duplicated */
- for (int index = 0; index < this->getNumberOfInputSockets(); ++index) {
- InputSocket *sock = this->getInputSocket(index);
- sock->unlinkConnections(&system);
- }
- for (int index = 0; index < this->getNumberOfOutputSockets(); ++index) {
- OutputSocket *sock = this->getOutputSocket(index);
- sock->clearConnections();
- }
-
- ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, this->getInstanceKey());
-}
-
-bNodeSocket *GroupNode::findInterfaceInput(InputSocket *socket)
-{
- bNode *bnode = this->getbNode();
- bNodeTree *subtree = (bNodeTree *)bnode->id;
- if (!subtree)
- return NULL;
-
- const char *identifier = socket->getbNodeSocket()->identifier;
- for (bNodeSocket *iosock = (bNodeSocket *)subtree->inputs.first; iosock; iosock = iosock->next)
- if (STREQ(iosock->identifier, identifier))
- return iosock;
- return NULL;
-}
-
-bNodeSocket *GroupNode::findInterfaceOutput(OutputSocket *socket)
-{
- bNode *bnode = this->getbNode();
- bNodeTree *subtree = (bNodeTree *)bnode->id;
- if (!subtree)
- return NULL;
-
- const char *identifier = socket->getbNodeSocket()->identifier;
- for (bNodeSocket *iosock = (bNodeSocket *)subtree->outputs.first; iosock; iosock = iosock->next)
- if (STREQ(iosock->identifier, identifier))
- return iosock;
- return NULL;
-}
-
-void GroupNode::addDefaultOutputOperation(ExecutionSystem &system, OutputSocket *outputsocket)
-{
- bNodeSocket *iosock = findInterfaceOutput(outputsocket);
- if (!iosock)
- return;
-
- PointerRNA ptr;
- RNA_pointer_create(&getbNodeTree()->id, &RNA_NodeSocket, iosock, &ptr);
-
- NodeOperation *operation = NULL;
- switch (iosock->typeinfo->type) {
- case SOCK_FLOAT:
- {
- float value = RNA_float_get(&ptr, "default_value");
- SetValueOperation *value_op = new SetValueOperation();
- value_op->setValue(value);
- operation = value_op;
- break;
- }
- case SOCK_VECTOR:
- {
- float vector[3];
- RNA_float_get_array(&ptr, "default_value", vector);
- SetVectorOperation *vector_op = new SetVectorOperation();
- vector_op->setVector(vector);
- operation = vector_op;
- break;
- }
- case SOCK_RGBA:
- {
- float color[4];
- RNA_float_get_array(&ptr, "default_value", color);
- SetColorOperation *color_op = new SetColorOperation();
- color_op->setChannels(color);
- operation = color_op;
- break;
- }
- }
-
- outputsocket->relinkConnections(operation->getOutputSocket());
- system.addOperation(operation);
-}
diff --git a/source/blender/compositor/nodes/COM_GroupNode.h b/source/blender/compositor/nodes/COM_GroupNode.h
deleted file mode 100644
index 02b63fe27e3..00000000000
--- a/source/blender/compositor/nodes/COM_GroupNode.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_GroupNode_h_
-#define _COM_GroupNode_h_
-
-#include "COM_Node.h"
-#include "COM_ExecutionSystem.h"
-
-/**
- * @brief Represents a group node
- * @ingroup Node
- */
-class GroupNode : public Node {
-public:
- GroupNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-
- /**
- * @brief check if this node a group node.
- * @returns true
- */
- bool isGroupNode() const { return true; }
-
- /**
- * @brief ungroup this group node.
- * during ungroup the subtree (internal nodes and links) of the group node
- * are added to the ExecutionSystem.
- *
- * Between the main tree and the subtree proxy nodes will be added
- * to translate between InputSocket and OutputSocket
- *
- * @param system the ExecutionSystem where to add the subtree
- */
- void ungroup(ExecutionSystem &system);
-
- bNodeSocket *findInterfaceInput(InputSocket *socket);
- bNodeSocket *findInterfaceOutput(OutputSocket *socket);
- void addDefaultOutputOperation(ExecutionSystem &system, OutputSocket *outputsocket);
-};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp
index 66b98b29d5e..003bc91edd3 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cpp
@@ -36,33 +36,33 @@ HueSaturationValueCorrectNode::HueSaturationValueCorrectNode(bNode *editorNode)
/* pass */
}
-void HueSaturationValueCorrectNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void HueSaturationValueCorrectNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *valueSocket = this->getInputSocket(0);
- InputSocket *colorSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *valueSocket = this->getInputSocket(0);
+ NodeInput *colorSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
bNode *editorsnode = getbNode();
CurveMapping *storage = (CurveMapping *)editorsnode->storage;
ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation();
+ converter.addOperation(rgbToHSV);
+
ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation();
+ converter.addOperation(hsvToRGB);
+
HueSaturationValueCorrectOperation *changeHSV = new HueSaturationValueCorrectOperation();
- MixBlendOperation *blend = new MixBlendOperation();
-
- colorSocket->relinkConnections(rgbToHSV->getInputSocket(0), 1, graph);
- addLink(graph, rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0));
- addLink(graph, changeHSV->getOutputSocket(), hsvToRGB->getInputSocket(0));
- addLink(graph, hsvToRGB->getOutputSocket(), blend->getInputSocket(2));
- addLink(graph, rgbToHSV->getInputSocket(0)->getConnection()->getFromSocket(), blend->getInputSocket(1));
- valueSocket->relinkConnections(blend->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(blend->getOutputSocket());
-
changeHSV->setCurveMapping(storage);
-
+ converter.addOperation(changeHSV);
+
+ MixBlendOperation *blend = new MixBlendOperation();
blend->setResolutionInputSocketIndex(1);
+ converter.addOperation(blend);
- graph->addOperation(rgbToHSV);
- graph->addOperation(hsvToRGB);
- graph->addOperation(changeHSV);
- graph->addOperation(blend);
+ converter.mapInputSocket(colorSocket, rgbToHSV->getInputSocket(0));
+ converter.addLink(rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0));
+ converter.addLink(changeHSV->getOutputSocket(), hsvToRGB->getInputSocket(0));
+ converter.addLink(hsvToRGB->getOutputSocket(), blend->getInputSocket(2));
+ converter.mapInputSocket(colorSocket, blend->getInputSocket(1));
+ converter.mapInputSocket(valueSocket, blend->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, blend->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
index dd5f70f6579..099ea3d11ce 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
@@ -32,6 +32,6 @@
class HueSaturationValueCorrectNode : public Node {
public:
HueSaturationValueCorrectNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp
index 5001433513c..cdec1250c6e 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp
@@ -35,35 +35,35 @@ HueSaturationValueNode::HueSaturationValueNode(bNode *editorNode) : Node(editorN
/* pass */
}
-void HueSaturationValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void HueSaturationValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *valueSocket = this->getInputSocket(0);
- InputSocket *colorSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *valueSocket = this->getInputSocket(0);
+ NodeInput *colorSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
bNode *editorsnode = getbNode();
NodeHueSat *storage = (NodeHueSat *)editorsnode->storage;
ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation();
+ converter.addOperation(rgbToHSV);
+
ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation();
+ converter.addOperation(hsvToRGB);
+
ChangeHSVOperation *changeHSV = new ChangeHSVOperation();
- MixBlendOperation *blend = new MixBlendOperation();
-
- colorSocket->relinkConnections(rgbToHSV->getInputSocket(0), 1, graph);
- addLink(graph, rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0));
- addLink(graph, changeHSV->getOutputSocket(), hsvToRGB->getInputSocket(0));
- addLink(graph, hsvToRGB->getOutputSocket(), blend->getInputSocket(2));
- addLink(graph, rgbToHSV->getInputSocket(0)->getConnection()->getFromSocket(), blend->getInputSocket(1));
- valueSocket->relinkConnections(blend->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(blend->getOutputSocket());
-
changeHSV->setHue(storage->hue);
changeHSV->setSaturation(storage->sat);
changeHSV->setValue(storage->val);
-
+ converter.addOperation(changeHSV);
+
+ MixBlendOperation *blend = new MixBlendOperation();
blend->setResolutionInputSocketIndex(1);
+ converter.addOperation(blend);
- graph->addOperation(rgbToHSV);
- graph->addOperation(hsvToRGB);
- graph->addOperation(changeHSV);
- graph->addOperation(blend);
+ converter.mapInputSocket(colorSocket, rgbToHSV->getInputSocket(0));
+ converter.addLink(rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0));
+ converter.addLink(changeHSV->getOutputSocket(), hsvToRGB->getInputSocket(0));
+ converter.addLink(hsvToRGB->getOutputSocket(), blend->getInputSocket(2));
+ converter.mapInputSocket(colorSocket, blend->getInputSocket(1));
+ converter.mapInputSocket(valueSocket, blend->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, blend->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
index 47b89a35269..a599781a3b1 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
@@ -32,6 +32,6 @@
class HueSaturationValueNode : public Node {
public:
HueSaturationValueNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cpp b/source/blender/compositor/nodes/COM_IDMaskNode.cpp
index 12a508c75f5..2c16616dc59 100644
--- a/source/blender/compositor/nodes/COM_IDMaskNode.cpp
+++ b/source/blender/compositor/nodes/COM_IDMaskNode.cpp
@@ -29,23 +29,24 @@ IDMaskNode::IDMaskNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
-void IDMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void IDMaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *bnode = this->getbNode();
+
IDMaskOperation *operation;
operation = new IDMaskOperation();
operation->setObjectIndex(bnode->custom1);
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- if (bnode->custom2 == 0 || context->getRenderData()->scemode & R_FULL_SAMPLE) {
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ if (bnode->custom2 == 0 || context.getRenderData()->scemode & R_FULL_SAMPLE) {
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
AntiAliasOperation *antiAliasOperation = new AntiAliasOperation();
- addLink(graph, operation->getOutputSocket(), antiAliasOperation->getInputSocket(0));
- this->getOutputSocket(0)->relinkConnections(antiAliasOperation->getOutputSocket(0));
- graph->addOperation(antiAliasOperation);
+ converter.addOperation(antiAliasOperation);
+
+ converter.addLink(operation->getOutputSocket(), antiAliasOperation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), antiAliasOperation->getOutputSocket(0));
}
- graph->addOperation(operation);
-
}
diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h
index 9fd52be2120..a549a3e6ef8 100644
--- a/source/blender/compositor/nodes/COM_IDMaskNode.h
+++ b/source/blender/compositor/nodes/COM_IDMaskNode.h
@@ -32,7 +32,7 @@
class IDMaskNode : public Node {
public:
IDMaskNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 5571a186333..e105f530eb2 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -38,9 +38,10 @@ ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int passindex, DataType datatype)
+NodeOperation *ImageNode::doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user,
+ int framenumber, int outputsocketIndex, int passindex, DataType datatype) const
{
- OutputSocket *outputSocket = this->getOutputSocket(outputsocketIndex);
+ NodeOutput *outputSocket = this->getOutputSocket(outputsocketIndex);
MultilayerBaseOperation *operation = NULL;
switch (datatype) {
case COM_DT_VALUE:
@@ -59,22 +60,24 @@ NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer
operation->setRenderLayer(rl);
operation->setImageUser(user);
operation->setFramenumber(framenumber);
- outputSocket->relinkConnections(operation->getOutputSocket());
- system->addOperation(operation);
+
+ converter.addOperation(operation);
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+
return operation;
}
-void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ImageNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
/// Image output
- OutputSocket *outputImage = this->getOutputSocket(0);
+ NodeOutput *outputImage = this->getOutputSocket(0);
bNode *editorNode = this->getbNode();
Image *image = (Image *)editorNode->id;
ImageUser *imageuser = (ImageUser *)editorNode->storage;
- int framenumber = context->getFramenumber();
+ int framenumber = context.getFramenumber();
int numberOfOutputs = this->getNumberOfOutputSockets();
bool outputStraightAlpha = (editorNode->custom1 & CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT) != 0;
- BKE_image_user_frame_calc(imageuser, context->getFramenumber(), 0);
+ BKE_image_user_frame_calc(imageuser, context.getFramenumber(), 0);
/* force a load, we assume iuser index will be set OK anyway */
if (image && image->type == IMA_TYPE_MULTILAYER) {
@@ -83,7 +86,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
if (image->rr) {
RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer);
if (rl) {
- OutputSocket *socket;
+ NodeOutput *socket;
int index;
is_multilayer_ok = true;
@@ -91,50 +94,47 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
for (index = 0; index < numberOfOutputs; index++) {
NodeOperation *operation = NULL;
socket = this->getOutputSocket(index);
- if (socket->isConnected() || index == 0) {
- bNodeSocket *bnodeSocket = socket->getbNodeSocket();
- /* Passes in the file can differ from passes stored in sockets (#36755).
- * Look up the correct file pass using the socket identifier instead.
- */
+ bNodeSocket *bnodeSocket = socket->getbNodeSocket();
+ /* Passes in the file can differ from passes stored in sockets (#36755).
+ * Look up the correct file pass using the socket identifier instead.
+ */
#if 0
- NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;*/
- int passindex = storage->pass_index;*/
- RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
+ NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;*/
+ int passindex = storage->pass_index;*/
+ RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
#endif
- int passindex;
- RenderPass *rpass;
- for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
- if (STREQ(rpass->name, bnodeSocket->identifier))
+ int passindex;
+ RenderPass *rpass;
+ for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
+ if (STREQ(rpass->name, bnodeSocket->identifier))
+ break;
+ if (rpass) {
+ imageuser->pass = passindex;
+ switch (rpass->channels) {
+ case 1:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
break;
- if (rpass) {
- imageuser->pass = passindex;
- switch (rpass->channels) {
- case 1:
- operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
- break;
/* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */
/* XXX any way to detect actual vector images? */
- case 3:
- operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
- break;
- case 4:
- operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
- break;
- default:
- /* dummy operation is added below */
- break;
- }
-
- if (index == 0 && operation) {
- addPreviewOperation(graph, context, operation->getOutputSocket());
- }
+ case 3:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
+ break;
+ case 4:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
+ break;
+ default:
+ /* dummy operation is added below */
+ break;
+ }
+
+ if (index == 0 && operation) {
+ converter.addPreview(operation->getOutputSocket());
}
}
-
+
/* incase we can't load the layer */
- if (operation == NULL) {
- convertToOperations_invalid_index(graph, index);
- }
+ if (operation == NULL)
+ converter.setInvalidOutput(getOutputSocket(index));
}
}
}
@@ -142,66 +142,56 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
/* without this, multilayer that fail to load will crash blender [#32490] */
if (is_multilayer_ok == false) {
- int index;
- vector<OutputSocket *> &outputsockets = this->getOutputSockets();
- for (index = 0; index < outputsockets.size(); index++) {
- const float warning_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- SetColorOperation *operation = new SetColorOperation();
- operation->setChannels(warning_color);
-
- /* link the operation */
- this->getOutputSocket(index)->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
- }
+ for (int i = 0; i < getNumberOfOutputSockets(); ++i)
+ converter.setInvalidOutput(getOutputSocket(i));
}
}
else {
if (numberOfOutputs > 0) {
ImageOperation *operation = new ImageOperation();
- if (outputImage->isConnected()) {
- if (outputStraightAlpha) {
- NodeOperation *alphaConvertOperation = new ConvertPremulToStraightOperation();
- addLink(graph, operation->getOutputSocket(0), alphaConvertOperation->getInputSocket(0));
- outputImage->relinkConnections(alphaConvertOperation->getOutputSocket());
- graph->addOperation(alphaConvertOperation);
- }
- else {
- outputImage->relinkConnections(operation->getOutputSocket());
- }
- }
operation->setImage(image);
operation->setImageUser(imageuser);
operation->setFramenumber(framenumber);
- graph->addOperation(operation);
- addPreviewOperation(graph, context, operation->getOutputSocket());
+ converter.addOperation(operation);
+
+ if (outputStraightAlpha) {
+ NodeOperation *alphaConvertOperation = new ConvertPremulToStraightOperation();
+
+ converter.addOperation(alphaConvertOperation);
+ converter.mapOutputSocket(outputImage, alphaConvertOperation->getOutputSocket());
+ converter.addLink(operation->getOutputSocket(0), alphaConvertOperation->getInputSocket(0));
+ }
+ else {
+ converter.mapOutputSocket(outputImage, operation->getOutputSocket());
+ }
+
+ converter.addPreview(operation->getOutputSocket());
}
if (numberOfOutputs > 1) {
- OutputSocket *alphaImage = this->getOutputSocket(1);
- if (alphaImage->isConnected()) {
- ImageAlphaOperation *alphaOperation = new ImageAlphaOperation();
- alphaOperation->setImage(image);
- alphaOperation->setImageUser(imageuser);
- alphaOperation->setFramenumber(framenumber);
- alphaImage->relinkConnections(alphaOperation->getOutputSocket());
- graph->addOperation(alphaOperation);
- }
+ NodeOutput *alphaImage = this->getOutputSocket(1);
+ ImageAlphaOperation *alphaOperation = new ImageAlphaOperation();
+ alphaOperation->setImage(image);
+ alphaOperation->setImageUser(imageuser);
+ alphaOperation->setFramenumber(framenumber);
+ converter.addOperation(alphaOperation);
+
+ converter.mapOutputSocket(alphaImage, alphaOperation->getOutputSocket());
}
if (numberOfOutputs > 2) {
- OutputSocket *depthImage = this->getOutputSocket(2);
- if (depthImage->isConnected()) {
- ImageDepthOperation *depthOperation = new ImageDepthOperation();
- depthOperation->setImage(image);
- depthOperation->setImageUser(imageuser);
- depthOperation->setFramenumber(framenumber);
- depthImage->relinkConnections(depthOperation->getOutputSocket());
- graph->addOperation(depthOperation);
- }
+ NodeOutput *depthImage = this->getOutputSocket(2);
+ ImageDepthOperation *depthOperation = new ImageDepthOperation();
+ depthOperation->setImage(image);
+ depthOperation->setImageUser(imageuser);
+ depthOperation->setFramenumber(framenumber);
+ converter.addOperation(depthOperation);
+
+ converter.mapOutputSocket(depthImage, depthOperation->getOutputSocket());
}
if (numberOfOutputs > 3) {
/* happens when unlinking image datablock from multilayer node */
for (int i = 3; i < numberOfOutputs; i++) {
- OutputSocket *output = this->getOutputSocket(i);
+ NodeOutput *output = this->getOutputSocket(i);
NodeOperation *operation = NULL;
switch (output->getDataType()) {
case COM_DT_VALUE:
@@ -233,8 +223,8 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
}
if (operation) {
- output->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+ converter.addOperation(operation);
+ converter.mapOutputSocket(output, operation->getOutputSocket());
}
}
}
diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h
index c8d53b405a0..1daa39a2a1f 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.h
+++ b/source/blender/compositor/nodes/COM_ImageNode.h
@@ -35,9 +35,10 @@ extern "C" {
*/
class ImageNode : public Node {
private:
- NodeOperation *doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int passindex, DataType datatype);
+ NodeOperation *doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user,
+ int framenumber, int outputsocketIndex, int passindex, DataType datatype) const;
public:
ImageNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_InpaintNode.cpp b/source/blender/compositor/nodes/COM_InpaintNode.cpp
index e90a3921edc..1371cdb5f1d 100644
--- a/source/blender/compositor/nodes/COM_InpaintNode.cpp
+++ b/source/blender/compositor/nodes/COM_InpaintNode.cpp
@@ -31,7 +31,7 @@ InpaintNode::InpaintNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void InpaintNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void InpaintNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
@@ -39,10 +39,10 @@ void InpaintNode::convertToOperations(ExecutionSystem *graph, CompositorContext
/* if (editorNode->custom1 == CMP_NODE_INPAINT_SIMPLE) { */
if (true) {
InpaintSimpleOperation *operation = new InpaintSimpleOperation();
- operation->setbNode(editorNode);
operation->setIterations(editorNode->custom2);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
}
diff --git a/source/blender/compositor/nodes/COM_InpaintNode.h b/source/blender/compositor/nodes/COM_InpaintNode.h
index 5837b979958..c5ef1c0549e 100644
--- a/source/blender/compositor/nodes/COM_InpaintNode.h
+++ b/source/blender/compositor/nodes/COM_InpaintNode.h
@@ -32,7 +32,7 @@
class InpaintNode : public Node {
public:
InpaintNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_InvertNode.cpp b/source/blender/compositor/nodes/COM_InvertNode.cpp
index 9c4e28a2971..ed4a21132ca 100644
--- a/source/blender/compositor/nodes/COM_InvertNode.cpp
+++ b/source/blender/compositor/nodes/COM_InvertNode.cpp
@@ -30,15 +30,15 @@ InvertNode::InvertNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void InvertNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void InvertNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
InvertOperation *operation = new InvertOperation();
bNode *node = this->getbNode();
operation->setColor(node->custom1 & CMP_CHAN_RGB);
operation->setAlpha(node->custom1 & CMP_CHAN_A);
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h
index d061f1c12bd..27f3da6cdca 100644
--- a/source/blender/compositor/nodes/COM_InvertNode.h
+++ b/source/blender/compositor/nodes/COM_InvertNode.h
@@ -32,7 +32,7 @@
class InvertNode : public Node {
public:
InvertNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp
index 786530bd3c4..e896b7144e5 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.cpp
+++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp
@@ -47,83 +47,74 @@ KeyingNode::KeyingNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage)
+NodeOperationOutput *KeyingNode::setupPreBlur(NodeConverter &converter, NodeInput *inputImage, int size) const
{
ConvertRGBToYCCOperation *convertRGBToYCCOperation = new ConvertRGBToYCCOperation();
convertRGBToYCCOperation->setMode(0); /* ITU 601 */
-
- inputImage->relinkConnections(convertRGBToYCCOperation->getInputSocket(0), 0, graph);
- graph->addOperation(convertRGBToYCCOperation);
-
+ converter.addOperation(convertRGBToYCCOperation);
+
+ converter.mapInputSocket(inputImage, convertRGBToYCCOperation->getInputSocket(0));
+
CombineChannelsOperation *combineOperation = new CombineChannelsOperation();
- graph->addOperation(combineOperation);
+ converter.addOperation(combineOperation);
for (int channel = 0; channel < 4; channel++) {
SeparateChannelOperation *separateOperation = new SeparateChannelOperation();
separateOperation->setChannel(channel);
- addLink(graph, convertRGBToYCCOperation->getOutputSocket(0), separateOperation->getInputSocket(0));
- graph->addOperation(separateOperation);
-
+ converter.addOperation(separateOperation);
+
+ converter.addLink(convertRGBToYCCOperation->getOutputSocket(0), separateOperation->getInputSocket(0));
+
if (channel == 0 || channel == 3) {
- addLink(graph, separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
+ converter.addLink(separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
}
else {
KeyingBlurOperation *blurXOperation = new KeyingBlurOperation();
- KeyingBlurOperation *blurYOperation = new KeyingBlurOperation();
-
blurXOperation->setSize(size);
blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X);
- blurXOperation->setbNode(this->getbNode());
-
+ converter.addOperation(blurXOperation);
+
+ KeyingBlurOperation *blurYOperation = new KeyingBlurOperation();
blurYOperation->setSize(size);
blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y);
- blurYOperation->setbNode(this->getbNode());
-
- addLink(graph, separateOperation->getOutputSocket(), blurXOperation->getInputSocket(0));
- addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0));
- addLink(graph, blurYOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
-
- graph->addOperation(blurXOperation);
- graph->addOperation(blurYOperation);
+ converter.addOperation(blurYOperation);
+
+ converter.addLink(separateOperation->getOutputSocket(), blurXOperation->getInputSocket(0));
+ converter.addLink(blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0));
+ converter.addLink(blurYOperation->getOutputSocket(0), combineOperation->getInputSocket(channel));
}
}
-
+
ConvertYCCToRGBOperation *convertYCCToRGBOperation = new ConvertYCCToRGBOperation();
convertYCCToRGBOperation->setMode(0); /* ITU 601 */
- addLink(graph, combineOperation->getOutputSocket(0), convertYCCToRGBOperation->getInputSocket(0));
- graph->addOperation(convertYCCToRGBOperation);
-
- *originalImage = convertRGBToYCCOperation->getInputSocket(0)->getConnection()->getFromSocket();
-
+ converter.addOperation(convertYCCToRGBOperation);
+
+ converter.addLink(combineOperation->getOutputSocket(0), convertYCCToRGBOperation->getInputSocket(0));
+
return convertYCCToRGBOperation->getOutputSocket(0);
}
-OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *postBlurInput, int size)
+NodeOperationOutput *KeyingNode::setupPostBlur(NodeConverter &converter, NodeOperationOutput *postBlurInput, int size) const
{
KeyingBlurOperation *blurXOperation = new KeyingBlurOperation();
- KeyingBlurOperation *blurYOperation = new KeyingBlurOperation();
-
blurXOperation->setSize(size);
blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X);
- blurXOperation->setbNode(this->getbNode());
-
+ converter.addOperation(blurXOperation);
+
+ KeyingBlurOperation *blurYOperation = new KeyingBlurOperation();
blurYOperation->setSize(size);
blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y);
- blurYOperation->setbNode(this->getbNode());
-
- addLink(graph, postBlurInput, blurXOperation->getInputSocket(0));
- addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0));
-
- graph->addOperation(blurXOperation);
- graph->addOperation(blurYOperation);
-
+ converter.addOperation(blurYOperation);
+
+ converter.addLink(postBlurInput, blurXOperation->getInputSocket(0));
+ converter.addLink(blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0));
+
return blurYOperation->getOutputSocket();
}
-OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance)
+NodeOperationOutput *KeyingNode::setupDilateErode(NodeConverter &converter, NodeOperationOutput *dilateErodeInput, int distance) const
{
DilateDistanceOperation *dilateErodeOperation;
-
if (distance > 0) {
dilateErodeOperation = new DilateDistanceOperation();
dilateErodeOperation->setDistance(distance);
@@ -132,211 +123,194 @@ OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket
dilateErodeOperation = new ErodeDistanceOperation();
dilateErodeOperation->setDistance(-distance);
}
- dilateErodeOperation->setbNode(this->getbNode());
-
- addLink(graph, dilateErodeInput, dilateErodeOperation->getInputSocket(0));
-
- graph->addOperation(dilateErodeOperation);
-
+ converter.addOperation(dilateErodeOperation);
+
+ converter.addLink(dilateErodeInput, dilateErodeOperation->getInputSocket(0));
+
return dilateErodeOperation->getOutputSocket(0);
}
-OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext *context,
- OutputSocket *featherInput, int falloff, int distance)
+NodeOperationOutput *KeyingNode::setupFeather(NodeConverter &converter, const CompositorContext &context,
+ NodeOperationOutput *featherInput, int falloff, int distance) const
{
/* this uses a modified gaussian blur function otherwise its far too slow */
- CompositorQuality quality = context->getQuality();
+ CompositorQuality quality = context.getQuality();
/* initialize node data */
- NodeBlurData *data = &this->m_alpha_blur;
- memset(data, 0, sizeof(*data));
- data->filtertype = R_FILTER_GAUSS;
-
+ NodeBlurData data;
+ memset(&data, 0, sizeof(NodeBlurData));
+ data.filtertype = R_FILTER_GAUSS;
if (distance > 0) {
- data->sizex = data->sizey = distance;
+ data.sizex = data.sizey = distance;
}
else {
- data->sizex = data->sizey = -distance;
+ data.sizex = data.sizey = -distance;
}
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
- operationx->setData(data);
+ operationx->setData(&data);
operationx->setQuality(quality);
operationx->setSize(1.0f);
operationx->setSubtract(distance < 0);
operationx->setFalloff(falloff);
- operationx->setbNode(this->getbNode());
- graph->addOperation(operationx);
+ converter.addOperation(operationx);
GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
- operationy->setData(data);
+ operationy->setData(&data);
operationy->setQuality(quality);
operationy->setSize(1.0f);
operationy->setSubtract(distance < 0);
operationy->setFalloff(falloff);
- operationy->setbNode(this->getbNode());
- graph->addOperation(operationy);
+ converter.addOperation(operationy);
- addLink(graph, featherInput, operationx->getInputSocket(0));
- addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
+ converter.addLink(featherInput, operationx->getInputSocket(0));
+ converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
return operationy->getOutputSocket();
}
-OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputScreen,
- float factor, float colorBalance)
+NodeOperationOutput *KeyingNode::setupDespill(NodeConverter &converter, NodeOperationOutput *despillInput, NodeInput *inputScreen,
+ float factor, float colorBalance) const
{
KeyingDespillOperation *despillOperation = new KeyingDespillOperation();
-
despillOperation->setDespillFactor(factor);
despillOperation->setColorBalance(colorBalance);
-
- addLink(graph, despillInput, despillOperation->getInputSocket(0));
- addLink(graph, inputScreen, despillOperation->getInputSocket(1));
-
- graph->addOperation(despillOperation);
-
+ converter.addOperation(despillOperation);
+
+ converter.addLink(despillInput, despillOperation->getInputSocket(0));
+ converter.mapInputSocket(inputScreen, despillOperation->getInputSocket(1));
+
return despillOperation->getOutputSocket(0);
}
-OutputSocket *KeyingNode::setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance,
- float clipBlack, float clipWhite, bool edgeMatte)
+NodeOperationOutput *KeyingNode::setupClip(NodeConverter &converter, NodeOperationOutput *clipInput, int kernelRadius, float kernelTolerance,
+ float clipBlack, float clipWhite, bool edgeMatte) const
{
KeyingClipOperation *clipOperation = new KeyingClipOperation();
-
clipOperation->setKernelRadius(kernelRadius);
clipOperation->setKernelTolerance(kernelTolerance);
-
clipOperation->setClipBlack(clipBlack);
clipOperation->setClipWhite(clipWhite);
clipOperation->setIsEdgeMatte(edgeMatte);
-
- addLink(graph, clipInput, clipOperation->getInputSocket(0));
-
- graph->addOperation(clipOperation);
-
+ converter.addOperation(clipOperation);
+
+ converter.addLink(clipInput, clipOperation->getInputSocket(0));
+
return clipOperation->getOutputSocket(0);
}
-void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void KeyingNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputImage = this->getInputSocket(0);
- InputSocket *inputScreen = this->getInputSocket(1);
- InputSocket *inputGarbageMatte = this->getInputSocket(2);
- InputSocket *inputCoreMatte = this->getInputSocket(3);
- OutputSocket *outputImage = this->getOutputSocket(0);
- OutputSocket *outputMatte = this->getOutputSocket(1);
- OutputSocket *outputEdges = this->getOutputSocket(2);
- OutputSocket *postprocessedMatte = NULL, *postprocessedImage = NULL, *originalImage = NULL, *edgesMatte = NULL;
-
bNode *editorNode = this->getbNode();
NodeKeyingData *keying_data = (NodeKeyingData *) editorNode->storage;
-
+
+ NodeInput *inputImage = this->getInputSocket(0);
+ NodeInput *inputScreen = this->getInputSocket(1);
+ NodeInput *inputGarbageMatte = this->getInputSocket(2);
+ NodeInput *inputCoreMatte = this->getInputSocket(3);
+ NodeOutput *outputImage = this->getOutputSocket(0);
+ NodeOutput *outputMatte = this->getOutputSocket(1);
+ NodeOutput *outputEdges = this->getOutputSocket(2);
+ NodeOperationOutput *postprocessedMatte = NULL, *postprocessedImage = NULL, *edgesMatte = NULL;
+
/* keying operation */
KeyingOperation *keyingOperation = new KeyingOperation();
-
keyingOperation->setScreenBalance(keying_data->screen_balance);
-
- inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph);
-
+ converter.addOperation(keyingOperation);
+
+ converter.mapInputSocket(inputScreen, keyingOperation->getInputSocket(1));
+
if (keying_data->blur_pre) {
/* chroma preblur operation for input of keying operation */
- OutputSocket *preBluredImage = setupPreBlur(graph, inputImage, keying_data->blur_pre, &originalImage);
- addLink(graph, preBluredImage, keyingOperation->getInputSocket(0));
+ NodeOperationOutput *preBluredImage = setupPreBlur(converter, inputImage, keying_data->blur_pre);
+ converter.addLink(preBluredImage, keyingOperation->getInputSocket(0));
}
else {
- inputImage->relinkConnections(keyingOperation->getInputSocket(0), 0, graph);
- originalImage = keyingOperation->getInputSocket(0)->getConnection()->getFromSocket();
+ converter.mapInputSocket(inputImage, keyingOperation->getInputSocket(0));
}
-
- graph->addOperation(keyingOperation);
-
+
postprocessedMatte = keyingOperation->getOutputSocket();
-
+
/* black / white clipping */
if (keying_data->clip_black > 0.0f || keying_data->clip_white < 1.0f) {
- postprocessedMatte = setupClip(graph, postprocessedMatte,
+ postprocessedMatte = setupClip(converter, postprocessedMatte,
keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
keying_data->clip_black, keying_data->clip_white, false);
}
-
+
/* output edge matte */
- if (outputEdges->isConnected()) {
- edgesMatte = setupClip(graph, postprocessedMatte,
- keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
- keying_data->clip_black, keying_data->clip_white, true);
- }
-
+ edgesMatte = setupClip(converter, postprocessedMatte,
+ keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
+ keying_data->clip_black, keying_data->clip_white, true);
+
/* apply garbage matte */
- if (inputGarbageMatte->isConnected()) {
+ if (inputGarbageMatte->isLinked()) {
SetValueOperation *valueOperation = new SetValueOperation();
+ valueOperation->setValue(1.0f);
+ converter.addOperation(valueOperation);
+
MathSubtractOperation *subtractOperation = new MathSubtractOperation();
+ converter.addOperation(subtractOperation);
+
MathMinimumOperation *minOperation = new MathMinimumOperation();
-
- valueOperation->setValue(1.0f);
-
- addLink(graph, valueOperation->getOutputSocket(), subtractOperation->getInputSocket(0));
- inputGarbageMatte->relinkConnections(subtractOperation->getInputSocket(1), 0, graph);
-
- addLink(graph, subtractOperation->getOutputSocket(), minOperation->getInputSocket(0));
- addLink(graph, postprocessedMatte, minOperation->getInputSocket(1));
-
+ converter.addOperation(minOperation);
+
+ converter.addLink(valueOperation->getOutputSocket(), subtractOperation->getInputSocket(0));
+ converter.mapInputSocket(inputGarbageMatte, subtractOperation->getInputSocket(1));
+
+ converter.addLink(subtractOperation->getOutputSocket(), minOperation->getInputSocket(0));
+ converter.addLink(postprocessedMatte, minOperation->getInputSocket(1));
+
postprocessedMatte = minOperation->getOutputSocket();
-
- graph->addOperation(valueOperation);
- graph->addOperation(subtractOperation);
- graph->addOperation(minOperation);
}
-
+
/* apply core matte */
- if (inputCoreMatte->isConnected()) {
+ if (inputCoreMatte->isLinked()) {
MathMaximumOperation *maxOperation = new MathMaximumOperation();
-
- inputCoreMatte->relinkConnections(maxOperation->getInputSocket(0), 0, graph);
-
- addLink(graph, postprocessedMatte, maxOperation->getInputSocket(1));
-
+ converter.addOperation(maxOperation);
+
+ converter.mapInputSocket(inputCoreMatte, maxOperation->getInputSocket(0));
+ converter.addLink(postprocessedMatte, maxOperation->getInputSocket(1));
+
postprocessedMatte = maxOperation->getOutputSocket();
-
- graph->addOperation(maxOperation);
}
-
+
/* apply blur on matte if needed */
if (keying_data->blur_post)
- postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post);
+ postprocessedMatte = setupPostBlur(converter, postprocessedMatte, keying_data->blur_post);
/* matte dilate/erode */
if (keying_data->dilate_distance != 0) {
- postprocessedMatte = setupDilateErode(graph, postprocessedMatte, keying_data->dilate_distance);
+ postprocessedMatte = setupDilateErode(converter, postprocessedMatte, keying_data->dilate_distance);
}
/* matte feather */
if (keying_data->feather_distance != 0) {
- postprocessedMatte = setupFeather(graph, context, postprocessedMatte, keying_data->feather_falloff,
+ postprocessedMatte = setupFeather(converter, context, postprocessedMatte, keying_data->feather_falloff,
keying_data->feather_distance);
}
/* set alpha channel to output image */
SetAlphaOperation *alphaOperation = new SetAlphaOperation();
- addLink(graph, originalImage, alphaOperation->getInputSocket(0));
- addLink(graph, postprocessedMatte, alphaOperation->getInputSocket(1));
+ converter.addOperation(alphaOperation);
+
+ converter.mapInputSocket(inputImage, alphaOperation->getInputSocket(0));
+ converter.addLink(postprocessedMatte, alphaOperation->getInputSocket(1));
postprocessedImage = alphaOperation->getOutputSocket();
/* despill output image */
if (keying_data->despill_factor > 0.0f) {
- postprocessedImage = setupDespill(graph, postprocessedImage,
- keyingOperation->getInputSocket(1)->getConnection()->getFromSocket(),
+ postprocessedImage = setupDespill(converter, postprocessedImage,
+ inputScreen,
keying_data->despill_factor,
keying_data->despill_balance);
}
/* connect result to output sockets */
- outputImage->relinkConnections(postprocessedImage);
- outputMatte->relinkConnections(postprocessedMatte);
+ converter.mapOutputSocket(outputImage, postprocessedImage);
+ converter.mapOutputSocket(outputMatte, postprocessedMatte);
if (edgesMatte)
- outputEdges->relinkConnections(edgesMatte);
-
- graph->addOperation(alphaOperation);
+ converter.mapOutputSocket(outputEdges, edgesMatte);
}
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h
index 6ab6a60a44d..f4a6c02aa56 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.h
+++ b/source/blender/compositor/nodes/COM_KeyingNode.h
@@ -29,19 +29,17 @@
*/
class KeyingNode : public Node {
protected:
- NodeBlurData m_alpha_blur; /* only used for blurring alpha, since the dilate/erode node doesnt have this */
-
- OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage);
- OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBlurInput, int size);
- OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance);
- OutputSocket *setupFeather(ExecutionSystem *graph, CompositorContext *context, OutputSocket *featherInput,
- int falloff, int distance);
- OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputSrceen,
- float factor, float colorBalance);
- OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance,
- float clipBlack, float clipWhite, bool edgeMatte);
+ NodeOperationOutput *setupPreBlur(NodeConverter &converter, NodeInput *inputImage, int size) const;
+ NodeOperationOutput *setupPostBlur(NodeConverter &converter, NodeOperationOutput *postBlurInput, int size) const;
+ NodeOperationOutput *setupDilateErode(NodeConverter &converter, NodeOperationOutput *dilateErodeInput, int distance) const;
+ NodeOperationOutput *setupFeather(NodeConverter &converter, const CompositorContext &context, NodeOperationOutput *featherInput,
+ int falloff, int distance) const;
+ NodeOperationOutput *setupDespill(NodeConverter &converter, NodeOperationOutput *despillInput, NodeInput *inputSrceen,
+ float factor, float colorBalance) const;
+ NodeOperationOutput *setupClip(NodeConverter &converter, NodeOperationOutput *clipInput, int kernelRadius, float kernelTolerance,
+ float clipBlack, float clipWhite, bool edgeMatte) const;
public:
KeyingNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp
index 59d889d0c84..70b3b696e37 100644
--- a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp
+++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp
@@ -34,26 +34,20 @@ KeyingScreenNode::KeyingScreenNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void KeyingScreenNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- OutputSocket *outputScreen = this->getOutputSocket(0);
-
bNode *editorNode = this->getbNode();
MovieClip *clip = (MovieClip *) editorNode->id;
-
NodeKeyingScreenData *keyingscreen_data = (NodeKeyingScreenData *) editorNode->storage;
-
+
+ NodeOutput *outputScreen = this->getOutputSocket(0);
+
// always connect the output image
KeyingScreenOperation *operation = new KeyingScreenOperation();
- operation->setbNode(editorNode);
-
- if (outputScreen->isConnected()) {
- outputScreen->relinkConnections(operation->getOutputSocket());
- }
-
operation->setMovieClip(clip);
operation->setTrackingObject(keyingscreen_data->tracking_object);
- operation->setFramenumber(context->getFramenumber());
-
- graph->addOperation(operation);
+ operation->setFramenumber(context.getFramenumber());
+ converter.addOperation(operation);
+
+ converter.mapOutputSocket(outputScreen, operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h
index 9b8ac88bb6e..be29b939690 100644
--- a/source/blender/compositor/nodes/COM_KeyingScreenNode.h
+++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h
@@ -31,6 +31,6 @@
class KeyingScreenNode : public Node {
public:
KeyingScreenNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp
index 9af1fceaae0..32db452e6c2 100644
--- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp
+++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp
@@ -30,38 +30,33 @@ LensDistortionNode::LensDistortionNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void LensDistortionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
NodeLensDist *data = (NodeLensDist *)editorNode->storage;
if (data->proj) {
ProjectorLensDistortionOperation *operation = new ProjectorLensDistortionOperation();
- operation->setbNode(editorNode);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(1), 2, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
-
- graph->addOperation(operation);
-
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation();
- operation->setbNode(editorNode);
operation->setFit(data->fit);
operation->setJitter(data->jit);
- if (!getInputSocket(1)->isConnected())
+ if (!getInputSocket(1)->isLinked())
operation->setDistortion(getInputSocket(1)->getEditorValueFloat());
- if (!getInputSocket(2)->isConnected())
+ if (!getInputSocket(2)->isLinked())
operation->setDispersion(getInputSocket(2)->getEditorValueFloat());
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
-
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
-
}
diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h
index 52529823441..4d5dc2e2705 100644
--- a/source/blender/compositor/nodes/COM_LensDistortionNode.h
+++ b/source/blender/compositor/nodes/COM_LensDistortionNode.h
@@ -32,7 +32,7 @@
class LensDistortionNode : public Node {
public:
LensDistortionNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp
index b1e6967ba42..e23ec243ff4 100644
--- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cpp
@@ -30,34 +30,29 @@ LuminanceMatteNode::LuminanceMatteNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void LuminanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void LuminanceMatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocketImage = this->getOutputSocket(0);
- OutputSocket *outputSocketMatte = this->getOutputSocket(1);
+ bNode *editorsnode = getbNode();
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocketImage = this->getOutputSocket(0);
+ NodeOutput *outputSocketMatte = this->getOutputSocket(1);
ConvertRGBToYUVOperation *rgbToYUV = new ConvertRGBToYUVOperation();
LuminanceMatteOperation *operationSet = new LuminanceMatteOperation();
- bNode *editorsnode = getbNode();
operationSet->setSettings((NodeChroma *)editorsnode->storage);
+ converter.addOperation(rgbToYUV);
+ converter.addOperation(operationSet);
- inputSocket->relinkConnections(rgbToYUV->getInputSocket(0), 0, graph);
- addLink(graph, rgbToYUV->getOutputSocket(), operationSet->getInputSocket(0));
-
- if (outputSocketMatte->isConnected()) {
- outputSocketMatte->relinkConnections(operationSet->getOutputSocket(0));
- }
-
- graph->addOperation(rgbToYUV);
- graph->addOperation(operationSet);
+ converter.mapInputSocket(inputSocket, rgbToYUV->getInputSocket(0));
+ converter.addLink(rgbToYUV->getOutputSocket(), operationSet->getInputSocket(0));
+ converter.mapOutputSocket(outputSocketMatte, operationSet->getOutputSocket(0));
SetAlphaOperation *operation = new SetAlphaOperation();
- addLink(graph, rgbToYUV->getInputSocket(0)->getConnection()->getFromSocket(), operation->getInputSocket(0));
- addLink(graph, operationSet->getOutputSocket(), operation->getInputSocket(1));
- graph->addOperation(operation);
- addPreviewOperation(graph, context, operation->getOutputSocket());
-
- if (outputSocketImage->isConnected()) {
- outputSocketImage->relinkConnections(operation->getOutputSocket());
- }
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.addLink(operationSet->getOutputSocket(), operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketImage, operation->getOutputSocket());
+
+ converter.addPreview(operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
index a71e68cf636..a36e6f2e732 100644
--- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
@@ -31,7 +31,7 @@
class LuminanceMatteNode : public Node {
public:
LuminanceMatteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_LUMINANCEMATTENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.cpp b/source/blender/compositor/nodes/COM_MapRangeNode.cpp
index 232be3d41b0..2c164cfad32 100644
--- a/source/blender/compositor/nodes/COM_MapRangeNode.cpp
+++ b/source/blender/compositor/nodes/COM_MapRangeNode.cpp
@@ -30,25 +30,23 @@ MapRangeNode::MapRangeNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MapRangeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MapRangeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *valueSocket = this->getInputSocket(0);
- InputSocket *sourceMinSocket = this->getInputSocket(1);
- InputSocket *sourceMaxSocket = this->getInputSocket(2);
- InputSocket *destMinSocket = this->getInputSocket(3);
- InputSocket *destMaxSocket = this->getInputSocket(4);
- OutputSocket *outputSocket = this->getOutputSocket(0);
-
+ NodeInput *valueSocket = this->getInputSocket(0);
+ NodeInput *sourceMinSocket = this->getInputSocket(1);
+ NodeInput *sourceMaxSocket = this->getInputSocket(2);
+ NodeInput *destMinSocket = this->getInputSocket(3);
+ NodeInput *destMaxSocket = this->getInputSocket(4);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
MapRangeOperation *operation = new MapRangeOperation();
-
- valueSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- sourceMinSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- sourceMaxSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
- destMinSocket->relinkConnections(operation->getInputSocket(3), 3, graph);
- destMaxSocket->relinkConnections(operation->getInputSocket(4), 4, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
-
operation->setUseClamp(this->getbNode()->custom1);
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(valueSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(sourceMinSocket, operation->getInputSocket(1));
+ converter.mapInputSocket(sourceMaxSocket, operation->getInputSocket(2));
+ converter.mapInputSocket(destMinSocket, operation->getInputSocket(3));
+ converter.mapInputSocket(destMaxSocket, operation->getInputSocket(4));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h
index 6667720be3d..0ef4309602d 100644
--- a/source/blender/compositor/nodes/COM_MapRangeNode.h
+++ b/source/blender/compositor/nodes/COM_MapRangeNode.h
@@ -32,7 +32,7 @@
class MapRangeNode : public Node {
public:
MapRangeNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_MAPRANGENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cpp b/source/blender/compositor/nodes/COM_MapUVNode.cpp
index 447b8239a93..25ca7b8b8c6 100644
--- a/source/blender/compositor/nodes/COM_MapUVNode.cpp
+++ b/source/blender/compositor/nodes/COM_MapUVNode.cpp
@@ -28,17 +28,16 @@ MapUVNode::MapUVNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MapUVNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MapUVNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- MapUVOperation *operation = new MapUVOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
bNode *node = this->getbNode();
+
+ MapUVOperation *operation = new MapUVOperation();
operation->setAlpha((float)node->custom1);
operation->setResolutionInputSocketIndex(1);
+ converter.addOperation(operation);
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h
index 2e5616e0bd0..286ec4205f1 100644
--- a/source/blender/compositor/nodes/COM_MapUVNode.h
+++ b/source/blender/compositor/nodes/COM_MapUVNode.h
@@ -31,6 +31,6 @@
class MapUVNode : public Node {
public:
MapUVNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_MapValueNode.cpp b/source/blender/compositor/nodes/COM_MapValueNode.cpp
index ac57ffed9da..d7ee4e6a38b 100644
--- a/source/blender/compositor/nodes/COM_MapValueNode.cpp
+++ b/source/blender/compositor/nodes/COM_MapValueNode.cpp
@@ -30,14 +30,17 @@ MapValueNode::MapValueNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MapValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MapValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *colorSocket = this->getInputSocket(0);
- OutputSocket *valueSocket = this->getOutputSocket(0);
TexMapping *storage = (TexMapping *)this->getbNode()->storage;
+
+ NodeInput *colorSocket = this->getInputSocket(0);
+ NodeOutput *valueSocket = this->getOutputSocket(0);
+
MapValueOperation *convertProg = new MapValueOperation();
convertProg->setSettings(storage);
- colorSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
- valueSocket->relinkConnections(convertProg->getOutputSocket(0));
- graph->addOperation(convertProg);
+ converter.addOperation(convertProg);
+
+ converter.mapInputSocket(colorSocket, convertProg->getInputSocket(0));
+ converter.mapOutputSocket(valueSocket, convertProg->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h
index bd8e3d08e9c..8b82b31350d 100644
--- a/source/blender/compositor/nodes/COM_MapValueNode.h
+++ b/source/blender/compositor/nodes/COM_MapValueNode.h
@@ -32,7 +32,7 @@
class MapValueNode : public Node {
public:
MapValueNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_MAPVALUENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp
index 65ff443b55b..be05840f601 100644
--- a/source/blender/compositor/nodes/COM_MaskNode.cpp
+++ b/source/blender/compositor/nodes/COM_MaskNode.cpp
@@ -34,11 +34,11 @@ MaskNode::MaskNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MaskNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- const RenderData *rd = context->getRenderData();
+ const RenderData *rd = context.getRenderData();
- OutputSocket *outputMask = this->getOutputSocket(0);
+ NodeOutput *outputMask = this->getOutputSocket(0);
bNode *editorNode = this->getbNode();
NodeMask *data = (NodeMask *)editorNode->storage;
@@ -46,7 +46,6 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
// always connect the output image
MaskOperation *operation = new MaskOperation();
- operation->setbNode(editorNode);
if (editorNode->custom1 & CMP_NODEFLAG_MASK_FIXED) {
operation->setMaskWidth(data->size_x);
@@ -61,12 +60,8 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
operation->setMaskHeight(rd->ysch * rd->size / 100.0f);
}
- if (outputMask->isConnected()) {
- outputMask->relinkConnections(operation->getOutputSocket());
- }
-
operation->setMask(mask);
- operation->setFramenumber(context->getFramenumber());
+ operation->setFramenumber(context.getFramenumber());
operation->setSmooth((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_AA) != 0);
operation->setFeather((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
@@ -78,5 +73,6 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
operation->setMotionBlurShutter(editorNode->custom3);
}
- graph->addOperation(operation);
+ converter.addOperation(operation);
+ converter.mapOutputSocket(outputMask, operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h
index 9ef3e5deb50..834c421ac08 100644
--- a/source/blender/compositor/nodes/COM_MaskNode.h
+++ b/source/blender/compositor/nodes/COM_MaskNode.h
@@ -34,7 +34,7 @@
class MaskNode : public Node {
public:
MaskNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp
index 23e9a9d623d..ef7046b8165 100644
--- a/source/blender/compositor/nodes/COM_MathNode.cpp
+++ b/source/blender/compositor/nodes/COM_MathNode.cpp
@@ -24,7 +24,7 @@
#include "COM_MathBaseOperation.h"
#include "COM_ExecutionSystem.h"
-void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MathNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
MathBaseOperation *operation = NULL;
@@ -83,17 +83,18 @@ void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
case 17: /* Modulo */
operation = new MathModuloOperation();
break;
+ case 18: /* Absolute Value */
+ operation = new MathAbsoluteOperation();
+ break;
}
- if (operation != NULL) {
- bool useClamp = this->getbNode()->custom2;
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
+ if (operation) {
+ bool useClamp = getbNode()->custom2;
operation->setUseClamp(useClamp);
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
}
diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h
index 4f8e64754e7..72403e7059f 100644
--- a/source/blender/compositor/nodes/COM_MathNode.h
+++ b/source/blender/compositor/nodes/COM_MathNode.h
@@ -32,7 +32,7 @@
class MathNode : public Node {
public:
MathNode(bNode *editorNode) : Node(editorNode) {}
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp
index 42217243fdf..b12dfc02ed7 100644
--- a/source/blender/compositor/nodes/COM_MixNode.cpp
+++ b/source/blender/compositor/nodes/COM_MixNode.cpp
@@ -34,18 +34,17 @@ MixNode::MixNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MixNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *valueSocket = this->getInputSocket(0);
- InputSocket *color1Socket = this->getInputSocket(1);
- InputSocket *color2Socket = this->getInputSocket(2);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *valueSocket = this->getInputSocket(0);
+ NodeInput *color1Socket = this->getInputSocket(1);
+ NodeInput *color2Socket = this->getInputSocket(2);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
bNode *editorNode = this->getbNode();
bool useAlphaPremultiply = this->getbNode()->custom2 & 1;
bool useClamp = this->getbNode()->custom2 & 2;
MixBaseOperation *convertProg;
-
switch (editorNode->custom1) {
case MA_RAMP_ADD:
convertProg = new MixAddOperation();
@@ -106,14 +105,12 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *con
}
convertProg->setUseValueAlphaMultiply(useAlphaPremultiply);
convertProg->setUseClamp(useClamp);
-
- valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
- color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
- color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph);
- outputSocket->relinkConnections(convertProg->getOutputSocket(0));
- addPreviewOperation(graph, context, convertProg->getOutputSocket(0));
+ converter.addOperation(convertProg);
- convertProg->getInputSocket(2)->setResizeMode(color2Socket->getResizeMode());
+ converter.mapInputSocket(valueSocket, convertProg->getInputSocket(0));
+ converter.mapInputSocket(color1Socket, convertProg->getInputSocket(1));
+ converter.mapInputSocket(color2Socket, convertProg->getInputSocket(2));
+ converter.mapOutputSocket(outputSocket, convertProg->getOutputSocket(0));
- graph->addOperation(convertProg);
+ converter.addPreview(convertProg->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h
index 76076d01427..3e61a855d31 100644
--- a/source/blender/compositor/nodes/COM_MixNode.h
+++ b/source/blender/compositor/nodes/COM_MixNode.h
@@ -32,6 +32,6 @@
class MixNode : public Node {
public:
MixNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp
index 041fa9f7c4c..933223dacac 100644
--- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp
+++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp
@@ -38,19 +38,19 @@ MovieClipNode::MovieClipNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void MovieClipNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- OutputSocket *outputMovieClip = this->getOutputSocket(0);
- OutputSocket *alphaMovieClip = this->getOutputSocket(1);
- OutputSocket *offsetXMovieClip = this->getOutputSocket(2);
- OutputSocket *offsetYMovieClip = this->getOutputSocket(3);
- OutputSocket *scaleMovieClip = this->getOutputSocket(4);
- OutputSocket *angleMovieClip = this->getOutputSocket(5);
+ NodeOutput *outputMovieClip = this->getOutputSocket(0);
+ NodeOutput *alphaMovieClip = this->getOutputSocket(1);
+ NodeOutput *offsetXMovieClip = this->getOutputSocket(2);
+ NodeOutput *offsetYMovieClip = this->getOutputSocket(3);
+ NodeOutput *scaleMovieClip = this->getOutputSocket(4);
+ NodeOutput *angleMovieClip = this->getOutputSocket(5);
bNode *editorNode = this->getbNode();
MovieClip *movieClip = (MovieClip *)editorNode->id;
MovieClipUser *movieClipUser = (MovieClipUser *)editorNode->storage;
- bool cacheFrame = !context->isRendering();
+ bool cacheFrame = !context.isRendering();
ImBuf *ibuf = NULL;
if (movieClip) {
@@ -62,27 +62,23 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex
// always connect the output image
MovieClipOperation *operation = new MovieClipOperation();
-
- addPreviewOperation(graph, context, operation->getOutputSocket());
- if (outputMovieClip->isConnected()) {
- outputMovieClip->relinkConnections(operation->getOutputSocket());
- }
-
operation->setMovieClip(movieClip);
operation->setMovieClipUser(movieClipUser);
- operation->setFramenumber(context->getFramenumber());
+ operation->setFramenumber(context.getFramenumber());
operation->setCacheFrame(cacheFrame);
- graph->addOperation(operation);
- if (alphaMovieClip->isConnected()) {
- MovieClipAlphaOperation *alphaOperation = new MovieClipAlphaOperation();
- alphaOperation->setMovieClip(movieClip);
- alphaOperation->setMovieClipUser(movieClipUser);
- alphaOperation->setFramenumber(context->getFramenumber());
- alphaOperation->setCacheFrame(cacheFrame);
- alphaMovieClip->relinkConnections(alphaOperation->getOutputSocket());
- graph->addOperation(alphaOperation);
- }
+ converter.addOperation(operation);
+ converter.mapOutputSocket(outputMovieClip, operation->getOutputSocket());
+ converter.addPreview(operation->getOutputSocket());
+
+ MovieClipAlphaOperation *alphaOperation = new MovieClipAlphaOperation();
+ alphaOperation->setMovieClip(movieClip);
+ alphaOperation->setMovieClipUser(movieClipUser);
+ alphaOperation->setFramenumber(context.getFramenumber());
+ alphaOperation->setCacheFrame(cacheFrame);
+
+ converter.addOperation(alphaOperation);
+ converter.mapOutputSocket(alphaMovieClip, alphaOperation->getOutputSocket());
MovieTrackingStabilization *stab = &movieClip->tracking.stabilization;
float loc[2], scale, angle;
@@ -93,37 +89,17 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex
if (ibuf) {
if (stab->flag & TRACKING_2D_STABILIZATION) {
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movieClip, context->getFramenumber());
+ int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movieClip, context.getFramenumber());
BKE_tracking_stabilization_data_get(&movieClip->tracking, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle);
}
}
- if (offsetXMovieClip->isConnected()) {
- SetValueOperation *operationSetValue = new SetValueOperation();
- operationSetValue->setValue(loc[0]);
- offsetXMovieClip->relinkConnections(operationSetValue->getOutputSocket());
- graph->addOperation(operationSetValue);
- }
- if (offsetYMovieClip->isConnected()) {
- SetValueOperation *operationSetValue = new SetValueOperation();
- operationSetValue->setValue(loc[1]);
- offsetYMovieClip->relinkConnections(operationSetValue->getOutputSocket());
- graph->addOperation(operationSetValue);
- }
- if (scaleMovieClip->isConnected()) {
- SetValueOperation *operationSetValue = new SetValueOperation();
- operationSetValue->setValue(scale);
- scaleMovieClip->relinkConnections(operationSetValue->getOutputSocket());
- graph->addOperation(operationSetValue);
- }
- if (angleMovieClip->isConnected()) {
- SetValueOperation *operationSetValue = new SetValueOperation();
- operationSetValue->setValue(angle);
- angleMovieClip->relinkConnections(operationSetValue->getOutputSocket());
- graph->addOperation(operationSetValue);
- }
-
+ converter.addOutputValue(offsetXMovieClip, loc[0]);
+ converter.addOutputValue(offsetYMovieClip, loc[1]);
+ converter.addOutputValue(scaleMovieClip, scale);
+ converter.addOutputValue(angleMovieClip, angle);
+
if (ibuf) {
IMB_freeImBuf(ibuf);
}
diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h
index 2fb38860a34..ff7b2869f05 100644
--- a/source/blender/compositor/nodes/COM_MovieClipNode.h
+++ b/source/blender/compositor/nodes/COM_MovieClipNode.h
@@ -33,7 +33,7 @@
class MovieClipNode : public Node {
public:
MovieClipNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_MOVIECLIPNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp b/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp
index c29bc27cd80..fd907465984 100644
--- a/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp
+++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.cpp
@@ -31,18 +31,19 @@ MovieDistortionNode::MovieDistortionNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void MovieDistortionNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void MovieDistortionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
bNode *bnode = this->getbNode();
MovieClip *clip = (MovieClip *)bnode->id;
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
MovieDistortionOperation *operation = new MovieDistortionOperation(bnode->custom1 == 1);
operation->setMovieClip(clip);
- operation->setFramenumber(context->getFramenumber());
+ operation->setFramenumber(context.getFramenumber());
+ converter.addOperation(operation);
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, system);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- system->addOperation(operation);
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h
index b97600bb64e..6ff0295083f 100644
--- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h
+++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.h
@@ -32,7 +32,7 @@
class MovieDistortionNode : public Node {
public:
MovieDistortionNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp
deleted file mode 100644
index 5155b55a2ec..00000000000
--- a/source/blender/compositor/nodes/COM_MuteNode.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_MuteNode.h"
-#include "COM_SocketConnection.h"
-#include "COM_SetValueOperation.h"
-#include "COM_SetVectorOperation.h"
-#include "COM_SetColorOperation.h"
-
-extern "C" {
-# include "BLI_listbase.h"
-}
-
-MuteNode::MuteNode(bNode *editorNode) : Node(editorNode)
-{
- /* pass */
-}
-
-void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output)
-{
- vector<InputSocket *> &inputsockets = this->getInputSockets();
- for (unsigned int index = 0; index < inputsockets.size(); index++) {
- InputSocket *input = inputsockets[index];
- if (input->getDataType() == output->getDataType()) {
- if (input->isConnected()) {
- output->relinkConnections(input->getConnection()->getFromSocket(), false);
- /* output connections have been redirected,
- * remove the input connection to completely unlink the node.
- */
- input->unlinkConnections(graph);
- return;
- }
- }
- }
-
- createDefaultOutput(graph, output);
-}
-
-void MuteNode::createDefaultOutput(ExecutionSystem *graph, OutputSocket *output)
-{
- NodeOperation *operation = NULL;
- switch (output->getDataType()) {
- case COM_DT_VALUE:
- {
- SetValueOperation *valueoperation = new SetValueOperation();
- valueoperation->setValue(0.0f);
- operation = valueoperation;
- break;
- }
- case COM_DT_VECTOR:
- {
- SetVectorOperation *vectoroperation = new SetVectorOperation();
- vectoroperation->setX(0.0f);
- vectoroperation->setY(0.0f);
- vectoroperation->setW(0.0f);
- operation = vectoroperation;
- break;
- }
- case COM_DT_COLOR:
- {
- SetColorOperation *coloroperation = new SetColorOperation();
- coloroperation->setChannel1(0.0f);
- coloroperation->setChannel2(0.0f);
- coloroperation->setChannel3(0.0f);
- coloroperation->setChannel4(0.0f);
- operation = coloroperation;
- break;
- }
- }
-
- if (operation) {
- output->relinkConnections(operation->getOutputSocket(), false);
- graph->addOperation(operation);
- }
-
- output->clearConnections();
-}
-
-template<class SocketType> void MuteNode::fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap)
-{
- for (typename vector<SocketType *>::iterator it = sockets.begin(); it != sockets.end(); it++) {
- Socket *socket = (Socket *) *it;
-
- socketMap.insert(std::pair<bNodeSocket *, Socket *>(socket->getbNodeSocket(), socket));
- }
-}
-
-void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- bNode *editorNode = this->getbNode();
- vector<OutputSocket *> &outputsockets = this->getOutputSockets();
-
- /* mute node is also used for unknown nodes and couple of nodes in fast mode
- * can't use generic routines in that case
- */
- if (editorNode->flag & NODE_MUTED) {
- vector<InputSocket *> &inputsockets = this->getInputSockets();
- vector<OutputSocket *> relinkedsockets;
- SocketMap socketMap;
- bNodeLink *link;
-
- this->fillSocketMap<OutputSocket>(outputsockets, socketMap);
- this->fillSocketMap<InputSocket>(inputsockets, socketMap);
-
- for (link = (bNodeLink *) editorNode->internal_links.first; link; link = link->next) {
- if (link->fromnode == editorNode) {
- InputSocket *fromSocket = (InputSocket *) socketMap.find(link->fromsock)->second;
- OutputSocket *toSocket = (OutputSocket *) socketMap.find(link->tosock)->second;
-
- if (toSocket->isConnected()) {
- if (fromSocket->isConnected()) {
- toSocket->relinkConnections(fromSocket->getConnection()->getFromSocket(), false);
- }
- else {
- createDefaultOutput(graph, toSocket);
- }
-
- relinkedsockets.push_back(toSocket);
- }
- }
- }
-
- /* in some cases node could be marked as muted, but it wouldn't have internal connections
- * this happens in such cases as muted render layer node
- *
- * to deal with such cases create default operation for not-relinked output sockets
- */
-
- for (unsigned int index = 0; index < outputsockets.size(); index++) {
- OutputSocket *output = outputsockets[index];
-
- if (output->isConnected()) {
- bool relinked = false;
- vector<OutputSocket *>::iterator it;
-
- for (it = relinkedsockets.begin(); it != relinkedsockets.end(); it++) {
- if (*it == output) {
- relinked = true;
- break;
- }
- }
-
- if (!relinked)
- createDefaultOutput(graph, output);
- }
- }
- }
- else {
- for (unsigned int index = 0; index < outputsockets.size(); index++) {
- OutputSocket *output = outputsockets[index];
- if (output->isConnected()) {
- reconnect(graph, output);
- }
- }
- }
-}
diff --git a/source/blender/compositor/nodes/COM_MuteNode.h b/source/blender/compositor/nodes/COM_MuteNode.h
deleted file mode 100644
index 7b0f1c2c298..00000000000
--- a/source/blender/compositor/nodes/COM_MuteNode.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_MuteNode_h_
-#define _COM_MuteNode_h_
-
-#include <map>
-
-#include "COM_Node.h"
-
-extern "C" {
-# include "BKE_node.h"
-}
-
-/**
- * @brief MuteNode
- * @ingroup Node
- */
-class MuteNode : public Node {
-public:
- MuteNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-private:
- typedef std::map<bNodeSocket *, Socket *> SocketMap;
-
- void reconnect(ExecutionSystem *graph, OutputSocket *output);
- void createDefaultOutput(ExecutionSystem *graph, OutputSocket *output);
-
- template<class SocketType> void fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap);
-};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp
index 41b91f61328..d7c3fd11844 100644
--- a/source/blender/compositor/nodes/COM_NormalNode.cpp
+++ b/source/blender/compositor/nodes/COM_NormalNode.cpp
@@ -31,32 +31,29 @@ NormalNode::NormalNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void NormalNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
- OutputSocket *outputSocketDotproduct = this->getOutputSocket(1);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+ NodeOutput *outputSocketDotproduct = this->getOutputSocket(1);
SetVectorOperation *operationSet = new SetVectorOperation();
float normal[3];
outputSocket->getEditorValueVector(normal);
-
/* animation can break normalization, this restores it */
normalize_v3(normal);
-
operationSet->setX(normal[0]);
operationSet->setY(normal[1]);
operationSet->setZ(normal[2]);
operationSet->setW(0.0f);
+ converter.addOperation(operationSet);
+
+ converter.mapOutputSocket(outputSocket, operationSet->getOutputSocket(0));
- outputSocket->relinkConnections(operationSet->getOutputSocket(0));
- graph->addOperation(operationSet);
+ DotproductOperation *operation = new DotproductOperation();
+ converter.addOperation(operation);
- if (outputSocketDotproduct->isConnected()) {
- DotproductOperation *operation = new DotproductOperation();
- outputSocketDotproduct->relinkConnections(operation->getOutputSocket(0));
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- addLink(graph, operationSet->getOutputSocket(0), operation->getInputSocket(1));
- graph->addOperation(operation);
- }
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.addLink(operationSet->getOutputSocket(0), operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocketDotproduct, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h
index 64d4e3a3656..5cccaab5875 100644
--- a/source/blender/compositor/nodes/COM_NormalNode.h
+++ b/source/blender/compositor/nodes/COM_NormalNode.h
@@ -32,7 +32,7 @@
class NormalNode : public Node {
public:
NormalNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* COM_NormalNODE_H */
diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.cpp b/source/blender/compositor/nodes/COM_NormalizeNode.cpp
index 7c1c695f8b6..f6e919c168f 100644
--- a/source/blender/compositor/nodes/COM_NormalizeNode.cpp
+++ b/source/blender/compositor/nodes/COM_NormalizeNode.cpp
@@ -28,12 +28,11 @@ NormalizeNode::NormalizeNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void NormalizeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void NormalizeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NormalizeOperation *operation = new NormalizeOperation();
+ converter.addOperation(operation);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
-
- graph->addOperation(operation);
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h
index ea1497efdc6..a0eb7c9f5a9 100644
--- a/source/blender/compositor/nodes/COM_NormalizeNode.h
+++ b/source/blender/compositor/nodes/COM_NormalizeNode.h
@@ -31,7 +31,7 @@
class NormalizeNode : public Node {
public:
NormalizeNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp
index 94e5efe77e0..92fa74b9a2e 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp
@@ -32,52 +32,47 @@ OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void OutputFileNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeImageMultiFile *storage = (NodeImageMultiFile *)this->getbNode()->storage;
- if (!context->isRendering()) {
+ if (!context.isRendering()) {
/* only output files when rendering a sequence -
* otherwise, it overwrites the output files just
* scrubbing through the timeline when the compositor updates.
*/
-
- /* still, need to unlink input sockets to remove the node from the graph completely */
- int num_inputs = getNumberOfInputSockets();
- for (int i = 0; i < num_inputs; ++i) {
- getInputSocket(i)->unlinkConnections(graph);
- }
return;
}
if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
/* single output operation for the multilayer file */
OutputOpenExrMultiLayerOperation *outputOperation = new OutputOpenExrMultiLayerOperation(
- context->getRenderData(), context->getbNodeTree(), storage->base_path, storage->format.exr_codec);
+ context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec);
+ converter.addOperation(outputOperation);
int num_inputs = getNumberOfInputSockets();
- bool hasConnections = false;
+ bool previewAdded = false;
for (int i = 0; i < num_inputs; ++i) {
- InputSocket *input = getInputSocket(i);
+ NodeInput *input = getInputSocket(i);
NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage;
- outputOperation->add_layer(sockdata->layer, input->getDataType());
+ /* note: layer becomes an empty placeholder if the input is not linked */
+ outputOperation->add_layer(sockdata->layer, input->getDataType(), input->isLinked());
- if (input->isConnected()) {
- hasConnections = true;
- input->relinkConnections(outputOperation->getInputSocket(i));
+ converter.mapInputSocket(input, outputOperation->getInputSocket(i));
+
+ if (!previewAdded) {
+ converter.addNodeInputPreview(input);
+ previewAdded = true;
}
}
- if (hasConnections) addPreviewOperation(graph, context, outputOperation->getInputSocket(0));
-
- graph->addOperation(outputOperation);
}
else { /* single layer format */
int num_inputs = getNumberOfInputSockets();
bool previewAdded = false;
for (int i = 0; i < num_inputs; ++i) {
- InputSocket *input = getInputSocket(i);
- if (input->isConnected()) {
+ NodeInput *input = getInputSocket(i);
+ if (input->isLinked()) {
NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage;
ImageFormatData *format = (sockdata->use_node_format ? &storage->format : &sockdata->format);
char path[FILE_MAX];
@@ -86,16 +81,17 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte
BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation(
- context->getRenderData(), context->getbNodeTree(), input->getDataType(), format, path,
- context->getViewSettings(), context->getDisplaySettings());
- input->relinkConnections(outputOperation->getInputSocket(0));
- graph->addOperation(outputOperation);
+ context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
+ context.getViewSettings(), context.getDisplaySettings());
+ converter.addOperation(outputOperation);
+
+ converter.mapInputSocket(input, outputOperation->getInputSocket(0));
+
if (!previewAdded) {
- addPreviewOperation(graph, context, outputOperation->getInputSocket(0));
+ converter.addNodeInputPreview(input);
previewAdded = true;
}
}
}
}
}
-
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.h b/source/blender/compositor/nodes/COM_OutputFileNode.h
index e3194436f7f..54e29417c14 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.h
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.h
@@ -34,7 +34,7 @@
class OutputFileNode : public Node {
public:
OutputFileNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp
index b751c9a6e9f..da3cd74e771 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.cpp
+++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp
@@ -30,19 +30,20 @@ PixelateNode::PixelateNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void PixelateNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
DataType datatype = inputSocket->getDataType();
- if (inputSocket->isConnected()) {
- SocketConnection *connection = inputSocket->getConnection();
- OutputSocket *otherOutputSocket = connection->getFromSocket();
- datatype = otherOutputSocket->getDataType();
+
+ if (inputSocket->isLinked()) {
+ NodeOutput *link = inputSocket->getLink();
+ datatype = link->getDataType();
}
PixelateOperation *operation = new PixelateOperation(datatype);
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.h b/source/blender/compositor/nodes/COM_PixelateNode.h
index c142d2d7a5b..a5e73eb3683 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.h
+++ b/source/blender/compositor/nodes/COM_PixelateNode.h
@@ -32,7 +32,7 @@
class PixelateNode : public Node {
public:
PixelateNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
index f52c696b772..9b69bc5a46e 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
@@ -24,8 +24,7 @@
#include "COM_PlaneTrackDeformNode.h"
#include "COM_ExecutionSystem.h"
-#include "COM_PlaneTrackMaskOperation.h"
-#include "COM_PlaneTrackWarpImageOperation.h"
+#include "COM_PlaneTrackOperation.h"
extern "C" {
# include "BKE_node.h"
@@ -38,44 +37,34 @@ PlaneTrackDeformNode::PlaneTrackDeformNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void PlaneTrackDeformNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *input_image = this->getInputSocket(0);
-
- OutputSocket *output_warped_image = this->getOutputSocket(0);
- OutputSocket *output_plane = this->getOutputSocket(1);
-
bNode *editorNode = this->getbNode();
MovieClip *clip = (MovieClip *) editorNode->id;
-
NodePlaneTrackDeformData *data = (NodePlaneTrackDeformData *) editorNode->storage;
-
- int frame_number = context->getFramenumber();
-
- if (output_warped_image->isConnected()) {
- PlaneTrackWarpImageOperation *warp_image_operation = new PlaneTrackWarpImageOperation();
-
- warp_image_operation->setMovieClip(clip);
- warp_image_operation->setTrackingObject(data->tracking_object);
- warp_image_operation->setPlaneTrackName(data->plane_track_name);
- warp_image_operation->setFramenumber(frame_number);
-
- input_image->relinkConnections(warp_image_operation->getInputSocket(0), 0, graph);
- output_warped_image->relinkConnections(warp_image_operation->getOutputSocket());
-
- graph->addOperation(warp_image_operation);
- }
-
- if (output_plane->isConnected()) {
- PlaneTrackMaskOperation *plane_mask_operation = new PlaneTrackMaskOperation();
-
- plane_mask_operation->setMovieClip(clip);
- plane_mask_operation->setTrackingObject(data->tracking_object);
- plane_mask_operation->setPlaneTrackName(data->plane_track_name);
- plane_mask_operation->setFramenumber(frame_number);
-
- output_plane->relinkConnections(plane_mask_operation->getOutputSocket());
-
- graph->addOperation(plane_mask_operation);
- }
+
+ int frame_number = context.getFramenumber();
+
+ NodeInput *input_image = this->getInputSocket(0);
+ NodeOutput *output_warped_image = this->getOutputSocket(0);
+ NodeOutput *output_plane = this->getOutputSocket(1);
+
+ PlaneTrackWarpImageOperation *warp_image_operation = new PlaneTrackWarpImageOperation();
+ warp_image_operation->setMovieClip(clip);
+ warp_image_operation->setTrackingObject(data->tracking_object);
+ warp_image_operation->setPlaneTrackName(data->plane_track_name);
+ warp_image_operation->setFramenumber(frame_number);
+ converter.addOperation(warp_image_operation);
+
+ converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
+ converter.mapOutputSocket(output_warped_image, warp_image_operation->getOutputSocket());
+
+ PlaneTrackMaskOperation *plane_mask_operation = new PlaneTrackMaskOperation();
+ plane_mask_operation->setMovieClip(clip);
+ plane_mask_operation->setTrackingObject(data->tracking_object);
+ plane_mask_operation->setPlaneTrackName(data->plane_track_name);
+ plane_mask_operation->setFramenumber(frame_number);
+ converter.addOperation(plane_mask_operation);
+
+ converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
index 3c37f4474dd..71e6ab12dfc 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
@@ -34,5 +34,5 @@ extern "C" {
class PlaneTrackDeformNode : public Node {
public:
PlaneTrackDeformNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
index 512f8eec90f..cc66c688379 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_RenderLayersNode.h"
-#include "COM_ExecutionSystem.h"
#include "COM_RenderLayersProg.h"
#include "COM_TranslateOperation.h"
#include "COM_RotateOperation.h"
@@ -33,69 +32,57 @@ RenderLayersNode::RenderLayersNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void RenderLayersNode::testSocketConnection(ExecutionSystem *system, CompositorContext *context, int outputSocketNumber, RenderLayersBaseProg *operation)
+void RenderLayersNode::testSocketLink(NodeConverter &converter, const CompositorContext &context,
+ int outputSocketNumber, RenderLayersBaseProg *operation) const
{
- OutputSocket *outputSocket = this->getOutputSocket(outputSocketNumber);
+ NodeOutput *outputSocket = this->getOutputSocket(outputSocketNumber);
Scene *scene = (Scene *)this->getbNode()->id;
short layerId = this->getbNode()->custom1;
- if (outputSocket->isConnected()) {
- operation->setScene(scene);
- operation->setLayerId(layerId);
- operation->setRenderData(context->getRenderData());
- outputSocket->relinkConnections(operation->getOutputSocket());
- system->addOperation(operation);
- if (outputSocketNumber == 0) { // only do for image socket if connected
- addPreviewOperation(system, context, operation->getOutputSocket());
- }
- }
- else {
- if (outputSocketNumber == 0) {
- system->addOperation(operation);
- operation->setScene(scene);
- operation->setLayerId(layerId);
- operation->setRenderData(context->getRenderData());
- addPreviewOperation(system, context, operation->getOutputSocket());
- }
- else {
- delete operation;
- }
- }
+ operation->setScene(scene);
+ operation->setLayerId(layerId);
+ operation->setRenderData(context.getRenderData());
+
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+ converter.addOperation(operation);
+
+ if (outputSocketNumber == 0) /* only for image socket */
+ converter.addPreview(operation->getOutputSocket());
}
-void RenderLayersNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void RenderLayersNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- testSocketConnection(graph, context, 0, new RenderLayersColorProg());
- testSocketConnection(graph, context, 1, new RenderLayersAlphaProg());
- testSocketConnection(graph, context, 2, new RenderLayersDepthProg());
- testSocketConnection(graph, context, 3, new RenderLayersNormalOperation());
- testSocketConnection(graph, context, 4, new RenderLayersUVOperation());
- testSocketConnection(graph, context, 5, new RenderLayersSpeedOperation());
- testSocketConnection(graph, context, 6, new RenderLayersColorOperation());
- testSocketConnection(graph, context, 7, new RenderLayersDiffuseOperation());
- testSocketConnection(graph, context, 8, new RenderLayersSpecularOperation());
- testSocketConnection(graph, context, 9, new RenderLayersShadowOperation());
- testSocketConnection(graph, context, 10, new RenderLayersAOOperation());
- testSocketConnection(graph, context, 11, new RenderLayersReflectionOperation());
- testSocketConnection(graph, context, 12, new RenderLayersRefractionOperation());
- testSocketConnection(graph, context, 13, new RenderLayersIndirectOperation());
- testSocketConnection(graph, context, 14, new RenderLayersObjectIndexOperation());
- testSocketConnection(graph, context, 15, new RenderLayersMaterialIndexOperation());
- testSocketConnection(graph, context, 16, new RenderLayersMistOperation());
- testSocketConnection(graph, context, 17, new RenderLayersEmitOperation());
- testSocketConnection(graph, context, 18, new RenderLayersEnvironmentOperation());
+ testSocketLink(converter, context, 0, new RenderLayersColorProg());
+ testSocketLink(converter, context, 1, new RenderLayersAlphaProg());
+ testSocketLink(converter, context, 2, new RenderLayersDepthProg());
+ testSocketLink(converter, context, 3, new RenderLayersNormalOperation());
+ testSocketLink(converter, context, 4, new RenderLayersUVOperation());
+ testSocketLink(converter, context, 5, new RenderLayersSpeedOperation());
+ testSocketLink(converter, context, 6, new RenderLayersColorOperation());
+ testSocketLink(converter, context, 7, new RenderLayersDiffuseOperation());
+ testSocketLink(converter, context, 8, new RenderLayersSpecularOperation());
+ testSocketLink(converter, context, 9, new RenderLayersShadowOperation());
+ testSocketLink(converter, context, 10, new RenderLayersAOOperation());
+ testSocketLink(converter, context, 11, new RenderLayersReflectionOperation());
+ testSocketLink(converter, context, 12, new RenderLayersRefractionOperation());
+ testSocketLink(converter, context, 13, new RenderLayersIndirectOperation());
+ testSocketLink(converter, context, 14, new RenderLayersObjectIndexOperation());
+ testSocketLink(converter, context, 15, new RenderLayersMaterialIndexOperation());
+ testSocketLink(converter, context, 16, new RenderLayersMistOperation());
+ testSocketLink(converter, context, 17, new RenderLayersEmitOperation());
+ testSocketLink(converter, context, 18, new RenderLayersEnvironmentOperation());
// cycles passes
- testSocketConnection(graph, context, 19, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_DIRECT));
- testSocketConnection(graph, context, 20, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_INDIRECT));
- testSocketConnection(graph, context, 21, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_COLOR));
- testSocketConnection(graph, context, 22, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_DIRECT));
- testSocketConnection(graph, context, 23, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_INDIRECT));
- testSocketConnection(graph, context, 24, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_COLOR));
- testSocketConnection(graph, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT));
- testSocketConnection(graph, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT));
- testSocketConnection(graph, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR));
- testSocketConnection(graph, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT));
- testSocketConnection(graph, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT));
- testSocketConnection(graph, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR));
+ testSocketLink(converter, context, 19, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_DIRECT));
+ testSocketLink(converter, context, 20, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_INDIRECT));
+ testSocketLink(converter, context, 21, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_COLOR));
+ testSocketLink(converter, context, 22, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_DIRECT));
+ testSocketLink(converter, context, 23, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_INDIRECT));
+ testSocketLink(converter, context, 24, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_COLOR));
+ testSocketLink(converter, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT));
+ testSocketLink(converter, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT));
+ testSocketLink(converter, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR));
+ testSocketLink(converter, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT));
+ testSocketLink(converter, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT));
+ testSocketLink(converter, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR));
}
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h
index 0c769d32aea..5863cbb390c 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.h
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.h
@@ -31,7 +31,7 @@
class RenderLayersNode : public Node {
public:
RenderLayersNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
private:
- void testSocketConnection(ExecutionSystem *graph, CompositorContext *context, int outputSocketNumber, RenderLayersBaseProg *operation);
+ void testSocketLink(NodeConverter &converter, const CompositorContext &context, int outputSocketNumber, RenderLayersBaseProg *operation) const;
};
diff --git a/source/blender/compositor/nodes/COM_RotateNode.cpp b/source/blender/compositor/nodes/COM_RotateNode.cpp
index d7712323a27..c5fe88b3636 100644
--- a/source/blender/compositor/nodes/COM_RotateNode.cpp
+++ b/source/blender/compositor/nodes/COM_RotateNode.cpp
@@ -31,21 +31,20 @@ RotateNode::RotateNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void RotateNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void RotateNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputDegreeSocket = this->getInputSocket(1);
- OutputSocket *outputSocket = this->getOutputSocket(0);
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputDegreeSocket = this->getInputSocket(1);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
RotateOperation *operation = new RotateOperation();
SetSamplerOperation *sampler = new SetSamplerOperation();
-
sampler->setSampler((PixelSampler)this->getbNode()->custom1);
- addLink(system, sampler->getOutputSocket(), operation->getInputSocket(0));
- inputSocket->relinkConnections(sampler->getInputSocket(0), 0, system);
- inputDegreeSocket->relinkConnections(operation->getInputSocket(1), 1, system);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- system->addOperation(sampler);
- system->addOperation(operation);
+ converter.addOperation(sampler);
+ converter.addOperation(operation);
+ converter.addLink(sampler->getOutputSocket(), operation->getInputSocket(0));
+ converter.mapInputSocket(inputSocket, sampler->getInputSocket(0));
+ converter.mapInputSocket(inputDegreeSocket, operation->getInputSocket(1));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h
index 6e3801e5353..f192fa8db25 100644
--- a/source/blender/compositor/nodes/COM_RotateNode.h
+++ b/source/blender/compositor/nodes/COM_RotateNode.h
@@ -32,7 +32,7 @@
class RotateNode : public Node {
public:
RotateNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp
index e139eb83e04..61eea9227dc 100644
--- a/source/blender/compositor/nodes/COM_ScaleNode.cpp
+++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp
@@ -33,71 +33,70 @@ ScaleNode::ScaleNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputXSocket = this->getInputSocket(1);
- InputSocket *inputYSocket = this->getInputSocket(2);
- OutputSocket *outputSocket = this->getOutputSocket(0);
- BaseScaleOperation *scaleoperation = NULL;
bNode *bnode = this->getbNode();
+
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputXSocket = this->getInputSocket(1);
+ NodeInput *inputYSocket = this->getInputSocket(2);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
switch (bnode->custom1) {
case CMP_SCALE_RELATIVE:
{
ScaleOperation *operation = new ScaleOperation();
-
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
-
- scaleoperation = operation;
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
+ converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
break;
}
case CMP_SCALE_SCENEPERCENT:
{
SetValueOperation *scaleFactorOperation = new SetValueOperation();
- scaleFactorOperation->setValue(context->getRenderData()->size / 100.0f);
+ scaleFactorOperation->setValue(context.getRenderData()->size / 100.0f);
+ converter.addOperation(scaleFactorOperation);
+
ScaleOperation *operation = new ScaleOperation();
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1));
- addLink(graph, scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2));
- graph->addOperation(scaleFactorOperation);
-
- scaleoperation = operation;
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1));
+ converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
break;
}
case CMP_SCALE_RENDERPERCENT:
{
- const RenderData *rd = context->getRenderData();
+ const RenderData *rd = context.getRenderData();
ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation();
-
/* framing options */
operation->setIsAspect((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) != 0);
operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0);
operation->setOffset(bnode->custom3, bnode->custom4);
-
operation->setNewWidth(rd->xsch * rd->size / 100.0f);
operation->setNewHeight(rd->ysch * rd->size / 100.0f);
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- operation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true);
-
- scaleoperation = operation;
+ operation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
break;
}
case CMP_SCALE_ABSOLUTE:
{
- ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated....
-
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
- inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
-
- scaleoperation = operation;
+ /* TODO: what is the use of this one.... perhaps some issues when the ui was updated... */
+ ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation();
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+ converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
+ converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
break;
}
}
-
- outputSocket->relinkConnections(scaleoperation->getOutputSocket(0));
- graph->addOperation(scaleoperation);
}
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h
index 17c7b672a59..d009b3f6781 100644
--- a/source/blender/compositor/nodes/COM_ScaleNode.h
+++ b/source/blender/compositor/nodes/COM_ScaleNode.h
@@ -32,7 +32,7 @@
class ScaleNode : public Node {
public:
ScaleNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cpp b/source/blender/compositor/nodes/COM_SeparateColorNode.cpp
new file mode 100644
index 00000000000..a6fa9065364
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_SeparateColorNode.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Lukas Toenne
+ */
+
+#include "COM_SeparateColorNode.h"
+
+#include "COM_ConvertOperation.h"
+
+
+SeparateColorNode::SeparateColorNode(bNode *editorNode) :
+ Node(editorNode)
+{
+}
+
+void SeparateColorNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
+{
+ NodeInput *imageSocket = this->getInputSocket(0);
+ NodeOutput *outputRSocket = this->getOutputSocket(0);
+ NodeOutput *outputGSocket = this->getOutputSocket(1);
+ NodeOutput *outputBSocket = this->getOutputSocket(2);
+ NodeOutput *outputASocket = this->getOutputSocket(3);
+
+ NodeOperation *color_conv = getColorConverter(context);
+ if (color_conv) {
+ converter.addOperation(color_conv);
+
+ converter.mapInputSocket(imageSocket, color_conv->getInputSocket(0));
+ }
+
+ {
+ SeparateChannelOperation *operation = new SeparateChannelOperation();
+ operation->setChannel(0);
+ converter.addOperation(operation);
+
+ if (color_conv)
+ converter.addLink(color_conv->getOutputSocket(), operation->getInputSocket(0));
+ else
+ converter.mapInputSocket(imageSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputRSocket, operation->getOutputSocket(0));
+ }
+
+ {
+ SeparateChannelOperation *operation = new SeparateChannelOperation();
+ operation->setChannel(1);
+ converter.addOperation(operation);
+
+ if (color_conv)
+ converter.addLink(color_conv->getOutputSocket(), operation->getInputSocket(0));
+ else
+ converter.mapInputSocket(imageSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputGSocket, operation->getOutputSocket(0));
+ }
+
+ {
+ SeparateChannelOperation *operation = new SeparateChannelOperation();
+ operation->setChannel(2);
+ converter.addOperation(operation);
+
+ if (color_conv)
+ converter.addLink(color_conv->getOutputSocket(), operation->getInputSocket(0));
+ else
+ converter.mapInputSocket(imageSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputBSocket, operation->getOutputSocket(0));
+ }
+
+ {
+ SeparateChannelOperation *operation = new SeparateChannelOperation();
+ operation->setChannel(3);
+ converter.addOperation(operation);
+
+ if (color_conv)
+ converter.addLink(color_conv->getOutputSocket(), operation->getInputSocket(0));
+ else
+ converter.mapInputSocket(imageSocket, operation->getInputSocket(0));
+ converter.mapOutputSocket(outputASocket, operation->getOutputSocket(0));
+ }
+}
+
+
+NodeOperation *SeparateRGBANode::getColorConverter(const CompositorContext &context) const
+{
+ return NULL; /* no conversion needed */
+}
+
+NodeOperation *SeparateHSVANode::getColorConverter(const CompositorContext &context) const
+{
+ return new ConvertRGBToHSVOperation();
+}
+
+NodeOperation *SeparateYCCANode::getColorConverter(const CompositorContext &context) const
+{
+ ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation();
+ bNode *editorNode = this->getbNode();
+ operation->setMode(editorNode->custom1);
+ return operation;
+}
+
+NodeOperation *SeparateYUVANode::getColorConverter(const CompositorContext &context) const
+{
+ return new ConvertRGBToYUVOperation();
+}
diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.h b/source/blender/compositor/nodes/COM_SeparateColorNode.h
new file mode 100644
index 00000000000..6730e471e06
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_SeparateColorNode.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Lukas Toenne
+ */
+
+#ifndef _COM_SeparateColorNode_h_
+#define _COM_SeparateColorNode_h_
+
+#include "COM_Node.h"
+
+class SeparateColorNode : public Node {
+public:
+ SeparateColorNode(bNode *editorNode);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
+
+protected:
+ virtual NodeOperation *getColorConverter(const CompositorContext &context) const = 0;
+};
+
+class SeparateRGBANode : public SeparateColorNode {
+public:
+ SeparateRGBANode(bNode *editorNode) :
+ SeparateColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class SeparateHSVANode : public SeparateColorNode {
+public:
+ SeparateHSVANode(bNode *editorNode) :
+ SeparateColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class SeparateYCCANode : public SeparateColorNode {
+public:
+ SeparateYCCANode(bNode *editorNode) :
+ SeparateColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+class SeparateYUVANode : public SeparateColorNode {
+public:
+ SeparateYUVANode(bNode *editorNode) :
+ SeparateColorNode(editorNode)
+ {}
+
+ NodeOperation *getColorConverter(const CompositorContext &context) const;
+};
+
+#endif
diff --git a/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp b/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp
deleted file mode 100644
index 4cd77d4bae6..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateHSVANode.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_SeparateHSVANode.h"
-
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "COM_ConvertOperation.h"
-
-SeparateHSVANode::SeparateHSVANode(bNode *editorNode) : SeparateRGBANode(editorNode)
-{
- /* pass */
-}
-
-void SeparateHSVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertRGBToHSVOperation *operation = new ConvertRGBToHSVOperation();
- InputSocket *inputSocket = this->getInputSocket(0);
- if (inputSocket->isConnected()) {
- inputSocket->relinkConnections(operation->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), inputSocket);
- }
- graph->addOperation(operation);
- SeparateRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_SeparateHSVANode.h b/source/blender/compositor/nodes/COM_SeparateHSVANode.h
deleted file mode 100644
index 6199237ebda..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateHSVANode.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_SeparateHSVANode_h_
-#define _COM_SeparateHSVANode_h_
-
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-#include "COM_SeparateRGBANode.h"
-
-/**
- * @brief SeparateHSVANode
- * @ingroup Node
- */
-class SeparateHSVANode : public SeparateRGBANode {
-public:
- SeparateHSVANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
diff --git a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp b/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp
deleted file mode 100644
index 7d9bff30a93..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_SeparateRGBANode.h"
-
-#include "COM_ConvertOperation.h"
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "DNA_material_types.h" // the ramp types
-
-
-SeparateRGBANode::SeparateRGBANode(bNode *editorNode) : Node(editorNode)
-{
- /* pass */
-}
-
-
-void SeparateRGBANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- InputSocket *imageSocket = this->getInputSocket(0);
- OutputSocket *outputRSocket = this->getOutputSocket(0);
- OutputSocket *outputGSocket = this->getOutputSocket(1);
- OutputSocket *outputBSocket = this->getOutputSocket(2);
- OutputSocket *outputASocket = this->getOutputSocket(3);
-
- if (outputRSocket->isConnected()) {
- SeparateChannelOperation *operation = new SeparateChannelOperation();
- operation->setChannel(0);
- imageSocket->relinkConnectionsDuplicate(operation->getInputSocket(0), 0, graph);
- outputRSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- }
- if (outputGSocket->isConnected()) {
- SeparateChannelOperation *operation = new SeparateChannelOperation();
- operation->setChannel(1);
- imageSocket->relinkConnectionsDuplicate(operation->getInputSocket(0), 0, graph);
- outputGSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- }
- if (outputBSocket->isConnected()) {
- SeparateChannelOperation *operation = new SeparateChannelOperation();
- operation->setChannel(2);
- imageSocket->relinkConnectionsDuplicate(operation->getInputSocket(0), 0, graph);
- outputBSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- }
- if (outputASocket->isConnected()) {
- SeparateChannelOperation *operation = new SeparateChannelOperation();
- operation->setChannel(3);
- imageSocket->relinkConnectionsDuplicate(operation->getInputSocket(0), 0, graph);
- outputASocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- }
-
- /* remove the original connection to the node, this has been duplicated for all operations */
- imageSocket->unlinkConnections(graph);
-}
diff --git a/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp b/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp
deleted file mode 100644
index 797cd49316a..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateYCCANode.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#include "COM_SeparateYCCANode.h"
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "COM_ConvertOperation.h"
-
-SeparateYCCANode::SeparateYCCANode(bNode *editorNode) : SeparateRGBANode(editorNode)
-{
- /* pass */
-}
-
-void SeparateYCCANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation();
- InputSocket *inputSocket = this->getInputSocket(0);
-
- bNode *node = this->getbNode();
- operation->setMode(node->custom1);
-
- if (inputSocket->isConnected()) {
- inputSocket->relinkConnections(operation->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), inputSocket);
- }
- graph->addOperation(operation);
- SeparateRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp b/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp
deleted file mode 100644
index 9a6ec20fa80..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateYUVANode.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#include "COM_SeparateYUVANode.h"
-#include "COM_ExecutionSystem.h"
-#include "COM_SetValueOperation.h"
-#include "COM_ConvertOperation.h"
-
-SeparateYUVANode::SeparateYUVANode(bNode *editorNode) : SeparateRGBANode(editorNode)
-{
- /* pass */
-}
-
-void SeparateYUVANode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
-{
- ConvertRGBToYUVOperation *operation = new ConvertRGBToYUVOperation();
- InputSocket *inputSocket = this->getInputSocket(0);
- if (inputSocket->isConnected()) {
- inputSocket->relinkConnections(operation->getInputSocket(0));
- addLink(graph, operation->getOutputSocket(), inputSocket);
- }
- graph->addOperation(operation);
- SeparateRGBANode::convertToOperations(graph, context);
-}
diff --git a/source/blender/compositor/nodes/COM_SeparateYUVANode.h b/source/blender/compositor/nodes/COM_SeparateYUVANode.h
deleted file mode 100644
index e51c0ce4fa6..00000000000
--- a/source/blender/compositor/nodes/COM_SeparateYUVANode.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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:
- * Dalai Felinto
- */
-
-#ifndef _COM_SeparateYUVANode_h_
-#define _COM_SeparateYUVANode_h_
-
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-#include "COM_SeparateRGBANode.h"
-
-/**
- * @brief SeparateYUVANode
- * @ingroup Node
- */
-class SeparateYUVANode : public SeparateRGBANode {
-public:
- SeparateYUVANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
index dd3ff5fbaa7..22ddd5bb157 100644
--- a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
+++ b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
@@ -24,17 +24,17 @@
#include "COM_SetAlphaOperation.h"
#include "COM_ExecutionSystem.h"
-void SetAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void SetAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
SetAlphaOperation *operation = new SetAlphaOperation();
-
- if (!this->getInputSocket(0)->isConnected() && this->getInputSocket(1)->isConnected()) {
+
+ if (!this->getInputSocket(0)->isLinked() && this->getInputSocket(1)->isLinked()) {
operation->setResolutionInputSocketIndex(1);
}
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h
index e82fa210a89..6dbc7ebed04 100644
--- a/source/blender/compositor/nodes/COM_SetAlphaNode.h
+++ b/source/blender/compositor/nodes/COM_SetAlphaNode.h
@@ -32,7 +32,7 @@
class SetAlphaNode : public Node {
public:
SetAlphaNode(bNode *editorNode) : Node(editorNode) {}
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
index c822d2107ec..f750a44a788 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_SocketProxyNode.h"
-#include "COM_SocketConnection.h"
#include "COM_SocketProxyOperation.h"
#include "COM_ExecutionSystem.h"
#include "COM_SetValueOperation.h"
@@ -30,15 +29,14 @@
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
-SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer) : Node(editorNode, false)
+SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput) : Node(editorNode, false)
{
DataType dt;
- this->m_buffer = buffer;
dt = COM_DT_VALUE;
if (editorInput->type == SOCK_RGBA) dt = COM_DT_COLOR;
if (editorInput->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
- this->addInputSocket(dt, (InputSocketResizeMode)editorInput->resizemode, editorInput);
+ this->addInputSocket(dt, editorInput);
dt = COM_DT_VALUE;
if (editorOutput->type == SOCK_RGBA) dt = COM_DT_COLOR;
@@ -46,59 +44,39 @@ SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bN
this->addOutputSocket(dt, editorOutput);
}
-void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void SocketProxyNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- OutputSocket *outputsocket = this->getOutputSocket(0);
- InputSocket *inputsocket = this->getInputSocket(0);
- if (inputsocket->isConnected()) {
- SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType());
- inputsocket->relinkConnections(operation->getInputSocket(0));
- outputsocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
-
- if (m_buffer) {
- WriteBufferOperation *writeOperation = new WriteBufferOperation();
- ReadBufferOperation *readOperation = new ReadBufferOperation();
- readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
-
- operation->getOutputSocket()->relinkConnections(readOperation->getOutputSocket());
- addLink(graph, operation->getOutputSocket(), writeOperation->getInputSocket(0));
-
- graph->addOperation(writeOperation);
- graph->addOperation(readOperation);
- }
- }
- else if (outputsocket->isConnected()) {
- /* If input is not connected, add a constant value operation instead */
- switch (outputsocket->getDataType()) {
- case COM_DT_VALUE:
- {
- SetValueOperation *operation = new SetValueOperation();
- operation->setValue(inputsocket->getEditorValueFloat());
- outputsocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- break;
- }
- case COM_DT_COLOR:
- {
- SetColorOperation *operation = new SetColorOperation();
- float col[4];
- inputsocket->getEditorValueColor(col);
- operation->setChannels(col);
- outputsocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- break;
- }
- case COM_DT_VECTOR:
- {
- SetVectorOperation *operation = new SetVectorOperation();
- float vec[3];
- inputsocket->getEditorValueVector(vec);
- operation->setVector(vec);
- outputsocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
- break;
- }
- }
- }
+ NodeOperationOutput *proxy_output = converter.addInputProxy(getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), proxy_output);
+}
+
+
+SocketBufferNode::SocketBufferNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput) : Node(editorNode, false)
+{
+ DataType dt;
+
+ dt = COM_DT_VALUE;
+ if (editorInput->type == SOCK_RGBA) dt = COM_DT_COLOR;
+ if (editorInput->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
+ this->addInputSocket(dt, editorInput);
+
+ dt = COM_DT_VALUE;
+ if (editorOutput->type == SOCK_RGBA) dt = COM_DT_COLOR;
+ if (editorOutput->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
+ this->addOutputSocket(dt, editorOutput);
+}
+
+void SocketBufferNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
+{
+ NodeOutput *output = this->getOutputSocket(0);
+ NodeInput *input = this->getInputSocket(0);
+
+ WriteBufferOperation *writeOperation = new WriteBufferOperation();
+ ReadBufferOperation *readOperation = new ReadBufferOperation();
+ readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
+ converter.addOperation(writeOperation);
+ converter.addOperation(readOperation);
+
+ converter.mapInputSocket(input, writeOperation->getInputSocket(0));
+ converter.mapOutputSocket(output, readOperation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h
index b679901ba2c..2fbaa71421c 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.h
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h
@@ -30,13 +30,16 @@
* @ingroup Node
*/
class SocketProxyNode : public Node {
-private:
- bool m_buffer;
public:
- SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
+};
+
- virtual bool isProxyNode() const { return true; }
+class SocketBufferNode : public Node {
+public:
+ SocketBufferNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
index 6fb8467674b..8eb1b76e890 100644
--- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
@@ -32,14 +32,14 @@ SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void SplitViewerNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
- bool is_active = ((editorNode->flag & NODE_DO_OUTPUT_RECALC || context->isRendering()) &&
+ bool is_active = ((editorNode->flag & NODE_DO_OUTPUT_RECALC || context.isRendering()) &&
(editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup());
- InputSocket *image1Socket = this->getInputSocket(0);
- InputSocket *image2Socket = this->getInputSocket(1);
+ NodeInput *image1Socket = this->getInputSocket(0);
+ NodeInput *image2Socket = this->getInputSocket(1);
Image *image = (Image *)this->getbNode()->id;
ImageUser *imageUser = (ImageUser *) this->getbNode()->storage;
@@ -47,15 +47,16 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont
splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
splitViewerOperation->setXSplit(!this->getbNode()->custom2);
- image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
- image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph);
+ converter.addOperation(splitViewerOperation);
+ converter.mapInputSocket(image1Socket, splitViewerOperation->getInputSocket(0));
+ converter.mapInputSocket(image2Socket, splitViewerOperation->getInputSocket(1));
ViewerOperation *viewerOperation = new ViewerOperation();
viewerOperation->setImage(image);
viewerOperation->setImageUser(imageUser);
viewerOperation->setActive(is_active);
- viewerOperation->setViewSettings(context->getViewSettings());
- viewerOperation->setDisplaySettings(context->getDisplaySettings());
+ viewerOperation->setViewSettings(context.getViewSettings());
+ viewerOperation->setDisplaySettings(context.getDisplaySettings());
/* defaults - the viewer node has these options but not exposed for split view
* we could use the split to define an area of interest on one axis at least */
@@ -63,10 +64,8 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont
viewerOperation->setCenterX(0.5f);
viewerOperation->setCenterY(0.5f);
- addLink(graph, splitViewerOperation->getOutputSocket(), viewerOperation->getInputSocket(0));
+ converter.addOperation(viewerOperation);
+ converter.addLink(splitViewerOperation->getOutputSocket(), viewerOperation->getInputSocket(0));
- addPreviewOperation(graph, context, viewerOperation->getInputSocket(0));
-
- graph->addOperation(splitViewerOperation);
- graph->addOperation(viewerOperation);
+ converter.addPreview(splitViewerOperation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.h b/source/blender/compositor/nodes/COM_SplitViewerNode.h
index f17cfd57cbf..1cc0c4cb9a8 100644
--- a/source/blender/compositor/nodes/COM_SplitViewerNode.h
+++ b/source/blender/compositor/nodes/COM_SplitViewerNode.h
@@ -32,6 +32,6 @@
class SplitViewerNode : public Node {
public:
SplitViewerNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp b/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp
index 8f17c4d9345..d1babcc8103 100644
--- a/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp
+++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.cpp
@@ -38,60 +38,59 @@ Stabilize2dNode::Stabilize2dNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void Stabilize2dNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void Stabilize2dNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *imageInput = this->getInputSocket(0);
+ NodeInput *imageInput = this->getInputSocket(0);
MovieClip *clip = (MovieClip *)getbNode()->id;
ScaleOperation *scaleOperation = new ScaleOperation();
+ scaleOperation->setSampler((PixelSampler)this->getbNode()->custom1);
RotateOperation *rotateOperation = new RotateOperation();
+ rotateOperation->setDoDegree2RadConversion(false);
TranslateOperation *translateOperation = new TranslateOperation();
MovieClipAttributeOperation *scaleAttribute = new MovieClipAttributeOperation();
MovieClipAttributeOperation *angleAttribute = new MovieClipAttributeOperation();
MovieClipAttributeOperation *xAttribute = new MovieClipAttributeOperation();
MovieClipAttributeOperation *yAttribute = new MovieClipAttributeOperation();
SetSamplerOperation *psoperation = new SetSamplerOperation();
-
+ psoperation->setSampler((PixelSampler)this->getbNode()->custom1);
+
scaleAttribute->setAttribute(MCA_SCALE);
- scaleAttribute->setFramenumber(context->getFramenumber());
+ scaleAttribute->setFramenumber(context.getFramenumber());
scaleAttribute->setMovieClip(clip);
-
+
angleAttribute->setAttribute(MCA_ANGLE);
- angleAttribute->setFramenumber(context->getFramenumber());
+ angleAttribute->setFramenumber(context.getFramenumber());
angleAttribute->setMovieClip(clip);
-
+
xAttribute->setAttribute(MCA_X);
- xAttribute->setFramenumber(context->getFramenumber());
+ xAttribute->setFramenumber(context.getFramenumber());
xAttribute->setMovieClip(clip);
yAttribute->setAttribute(MCA_Y);
- yAttribute->setFramenumber(context->getFramenumber());
+ yAttribute->setFramenumber(context.getFramenumber());
yAttribute->setMovieClip(clip);
- imageInput->relinkConnections(scaleOperation->getInputSocket(0), 0, graph);
- addLink(graph, scaleAttribute->getOutputSocket(), scaleOperation->getInputSocket(1));
- addLink(graph, scaleAttribute->getOutputSocket(), scaleOperation->getInputSocket(2));
+ converter.addOperation(scaleAttribute);
+ converter.addOperation(angleAttribute);
+ converter.addOperation(xAttribute);
+ converter.addOperation(yAttribute);
+ converter.addOperation(scaleOperation);
+ converter.addOperation(translateOperation);
+ converter.addOperation(rotateOperation);
+ converter.addOperation(psoperation);
- scaleOperation->setSampler((PixelSampler)this->getbNode()->custom1);
+ converter.mapInputSocket(imageInput, scaleOperation->getInputSocket(0));
+ converter.addLink(scaleAttribute->getOutputSocket(), scaleOperation->getInputSocket(1));
+ converter.addLink(scaleAttribute->getOutputSocket(), scaleOperation->getInputSocket(2));
- addLink(graph, scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
- addLink(graph, angleAttribute->getOutputSocket(), rotateOperation->getInputSocket(1));
- rotateOperation->setDoDegree2RadConversion(false);
+ converter.addLink(scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
+ converter.addLink(angleAttribute->getOutputSocket(), rotateOperation->getInputSocket(1));
- addLink(graph, rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
- addLink(graph, xAttribute->getOutputSocket(), translateOperation->getInputSocket(1));
- addLink(graph, yAttribute->getOutputSocket(), translateOperation->getInputSocket(2));
-
- psoperation->setSampler((PixelSampler)this->getbNode()->custom1);
- addLink(graph, translateOperation->getOutputSocket(), psoperation->getInputSocket(0));
- this->getOutputSocket()->relinkConnections(psoperation->getOutputSocket());
+ converter.addLink(rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
+ converter.addLink(xAttribute->getOutputSocket(), translateOperation->getInputSocket(1));
+ converter.addLink(yAttribute->getOutputSocket(), translateOperation->getInputSocket(2));
- graph->addOperation(scaleAttribute);
- graph->addOperation(angleAttribute);
- graph->addOperation(xAttribute);
- graph->addOperation(yAttribute);
- graph->addOperation(scaleOperation);
- graph->addOperation(translateOperation);
- graph->addOperation(rotateOperation);
- graph->addOperation(psoperation);
+ converter.addLink(translateOperation->getOutputSocket(), psoperation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(), psoperation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h
index 3363ff4142c..3b5890460c2 100644
--- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h
+++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.h
@@ -33,7 +33,7 @@
class Stabilize2dNode : public Node {
public:
Stabilize2dNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_SwitchNode.cpp b/source/blender/compositor/nodes/COM_SwitchNode.cpp
index 2a4616fcd3e..692b8d743f6 100644
--- a/source/blender/compositor/nodes/COM_SwitchNode.cpp
+++ b/source/blender/compositor/nodes/COM_SwitchNode.cpp
@@ -21,27 +21,21 @@
*/
#include "COM_SwitchNode.h"
-#include "COM_ExecutionSystem.h"
-#include "COM_SocketProxyOperation.h"
SwitchNode::SwitchNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
-
-void SwitchNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void SwitchNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- SocketProxyOperation *operation = new SocketProxyOperation(COM_DT_COLOR);
- int switchFrame = this->getbNode()->custom1;
-
- if (!switchFrame) {
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- }
- else {
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(0), 1, graph);
- }
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
- graph->addOperation(operation);
+ bool condition = this->getbNode()->custom1;
+
+ NodeOperationOutput *result;
+ if (!condition)
+ result = converter.addInputProxy(getInputSocket(0));
+ else
+ result = converter.addInputProxy(getInputSocket(1));
+
+ converter.mapOutputSocket(getOutputSocket(0), result);
}
diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h
index 16d9e18885b..4fedf4b0aa7 100644
--- a/source/blender/compositor/nodes/COM_SwitchNode.h
+++ b/source/blender/compositor/nodes/COM_SwitchNode.h
@@ -33,6 +33,6 @@
class SwitchNode : public Node {
public:
SwitchNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp
index 6f2baa63b0e..2ac027ca326 100644
--- a/source/blender/compositor/nodes/COM_TextureNode.cpp
+++ b/source/blender/compositor/nodes/COM_TextureNode.cpp
@@ -29,30 +29,31 @@ TextureNode::TextureNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TextureNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void TextureNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
Tex *texture = (Tex *)editorNode->id;
TextureOperation *operation = new TextureOperation();
- const ColorManagedDisplaySettings *displaySettings = context->getDisplaySettings();
+ const ColorManagedDisplaySettings *displaySettings = context.getDisplaySettings();
bool sceneColorManage = strcmp(displaySettings->display_device, "None") != 0;
- this->getOutputSocket(1)->relinkConnections(operation->getOutputSocket());
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system);
operation->setTexture(texture);
- operation->setRenderData(context->getRenderData());
+ operation->setRenderData(context.getRenderData());
operation->setSceneColorManage(sceneColorManage);
- system->addOperation(operation);
- addPreviewOperation(system, context, operation->getOutputSocket());
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(1), operation->getOutputSocket());
+
+ converter.addPreview(operation->getOutputSocket());
- if (this->getOutputSocket(0)->isConnected()) {
- TextureAlphaOperation *alphaOperation = new TextureAlphaOperation();
- this->getOutputSocket(0)->relinkConnections(alphaOperation->getOutputSocket());
- addLink(system, operation->getInputSocket(0)->getConnection()->getFromSocket(), alphaOperation->getInputSocket(0));
- addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), alphaOperation->getInputSocket(1));
- alphaOperation->setTexture(texture);
- alphaOperation->setRenderData(context->getRenderData());
- alphaOperation->setSceneColorManage(sceneColorManage);
- system->addOperation(alphaOperation);
- }
+ TextureAlphaOperation *alphaOperation = new TextureAlphaOperation();
+ alphaOperation->setTexture(texture);
+ alphaOperation->setRenderData(context.getRenderData());
+ alphaOperation->setSceneColorManage(sceneColorManage);
+ converter.addOperation(alphaOperation);
+
+ converter.mapInputSocket(getInputSocket(0), alphaOperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), alphaOperation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(0), alphaOperation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_TextureNode.h b/source/blender/compositor/nodes/COM_TextureNode.h
index e0d931c65da..8d0fb467b1b 100644
--- a/source/blender/compositor/nodes/COM_TextureNode.h
+++ b/source/blender/compositor/nodes/COM_TextureNode.h
@@ -30,5 +30,5 @@
class TextureNode : public Node {
public:
TextureNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp
index 83f99a16d9f..b5e8ece9028 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.cpp
+++ b/source/blender/compositor/nodes/COM_TimeNode.cpp
@@ -33,15 +33,14 @@ TimeNode::TimeNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void TimeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
SetValueOperation *operation = new SetValueOperation();
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
bNode *node = this->getbNode();
/* stack order output: fac */
float fac = 0.0f;
- const int framenumber = context->getFramenumber();
+ const int framenumber = context.getFramenumber();
if (framenumber < node->custom1) {
fac = 0.0f;
@@ -50,11 +49,13 @@ void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
fac = 1.0f;
}
else if (node->custom1 < node->custom2) {
- fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
+ fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
}
curvemapping_initialize((CurveMapping *)node->storage);
fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
operation->setValue(CLAMPIS(fac, 0.0f, 1.0f));
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h
index df3cf024714..078720f7150 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.h
+++ b/source/blender/compositor/nodes/COM_TimeNode.h
@@ -32,7 +32,7 @@
class TimeNode : public Node {
public:
TimeNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cpp b/source/blender/compositor/nodes/COM_TonemapNode.cpp
index 440e6b62414..5ac73b9f9c2 100644
--- a/source/blender/compositor/nodes/COM_TonemapNode.cpp
+++ b/source/blender/compositor/nodes/COM_TonemapNode.cpp
@@ -29,13 +29,14 @@ TonemapNode::TonemapNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TonemapNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void TonemapNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeTonemap *data = (NodeTonemap *)this->getbNode()->storage;
+
TonemapOperation *operation = data->type == 1 ? new PhotoreceptorTonemapOperation() : new TonemapOperation();
- operation->setbNode(this->getbNode());
operation->setData(data);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
- system->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h
index ad0d218826a..4a8636fd041 100644
--- a/source/blender/compositor/nodes/COM_TonemapNode.h
+++ b/source/blender/compositor/nodes/COM_TonemapNode.h
@@ -32,7 +32,7 @@
class TonemapNode : public Node {
public:
TonemapNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp
index bb8cecc60ad..75c8c786ae8 100644
--- a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp
+++ b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp
@@ -36,27 +36,24 @@ TrackPositionNode::TrackPositionNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void TrackPositionNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- OutputSocket *outputX = this->getOutputSocket(0);
- OutputSocket *outputY = this->getOutputSocket(1);
-
bNode *editorNode = this->getbNode();
MovieClip *clip = (MovieClip *) editorNode->id;
-
NodeTrackPosData *trackpos_data = (NodeTrackPosData *) editorNode->storage;
+
+ NodeOutput *outputX = this->getOutputSocket(0);
+ NodeOutput *outputY = this->getOutputSocket(1);
int frame_number;
if (editorNode->custom1 == CMP_TRACKPOS_ABSOLUTE_FRAME) {
frame_number = editorNode->custom2;
}
else {
- frame_number = context->getFramenumber();
+ frame_number = context.getFramenumber();
}
TrackPositionOperation *operationX = new TrackPositionOperation();
- TrackPositionOperation *operationY = new TrackPositionOperation();
-
operationX->setMovieClip(clip);
operationX->setTrackingObject(trackpos_data->tracking_object);
operationX->setTrackName(trackpos_data->track_name);
@@ -64,7 +61,9 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo
operationX->setAxis(0);
operationX->setPosition(editorNode->custom1);
operationX->setRelativeFrame(editorNode->custom2);
-
+ converter.addOperation(operationX);
+
+ TrackPositionOperation *operationY = new TrackPositionOperation();
operationY->setMovieClip(clip);
operationY->setTrackingObject(trackpos_data->tracking_object);
operationY->setTrackName(trackpos_data->track_name);
@@ -72,10 +71,8 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo
operationY->setAxis(1);
operationY->setPosition(editorNode->custom1);
operationY->setRelativeFrame(editorNode->custom2);
-
- outputX->relinkConnections(operationX->getOutputSocket());
- outputY->relinkConnections(operationY->getOutputSocket());
-
- graph->addOperation(operationX);
- graph->addOperation(operationY);
+ converter.addOperation(operationY);
+
+ converter.mapOutputSocket(outputX, operationX->getOutputSocket());
+ converter.mapOutputSocket(outputY, operationY->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.h b/source/blender/compositor/nodes/COM_TrackPositionNode.h
index 3d92ec3978c..375e28b6f8f 100644
--- a/source/blender/compositor/nodes/COM_TrackPositionNode.h
+++ b/source/blender/compositor/nodes/COM_TrackPositionNode.h
@@ -31,6 +31,6 @@
class TrackPositionNode : public Node {
public:
TrackPositionNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
diff --git a/source/blender/compositor/nodes/COM_TransformNode.cpp b/source/blender/compositor/nodes/COM_TransformNode.cpp
index 154761665cf..f1d5771bab3 100644
--- a/source/blender/compositor/nodes/COM_TransformNode.cpp
+++ b/source/blender/compositor/nodes/COM_TransformNode.cpp
@@ -33,38 +33,39 @@ TransformNode::TransformNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TransformNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void TransformNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *imageInput = this->getInputSocket(0);
- InputSocket *xInput = this->getInputSocket(1);
- InputSocket *yInput = this->getInputSocket(2);
- InputSocket *angleInput = this->getInputSocket(3);
- InputSocket *scaleInput = this->getInputSocket(4);
+ NodeInput *imageInput = this->getInputSocket(0);
+ NodeInput *xInput = this->getInputSocket(1);
+ NodeInput *yInput = this->getInputSocket(2);
+ NodeInput *angleInput = this->getInputSocket(3);
+ NodeInput *scaleInput = this->getInputSocket(4);
ScaleOperation *scaleOperation = new ScaleOperation();
+ converter.addOperation(scaleOperation);
+
RotateOperation *rotateOperation = new RotateOperation();
+ rotateOperation->setDoDegree2RadConversion(false);
+ converter.addOperation(rotateOperation);
+
TranslateOperation *translateOperation = new TranslateOperation();
+ converter.addOperation(translateOperation);
+
SetSamplerOperation *sampler = new SetSamplerOperation();
-
sampler->setSampler((PixelSampler)this->getbNode()->custom1);
+ converter.addOperation(sampler);
- imageInput->relinkConnections(sampler->getInputSocket(0), 0, graph);
- addLink(graph, sampler->getOutputSocket(), scaleOperation->getInputSocket(0));
- scaleInput->relinkConnections(scaleOperation->getInputSocket(1), 4, graph);
- addLink(graph, scaleOperation->getInputSocket(1)->getConnection()->getFromSocket(), scaleOperation->getInputSocket(2)); // xscale = yscale
+ converter.mapInputSocket(imageInput, sampler->getInputSocket(0));
+ converter.addLink(sampler->getOutputSocket(), scaleOperation->getInputSocket(0));
+ converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(1));
+ converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(2)); // xscale = yscale
- addLink(graph, scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
- rotateOperation->setDoDegree2RadConversion(false);
- angleInput->relinkConnections(rotateOperation->getInputSocket(1), 3, graph);
-
- addLink(graph, rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
- xInput->relinkConnections(translateOperation->getInputSocket(1), 1, graph);
- yInput->relinkConnections(translateOperation->getInputSocket(2), 2, graph);
+ converter.addLink(scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
+ converter.mapInputSocket(angleInput, rotateOperation->getInputSocket(1));
- this->getOutputSocket()->relinkConnections(translateOperation->getOutputSocket());
+ converter.addLink(rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
+ converter.mapInputSocket(xInput, translateOperation->getInputSocket(1));
+ converter.mapInputSocket(yInput, translateOperation->getInputSocket(2));
- graph->addOperation(sampler);
- graph->addOperation(scaleOperation);
- graph->addOperation(rotateOperation);
- graph->addOperation(translateOperation);
+ converter.mapOutputSocket(getOutputSocket(), translateOperation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h
index 666f2da775e..6e210d266de 100644
--- a/source/blender/compositor/nodes/COM_TransformNode.h
+++ b/source/blender/compositor/nodes/COM_TransformNode.h
@@ -33,7 +33,7 @@
class TransformNode : public Node {
public:
TransformNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif /* __COM_TRANSFORMNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cpp b/source/blender/compositor/nodes/COM_TranslateNode.cpp
index d2cd009449c..990cbe19be2 100644
--- a/source/blender/compositor/nodes/COM_TranslateNode.cpp
+++ b/source/blender/compositor/nodes/COM_TranslateNode.cpp
@@ -32,44 +32,43 @@ TranslateNode::TranslateNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void TranslateNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void TranslateNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *inputSocket = this->getInputSocket(0);
- InputSocket *inputXSocket = this->getInputSocket(1);
- InputSocket *inputYSocket = this->getInputSocket(2);
- OutputSocket *outputSocket = this->getOutputSocket(0);
- TranslateOperation *operation = new TranslateOperation();
-
bNode *bnode = this->getbNode();
NodeTranslateData *data = (NodeTranslateData *)bnode->storage;
-
+
+ NodeInput *inputSocket = this->getInputSocket(0);
+ NodeInput *inputXSocket = this->getInputSocket(1);
+ NodeInput *inputYSocket = this->getInputSocket(2);
+ NodeOutput *outputSocket = this->getOutputSocket(0);
+
+ TranslateOperation *operation = new TranslateOperation();
+ if (data->relative) {
+ const RenderData *rd = context.getRenderData();
+ float fx = rd->xsch * rd->size / 100.0f;
+ float fy = rd->ysch * rd->size / 100.0f;
+
+ operation->setFactorXY(fx, fy);
+ }
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
+ converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
+ converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
+
if (data->wrap_axis) {
WriteBufferOperation *writeOperation = new WriteBufferOperation();
WrapOperation *wrapOperation = new WrapOperation();
wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy());
wrapOperation->setWrapping(data->wrap_axis);
- inputSocket->relinkConnections(writeOperation->getInputSocket(0), 0, graph);
- addLink(graph, wrapOperation->getOutputSocket(), operation->getInputSocket(0));
-
- graph->addOperation(writeOperation);
- graph->addOperation(wrapOperation);
+ converter.addOperation(writeOperation);
+ converter.addOperation(wrapOperation);
+ converter.mapInputSocket(inputSocket, writeOperation->getInputSocket(0));
+ converter.addLink(wrapOperation->getOutputSocket(), operation->getInputSocket(0));
}
else {
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
+ converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
}
-
- if (data->relative) {
- const RenderData *rd = context->getRenderData();
- float fx = rd->xsch * rd->size / 100.0f;
- float fy = rd->ysch * rd->size / 100.0f;
-
- operation->setFactorXY(fx, fy);
- }
-
- inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
- inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
- outputSocket->relinkConnections(operation->getOutputSocket(0));
- graph->addOperation(operation);
}
diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h
index 8c350e9cfb3..160da410aff 100644
--- a/source/blender/compositor/nodes/COM_TranslateNode.h
+++ b/source/blender/compositor/nodes/COM_TranslateNode.h
@@ -32,7 +32,7 @@
class TranslateNode : public Node {
public:
TranslateNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ValueNode.cpp b/source/blender/compositor/nodes/COM_ValueNode.cpp
index ed4440aa099..62a312da67c 100644
--- a/source/blender/compositor/nodes/COM_ValueNode.cpp
+++ b/source/blender/compositor/nodes/COM_ValueNode.cpp
@@ -29,11 +29,12 @@ ValueNode::ValueNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ValueNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
SetValueOperation *operation = new SetValueOperation();
- OutputSocket *output = this->getOutputSocket(0);
- output->relinkConnections(operation->getOutputSocket());
+ NodeOutput *output = this->getOutputSocket(0);
operation->setValue(output->getEditorValueFloat());
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapOutputSocket(output, operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h
index 4f478ae93af..e5b80fb4c60 100644
--- a/source/blender/compositor/nodes/COM_ValueNode.h
+++ b/source/blender/compositor/nodes/COM_ValueNode.h
@@ -32,7 +32,7 @@
class ValueNode : public Node {
public:
ValueNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp
index 07c8120b1d2..cbe02388f90 100644
--- a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp
@@ -29,17 +29,18 @@ VectorBlurNode::VectorBlurNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void VectorBlurNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void VectorBlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *node = this->getbNode();
NodeBlurData *vectorBlurSettings = (NodeBlurData *)node->storage;
+
VectorBlurOperation *operation = new VectorBlurOperation();
- operation->setbNode(node);
operation->setVectorBlurSettings(vectorBlurSettings);
- operation->setQuality(context->getQuality());
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, system);
- this->getOutputSocket()->relinkConnections(operation->getOutputSocket());
- system->addOperation(operation);
+ operation->setQuality(context.getQuality());
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h
index 6b5d277a54b..f402aee9670 100644
--- a/source/blender/compositor/nodes/COM_VectorBlurNode.h
+++ b/source/blender/compositor/nodes/COM_VectorBlurNode.h
@@ -32,7 +32,7 @@
class VectorBlurNode : public Node {
public:
VectorBlurNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp
index dcf1059ece6..197b2c8bd0c 100644
--- a/source/blender/compositor/nodes/COM_VectorCurveNode.cpp
+++ b/source/blender/compositor/nodes/COM_VectorCurveNode.cpp
@@ -29,14 +29,12 @@ VectorCurveNode::VectorCurveNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void VectorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void VectorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
VectorCurveOperation *operation = new VectorCurveOperation();
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-
operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
-
- graph->addOperation(operation);
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h
index 3201090df14..8499bbf99df 100644
--- a/source/blender/compositor/nodes/COM_VectorCurveNode.h
+++ b/source/blender/compositor/nodes/COM_VectorCurveNode.h
@@ -32,7 +32,7 @@
class VectorCurveNode : public Node {
public:
VectorCurveNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp
index a515bfc7f47..30f51794e8d 100644
--- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp
@@ -31,52 +31,34 @@ ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ViewLevelsNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- InputSocket *input = this->getInputSocket(0);
- bool firstOperationConnected = false;
- if (input->isConnected()) {
- OutputSocket *inputSocket = input->getConnection()->getFromSocket();
+ NodeInput *input = this->getInputSocket(0);
+ if (input->isLinked()) {
// add preview to inputSocket;
- OutputSocket *socket = this->getOutputSocket(0);
- if (socket->isConnected()) {
- // calculate mean operation
+ /* calculate mean operation */
+ {
CalculateMeanOperation *operation = new CalculateMeanOperation();
- input->relinkConnections(operation->getInputSocket(0), 0, graph);
- firstOperationConnected = true;
operation->setSetting(this->getbNode()->custom1);
- socket->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(input, operation->getInputSocket(0));
+ converter.mapOutputSocket(this->getOutputSocket(0), operation->getOutputSocket());
}
- socket = this->getOutputSocket(1);
- if (socket->isConnected()) {
- // calculate standard deviation operation
+ /* calculate standard deviation operation */
+ {
CalculateStandardDeviationOperation *operation = new CalculateStandardDeviationOperation();
- if (firstOperationConnected) {
- addLink(graph, inputSocket, operation->getInputSocket(0));
- }
- else {
- input->relinkConnections(operation->getInputSocket(0), 0, graph);
- }
operation->setSetting(this->getbNode()->custom1);
- socket->relinkConnections(operation->getOutputSocket());
- graph->addOperation(operation);
+
+ converter.addOperation(operation);
+ converter.mapInputSocket(input, operation->getInputSocket(0));
+ converter.mapOutputSocket(this->getOutputSocket(1), operation->getOutputSocket());
}
}
else {
- SetValueOperation *meanOutput = new SetValueOperation();
- SetValueOperation *stdDevOutput = new SetValueOperation();
-
- meanOutput->setValue(0.0f);
- stdDevOutput->setValue(0.0f);
-
- this->getOutputSocket(0)->relinkConnections(meanOutput->getOutputSocket());
- this->getOutputSocket(1)->relinkConnections(stdDevOutput->getOutputSocket());
-
- graph->addOperation(meanOutput);
- graph->addOperation(stdDevOutput);
+ converter.addOutputValue(getOutputSocket(0), 0.0f);
+ converter.addOutputValue(getOutputSocket(1), 0.0f);
}
}
-
diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h
index 2ac84fad22f..dbcc770f88a 100644
--- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h
+++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.h
@@ -32,7 +32,7 @@
class ViewLevelsNode : public Node {
public:
ViewLevelsNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp
index 531fa4158bc..09a3cea2da1 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp
@@ -31,41 +31,47 @@ ViewerNode::ViewerNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
-void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+void ViewerNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
- bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC || context->isRendering()) &&
+ bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC || context.isRendering()) &&
((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup());
+ bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA;
- InputSocket *imageSocket = this->getInputSocket(0);
- InputSocket *alphaSocket = this->getInputSocket(1);
- InputSocket *depthSocket = this->getInputSocket(2);
+ NodeInput *imageSocket = this->getInputSocket(0);
+ NodeInput *alphaSocket = this->getInputSocket(1);
+ NodeInput *depthSocket = this->getInputSocket(2);
Image *image = (Image *)this->getbNode()->id;
ImageUser *imageUser = (ImageUser *) this->getbNode()->storage;
ViewerOperation *viewerOperation = new ViewerOperation();
- viewerOperation->setbNodeTree(context->getbNodeTree());
+ viewerOperation->setbNodeTree(context.getbNodeTree());
viewerOperation->setImage(image);
viewerOperation->setImageUser(imageUser);
viewerOperation->setActive(is_active);
viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1);
viewerOperation->setCenterX(editorNode->custom3);
viewerOperation->setCenterY(editorNode->custom4);
- viewerOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
+ /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */
+ viewerOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked());
- viewerOperation->setViewSettings(context->getViewSettings());
- viewerOperation->setDisplaySettings(context->getDisplaySettings());
+ viewerOperation->setViewSettings(context.getViewSettings());
+ viewerOperation->setDisplaySettings(context.getDisplaySettings());
viewerOperation->setResolutionInputSocketIndex(0);
- if (!imageSocket->isConnected()) {
- if (alphaSocket->isConnected()) {
+ if (!imageSocket->isLinked()) {
+ if (alphaSocket->isLinked()) {
viewerOperation->setResolutionInputSocketIndex(1);
}
}
- imageSocket->relinkConnections(viewerOperation->getInputSocket(0), 0, graph);
- alphaSocket->relinkConnections(viewerOperation->getInputSocket(1));
- depthSocket->relinkConnections(viewerOperation->getInputSocket(2));
- graph->addOperation(viewerOperation);
+ converter.addOperation(viewerOperation);
+ converter.mapInputSocket(imageSocket, viewerOperation->getInputSocket(0));
+ /* only use alpha link if "use alpha" is enabled */
+ if (ignore_alpha)
+ converter.addInputValue(viewerOperation->getInputSocket(1), 1.0f);
+ else
+ converter.mapInputSocket(alphaSocket, viewerOperation->getInputSocket(1));
+ converter.mapInputSocket(depthSocket, viewerOperation->getInputSocket(2));
- addPreviewOperation(graph, context, viewerOperation->getInputSocket(0));
+ converter.addNodeInputPreview(imageSocket);
}
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h
index 3a9954b8aea..289c2650342 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.h
+++ b/source/blender/compositor/nodes/COM_ViewerNode.h
@@ -32,6 +32,6 @@
class ViewerNode : public Node {
public:
ViewerNode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cpp b/source/blender/compositor/nodes/COM_ZCombineNode.cpp
index 685c9695eec..d46600cc368 100644
--- a/source/blender/compositor/nodes/COM_ZCombineNode.cpp
+++ b/source/blender/compositor/nodes/COM_ZCombineNode.cpp
@@ -32,79 +32,71 @@
#include "DNA_material_types.h" // the ramp types
-void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
+void ZCombineNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- if ((context->getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
- if (this->getOutputSocket(0)->isConnected()) {
- ZCombineOperation *operation = NULL;
- if (this->getbNode()->custom1) {
- operation = new ZCombineAlphaOperation();
- }
- else {
- operation = new ZCombineOperation();
- }
-
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
- this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system);
- this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, system);
- this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, system);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- system->addOperation(operation);
- if (this->getOutputSocket(1)->isConnected()) {
- MathMinimumOperation *zoperation = new MathMinimumOperation();
- addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(0));
- addLink(system, operation->getInputSocket(3)->getConnection()->getFromSocket(), zoperation->getInputSocket(1));
- this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
- system->addOperation(zoperation);
- }
+ if ((context.getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
+ ZCombineOperation *operation = NULL;
+ if (this->getbNode()->custom1) {
+ operation = new ZCombineAlphaOperation();
}
else {
- if (this->getOutputSocket(1)->isConnected()) {
- MathMinimumOperation *zoperation = new MathMinimumOperation();
- this->getInputSocket(1)->relinkConnections(zoperation->getInputSocket(0), 1, system);
- this->getInputSocket(3)->relinkConnections(zoperation->getInputSocket(1), 3, system);
- this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
- system->addOperation(zoperation);
- }
+ operation = new ZCombineOperation();
}
+ converter.addOperation(operation);
+
+ converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
+ converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
+ converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
+
+ MathMinimumOperation *zoperation = new MathMinimumOperation();
+ converter.addOperation(zoperation);
+
+ converter.mapInputSocket(getInputSocket(1), zoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(3), zoperation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(1), zoperation->getOutputSocket());
}
else {
+ /* XXX custom1 is "use_alpha", what on earth is this supposed to do here?!? */
// not full anti alias, use masking for Z combine. be aware it uses anti aliasing.
// step 1 create mask
NodeOperation *maskoperation;
-
if (this->getbNode()->custom1) {
maskoperation = new MathGreaterThanOperation();
- this->getInputSocket(1)->relinkConnections(maskoperation->getInputSocket(0), 3, system);
- this->getInputSocket(3)->relinkConnections(maskoperation->getInputSocket(1), 1, system);
+ converter.addOperation(maskoperation);
+
+ converter.mapInputSocket(getInputSocket(1), maskoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(3), maskoperation->getInputSocket(1));
}
else {
maskoperation = new MathLessThanOperation();
- this->getInputSocket(1)->relinkConnections(maskoperation->getInputSocket(0), 1, system);
- this->getInputSocket(3)->relinkConnections(maskoperation->getInputSocket(1), 3, system);
+ converter.addOperation(maskoperation);
+
+ converter.mapInputSocket(getInputSocket(1), maskoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(3), maskoperation->getInputSocket(1));
}
// step 2 anti alias mask bit of an expensive operation, but does the trick
AntiAliasOperation *antialiasoperation = new AntiAliasOperation();
- addLink(system, maskoperation->getOutputSocket(), antialiasoperation->getInputSocket(0));
+ converter.addOperation(antialiasoperation);
+
+ converter.addLink(maskoperation->getOutputSocket(), antialiasoperation->getInputSocket(0));
// use mask to blend between the input colors.
ZCombineMaskOperation *zcombineoperation = this->getbNode()->custom1 ? new ZCombineMaskAlphaOperation() : new ZCombineMaskOperation();
- addLink(system, antialiasoperation->getOutputSocket(), zcombineoperation->getInputSocket(0));
- this->getInputSocket(0)->relinkConnections(zcombineoperation->getInputSocket(1), 0, system);
- this->getInputSocket(2)->relinkConnections(zcombineoperation->getInputSocket(2), 2, system);
- this->getOutputSocket(0)->relinkConnections(zcombineoperation->getOutputSocket());
+ converter.addOperation(zcombineoperation);
+
+ converter.addLink(antialiasoperation->getOutputSocket(), zcombineoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(0), zcombineoperation->getInputSocket(1));
+ converter.mapInputSocket(getInputSocket(2), zcombineoperation->getInputSocket(2));
+ converter.mapOutputSocket(getOutputSocket(0), zcombineoperation->getOutputSocket());
- system->addOperation(maskoperation);
- system->addOperation(antialiasoperation);
- system->addOperation(zcombineoperation);
-
- if (this->getOutputSocket(1)->isConnected()) {
- MathMinimumOperation *zoperation = new MathMinimumOperation();
- addLink(system, maskoperation->getInputSocket(0)->getConnection()->getFromSocket(), zoperation->getInputSocket(0));
- addLink(system, maskoperation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(1));
- this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
- system->addOperation(zoperation);
- }
+ MathMinimumOperation *zoperation = new MathMinimumOperation();
+ converter.addOperation(zoperation);
+
+ converter.mapInputSocket(getInputSocket(1), zoperation->getInputSocket(0));
+ converter.mapInputSocket(getInputSocket(3), zoperation->getInputSocket(1));
+ converter.mapOutputSocket(getOutputSocket(1), zoperation->getOutputSocket());
}
}
diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h
index 61f4037be90..474be8db6ba 100644
--- a/source/blender/compositor/nodes/COM_ZCombineNode.h
+++ b/source/blender/compositor/nodes/COM_ZCombineNode.h
@@ -32,7 +32,7 @@
class ZCombineNode : public Node {
public:
ZCombineNode(bNode *editorNode) : Node(editorNode) {}
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+ void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
index d13fea921be..e7af9319f88 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp
@@ -36,30 +36,29 @@ BlurBaseOperation::BlurBaseOperation(DataType data_type) : NodeOperation()
this->addOutputSocket(data_type);
this->setComplex(true);
this->m_inputProgram = NULL;
- this->m_data = NULL;
+ memset(&m_data, 0, sizeof(NodeBlurData));
this->m_size = 1.0f;
- this->m_deleteData = false;
this->m_sizeavailable = false;
}
void BlurBaseOperation::initExecution()
{
this->m_inputProgram = this->getInputSocketReader(0);
this->m_inputSize = this->getInputSocketReader(1);
- this->m_data->image_in_width = this->getWidth();
- this->m_data->image_in_height = this->getHeight();
- if (this->m_data->relative) {
- switch (this->m_data->aspect) {
+ this->m_data.image_in_width = this->getWidth();
+ this->m_data.image_in_height = this->getHeight();
+ if (this->m_data.relative) {
+ switch (this->m_data.aspect) {
case CMP_NODE_BLUR_ASPECT_NONE:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_width);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_height);
break;
case CMP_NODE_BLUR_ASPECT_Y:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_width);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_width);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_width);
break;
case CMP_NODE_BLUR_ASPECT_X:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_height);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_height);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_height);
break;
}
}
@@ -78,9 +77,9 @@ float *BlurBaseOperation::make_gausstab(float rad, int size)
gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
sum = 0.0f;
- float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+ float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
- val = RE_filter_value(this->m_data->filtertype, (float)i * fac);
+ val = RE_filter_value(this->m_data.filtertype, (float)i * fac);
sum += val;
gausstab[i + size] = val;
}
@@ -103,7 +102,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff
dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__);
- float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+ float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
val = 1.0f - fabsf((float)i * fac);
@@ -144,10 +143,11 @@ void BlurBaseOperation::deinitExecution()
{
this->m_inputProgram = NULL;
this->m_inputSize = NULL;
- if (this->m_deleteData) {
- delete this->m_data;
- }
- this->m_data = NULL;
+}
+
+void BlurBaseOperation::setData(const NodeBlurData *data)
+{
+ memcpy(&m_data, data, sizeof(NodeBlurData));
}
void BlurBaseOperation::updateSize()
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h
index c5d89b1bc91..052a525ef2c 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.h
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h
@@ -43,10 +43,9 @@ protected:
*/
SocketReader *m_inputProgram;
SocketReader *m_inputSize;
- NodeBlurData *m_data;
+ NodeBlurData m_data;
float m_size;
- bool m_deleteData;
bool m_sizeavailable;
public:
@@ -60,9 +59,7 @@ public:
*/
void deinitExecution();
- void setData(NodeBlurData *data) { this->m_data = data; }
-
- void deleteDataWhenFinished() { this->m_deleteData = true; }
+ void setData(const NodeBlurData *data);
void setSize(float size) { this->m_size = size; this->m_sizeavailable = true; }
};
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp
index d4629a8d527..ef331a50dfd 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cpp
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_CompositorOperation.h"
-#include "COM_SocketConnection.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
@@ -49,7 +48,7 @@ CompositorOperation::CompositorOperation() : NodeOperation()
this->m_alphaInput = NULL;
this->m_depthInput = NULL;
- this->m_ignoreAlpha = false;
+ this->m_useAlphaInput = false;
this->m_active = false;
this->m_sceneName[0] = '\0';
@@ -189,21 +188,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int input_x = x + dx, input_y = y + dy;
this->m_imageInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
- if (this->m_ignoreAlpha) {
- color[3] = 1.0f;
- }
- else {
- if (this->m_alphaInput != NULL) {
- this->m_alphaInput->readSampled(&(color[3]), input_x, input_y, COM_PS_NEAREST);
- }
+ if (this->m_useAlphaInput) {
+ this->m_alphaInput->readSampled(&(color[3]), input_x, input_y, COM_PS_NEAREST);
}
copy_v4_v4(buffer + offset4, color);
- if (this->m_depthInput != NULL) {
- this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
- zbuffer[offset] = color[0];
- }
+ this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
+ zbuffer[offset] = color[0];
offset4 += COM_NUMBER_OF_CHANNELS;
offset++;
if (isBreaked()) {
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h
index d33e89ed742..771c32ffd12 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.h
+++ b/source/blender/compositor/operations/COM_CompositorOperation.h
@@ -69,7 +69,7 @@ private:
/**
* @brief Ignore any alpha input
*/
- bool m_ignoreAlpha;
+ bool m_useAlphaInput;
/**
* @brief operation is active for calculating final compo result
@@ -86,7 +86,7 @@ public:
void deinitExecution();
const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
- void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
+ void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; }
void setActive(bool active) { this->m_active = active; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
index 2842b47dd74..7dacc3239c5 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
@@ -72,8 +72,8 @@ bool DisplaceOperation::read_displacement(float x, float y, float xscale, float
else {
float col[4];
m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR);
- r_u = origin[0] - col[0] * xscale + 0.5f;
- r_v = origin[1] - col[1] * yscale + 0.5f;
+ r_u = origin[0] - col[0] * xscale;
+ r_v = origin[1] - col[1] * yscale;
return true;
}
}
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index a6be9254f6f..9d96ebbb33f 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -45,12 +45,13 @@ void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void
// the whole image.
bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output)
{
- // m_data->sizex * m_size should be enough? For some reason there
+ // m_data.sizex * m_size should be enough? For some reason there
// seem to be errors in the boundary between tiles.
- int sx = this->m_data->sizex * this->m_size * 2;
+ float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER;
+ int sx = this->m_data.sizex * size;
if (sx < 1)
sx = 1;
- int sy = this->m_data->sizey * this->m_size * 2;
+ int sy = this->m_data.sizey * size;
if (sy < 1)
sy = 1;
@@ -124,8 +125,8 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
updateSize();
int c;
- this->m_sx = this->m_data->sizex * this->m_size / 2.0f;
- this->m_sy = this->m_data->sizey * this->m_size / 2.0f;
+ this->m_sx = this->m_data.sizex * this->m_size / 2.0f;
+ this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
@@ -173,8 +174,8 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
tile->copyContentFrom(buffer);
int c;
- float sx = this->m_data->sizex * this->m_size / 2.0f;
- float sy = this->m_data->sizey * this->m_size / 2.0f;
+ float sx = this->m_data.sizex * this->m_size / 2.0f;
+ float sy = this->m_data.sizey * this->m_size / 2.0f;
if ((sx == sy) && (sx > 0.f)) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index 4ae0b4e78b2..69aa7d0fee5 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -54,7 +54,7 @@ void GaussianAlphaXBlurOperation::initExecution()
initMutex();
if (this->m_sizeavailable) {
- float rad = max_ff(m_size * m_data->sizex, 0.0f);
+ float rad = max_ff(m_size * m_data.sizex, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -66,7 +66,7 @@ void GaussianAlphaXBlurOperation::updateGauss()
{
if (this->m_gausstab == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizex, 0.0f);
+ float rad = max_ff(m_size * m_data.sizex, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -74,7 +74,7 @@ void GaussianAlphaXBlurOperation::updateGauss()
if (this->m_distbuf_inv == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizex, 0.0f);
+ float rad = max_ff(m_size * m_data.sizex, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index fb407bf9ee4..ae1f309c54f 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -54,7 +54,7 @@ void GaussianAlphaYBlurOperation::initExecution()
initMutex();
if (this->m_sizeavailable) {
- float rad = max_ff(m_size * m_data->sizey, 0.0f);
+ float rad = max_ff(m_size * m_data.sizey, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -66,7 +66,7 @@ void GaussianAlphaYBlurOperation::updateGauss()
{
if (this->m_gausstab == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizey, 0.0f);
+ float rad = max_ff(m_size * m_data.sizey, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -74,7 +74,7 @@ void GaussianAlphaYBlurOperation::updateGauss()
if (this->m_distbuf_inv == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizey, 0.0f);
+ float rad = max_ff(m_size * m_data.sizey, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
index 44752d4e12e..d5743c41c94 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
@@ -68,11 +68,11 @@ void GaussianBokehBlurOperation::updateGauss()
if (!this->m_sizeavailable) {
updateSize();
}
- radxf = this->m_size * (float)this->m_data->sizex;
+ radxf = this->m_size * (float)this->m_data.sizex;
CLAMP(radxf, 0.0f, width / 2.0f);
/* vertical */
- radyf = this->m_size * (float)this->m_data->sizey;
+ radyf = this->m_size * (float)this->m_data.sizey;
CLAMP(radyf, 0.0f, height / 2.0f);
this->m_radx = ceil(radxf);
@@ -86,14 +86,14 @@ void GaussianBokehBlurOperation::updateGauss()
ddgauss = (float *)MEM_mallocN(sizeof(float) * n, __func__);
dgauss = ddgauss;
float sum = 0.0f;
- float facx = (radxf > 0.0f ? 1.0f/radxf : 0.0f);
- float facy = (radyf > 0.0f ? 1.0f/radyf : 0.0f);
+ float facx = (radxf > 0.0f ? 1.0f / radxf : 0.0f);
+ float facy = (radyf > 0.0f ? 1.0f / radyf : 0.0f);
for (j = -this->m_rady; j <= this->m_rady; j++) {
for (i = -this->m_radx; i <= this->m_radx; i++, dgauss++) {
float fj = (float)j * facy;
float fi = (float)i * facx;
float dist = sqrt(fj * fj + fi * fi);
- *dgauss = RE_filter_value(this->m_data->filtertype, dist);
+ *dgauss = RE_filter_value(this->m_data.filtertype, dist);
sum += *dgauss;
}
@@ -212,28 +212,28 @@ void GaussianBlurReferenceOperation::initExecution()
{
BlurBaseOperation::initExecution();
// setup gaustab
- this->m_data->image_in_width = this->getWidth();
- this->m_data->image_in_height = this->getHeight();
- if (this->m_data->relative) {
- switch (this->m_data->aspect) {
+ this->m_data.image_in_width = this->getWidth();
+ this->m_data.image_in_height = this->getHeight();
+ if (this->m_data.relative) {
+ switch (this->m_data.aspect) {
case CMP_NODE_BLUR_ASPECT_NONE:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_width);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_height);
break;
case CMP_NODE_BLUR_ASPECT_Y:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_width);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_width);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_width);
break;
case CMP_NODE_BLUR_ASPECT_X:
- this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_height);
- this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height);
+ this->m_data.sizex = (int)(this->m_data.percentx * 0.01f * this->m_data.image_in_height);
+ this->m_data.sizey = (int)(this->m_data.percenty * 0.01f * this->m_data.image_in_height);
break;
}
}
/* horizontal */
- m_filtersizex = (float)this->m_data->sizex;
+ m_filtersizex = (float)this->m_data.sizex;
int imgx = getWidth() / 2;
if (m_filtersizex > imgx)
m_filtersizex = imgx;
@@ -242,7 +242,7 @@ void GaussianBlurReferenceOperation::initExecution()
m_radx = (float)m_filtersizex;
/* vertical */
- m_filtersizey = (float)this->m_data->sizey;
+ m_filtersizey = (float)this->m_data.sizey;
int imgy = getHeight() / 2;
if (m_filtersizey > imgy)
m_filtersizey = imgy;
@@ -342,8 +342,8 @@ bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *inpu
return true;
}
else {
- int addx = this->m_data->sizex + 2;
- int addy = this->m_data->sizey + 2;
+ int addx = this->m_data.sizex + 2;
+ int addy = this->m_data.sizey + 2;
newInput.xmax = input->xmax + addx;
newInput.xmin = input->xmin - addx;
newInput.ymax = input->ymax + addy;
diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
index 127417bf701..815b89ae8d9 100644
--- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
@@ -52,7 +52,7 @@ void GaussianXBlurOperation::initExecution()
initMutex();
if (this->m_sizeavailable) {
- float rad = max_ff(m_size * m_data->sizex, 0.0f);
+ float rad = max_ff(m_size * m_data.sizex, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -63,7 +63,7 @@ void GaussianXBlurOperation::updateGauss()
{
if (this->m_gausstab == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizex, 0.0f);
+ float rad = max_ff(m_size * m_data.sizex, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
index 583305a0fc4..47c031757fb 100644
--- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
@@ -52,7 +52,7 @@ void GaussianYBlurOperation::initExecution()
initMutex();
if (this->m_sizeavailable) {
- float rad = max_ff(m_size * m_data->sizey, 0.0f);
+ float rad = max_ff(m_size * m_data.sizey, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
@@ -63,7 +63,7 @@ void GaussianYBlurOperation::updateGauss()
{
if (this->m_gausstab == NULL) {
updateSize();
- float rad = max_ff(m_size * m_data->sizey, 0.0f);
+ float rad = max_ff(m_size * m_data.sizey, 0.0f);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
index 8bfc3e436df..99c745d7fb0 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
@@ -23,7 +23,7 @@
#include "COM_GlareBaseOperation.h"
#include "BLI_math.h"
-GlareBaseOperation::GlareBaseOperation() : SingleThreadedNodeOperation()
+GlareBaseOperation::GlareBaseOperation() : SingleThreadedOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->addOutputSocket(COM_DT_COLOR);
@@ -31,14 +31,14 @@ GlareBaseOperation::GlareBaseOperation() : SingleThreadedNodeOperation()
}
void GlareBaseOperation::initExecution()
{
- SingleThreadedNodeOperation::initExecution();
+ SingleThreadedOperation::initExecution();
this->m_inputProgram = getInputSocketReader(0);
}
void GlareBaseOperation::deinitExecution()
{
this->m_inputProgram = NULL;
- SingleThreadedNodeOperation::deinitExecution();
+ SingleThreadedOperation::deinitExecution();
}
MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2)
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h
index f6a8f6879da..3f0893d895f 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.h
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h
@@ -23,7 +23,7 @@
#ifndef _COM_GlareBaseOperation_h
#define _COM_GlareBaseOperation_h
-#include "COM_SingleThreadedNodeOperation.h"
+#include "COM_SingleThreadedOperation.h"
#include "DNA_node_types.h"
@@ -36,7 +36,7 @@ typedef float fRGB[4];
#define fRGB_rgbmult(c, r, g, b) { c[0] *= (r); c[1] *= (g); c[2] *= (b); } (void)0
-class GlareBaseOperation : public SingleThreadedNodeOperation {
+class GlareBaseOperation : public SingleThreadedOperation {
private:
/**
* @brief Cached reference to the inputProgram
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
index f656b7f4892..99a7c5b64c4 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
@@ -251,7 +251,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
fRGB wt, *colp;
int x, y, ch;
int xbl, ybl, nxb, nyb, xbsz, ybsz;
- int in2done = FALSE;
+ bool in2done = false;
const unsigned int kernelWidth = in2->getWidth();
const unsigned int kernelHeight = in2->getHeight();
const unsigned int imageWidth = in1->getWidth();
@@ -358,7 +358,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
}
}
- in2done = TRUE;
+ in2done = true;
}
}
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
index 0a1587c6ffa..17b85847fcf 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
@@ -148,7 +148,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
continue;
}
- pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);
+ pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, true, false);
zero_v3(site->color);
diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
index 2e80d4f1ba3..7a89ba91b4c 100644
--- a/source/blender/compositor/operations/COM_MapRangeOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
@@ -31,7 +31,7 @@ MapRangeOperation::MapRangeOperation() : NodeOperation()
this->addInputSocket(COM_DT_VALUE);
this->addOutputSocket(COM_DT_VALUE);
this->m_inputOperation = NULL;
- this->m_useClamp = FALSE;
+ this->m_useClamp = false;
}
void MapRangeOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
index 292f073548a..87ad1d6afa4 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -29,6 +29,7 @@ MapUVOperation::MapUVOperation() : NodeOperation()
this->addOutputSocket(COM_DT_COLOR);
this->m_alpha = 0.0f;
this->setComplex(true);
+ setResolutionInputSocketIndex(1);
this->m_inputUVProgram = NULL;
this->m_inputColorProgram = NULL;
@@ -84,8 +85,8 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
else {
float col[4];
m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR);
- r_u = col[0] * width;
- r_v = col[1] * height;
+ r_u = col[0] * m_inputColorProgram->getWidth();
+ r_v = col[1] * m_inputColorProgram->getHeight();
r_alpha = col[2];
return true;
}
diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp
index 7ee2c111932..8c8ba93327d 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_MaskOperation.cpp
@@ -54,7 +54,7 @@ void MaskOperation::initExecution()
BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[0], this->m_mask,
this->m_maskWidth, this->m_maskHeight,
- TRUE, this->m_do_smooth, this->m_do_feather);
+ true, this->m_do_smooth, this->m_do_feather);
}
else {
/* make a throw away copy of the mask */
@@ -88,7 +88,7 @@ void MaskOperation::initExecution()
BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[i], mask_temp,
this->m_maskWidth, this->m_maskHeight,
- TRUE, this->m_do_smooth, this->m_do_feather);
+ true, this->m_do_smooth, this->m_do_feather);
frame_iter += frame_step;
}
@@ -129,8 +129,9 @@ void MaskOperation::determineResolution(unsigned int resolution[2], unsigned int
void MaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- const float xy[2] = {x * this->m_maskWidthInv,
- y * this->m_maskHeightInv};
+ const float xy[2] = {
+ (x * this->m_maskWidthInv) + this->m_mask_px_ofs[0],
+ (y * this->m_maskHeightInv) + this->m_mask_px_ofs[1]};
if (this->m_rasterMaskHandleTot == 1) {
if (this->m_rasterMaskHandles[0]) {
diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h
index 18d7e594104..522b873e167 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.h
+++ b/source/blender/compositor/operations/COM_MaskOperation.h
@@ -43,6 +43,7 @@ protected:
int m_maskHeight;
float m_maskWidthInv; /* 1 / m_maskWidth */
float m_maskHeightInv; /* 1 / m_maskHeight */
+ float m_mask_px_ofs[2];
float m_frame_shutter;
int m_frame_number;
@@ -70,11 +71,13 @@ public:
{
this->m_maskWidth = width;
this->m_maskWidthInv = 1.0f / (float)width;
+ this->m_mask_px_ofs[0] = this->m_maskWidthInv * 0.5f;
}
void setMaskHeight(int height)
{
this->m_maskHeight = height;
this->m_maskHeightInv = 1.0f / (float)height;
+ this->m_mask_px_ofs[1] = this->m_maskHeightInv * 0.5f;
}
void setFramenumber(int frame_number) { this->m_frame_number = frame_number; }
void setSmooth(bool smooth) { this->m_do_smooth = smooth; }
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
index cc7511bb9fc..cbc60b5091d 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
@@ -50,7 +50,7 @@ void MathBaseOperation::deinitExecution()
void MathBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
- InputSocket *socket;
+ NodeOperationInput *socket;
unsigned int tempPreferredResolution[2] = {0, 0};
unsigned int tempResolution[2];
@@ -333,3 +333,14 @@ void MathModuloOperation::executePixelSampled(float output[4], float x, float y,
clampIfNeeded(output);
}
+void MathAbsoluteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+ float inputValue1[4];
+
+ this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+
+ output[0] = fabs(inputValue1[0]);
+
+ clampIfNeeded(output);
+}
+
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h
index 4ea7c43a67d..05d2bb054d3 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.h
@@ -163,4 +163,10 @@ public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
+class MathAbsoluteOperation : public MathBaseOperation {
+public:
+ MathAbsoluteOperation() : MathBaseOperation() {}
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
#endif
diff --git a/source/blender/compositor/operations/COM_MixOperation.cpp b/source/blender/compositor/operations/COM_MixOperation.cpp
index 125de842892..04025329ad4 100644
--- a/source/blender/compositor/operations/COM_MixOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixOperation.cpp
@@ -71,7 +71,7 @@ void MixBaseOperation::executePixelSampled(float output[4], float x, float y, Pi
void MixBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
- InputSocket *socket;
+ NodeOperationInput *socket;
unsigned int tempPreferredResolution[2] = {0, 0};
unsigned int tempResolution[2];
@@ -292,17 +292,9 @@ void MixDarkenOperation::executePixelSampled(float output[4], float x, float y,
value *= inputColor2[3];
}
float valuem = 1.0f - value;
- float tmp;
- tmp = inputColor2[0] + ((1.0f - inputColor2[0]) * valuem);
- if (tmp < inputColor1[0]) output[0] = tmp;
- else output[0] = inputColor1[0];
- tmp = inputColor2[1] + ((1.0f - inputColor2[1]) * valuem);
- if (tmp < inputColor1[1]) output[1] = tmp;
- else output[1] = inputColor1[1];
- tmp = inputColor2[2] + ((1.0f - inputColor2[2]) * valuem);
- if (tmp < inputColor1[2]) output[2] = tmp;
- else output[2] = inputColor1[2];
-
+ output[0] = min_ff(inputColor1[0], inputColor2[0]) * value + inputColor1[0] * valuem;
+ output[1] = min_ff(inputColor1[1], inputColor2[1]) * value + inputColor1[1] * valuem;
+ output[2] = min_ff(inputColor1[2], inputColor2[2]) * value + inputColor1[2] * valuem;
output[3] = inputColor1[3];
clampIfNeeded(output);
diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl
index d7a81001531..00b3825d8b3 100644
--- a/source/blender/compositor/operations/COM_OpenCLKernels.cl
+++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl
@@ -41,6 +41,7 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
float4 bokeh;
const float radius2 = radius*2.0f;
const int2 realCoordinate = coords + offsetOutput;
+ int2 imageCoordinates = realCoordinate - offsetInput;
tempBoundingBox = read_imagef(boundingBox, SAMPLER_NEAREST, coords).s0;
@@ -54,6 +55,11 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
float2 uv;
int2 inputXy;
+ if (radius < 2) {
+ color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);
+ multiplyer = (float4)(1.0f, 1.0f, 1.0f, 1.0f);
+ }
+
for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny += step, inputXy.y += step) {
uv.y = ((realCoordinate.y-ny)/radius2)*bokehImageDim.y+bokehImageCenter.y;
@@ -65,10 +71,8 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
}
}
color /= multiplyer;
-
}
else {
- int2 imageCoordinates = realCoordinate - offsetInput;
color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);
}
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 094b2c4268a..92e8f309ea1 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -22,7 +22,6 @@
*/
#include "COM_OutputFileOperation.h"
-#include "COM_SocketConnection.h"
#include <string.h>
#include "BLI_listbase.h"
#include "BLI_path_util.h"
@@ -141,8 +140,8 @@ void OutputSingleLayerOperation::deinitExecution()
IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings,
this->m_format);
- BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
- (this->m_rd->scemode & R_EXTENSION), true);
+ BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra,
+ this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
printf("Cannot save Node File Output to %s\n", filename);
@@ -156,10 +155,12 @@ void OutputSingleLayerOperation::deinitExecution()
}
-OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_)
+OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_)
{
BLI_strncpy(this->name, name_, sizeof(this->name));
this->datatype = datatype_;
+ this->use_layer = use_layer_;
+
/* these are created in initExecution */
this->outputBuffer = 0;
this->imageInput = 0;
@@ -175,21 +176,20 @@ OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation(
this->m_exr_codec = exr_codec;
}
-void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype)
+void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype, bool use_layer)
{
this->addInputSocket(datatype);
- this->m_layers.push_back(OutputOpenExrLayer(name, datatype));
+ this->m_layers.push_back(OutputOpenExrLayer(name, datatype, use_layer));
}
void OutputOpenExrMultiLayerOperation::initExecution()
{
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
- SocketReader *reader = getInputSocketReader(i);
- this->m_layers[i].imageInput = reader;
- if (reader)
+ if (this->m_layers[i].use_layer) {
+ SocketReader *reader = getInputSocketReader(i);
+ this->m_layers[i].imageInput = reader;
this->m_layers[i].outputBuffer = init_buffer(this->getWidth(), this->getHeight(), this->m_layers[i].datatype);
- else
- this->m_layers[i].outputBuffer = NULL;
+ }
}
}
@@ -212,7 +212,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
void *exrhandle = IMB_exr_get_handle();
BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
- (this->m_rd->scemode & R_EXTENSION), true);
+ (this->m_rd->scemode & R_EXTENSION) != 0, true);
BLI_make_existing_file(filename);
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index ada40bba014..03278c5b149 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -57,16 +57,19 @@ public:
void deinitExecution();
const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; }
- bool isFileOutputOperation() { return true; }
+ bool isFileOutputOperation() const { return true; }
};
/* extra info for OpenEXR layers */
struct OutputOpenExrLayer {
- OutputOpenExrLayer(const char *name, DataType datatype);
+ OutputOpenExrLayer(const char *name, DataType datatype, bool use_layer);
char name[EXR_TOT_MAXNAME - 2];
- float *outputBuffer;
DataType datatype;
+ bool use_layer;
+
+ /* internals */
+ float *outputBuffer;
SocketReader *imageInput;
};
@@ -85,7 +88,7 @@ private:
public:
OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec);
- void add_layer(const char *name, DataType datatype);
+ void add_layer(const char *name, DataType datatype, bool use_layer);
void executeRegion(rcti *rect, unsigned int tileNumber);
bool isOutputOperation(bool rendering) const { return true; }
@@ -93,7 +96,7 @@ public:
void deinitExecution();
const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; }
- bool isFileOutputOperation() { return true; }
+ bool isFileOutputOperation() const { return true; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
new file mode 100644
index 00000000000..fe272000b6e
--- /dev/null
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2014, Blender Foundation.
+ *
+ * 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:
+ * Lukas Toenne
+ */
+
+#include "COM_PlaneCornerPinOperation.h"
+#include "COM_ReadBufferOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_math_color.h"
+
+extern "C" {
+# include "BLI_jitter.h"
+
+# include "BKE_node.h"
+}
+
+static bool check_corners(float corners[4][2])
+{
+ int i, next, prev;
+ float cross = 0.0f;
+
+ for (i = 0; i < 4; i++) {
+ float v1[2], v2[2], cur_cross;
+
+ next = (i + 1) % 4;
+ prev = (4 + i - 1) % 4;
+
+ sub_v2_v2v2(v1, corners[i], corners[prev]);
+ sub_v2_v2v2(v2, corners[next], corners[i]);
+
+ cur_cross = cross_v2v2(v1, v2);
+ if (fabsf(cur_cross) <= FLT_EPSILON)
+ return false;
+
+ if (cross == 0.0f)
+ cross = cur_cross;
+ else if (cross * cur_cross < 0.0f)
+ return false;
+ }
+
+ return true;
+}
+
+static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float corners[4][2])
+{
+ for (int i = 0; i < 4; ++i) {
+ float result[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ readers[i]->readSampled(result, rect->xmin, rect->ymin, COM_PS_NEAREST);
+ corners[i][0] = result[0];
+ corners[i][1] = result[1];
+ }
+
+ /* convexity check:
+ * concave corners need to be prevented, otherwise
+ * BKE_tracking_homography_between_two_quads will freeze
+ */
+ if (!check_corners(corners)) {
+ /* simply revert to default corners
+ * there could be a more elegant solution,
+ * this prevents freezing at least.
+ */
+ corners[0][0] = 0.0f; corners[0][1] = 0.0f;
+ corners[1][0] = 1.0f; corners[1][1] = 0.0f;
+ corners[2][0] = 1.0f; corners[2][1] = 1.0f;
+ corners[3][0] = 0.0f; corners[3][1] = 1.0f;
+ }
+}
+
+
+/* ******** PlaneCornerPinMaskOperation ******** */
+
+PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() :
+ PlaneDistortMaskOperation(),
+ m_corners_ready(false)
+{
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+
+ /* XXX this is stupid: we need to make this "complex",
+ * so we can use the initializeTileData function
+ * to read corners from input sockets ...
+ */
+ setComplex(true);
+}
+
+void PlaneCornerPinMaskOperation::initExecution()
+{
+ PlaneDistortMaskOperation::initExecution();
+
+ initMutex();
+}
+
+void PlaneCornerPinMaskOperation::deinitExecution()
+{
+ PlaneDistortMaskOperation::deinitExecution();
+
+ deinitMutex();
+}
+
+void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect)
+{
+ void *data = PlaneDistortMaskOperation::initializeTileData(rect);
+
+ /* get corner values once, by reading inputs at (0,0)
+ * XXX this assumes invariable values (no image inputs),
+ * we don't have a nice generic system for that yet
+ */
+ lockMutex();
+ if (!m_corners_ready) {
+ SocketReader *readers[4] = { getInputSocketReader(0),
+ getInputSocketReader(1),
+ getInputSocketReader(2),
+ getInputSocketReader(3) };
+ float corners[4][2];
+ readCornersFromSockets(rect, readers, corners);
+ calculateCorners(corners, true);
+
+ m_corners_ready = true;
+ }
+ unlockMutex();
+
+ return data;
+}
+
+void PlaneCornerPinMaskOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+{
+ resolution[0] = preferredResolution[0];
+ resolution[1] = preferredResolution[1];
+}
+
+
+/* ******** PlaneCornerPinWarpImageOperation ******** */
+
+PlaneCornerPinWarpImageOperation::PlaneCornerPinWarpImageOperation() :
+ PlaneDistortWarpImageOperation(),
+ m_corners_ready(false)
+{
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+ addInputSocket(COM_DT_VECTOR);
+}
+
+void PlaneCornerPinWarpImageOperation::initExecution()
+{
+ PlaneDistortWarpImageOperation::initExecution();
+
+ initMutex();
+}
+
+void PlaneCornerPinWarpImageOperation::deinitExecution()
+{
+ PlaneDistortWarpImageOperation::deinitExecution();
+
+ deinitMutex();
+}
+
+void *PlaneCornerPinWarpImageOperation::initializeTileData(rcti *rect)
+{
+ void *data = PlaneDistortWarpImageOperation::initializeTileData(rect);
+
+ /* get corner values once, by reading inputs at (0,0)
+ * XXX this assumes invariable values (no image inputs),
+ * we don't have a nice generic system for that yet
+ */
+ lockMutex();
+ if (!m_corners_ready) {
+ /* corner sockets start at index 1 */
+ SocketReader *readers[4] = { getInputSocketReader(1),
+ getInputSocketReader(2),
+ getInputSocketReader(3),
+ getInputSocketReader(4) };
+ float corners[4][2];
+ readCornersFromSockets(rect, readers, corners);
+ calculateCorners(corners, true);
+ calculatePerspectiveMatrix();
+
+ m_corners_ready = true;
+ }
+ unlockMutex();
+
+ return data;
+}
+
+bool PlaneCornerPinWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ for (int i = 0; i < 4; ++i)
+ if (getInputOperation(i + 1)->determineDependingAreaOfInterest(input, readOperation, output))
+ return true;
+
+ /* XXX this is bad, but unavoidable with the current design:
+ * we don't know the actual corners and matrix at this point,
+ * so all we can do is get the full input image
+ */
+ output->xmin = 0;
+ output->ymin = 0;
+ output->xmax = getInputOperation(0)->getWidth();
+ output->ymax = getInputOperation(0)->getHeight();
+ return true;
+// return PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(input, readOperation, output);
+}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
index 7f763954079..ed70d9c80a3 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2013, Blender Foundation.
+ * Copyright 2014, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,15 +17,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
- * Sergey Sharybin
+ * Lukas Toenne
*/
-#ifndef _COM_PlaneTrackMaskOperation_h
-#define _COM_PlaneTrackMaskOperation_h
+#ifndef _COM_CornerPinWarpImageOperation_h
+#define _COM_CornerPinWarpImageOperation_h
#include <string.h>
-#include "COM_PlaneTrackCommonOperation.h"
+#include "COM_PlaneDistortCommonOperation.h"
#include "DNA_movieclip_types.h"
#include "DNA_tracking_types.h"
@@ -33,17 +33,36 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
-class PlaneTrackMaskOperation : public PlaneTrackCommonOperation {
-protected:
- int m_osa;
- float m_jitter[32][2];
+class PlaneCornerPinMaskOperation : public PlaneDistortMaskOperation {
+private:
+ bool m_corners_ready;
+
public:
- PlaneTrackMaskOperation();
-
+ PlaneCornerPinMaskOperation();
+
void initExecution();
+ void deinitExecution();
+
+ void *initializeTileData(rcti *rect);
+
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+};
+
- void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation {
+private:
+ bool m_corners_ready;
+
+public:
+ PlaneCornerPinWarpImageOperation();
+
+ void initExecution();
+ void deinitExecution();
+
+ void *initializeTileData(rcti *rect);
+
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
};
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
index 6579276fa9f..c507b4cfa98 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
@@ -17,25 +17,26 @@
*
* Contributor:
* Sergey Sharybin
+ * Lukas Toenne
*/
-#include "COM_PlaneTrackWarpImageOperation.h"
-#include "COM_ReadBufferOperation.h"
+#include "COM_PlaneDistortCommonOperation.h"
#include "MEM_guardedalloc.h"
+extern "C" {
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_color.h"
+#include "BLI_jitter.h"
-extern "C" {
-# include "BLI_jitter.h"
-
-# include "BKE_movieclip.h"
-# include "BKE_node.h"
-# include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+#include "BKE_node.h"
+#include "BKE_tracking.h"
}
+/* ******** PlaneDistort WarpImage ******** */
+
BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2], float deriv[2][2])
{
float vec[3] = {x, y, 1.0f};
@@ -49,7 +50,8 @@ BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2], flo
deriv[1][1] = (matrix[1][1] - matrix[1][2] * uv[1]) / vec[2];
}
-PlaneTrackWarpImageOperation::PlaneTrackWarpImageOperation() : PlaneTrackCommonOperation()
+PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() :
+ NodeOperation()
{
this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
this->addOutputSocket(COM_DT_COLOR);
@@ -57,12 +59,24 @@ PlaneTrackWarpImageOperation::PlaneTrackWarpImageOperation() : PlaneTrackCommonO
this->setComplex(true);
}
-void PlaneTrackWarpImageOperation::initExecution()
+void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], bool normalized)
{
- PlaneTrackCommonOperation::initExecution();
-
- this->m_pixelReader = this->getInputSocketReader(0);
+ if (normalized) {
+ for (int i = 0; i < 4; i++) {
+ this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ }
+ }
+ else {
+ for (int i = 0; i < 4; i++) {
+ this->m_frameSpaceCorners[i][0] = corners[i][0];
+ this->m_frameSpaceCorners[i][1] = corners[i][1];
+ }
+ }
+}
+void PlaneDistortWarpImageOperation::calculatePerspectiveMatrix()
+{
const int width = this->m_pixelReader->getWidth();
const int height = this->m_pixelReader->getHeight();
float frame_corners[4][2] = {{0.0f, 0.0f},
@@ -74,12 +88,17 @@ void PlaneTrackWarpImageOperation::initExecution()
this->m_perspectiveMatrix);
}
-void PlaneTrackWarpImageOperation::deinitExecution()
+void PlaneDistortWarpImageOperation::initExecution()
+{
+ this->m_pixelReader = this->getInputSocketReader(0);
+}
+
+void PlaneDistortWarpImageOperation::deinitExecution()
{
this->m_pixelReader = NULL;
}
-void PlaneTrackWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float xy[2] = {x, y};
float uv[2];
@@ -90,12 +109,12 @@ void PlaneTrackWarpImageOperation::executePixelSampled(float output[4], float x,
m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR);
}
-void PlaneTrackWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
+void PlaneDistortWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
{
warpCoord(xy[0], xy[1], m_perspectiveMatrix, r_uv, r_deriv);
}
-bool PlaneTrackWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
float UVs[4][2];
float deriv[2][2];
@@ -121,3 +140,55 @@ bool PlaneTrackWarpImageOperation::determineDependingAreaOfInterest(rcti *input,
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
+
+
+/* ******** PlaneDistort Mask ******** */
+
+PlaneDistortMaskOperation::PlaneDistortMaskOperation() :
+ NodeOperation()
+{
+ addOutputSocket(COM_DT_VALUE);
+
+ /* Currently hardcoded to 8 samples. */
+ m_osa = 8;
+}
+
+void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], bool normalized)
+{
+ if (normalized) {
+ for (int i = 0; i < 4; i++) {
+ this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ }
+ }
+ else {
+ for (int i = 0; i < 4; i++) {
+ this->m_frameSpaceCorners[i][0] = corners[i][0];
+ this->m_frameSpaceCorners[i][1] = corners[i][1];
+ }
+ }
+}
+
+void PlaneDistortMaskOperation::initExecution()
+{
+ BLI_jitter_init(m_jitter, m_osa);
+}
+
+void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+ float point[2];
+
+ int inside_counter = 0;
+ for (int sample = 0; sample < this->m_osa; sample++) {
+ point[0] = x + this->m_jitter[sample][0];
+ point[1] = y + this->m_jitter[sample][1];
+
+ if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
+
+ output[0] = (float) inside_counter / this->m_osa;
+}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index ceb002c8039..ee2874c6b46 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackWarpImageOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -20,12 +20,12 @@
* Sergey Sharybin
*/
-#ifndef _COM_PlaneTrackWarpImageOperation_h
-#define _COM_PlaneTrackWarpImageOperation_h
+#ifndef _COM_PlaneTrackCommonOperation_h
+#define _COM_PlaneTrackCommonOperation_h
#include <string.h>
-#include "COM_PlaneTrackCommonOperation.h"
+#include "COM_NodeOperation.h"
#include "DNA_movieclip_types.h"
#include "DNA_tracking_types.h"
@@ -33,13 +33,18 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
-class PlaneTrackWarpImageOperation : public PlaneTrackCommonOperation {
+
+class PlaneDistortWarpImageOperation : public NodeOperation {
protected:
SocketReader *m_pixelReader;
+ float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
float m_perspectiveMatrix[3][3];
public:
- PlaneTrackWarpImageOperation();
+ PlaneDistortWarpImageOperation();
+
+ void calculateCorners(const float corners[4][2], bool normalized);
+ void calculatePerspectiveMatrix();
void initExecution();
void deinitExecution();
@@ -50,4 +55,21 @@ public:
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
};
+
+class PlaneDistortMaskOperation : public NodeOperation {
+protected:
+ int m_osa;
+ float m_jitter[32][2];
+ float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+
+public:
+ PlaneDistortMaskOperation();
+
+ void calculateCorners(const float corners[4][2], bool normalized);
+
+ void initExecution();
+
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp
deleted file mode 100644
index e43f6ab05b3..00000000000
--- a/source/blender/compositor/operations/COM_PlaneTrackMaskOperation.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2013, Blender Foundation.
- *
- * 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:
- * Sergey Sharybin
- */
-
-#include "COM_PlaneTrackMaskOperation.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_listbase.h"
-#include "BLI_math.h"
-#include "BLI_math_color.h"
-
-extern "C" {
-# include "BLI_jitter.h"
-
-# include "BKE_movieclip.h"
-# include "BKE_node.h"
-# include "BKE_tracking.h"
-}
-
-PlaneTrackMaskOperation::PlaneTrackMaskOperation() : PlaneTrackCommonOperation()
-{
- this->addOutputSocket(COM_DT_VALUE);
-
- /* Currently hardcoded to 8 samples. */
- this->m_osa = 8;
-}
-
-void PlaneTrackMaskOperation::initExecution()
-{
- PlaneTrackCommonOperation::initExecution();
-
- BLI_jitter_init(this->m_jitter[0], this->m_osa);
-}
-
-void PlaneTrackMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
-{
- float point[2];
-
- int inside_counter = 0;
- for (int sample = 0; sample < this->m_osa; sample++) {
- point[0] = x + this->m_jitter[sample][0];
- point[1] = y + this->m_jitter[sample][1];
-
- if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) ||
- isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3]))
- {
- inside_counter++;
- }
- }
-
- output[0] = (float) inside_counter / this->m_osa;
-}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
index 5deb7b99bce..fec39cbfde0 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackCommonOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
@@ -19,7 +19,8 @@
* Sergey Sharybin
*/
-#include "COM_PlaneTrackMaskOperation.h"
+#include "COM_PlaneTrackOperation.h"
+#include "COM_ReadBufferOperation.h"
#include "MEM_guardedalloc.h"
@@ -28,12 +29,16 @@
#include "BLI_math_color.h"
extern "C" {
+# include "BLI_jitter.h"
+
# include "BKE_movieclip.h"
# include "BKE_node.h"
# include "BKE_tracking.h"
}
-PlaneTrackCommonOperation::PlaneTrackCommonOperation() : NodeOperation()
+/* ******** PlaneTrackCommon ******** */
+
+PlaneTrackCommon::PlaneTrackCommon()
{
this->m_movieClip = NULL;
this->m_framenumber = 0;
@@ -41,55 +46,72 @@ PlaneTrackCommonOperation::PlaneTrackCommonOperation() : NodeOperation()
this->m_planeTrackName[0] = '\0';
}
-void PlaneTrackCommonOperation::initExecution()
+void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
{
MovieTracking *tracking;
MovieTrackingObject *object;
- memset(this->m_corners, 0, sizeof(this->m_corners));
- memset(this->m_frameSpaceCorners, 0, sizeof(this->m_frameSpaceCorners));
-
if (!this->m_movieClip)
return;
-
+
tracking = &this->m_movieClip->tracking;
-
+
object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName);
if (object) {
MovieTrackingPlaneTrack *plane_track;
-
+
plane_track = BKE_tracking_plane_track_get_named(tracking, object, this->m_planeTrackName);
-
+
if (plane_track) {
MovieTrackingPlaneMarker *plane_marker;
int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);
-
+
plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
- memcpy(this->m_corners, plane_marker->corners, sizeof(this->m_corners));
+ copy_v2_v2(corners[0], plane_marker->corners[0]);
+ copy_v2_v2(corners[1], plane_marker->corners[1]);
+ copy_v2_v2(corners[2], plane_marker->corners[2]);
+ copy_v2_v2(corners[3], plane_marker->corners[3]);
}
}
-
- for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = this->m_corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = this->m_corners[i][1] * this->getHeight();
- }
}
-void PlaneTrackCommonOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
- NodeOperation::determineResolution(resolution, preferredResolution);
-
resolution[0] = 0;
resolution[1] = 0;
-
+
if (this->m_movieClip) {
int width, height;
MovieClipUser user = {0};
-
+
BKE_movieclip_user_set_frame(&user, this->m_framenumber);
BKE_movieclip_get_size(this->m_movieClip, &user, &width, &height);
-
+
resolution[0] = width;
resolution[1] = height;
}
}
+
+
+/* ******** PlaneTrackMaskOperation ******** */
+
+void PlaneTrackMaskOperation::initExecution()
+{
+ PlaneDistortMaskOperation::initExecution();
+
+ float corners[4][2];
+ readCornersFromTrack(corners);
+ calculateCorners(corners, true);
+}
+
+/* ******** PlaneTrackWarpImageOperation ******** */
+
+void PlaneTrackWarpImageOperation::initExecution()
+{
+ PlaneDistortWarpImageOperation::initExecution();
+
+ float corners[4][2];
+ readCornersFromTrack(corners);
+ calculateCorners(corners, true);
+ calculatePerspectiveMatrix();
+}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackCommonOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 705bdf4bd81..3c5dd783542 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -20,12 +20,12 @@
* Sergey Sharybin
*/
-#ifndef _COM_PlaneTrackCommonOperation_h
-#define _COM_PlaneTrackCommonOperation_h
+#ifndef _COM_PlaneTrackWarpImageOperation_h
+#define _COM_PlaneTrackWarpImageOperation_h
#include <string.h>
-#include "COM_NodeOperation.h"
+#include "COM_PlaneDistortCommonOperation.h"
#include "DNA_movieclip_types.h"
#include "DNA_tracking_types.h"
@@ -33,30 +33,64 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
-class PlaneTrackCommonOperation : public NodeOperation {
+class PlaneTrackCommon {
protected:
MovieClip *m_movieClip;
int m_framenumber;
char m_trackingObjectName[64];
char m_planeTrackName[64];
- float m_corners[4][2]; /* Corners coordinates in normalized space. */
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
-
- /**
- * Determine the output resolution. The resolution is retrieved from the Renderer
+ /* note: this class is not an operation itself (to prevent virtual inheritance issues)
+ * implementation classes must make wrappers to use these methods, see below.
*/
+ void readCornersFromTrack(float corners[4][2]);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
public:
- PlaneTrackCommonOperation();
+ PlaneTrackCommon();
void setMovieClip(MovieClip *clip) {this->m_movieClip = clip;}
void setTrackingObject(char *object) { BLI_strncpy(this->m_trackingObjectName, object, sizeof(this->m_trackingObjectName)); }
void setPlaneTrackName(char *plane_track) { BLI_strncpy(this->m_planeTrackName, plane_track, sizeof(this->m_planeTrackName)); }
void setFramenumber(int framenumber) {this->m_framenumber = framenumber;}
+};
+
+class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTrackCommon {
+public:
+ PlaneTrackMaskOperation() :
+ PlaneDistortMaskOperation(),
+ PlaneTrackCommon()
+ {}
+
+ void initExecution();
+
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+ {
+ PlaneTrackCommon::determineResolution(resolution, preferredResolution);
+
+ unsigned int temp[2];
+ NodeOperation::determineResolution(temp, resolution);
+ }
+};
+
+
+class PlaneTrackWarpImageOperation : public PlaneDistortWarpImageOperation, public PlaneTrackCommon {
+public:
+ PlaneTrackWarpImageOperation() :
+ PlaneDistortWarpImageOperation(),
+ PlaneTrackCommon()
+ {}
+
void initExecution();
+
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+ {
+ PlaneTrackCommon::determineResolution(resolution, preferredResolution);
+
+ unsigned int temp[2];
+ NodeOperation::determineResolution(temp, resolution);
+ }
};
#endif
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp
index 2ea18f64aab..69290cd7c3c 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.cpp
+++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_PreviewOperation.h"
-#include "COM_SocketConnection.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
#include "WM_api.h"
@@ -56,7 +55,7 @@ void PreviewOperation::verifyPreview(bNodeInstanceHash *previews, bNodeInstanceK
/* Size (0, 0) ensures the preview rect is not allocated in advance,
* this is set later in initExecution once the resolution is determined.
*/
- this->m_preview = BKE_node_preview_verify(previews, key, 0, 0, TRUE);
+ this->m_preview = BKE_node_preview_verify(previews, key, 0, 0, true);
}
void PreviewOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h
index bb60dfa0420..3e97acec7bb 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.h
+++ b/source/blender/compositor/operations/COM_PreviewOperation.h
@@ -53,7 +53,7 @@ public:
void executeRegion(rcti *rect, unsigned int tileNumber);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
- bool isPreviewOperation() { return true; }
+ bool isPreviewOperation() const { return true; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h
index cce519c6eb3..569920d51ef 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.h
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h
@@ -34,7 +34,6 @@ private:
MemoryBuffer *m_buffer;
public:
ReadBufferOperation();
- int isBufferOperation() { return true; }
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
index e7cda208319..af0d1b0b4f4 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
@@ -81,8 +81,16 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
case COM_PS_NEAREST: {
int ix = x;
int iy = y;
- if (ix < 0 || iy < 0 || ix >= width || iy >= height)
+ if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
+ if (this->m_elementsize == 1)
+ output[0] = 0.0f;
+ else if (this->m_elementsize == 3)
+ zero_v3(output);
+ else
+ zero_v4(output);
break;
+
+ }
offset = (iy * width + ix) * this->m_elementsize;
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp
index c6ad87bbf97..6aca9fe22c4 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cpp
+++ b/source/blender/compositor/operations/COM_RotateOperation.cpp
@@ -38,8 +38,8 @@ void RotateOperation::initExecution()
{
this->m_imageSocket = this->getInputSocketReader(0);
this->m_degreeSocket = this->getInputSocketReader(1);
- this->m_centerX = this->getWidth() / 2.0;
- this->m_centerY = this->getHeight() / 2.0;
+ this->m_centerX = (getWidth() - 1) / 2.0;
+ this->m_centerY = (getHeight() - 1) / 2.0;
}
void RotateOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp
index 452765a5ab7..23e8ce86fd9 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp
@@ -271,10 +271,10 @@ bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, Read
{
rcti newInput;
- newInput.xmax = input->xmax * this->m_relX;
- newInput.xmin = input->xmin * this->m_relX;
- newInput.ymax = input->ymax * this->m_relY;
- newInput.ymin = input->ymin * this->m_relY;
+ newInput.xmax = (input->xmax - m_offsetX) * this->m_relX;
+ newInput.xmin = (input->xmin - m_offsetX) * this->m_relX;
+ newInput.ymax = (input->ymax - m_offsetY) * this->m_relY;
+ newInput.ymin = (input->ymin - m_offsetY) * this->m_relY;
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h
index 6fd1b9768fc..d29ca726056 100644
--- a/source/blender/compositor/operations/COM_SetVectorOperation.h
+++ b/source/blender/compositor/operations/COM_SetVectorOperation.h
@@ -59,7 +59,7 @@ public:
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
bool isSetOperation() const { return true; }
- void setVector(float vector[3]) {
+ void setVector(const float vector[3]) {
setX(vector[0]);
setY(vector[1]);
setZ(vector[2]);
diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
index d047198ac93..da345b282fd 100644
--- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
+++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
@@ -26,22 +26,4 @@ SocketProxyOperation::SocketProxyOperation(DataType type) : NodeOperation()
{
this->addInputSocket(type);
this->addOutputSocket(type);
- this->m_inputOperation = NULL;
-}
-
-void SocketProxyOperation::initExecution()
-{
- this->m_inputOperation = this->getInputSocketReader(0);
-}
-
-void SocketProxyOperation::deinitExecution()
-{
- this->m_inputOperation = NULL;
-}
-
-void SocketProxyOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
-{
- if (this->m_inputOperation) {
- this->m_inputOperation->readSampled(output, x, y, sampler);
- }
}
diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h
index 6a6a0b351b0..9733a1fbeec 100644
--- a/source/blender/compositor/operations/COM_SocketProxyOperation.h
+++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h
@@ -26,14 +26,10 @@
#include "COM_NodeOperation.h"
class SocketProxyOperation : public NodeOperation {
-private:
- SocketReader *m_inputOperation;
public:
SocketProxyOperation(DataType type);
- void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
- void initExecution();
- void deinitExecution();
+ bool isProxyOperation() const { return true; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_SplitOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp
index 9278f1c3ec4..367c7eefa25 100644
--- a/source/blender/compositor/operations/COM_SplitOperation.cpp
+++ b/source/blender/compositor/operations/COM_SplitOperation.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_SplitOperation.h"
-#include "COM_SocketConnection.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index 96aea56050f..ede767cbff7 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -25,7 +25,7 @@
#include "BLI_listbase.h"
#include "BKE_image.h"
-TextureBaseOperation::TextureBaseOperation() : SingleThreadedNodeOperation()
+TextureBaseOperation::TextureBaseOperation() : SingleThreadedOperation()
{
this->addInputSocket(COM_DT_VECTOR); //offset
this->addInputSocket(COM_DT_VECTOR); //size
@@ -50,7 +50,7 @@ void TextureBaseOperation::initExecution()
this->m_inputOffset = getInputSocketReader(0);
this->m_inputSize = getInputSocketReader(1);
this->m_pool = BKE_image_pool_new();
- SingleThreadedNodeOperation::initExecution();
+ SingleThreadedOperation::initExecution();
}
void TextureBaseOperation::deinitExecution()
{
@@ -58,7 +58,7 @@ void TextureBaseOperation::deinitExecution()
this->m_inputOffset = NULL;
BKE_image_pool_free(this->m_pool);
this->m_pool = NULL;
- SingleThreadedNodeOperation::deinitExecution();
+ SingleThreadedOperation::deinitExecution();
}
void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index 114cee00530..47ef40882c5 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -24,7 +24,7 @@
#ifndef _COM_TextureOperation_h
#define _COM_TextureOperation_h
-#include "COM_SingleThreadedNodeOperation.h"
+#include "COM_SingleThreadedOperation.h"
#include "DNA_texture_types.h"
#include "BLI_listbase.h"
extern "C" {
@@ -39,7 +39,7 @@ extern "C" {
*
* @todo: rename to operation.
*/
-class TextureBaseOperation : public SingleThreadedNodeOperation {
+class TextureBaseOperation : public SingleThreadedOperation {
private:
Tex *m_texture;
const RenderData *m_rd;
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp
index 2d944b70f75..e8a578fa131 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.cpp
+++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp
@@ -24,8 +24,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-
-
TonemapOperation::TonemapOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index f53f2b87f98..53c0acd781a 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -21,7 +21,6 @@
*/
#include "COM_ViewerOperation.h"
-#include "COM_SocketConnection.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
#include "WM_api.h"
@@ -49,7 +48,7 @@ ViewerOperation::ViewerOperation() : NodeOperation()
this->m_doDepthBuffer = false;
this->m_viewSettings = NULL;
this->m_displaySettings = NULL;
- this->m_ignoreAlpha = false;
+ this->m_useAlphaInput = false;
this->addInputSocket(COM_DT_COLOR);
this->addInputSocket(COM_DT_VALUE);
@@ -102,19 +101,12 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
for (y = y1; y < y2 && (!breaked); y++) {
for (x = x1; x < x2; x++) {
this->m_imageInput->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
- if (this->m_ignoreAlpha) {
- buffer[offset4 + 3] = 1.0f;
- }
- else {
- if (this->m_alphaInput != NULL) {
- this->m_alphaInput->readSampled(alpha, x, y, COM_PS_NEAREST);
- buffer[offset4 + 3] = alpha[0];
- }
- }
- if (m_depthInput) {
- this->m_depthInput->readSampled(depth, x, y, COM_PS_NEAREST);
- depthbuffer[offset] = depth[0];
+ if (this->m_useAlphaInput) {
+ this->m_alphaInput->readSampled(alpha, x, y, COM_PS_NEAREST);
+ buffer[offset4 + 3] = alpha[0];
}
+ this->m_depthInput->readSampled(depth, x, y, COM_PS_NEAREST);
+ depthbuffer[offset] = depth[0];
offset ++;
offset4 += 4;
@@ -143,7 +135,9 @@ void ViewerOperation::initImage()
IMB_freezbuffloatImBuf(ibuf);
ibuf->x = getWidth();
ibuf->y = getHeight();
- imb_addrectfloatImBuf(ibuf);
+ /* zero size can happen if no image buffers exist to define a sensible resolution */
+ if (ibuf->x > 0 && ibuf->y > 0)
+ imb_addrectfloatImBuf(ibuf);
ima->ok = IMA_OK_LOADED;
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h
index 0b8d08d3974..dcc7ffa3730 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerOperation.h
@@ -39,7 +39,7 @@ private:
OrderOfChunks m_chunkOrder;
bool m_doDepthBuffer;
ImBuf *m_ibuf;
- bool m_ignoreAlpha;
+ bool m_useAlphaInput;
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
@@ -65,8 +65,8 @@ public:
float getCenterY() const { return this->m_centerY; }
OrderOfChunks getChunkOrder() const { return this->m_chunkOrder; }
const CompositorPriority getRenderPriority() const;
- bool isViewerOperation() { return true; }
- void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
+ bool isViewerOperation() const { return true; }
+ void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; }
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h
index 1f1f58b18f1..96466df979c 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.h
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h
@@ -27,7 +27,7 @@
#include "COM_MemoryProxy.h"
#include "COM_SocketReader.h"
/**
- * @brief Operation to write to a tile
+ * @brief NodeOperation to write to a tile
* @ingroup Operation
*/
class WriteBufferOperation : public NodeOperation {
@@ -37,7 +37,6 @@ class WriteBufferOperation : public NodeOperation {
public:
WriteBufferOperation();
~WriteBufferOperation();
- int isBufferOperation() { return true; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
const bool isWriteBufferOperation() const { return true; }
diff --git a/source/blender/datatoc/datatoc_icon.py b/source/blender/datatoc/datatoc_icon.py
index 930d588f859..930d588f859 100755..100644
--- a/source/blender/datatoc/datatoc_icon.py
+++ b/source/blender/datatoc/datatoc_icon.py
diff --git a/source/blender/datatoc/datatoc_icon_split.py b/source/blender/datatoc/datatoc_icon_split.py
index 44d8e5fd0fb..55f0a5c5f6a 100755..100644
--- a/source/blender/datatoc/datatoc_icon_split.py
+++ b/source/blender/datatoc/datatoc_icon_split.py
@@ -164,7 +164,6 @@ def dice(filepath, output, output_prefix, name_style,
minx_icon, miny_icon, maxx_icon, maxy_icon,
spacex_icon, spacey_icon,
):
- import struct
is_simple = (max(minx, miny, maxx, maxy,
minx_icon, miny_icon, maxx_icon, maxy_icon,
@@ -209,7 +208,7 @@ def dice(filepath, output, output_prefix, name_style,
# simple, no margins
if is_simple:
- sub_x = x * icon_x
+ sub_x = x * icon_w
sub_y = y * icon_h
else:
sub_x = minx + ((x * (icon_w + spacex_icon)) + minx_icon)
diff --git a/source/blender/datatoc/datatoc_icon_split_to_png.py b/source/blender/datatoc/datatoc_icon_split_to_png.py
index 39bbf1110fb..39bbf1110fb 100755..100644
--- a/source/blender/datatoc/datatoc_icon_split_to_png.py
+++ b/source/blender/datatoc/datatoc_icon_split_to_png.py
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 157527da087..98ccbd38805 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -366,14 +366,14 @@ static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, Pr
#if 0
/* channel type has no settings */
-static bool acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+static bool acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
return false;
}
#endif
/* check if some setting exists for this object-based data-expander (datablock only) */
-static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
+static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* expand is always supported */
@@ -439,14 +439,14 @@ static int acf_summary_icon(bAnimListElem *UNUSED(ale))
}
/* check if some setting exists for this channel */
-static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
/* only expanded is supported, as it is used for hiding all stuff which the summary covers */
return (setting == ACHANNEL_SETTING_EXPAND);
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
if (setting == ACHANNEL_SETTING_EXPAND) {
/* expanded */
@@ -461,7 +461,7 @@ static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_summary_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bAnimContext *ac = (bAnimContext *)ale->data;
@@ -486,6 +486,7 @@ static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *typ
static bAnimChannelType ACF_SUMMARY =
{
"Summary", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_summary_color, /* backdrop color */
acf_summary_backdrop, /* backdrop */
@@ -510,7 +511,7 @@ static int acf_scene_icon(bAnimListElem *UNUSED(ale))
}
/* check if some setting exists for this channel */
-static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
+static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* muted only in NLA */
@@ -532,7 +533,7 @@ static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale)
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -558,7 +559,7 @@ static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_scene_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Scene *scene = (Scene *)ale->data;
@@ -587,6 +588,7 @@ static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_SCENE =
{
"Scene", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_root_color, /* backdrop color */
acf_generic_root_backdrop, /* backdrop */
@@ -650,7 +652,7 @@ static void acf_object_name(bAnimListElem *ale, char *name)
}
/* check if some setting exists for this channel */
-static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
@@ -675,7 +677,7 @@ static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int s
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_object_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -701,7 +703,7 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *
}
/* get pointer to the setting */
-static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
@@ -731,6 +733,7 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type
static bAnimChannelType ACF_OBJECT =
{
"Object", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_root_color, /* backdrop color */
acf_generic_root_backdrop, /* backdrop */
@@ -813,7 +816,7 @@ static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA
}
/* check if some setting exists for this channel */
-static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
+static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
/* for now, all settings are supported, though some are only conditionally */
switch (setting) {
@@ -831,7 +834,7 @@ static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale)
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_group_setting_flag(bAnimContext *ac, int setting, bool *neg)
+static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -860,14 +863,15 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, bool *neg)
case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
*neg = 1;
return AGRP_NOTVISIBLE;
+
+ default:
+ /* this shouldn't happen */
+ return 0;
}
-
- /* this shouldn't happen */
- return 0;
}
/* get pointer to the setting */
-static void *acf_group_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_group_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bActionGroup *agrp = (bActionGroup *)ale->data;
@@ -879,6 +883,7 @@ static void *acf_group_setting_ptr(bAnimListElem *ale, int UNUSED(setting), shor
static bAnimChannelType ACF_GROUP =
{
"Group", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_group_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
@@ -924,7 +929,7 @@ static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
}
/* check if some setting exists for this channel */
-static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
FCurve *fcu = (FCurve *)ale->data;
@@ -951,7 +956,7 @@ static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int s
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -975,7 +980,7 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *
}
/* get pointer to the setting */
-static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_fcurve_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
FCurve *fcu = (FCurve *)ale->data;
@@ -987,6 +992,7 @@ static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int UNUSED(setting), sho
static bAnimChannelType ACF_FCURVE =
{
"F-Curve", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
@@ -1011,7 +1017,7 @@ static int acf_fillactd_icon(bAnimListElem *UNUSED(ale))
}
/* check if some setting exists for this channel */
-static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* only select and expand supported */
@@ -1025,7 +1031,7 @@ static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1044,7 +1050,7 @@ static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_fillactd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bAction *act = (bAction *)ale->data;
AnimData *adt = ale->adt;
@@ -1071,6 +1077,7 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *ty
static bAnimChannelType ACF_FILLACTD =
{
"Ob-Action Filler", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1101,7 +1108,7 @@ static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
/* check if some setting exists for this channel */
// TODO: this could be made more generic
-static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* only expand supported */
@@ -1114,7 +1121,7 @@ static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListEle
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1130,7 +1137,7 @@ static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, b
}
/* get pointer to the setting */
-static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
AnimData *adt = (AnimData *)ale->data;
@@ -1150,6 +1157,7 @@ static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short
static bAnimChannelType ACF_FILLDRIVERS =
{
"Drivers Filler", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1175,7 +1183,7 @@ static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1200,7 +1208,7 @@ static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsmat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Material *ma = (Material *)ale->data;
@@ -1227,6 +1235,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSMAT =
{
"Material Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1251,7 +1260,7 @@ static int acf_dslam_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1276,7 +1285,7 @@ static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dslam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Lamp *la = (Lamp *)ale->data;
@@ -1303,6 +1312,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSLAM =
{
"Lamp Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1334,7 +1344,7 @@ static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(al
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1359,7 +1369,7 @@ static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dstex_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dstex_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Tex *tex = (Tex *)ale->data;
@@ -1386,6 +1396,7 @@ static void *acf_dstex_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSTEX =
{
"Texture Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1410,7 +1421,7 @@ static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1435,7 +1446,7 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Camera *ca = (Camera *)ale->data;
@@ -1462,6 +1473,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSCAM =
{
"Camera Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1496,7 +1508,7 @@ static int acf_dscur_icon(bAnimListElem *ale)
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1521,7 +1533,7 @@ static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dscur_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Curve *cu = (Curve *)ale->data;
@@ -1548,6 +1560,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSCUR =
{
"Curve Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1572,7 +1585,7 @@ static int acf_dsskey_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1597,7 +1610,7 @@ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *
}
/* get pointer to the setting */
-static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsskey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Key *key = (Key *)ale->data;
@@ -1624,6 +1637,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type
static bAnimChannelType ACF_DSSKEY =
{
"Shape Key Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1648,7 +1662,7 @@ static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1673,7 +1687,7 @@ static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dswor_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
World *wo = (World *)ale->data;
@@ -1700,6 +1714,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSWOR =
{
"World Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1724,7 +1739,7 @@ static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1749,7 +1764,7 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *
}
/* get pointer to the setting */
-static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dspart_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
ParticleSettings *part = (ParticleSettings *)ale->data;
@@ -1776,6 +1791,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type
static bAnimChannelType ACF_DSPART =
{
"Particle Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1800,7 +1816,7 @@ static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1825,7 +1841,7 @@ static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsmball_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
MetaBall *mb = (MetaBall *)ale->data;
@@ -1852,6 +1868,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ
static bAnimChannelType ACF_DSMBALL =
{
"Metaball Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1876,7 +1893,7 @@ static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1901,7 +1918,7 @@ static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsarm_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bArmature *arm = (bArmature *)ale->data;
@@ -1928,6 +1945,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSARM =
{
"Armature Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -1963,7 +1981,7 @@ static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -1988,7 +2006,7 @@ static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsntree_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bNodeTree *ntree = (bNodeTree *)ale->data;
@@ -2015,6 +2033,7 @@ static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *typ
static bAnimChannelType ACF_DSNTREE =
{
"Node Tree Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -2035,11 +2054,11 @@ static bAnimChannelType ACF_DSNTREE =
/* TODO: just get this from RNA? */
static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_BRUSH_DATA; /* FIXME */
+ return ICON_LINE_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2064,7 +2083,7 @@ static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, b
}
/* get pointer to the setting */
-static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data;
@@ -2091,6 +2110,7 @@ static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short
static bAnimChannelType ACF_DSLINESTYLE =
{
"Line Style Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
@@ -2115,7 +2135,7 @@ static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2140,7 +2160,7 @@ static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *
}
/* get pointer to the setting */
-static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Mesh *me = (Mesh *)ale->data;
@@ -2167,6 +2187,7 @@ static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type
static bAnimChannelType ACF_DSMESH =
{
"Mesh Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -2191,7 +2212,7 @@ static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2216,7 +2237,7 @@ static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dslat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Lattice *lt = (Lattice *)ale->data;
@@ -2243,6 +2264,7 @@ static void *acf_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSLAT =
{
"Lattice Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -2267,7 +2289,7 @@ static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2292,7 +2314,7 @@ static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *n
}
/* get pointer to the setting */
-static void *acf_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_dsspk_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Speaker *spk = (Speaker *)ale->data;
@@ -2319,6 +2341,7 @@ static void *acf_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type)
static bAnimChannelType ACF_DSSPK =
{
"Speaker Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
@@ -2368,7 +2391,7 @@ static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property
}
/* check if some setting exists for this channel */
-static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
@@ -2383,7 +2406,7 @@ static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2404,7 +2427,7 @@ static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
+static void *acf_shapekey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
KeyBlock *kb = (KeyBlock *)ale->data;
@@ -2426,6 +2449,7 @@ static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *ty
static bAnimChannelType ACF_SHAPEKEY =
{
"Shape Key", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
@@ -2457,7 +2481,7 @@ static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
}
/* check if some setting exists for this channel */
-static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* only select and expand supported */
@@ -2471,7 +2495,7 @@ static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSE
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2482,14 +2506,15 @@ static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GP_DATA_EXPAND;
+
+ default:
+ /* these shouldn't happen */
+ return 0;
}
-
- /* this shouldn't happen */
- return 0;
}
/* get pointer to the setting */
-static void *acf_gpd_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_gpd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bGPdata *gpd = (bGPdata *)ale->data;
@@ -2501,6 +2526,7 @@ static void *acf_gpd_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short
static bAnimChannelType ACF_GPD =
{
"GPencil Datablock", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_gpd_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
@@ -2541,7 +2567,7 @@ static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA *
}
/* check if some setting exists for this channel */
-static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* unsupported */
@@ -2557,7 +2583,7 @@ static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSE
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2578,11 +2604,11 @@ static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg
}
/* get pointer to the setting */
-static void *acf_gpl_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_gpl_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
- /* all flags are just in agrp->flag for now... */
+ /* all flags are just in gpl->flag for now... */
return GET_ACF_FLAG_PTR(gpl->flag, type);
}
@@ -2590,6 +2616,7 @@ static void *acf_gpl_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short
static bAnimChannelType ACF_GPL =
{
"GPencil Layer", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
@@ -2622,7 +2649,7 @@ static int acf_mask_icon(bAnimListElem *UNUSED(ale))
}
/* check if some setting exists for this channel */
-static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* only select and expand supported */
@@ -2636,7 +2663,7 @@ static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUS
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2647,14 +2674,15 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *ne
case ACHANNEL_SETTING_EXPAND: /* expanded */
return MASK_ANIMF_EXPAND;
+
+ default:
+ /* this shouldn't happen */
+ return 0;
}
-
- /* this shouldn't happen */
- return 0;
}
/* get pointer to the setting */
-static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_mask_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
Mask *mask = (Mask *)ale->data;
@@ -2666,6 +2694,7 @@ static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short
static bAnimChannelType ACF_MASKDATA =
{
"Mask Datablock", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
acf_mask_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
@@ -2706,7 +2735,7 @@ static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyR
}
/* check if some setting exists for this channel */
-static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
+static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
{
switch (setting) {
/* unsupported */
@@ -2722,7 +2751,7 @@ static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *U
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2740,11 +2769,11 @@ static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_masklay_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_masklay_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
MaskLayer *masklay = (MaskLayer *)ale->data;
- /* all flags are just in agrp->flag for now... */
+ /* all flags are just in masklay->flag for now... */
return GET_ACF_FLAG_PTR(masklay->flag, type);
}
@@ -2752,6 +2781,7 @@ static void *acf_masklay_setting_ptr(bAnimListElem *ale, int UNUSED(setting), sh
static bAnimChannelType ACF_MASKLAYER =
{
"Mask Layer", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
@@ -2811,7 +2841,7 @@ static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property
}
/* check if some setting exists for this channel */
-static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, int setting)
+static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, eAnimChannel_Settings setting)
{
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
@@ -2856,7 +2886,7 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg)
+static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
*neg = false;
@@ -2880,7 +2910,7 @@ static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), int setting, bool
}
/* get pointer to the setting */
-static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
NlaTrack *nlt = (NlaTrack *)ale->data;
return GET_ACF_FLAG_PTR(nlt->flag, type);
@@ -2890,6 +2920,7 @@ static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, int UNUSED(setting), s
static bAnimChannelType ACF_NLATRACK =
{
"NLA Track", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
acf_nlatrack_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
@@ -2905,7 +2936,174 @@ static bAnimChannelType ACF_NLATRACK =
acf_nlatrack_setting_ptr /* pointer for setting */
};
+/* NLA Action ----------------------------------------------- */
+
+/* icon for action depends on whether it's in tweaking mode */
+static int acf_nlaaction_icon(bAnimListElem *ale)
+{
+ AnimData *adt = ale->adt;
+
+ /* indicate tweaking-action state by changing the icon... */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ return ICON_ACTION_TWEAK;
+ }
+ else {
+ return ICON_ACTION;
+ }
+}
+
+/* Backdrop color for nla action channel
+ * Although this can't be used directly for NLA Action drawing,
+ * it is still needed for use behind the RHS toggles
+ */
+static void acf_nlaaction_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
+{
+ float color[4];
+
+ /* Action Line
+ * The alpha values action_get_color returns are only useful for drawing
+ * strips backgrounds but here we're doing channel list backgrounds instead
+ * so we ignore that and use our own when needed
+ */
+ nla_action_get_color(ale->adt, (bAction *)ale->data, color);
+
+ /* NOTE: since the return types only allow rgb, we cannot do the alpha-blending we'd
+ * like for the solo-drawing case. Hence, this method isn't actually used for drawing
+ * most of the channel...
+ */
+ copy_v3_v3(r_color, color);
+}
+
+/* backdrop for nla action channel */
+static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+ bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ AnimData *adt = ale->adt;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[4];
+
+ /* Action Line
+ * The alpha values action_get_color returns are only useful for drawing
+ * strips backgrounds but here we're doing channel list backgrounds instead
+ * so we ignore that and use our own when needed
+ */
+ nla_action_get_color(adt, (bAction *)ale->data, color);
+
+ if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
+ /* Yes, the color vector has 4 components, BUT we only want to be using 3 of them! */
+ glColor3fv(color);
+ }
+ else {
+ float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
+ glColor4f(color[0], color[1], color[2], alpha);
+ }
+
+ /* only on top left corner, to show that this channel sits on top of the preceding ones
+ * while still linking into the action line strip to the right
+ */
+ uiSetRoundBox(UI_CNR_TOP_LEFT);
+
+ /* draw slightly shifted up vertically to look like it has more separation from other channels,
+ * but we then need to slightly shorten it so that it doesn't look like it overlaps
+ */
+ uiDrawBox(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8);
+}
+
+/* name for nla action entries */
+static void acf_nlaaction_name(bAnimListElem *ale, char *name)
+{
+ bAction *act = (bAction *)ale->data;
+
+ if (name) {
+ if (act) {
+ // TODO: add special decoration when doing this in tweaking mode?
+ BLI_strncpy(name, act->id.name + 2, ANIM_CHAN_NAME_SIZE);
+ }
+ else {
+ BLI_strncpy(name, "<No Action>", ANIM_CHAN_NAME_SIZE);
+ }
+ }
+}
+
+/* name property for nla action entries */
+static bool acf_nlaaction_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
+{
+ if (ale->data) {
+ RNA_pointer_create(ale->id, &RNA_Action, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
+
+ return (*prop != NULL);
+ }
+
+ return false;
+}
+
+/* check if some setting exists for this channel */
+static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, eAnimChannel_Settings setting)
+{
+ AnimData *adt = ale->adt;
+
+ /* visibility of settings depends on various states... */
+ switch (setting) {
+ /* conditionally supported */
+ case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ /* this should only appear in tweakmode */
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ /* unsupported */
+ default:
+ return false;
+ }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+{
+ /* clear extra return data first */
+ *neg = false;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
+ *neg = true; // XXX
+ return ADT_NLA_EDIT_NOMAP;
+
+ default: /* unsupported */
+ return 0;
+ }
+}
+
+/* get pointer to the setting */
+static void *acf_nlaaction_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+{
+ AnimData *adt = ale->adt;
+ return GET_ACF_FLAG_PTR(adt->flag, type);
+}
+/* nla action type define */
+static bAnimChannelType ACF_NLAACTION =
+{
+ "NLA Active Action", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too, since it needs special hacks) */
+ acf_nlaaction_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset, /* offset */ // XXX?
+
+ acf_nlaaction_name, /* name */
+ acf_nlaaction_name_prop, /* name prop */
+ acf_nlaaction_icon, /* icon */
+
+ acf_nlaaction_setting_valid, /* has setting */
+ acf_nlaaction_setting_flag, /* flag for setting */
+ acf_nlaaction_setting_ptr /* pointer for setting */
+};
/* *********************************************** */
@@ -2966,9 +3164,7 @@ static void ANIM_init_channel_typeinfo_data(void)
animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */
animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */
-
- // TODO: this channel type still hasn't been ported over yet, since it requires special attention
- animchannelTypeInfo[type++] = NULL; /* NLA Action */
+ animchannelTypeInfo[type++] = &ACF_NLAACTION; /* NLA Action */
}
}
@@ -3044,33 +3240,30 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting
switch (ptrsize) {
case sizeof(int): /* integer pointer for setting */
{
- int *val = (int *)ptr;
+ const int *val = (int *)ptr;
if (negflag)
return ((*val) & flag) == 0;
else
return ((*val) & flag) != 0;
- break;
}
case sizeof(short): /* short pointer for setting */
{
- short *val = (short *)ptr;
+ const short *val = (short *)ptr;
if (negflag)
return ((*val) & flag) == 0;
else
return ((*val) & flag) != 0;
- break;
}
case sizeof(char): /* char pointer for setting */
{
- char *val = (char *)ptr;
+ const char *val = (char *)ptr;
if (negflag)
return ((*val) & flag) == 0;
else
return ((*val) & flag) != 0;
- break;
}
}
}
@@ -3258,7 +3451,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
}
}
- /* step 6) draw backdrops behidn mute+protection toggles + (sliders) ....................... */
+ /* step 6) draw backdrops behind mute+protection toggles + (sliders) ....................... */
/* reset offset - now goes from RHS of panel */
offset = 0;
@@ -3266,6 +3459,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
if (v2d) {
short draw_sliders = 0;
+ float ymin_ofs = 0.0f;
float color[3];
/* get and set backdrop color */
@@ -3298,6 +3492,15 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* mute... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
offset += ICON_WIDTH;
+ /* pinned... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED))
+ offset += ICON_WIDTH;
+
+ /* NOTE: technically, NLA Action "pushdown" should be here too, but there are no sliders there */
+
+ /* NLA action channels have slightly different spacing requirements... */
+ if (ale->type == ANIMTYPE_NLAACTION)
+ ymin_ofs = NLACHANNEL_SKIP;
}
/* draw slider
@@ -3315,7 +3518,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
* - starts from the point where the first toggle/slider starts,
* - ends past the space that might be reserved for a scroller
*/
- gpuSingleFilledRectf(v2d->cur.xmax - offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ gpuSingleFilledRectf(v2d->cur.xmax - (float)offset, yminc + ymin_ofs, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
}
}
@@ -3409,7 +3612,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
Scene *scene = CTX_data_scene(C);
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
- short flag = 0, done = FALSE;
+ short flag = 0;
+ bool done = false;
float cfra;
/* get current frame */
@@ -3447,7 +3651,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
Scene *scene = CTX_data_scene(C);
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
- short flag = 0, done = FALSE;
+ short flag = 0;
+ bool done = false;
float cfra;
/* get current frame */
@@ -3540,10 +3745,28 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
//icon = ((enabled) ? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF);
icon = ICON_MUTE_IPO_OFF;
- if (ale->type == ANIMTYPE_FCURVE)
+ if (ale->type == ANIMTYPE_FCURVE) {
tooltip = TIP_("Does F-Curve contribute to result");
- else
- tooltip = TIP_("Do channels contribute to result");
+ }
+ else if ((ac) && (ac->spacetype == SPACE_NLA) && (ale->type != ANIMTYPE_NLATRACK)) {
+ tooltip = TIP_("Temporarily disable NLA stack evaluation (i.e. only the active action is evaluated)");
+ }
+ else {
+ tooltip = TIP_("Do channels contribute to result (toggle channel muting)");
+ }
+ break;
+
+ case ACHANNEL_SETTING_PINNED: /* pin icon */
+ //icon = ((enabled) ? ICON_PINNED : ICON_UNPINNED);
+ icon = ICON_UNPINNED;
+
+ if (ale->type == ANIMTYPE_NLAACTION) {
+ tooltip = TIP_("Display action without any time remapping (when unpinned)");
+ }
+ else {
+ /* TODO: there are no other tools which require the 'pinning' concept yet */
+ tooltip = NULL;
+ }
break;
default:
@@ -3584,6 +3807,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
case ACHANNEL_SETTING_MUTE: /* General - muting flags */
+ case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */
uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
break;
@@ -3723,6 +3947,31 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
offset += ICON_WIDTH;
draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_MUTE);
}
+
+ /* ----------- */
+
+ /* pinned... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
+ offset += ICON_WIDTH;
+ draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_PINNED);
+ }
+
+ /* NLA Action "pushdown" */
+ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->adt && ale->adt->action) && !(ale->adt->flag & ADT_NLA_EDIT_ON)) {
+ uiBut *but;
+ PointerRNA *opptr_b;
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ offset += UI_UNIT_X;
+ but = uiDefIconButO(block, BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
+ (int)v2d->cur.xmax - offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL);
+
+ opptr_b = uiButGetOperatorPtrRNA(but);
+ RNA_int_set(opptr_b, "channel_index", channel_index);
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ }
}
/* draw slider
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index efd057d4e76..5d97b7be9f7 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -36,6 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_library.h"
#include "DNA_anim_types.h"
@@ -386,7 +387,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s
* - setting: type of setting to set
* - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short on)
+void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short mode)
{
bAnimListElem *ale, *match = NULL;
int prevLevel = 0, matchLevel = 0;
@@ -436,8 +437,8 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
* - only flush up if the current state is now disabled (negative 'off' state is default)
* (otherwise, it's too much work to force the parents to be active too)
*/
- if ( ((setting == ACHANNEL_SETTING_VISIBLE) && on) ||
- ((setting != ACHANNEL_SETTING_VISIBLE) && on == 0) )
+ if ( ((setting == ACHANNEL_SETTING_VISIBLE) && (mode != ACHANNEL_SETFLAG_CLEAR)) ||
+ ((setting != ACHANNEL_SETTING_VISIBLE) && (mode == ACHANNEL_SETFLAG_CLEAR)))
{
/* go backwards in the list, until the highest-ranking element (by indention has been covered) */
for (ale = match->prev; ale; ale = ale->prev) {
@@ -460,7 +461,7 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
*/
if (level < prevLevel) {
/* flush the new status... */
- ANIM_channel_setting_set(ac, ale, setting, on);
+ ANIM_channel_setting_set(ac, ale, setting, mode);
/* store this level as the 'old' level now */
prevLevel = level;
@@ -501,7 +502,7 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
* flush the new status...
*/
if (level > matchLevel)
- ANIM_channel_setting_set(ac, ale, setting, on);
+ ANIM_channel_setting_set(ac, ale, setting, mode);
/* however, if the level is 'less than or equal to' the channel that was changed,
* (i.e. the current channel is as important if not more important than the changed channel)
* then we should stop, since we've found the last one of the children we should flush
@@ -653,7 +654,8 @@ typedef struct tReorderChannelIsland {
typedef enum eReorderIslandFlag {
REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
- REORDER_ISLAND_MOVED = (1 << 2) /* island has already been moved */
+ REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
+ REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
} eReorderIslandFlag;
@@ -691,7 +693,12 @@ static bool rearrange_island_up(ListBase *list, tReorderChannelIsland *island)
if (rearrange_island_ok(island)) {
/* moving up = moving before the previous island, otherwise we're in the same place */
tReorderChannelIsland *prev = island->prev;
-
+
+ /* Skip hidden islands! */
+ while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
+ prev = prev->prev;
+ }
+
if (prev) {
/* remove from current position */
BLI_remlink(list, island);
@@ -711,7 +718,12 @@ static bool rearrange_island_down(ListBase *list, tReorderChannelIsland *island)
if (rearrange_island_ok(island)) {
/* moving down = moving after the next island, otherwise we're in the same place */
tReorderChannelIsland *next = island->next;
-
+
+ /* Skip hidden islands! */
+ while (next && next->flag & REORDER_ISLAND_HIDDEN) {
+ next = next->next;
+ }
+
if (next) {
/* can only move past if next is not untouchable (i.e. nothing can go after it) */
if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
@@ -784,7 +796,7 @@ static AnimChanRearrangeFp rearrange_get_mode_func(short mode)
/* Rearrange Islands Generics ------------------------------------- */
/* add channel into list of islands */
-static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList, Link *channel, short type)
+static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList, Link *channel, short type, const bool is_hidden)
{
tReorderChannelIsland *island = islands->last; /* always try to add to last island if possible */
bool is_sel = false, is_untouchable = false;
@@ -819,9 +831,15 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
}
/* do we need to add to a new island? */
- if ((island == NULL) || /* 1) no islands yet */
- ((island->flag & REORDER_ISLAND_SELECTED) == 0) || /* 2) unselected islands have single channels only - to allow up/down movement */
- (is_sel == 0)) /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ if (/* 1) no islands yet */
+ (island == NULL) ||
+ /* 2) unselected islands have single channels only - to allow up/down movement */
+ ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
+ /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ (is_sel == 0) ||
+ /* 4) hidden status changes */
+ ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)
+ )
{
/* create a new island now */
island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
@@ -831,6 +849,8 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
island->flag |= REORDER_ISLAND_SELECTED;
if (is_untouchable)
island->flag |= REORDER_ISLAND_UNTOUCHABLE;
+ if (is_hidden)
+ island->flag |= REORDER_ISLAND_HIDDEN;
}
/* add channel to island - need to remove it from its existing list first though */
@@ -858,12 +878,20 @@ static void rearrange_animchannel_flatten_islands(ListBase *islands, ListBase *s
/* ............................. */
+static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, bAnimContext *ac, short type)
+{
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+
+ ANIM_animdata_filter(ac, anim_data_visible, filter, ac->data, type);
+}
+
/* performing rearranging of channels using islands */
-static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func, short mode, short type)
+static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func,
+ short mode, short type, ListBase *anim_data_visible)
{
ListBase islands = {NULL, NULL};
Link *channel, *chanNext = NULL;
- short done = FALSE;
+ bool done = false;
/* don't waste effort on an empty list */
if (BLI_listbase_is_empty(list))
@@ -871,8 +899,10 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
/* group channels into islands */
for (channel = list->first; channel; channel = chanNext) {
+ /* find out whether this channel is present in anim_data_visible or not! */
+ const bool is_hidden = (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
chanNext = channel->next;
- rearrange_animchannel_add_to_islands(&islands, list, channel, type);
+ rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
}
/* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
@@ -889,7 +919,7 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
/* perform rearranging */
if (rearrange_func(&islands, island)) {
island->flag |= REORDER_ISLAND_MOVED;
- done = TRUE;
+ done = true;
}
}
}
@@ -907,9 +937,10 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
* ! NLA tracks are displayed in opposite order, so directions need care
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, short mode)
+static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, short mode)
{
AnimChanRearrangeFp rearrange_func;
+ ListBase anim_data_visible = {NULL, NULL};
/* hack: invert mode so that functions will work in right order */
mode *= -1;
@@ -923,8 +954,14 @@ static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, shor
//if (EXPANDED_DRVD(adt) == 0)
// return;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
+
/* perform rearranging on tracks list */
- rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK);
+ rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Drivers Specific Stuff ------------------------------------------------- */
@@ -932,10 +969,11 @@ static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, shor
/* Change the order drivers within AnimData block
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_driver_channels(bAnimContext *UNUSED(ac), AnimData *adt, short mode)
+static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, short mode)
{
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ ListBase anim_data_visible = {NULL, NULL};
if (rearrange_func == NULL)
return;
@@ -944,8 +982,14 @@ static void rearrange_driver_channels(bAnimContext *UNUSED(ac), AnimData *adt, s
if (EXPANDED_DRVD(adt) == 0)
return;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+
/* perform rearranging on drivers list (drivers are really just F-Curves) */
- rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE);
+ rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Action Specific Stuff ------------------------------------------------- */
@@ -1027,6 +1071,7 @@ static void join_groups_action_temp(bAction *act)
static void rearrange_action_channels(bAnimContext *ac, bAction *act, short mode)
{
bActionGroup tgrp;
+ ListBase anim_data_visible = {NULL, NULL};
bool do_channels;
/* get rearranging function */
@@ -1038,21 +1083,35 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, short mode
/* make sure we're only operating with groups (vs a mixture of groups+curves) */
split_groups_action_temp(act, &tgrp);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
+
/* rearrange groups first
* - the group's channels will only get considered if nothing happened when rearranging the groups
* i.e. the rearrange function returned 0
*/
- do_channels = rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP) == 0;
+ do_channels = (rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP,
+ &anim_data_visible) == 0);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
if (do_channels) {
bActionGroup *agrp;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* only consider F-Curves if they're visible (group expanded) */
if (EXPANDED_AGRP(ac, agrp)) {
- rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE);
+ rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE,
+ &anim_data_visible);
}
}
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* assemble lists into one list (and clear moved tags) */
@@ -2121,6 +2180,32 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec
{
bActionGroup *agrp = (bActionGroup *)ale->data;
+ /* Armatures-Specific Feature:
+ * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ Object *ob = (Object *)ale->id;
+
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+
+ if (agrp->flag & AGRP_SELECTED) {
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ED_pose_bone_select(ob, pchan, false);
+ }
+ }
+ }
+ }
+
/* always clear active flag after doing this */
agrp->flag &= ~AGRP_ACTIVE;
break;
@@ -2202,7 +2287,7 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/* ******************* Rename Operator ***************************** */
@@ -2743,15 +2828,15 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
/* click-select */
/* XXX for now, only leftmouse.... */
WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "children_only", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "children_only", true);
/* rename */
WM_keymap_add_item(keymap, "ANIM_OT_channels_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
/* deselect all */
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", true);
/* borderselect */
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
@@ -2774,9 +2859,9 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "all", FALSE);
+ RNA_boolean_set(kmi->ptr, "all", false);
kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "all", FALSE);
+ RNA_boolean_set(kmi->ptr, "all", false);
/* rearranging */
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "direction", REARRANGE_ANIMCHAN_UP);
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index 618c1b04a71..c0543862265 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -243,13 +243,13 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
/* only affect if F-Curve involves sequence_editor.sequences */
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
char *seq_name;
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, FALSE);
+ seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
if (seq_name) MEM_freeN(seq_name);
/* update selection status */
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 8d359d401ca..7a8c2066ec5 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -31,7 +31,6 @@
#include "BLI_sys_types.h"
#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@@ -40,7 +39,6 @@
#include "BLI_timecode.h"
#include "BKE_context.h"
-#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_nla.h"
#include "BKE_object.h"
@@ -74,7 +72,7 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const
short slen;
/* because the frame number text is subject to the same scaling as the contents of the view */
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
gpuScale(1.0f / xscale, 1.0f, 1.0f);
/* get timecode string
@@ -233,7 +231,7 @@ static short bezt_nlamapping_apply(KeyframeEditData *ked, BezTriple *bezt)
* - restore = whether to map points back to non-mapped time
* - only_keys = whether to only adjust the location of the center point of beztriples
*/
-void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, short restore, short only_keys)
+void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys)
{
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc map_cb;
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 9d54d938cc7..6c28d05110f 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -914,14 +914,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
/* only consider if F-Curve involves sequence_editor.sequences */
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = NULL;
char *seq_name;
if (ed) {
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, FALSE);
+ seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
if (seq_name) MEM_freeN(seq_name);
}
@@ -1796,9 +1796,14 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
Material *base = give_current_material(ob, a);
Material *ma = give_node_material(base);
- /* add channels from the nested material if it exists */
- if (ma)
+ /* add channels from the nested material if it exists
+ * - skip if the same material is referenced in its node tree
+ * (which is common for BI materials) as that results in
+ * confusing duplicates
+ */
+ if ((ma) && (ma != base)) {
items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+ }
}
}
@@ -1862,7 +1867,7 @@ static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data
size_t items = 0;
/* 1) create a temporary "context" containing all the info we have here to pass to the callback
- * use to walk thorugh the dependencies of the modifiers
+ * use to walk through the dependencies of the modifiers
*
* ! Assumes that all other unspecified values (i.e. accumulation buffers) are zero'd out properly
*/
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index fa9b5defdbd..2d52628b134 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -326,7 +326,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
/* no time correction for framelen! space is drawn with old values */
ypixels = BLI_rcti_size_y(&v2d->mask);
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
gpuScale(1.0f / xscale, 1.0f, 1.0f);
@@ -1029,22 +1029,18 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
ARegion *ar = CTX_wm_region(C);
View2D *v2d = UI_view2d_fromcontext(C);
float viewx;
- int x, y, cfra;
+ int x, cfra;
if (markers == NULL)
return OPERATOR_PASS_THROUGH;
x = event->x - ar->winrct.xmin;
- y = event->y - ar->winrct.ymin;
- UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
+ viewx = UI_view2d_region_to_view_x(v2d, x);
cfra = ED_markers_find_nearest_marker_time(markers, viewx);
- if (extend)
- select_timeline_marker_frame(markers, cfra, 1);
- else
- select_timeline_marker_frame(markers, cfra, 0);
+ select_timeline_marker_frame(markers, cfra, extend);
#ifdef DURIAN_CAMERA_SWITCH
@@ -1155,22 +1151,19 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
View2D *v2d = UI_view2d_fromcontext(C);
ListBase *markers = ED_context_get_markers(C);
TimeMarker *marker;
- float xminf, xmaxf, yminf, ymaxf;
int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
bool extend = RNA_boolean_get(op->ptr, "extend");
- rcti rect;
+ rctf rect;
- WM_operator_properties_border_to_rcti(op, &rect);
-
- UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin, &xminf, &yminf);
- UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax, &xmaxf, &ymaxf);
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
if (markers == NULL)
return 0;
/* XXX marker context */
for (marker = markers->first; marker; marker = marker->next) {
- if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
+ if (BLI_rctf_isect_x(&rect, marker->frame)) {
switch (gesture_mode) {
case GESTURE_MODAL_SELECT:
marker->flag |= SELECT;
@@ -1215,7 +1208,7 @@ static void MARKER_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/* *********************** (de)select all ***************** */
@@ -1430,6 +1423,7 @@ static void MARKER_OT_make_links_scene(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
RNA_def_enum_funcs(prop, RNA_scene_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -1499,7 +1493,7 @@ void ED_operatortypes_marker(void)
}
/* called in screen_ops.c:ED_keymap_screen() */
-void ED_marker_keymap(wmKeyConfig *keyconf)
+void ED_keymap_marker(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Markers", 0, 0);
wmKeyMapItem *kmi;
@@ -1509,16 +1503,16 @@ void ED_marker_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
#ifdef DURIAN_CAMERA_SWITCH
kmi = WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "camera", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "camera", true);
kmi = WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "camera", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "camera", true);
#else
(void)kmi;
#endif
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 48b310b57ed..88429aa3867 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -66,25 +66,25 @@ static int change_frame_poll(bContext *C)
ScrArea *sa = CTX_wm_area(C);
/* XXX temp? prevent changes during render */
- if (G.is_rendering) return FALSE;
+ if (G.is_rendering) return false;
/* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
* this shouldn't show up in 3D editor (or others without 2D timeline view) via search
*/
if (sa) {
if (ELEM5(sa->spacetype, SPACE_TIME, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
- return TRUE;
+ return true;
}
else if (sa->spacetype == SPACE_IPO) {
/* NOTE: Graph Editor has special version which does some extra stuff.
* No need to show the generic error message for that case though!
*/
- return FALSE;
+ return false;
}
}
CTX_wm_operator_poll_msg_set(C, "Expected an timeline/animation area to be active");
- return FALSE;
+ return false;
}
/* Set the new frame number */
@@ -124,15 +124,15 @@ static int frame_from_event(bContext *C, const wmEvent *event)
int frame;
/* convert from region coordinates to View2D 'tot' space */
- UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &viewx, NULL);
+ viewx = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
/* round result to nearest int (frames are ints!) */
frame = iroundf(viewx);
-
+
if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
CLAMP(frame, PSFRA, PEFRA);
}
-
+
return frame;
}
@@ -212,8 +212,8 @@ static int previewrange_define_exec(bContext *C, wmOperator *op)
WM_operator_properties_border_to_rcti(op, &rect);
/* convert min/max values to frames (i.e. region to 'tot' rect) */
- UI_view2d_region_to_view(&ar->v2d, rect.xmin, 0, &sfra, NULL);
- UI_view2d_region_to_view(&ar->v2d, rect.xmax, 0, &efra, NULL);
+ sfra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmin);
+ efra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmax);
/* set start/end frames for preview-range
* - must clamp within allowable limits
@@ -277,6 +277,9 @@ static int previewrange_clear_exec(bContext *C, wmOperator *UNUSED(op))
ED_area_tag_redraw(curarea);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 668c8cdceec..839284905ff 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -46,7 +46,6 @@
#include "DNA_space_types.h"
#include "BKE_animsys.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -163,13 +162,13 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
*/
-short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
+int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
FCurve *fcu;
int array_index_max;
- int done = FALSE;
+ int done_tot = 0;
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
@@ -249,21 +248,21 @@ short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int ar
}
/* set the done status */
- done += (fcu != NULL);
+ done_tot += (fcu != NULL);
}
/* done */
- return done;
+ return done_tot;
}
/* Main Driver Management API calls:
* Remove the driver for the specified property on the given ID block (if available)
*/
-short ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
AnimData *adt;
FCurve *fcu;
- int success = 0;
+ bool success = false;
/* we don't check the validity of the path here yet, but it should be ok... */
adt = BKE_animdata_from_id(id);
@@ -282,7 +281,7 @@ short ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_pat
free_fcurve(fcu);
/* done successfully */
- success |= 1;
+ success = true;
}
}
else {
@@ -295,7 +294,7 @@ short ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_pat
BLI_remlink(&adt->drivers, fcu);
free_fcurve(fcu);
- success = 1;
+ success = true;
}
}
}
@@ -320,7 +319,7 @@ void free_anim_drivers_copybuf(void)
}
/* Checks if there is a driver in the copy/paste buffer */
-short ANIM_driver_can_paste(void)
+bool ANIM_driver_can_paste(void)
{
return (channeldriver_copypaste_buf != NULL);
}
@@ -330,7 +329,7 @@ short ANIM_driver_can_paste(void)
/* Main Driver Management API calls:
* Make a copy of the driver for the specified property on the given ID block
*/
-short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -377,7 +376,7 @@ short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int a
* Add a new driver for the specified property on the given ID block or replace an existing one
* with the driver + driver-curve data from the buffer
*/
-short ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -501,7 +500,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
- short success = 0;
+ int success = 0;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -544,7 +543,7 @@ void ANIM_OT_driver_button_add(wmOperatorType *ot)
//op->poll = ??? // TODO: need to have some animatable property to do this
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Create drivers for all elements of the array");
@@ -595,7 +594,7 @@ void ANIM_OT_driver_button_remove(wmOperatorType *ot)
//op->poll = ??? // TODO: need to have some driver to be able to do this...
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
@@ -642,7 +641,7 @@ void ANIM_OT_copy_driver_button(wmOperatorType *ot)
//op->poll = ??? // TODO: need to have some driver to be able to do this...
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* Paste Driver Button Operator ------------------------ */
@@ -686,7 +685,7 @@ void ANIM_OT_paste_driver_button(wmOperatorType *ot)
//op->poll = ??? // TODO: need to have some driver to be able to do this...
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ************************************************** */
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 75ea133176c..7ce33e01747 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -117,7 +117,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
/* basic settings (backdrop + mode selector + some padding) */
- /* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */
+ /* col = uiLayoutColumn(layout, true); */ /* UNUSED */
block = uiLayoutGetBlock(layout);
uiBlockBeginAlign(block);
but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
@@ -136,7 +136,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
int maxXWidth;
/* draw polynomial order selector */
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
&data->poly_order, 1, 100, 0, 0,
@@ -155,7 +155,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
}
/* draw controls for each coefficient and a + sign at end of row */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
cp = data->coefficients;
@@ -183,7 +183,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefBut(block, LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* next coefficient on a new row */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
}
else {
@@ -200,7 +200,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
unsigned int i;
/* draw polynomial order selector */
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
&data->poly_order, 1, 100, 0, 0,
@@ -209,7 +209,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* draw controls for each pair of coefficients */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
cp = data->coefficients;
@@ -236,7 +236,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefBut(block, LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* set up new row for the next pair of coefficients */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
}
else
@@ -259,11 +259,11 @@ static void draw_modifier__fn_generator(uiLayout *layout, ID *id, FModifier *fcm
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
/* add the settings */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
uiItemR(col, &ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE); // no grouping for now
+ col = uiLayoutColumn(layout, false); // no grouping for now
uiItemR(col, &ptr, "amplitude", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "phase_multiplier", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "phase_offset", 0, NULL, ICON_NONE);
@@ -284,16 +284,16 @@ static void draw_modifier__cycles(uiLayout *layout, ID *id, FModifier *fcm, shor
/* split into 2 columns
* NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
*/
- split = uiLayoutSplit(layout, 0.5f, FALSE);
+ split = uiLayoutSplit(layout, 0.5f, false);
/* before range */
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Before:"), ICON_NONE);
uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
/* after range */
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("After:"), ICON_NONE);
uiItemR(col, &ptr, "mode_after", 0, "", ICON_NONE);
uiItemR(col, &ptr, "cycles_after", 0, NULL, ICON_NONE);
@@ -314,16 +314,16 @@ static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short
uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
/* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, FALSE);
+ split = uiLayoutSplit(layout, 0.5f, false);
/* col 1 */
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
/* col 2 */
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
}
@@ -425,18 +425,18 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
RNA_pointer_create(id, &RNA_FModifierEnvelope, fcm, &ptr);
/* general settings */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
uiItemR(col, &ptr, "reference_value", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
uiItemR(row, &ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
/* control points header */
/* TODO: move this control-point control stuff to using the new special widgets for lists
* the current way is far too cramped */
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
uiDefBut(block, LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
@@ -448,7 +448,7 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
/* control points list */
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
/* get a new row to operate on */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
uiBlockBeginAlign(block);
@@ -481,36 +481,36 @@ static void draw_modifier__limits(uiLayout *layout, ID *id, FModifier *fcm, shor
/* row 1: minimum */
{
- /* row = uiLayoutRow(layout, FALSE); */ /* UNUSED */
+ /* row = uiLayoutRow(layout, false); */ /* UNUSED */
/* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, FALSE);
+ split = uiLayoutSplit(layout, 0.5f, false);
/* x-minimum */
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
/* y-minimum*/
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
}
/* row 2: maximum */
{
- /* row = uiLayoutRow(layout, FALSE); */ /* UNUSED */
+ /* row = uiLayoutRow(layout, false); */ /* UNUSED */
/* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, FALSE);
+ split = uiLayoutSplit(layout, 0.5f, false);
/* x-minimum */
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
/* y-minimum*/
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "max_y", 0, NULL, ICON_NONE);
}
@@ -528,23 +528,23 @@ static void draw_modifier__stepped(uiLayout *layout, ID *id, FModifier *fcm, sho
RNA_pointer_create(id, &RNA_FModifierStepped, fcm, &ptr);
/* block 1: "stepping" settings */
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
/* block 2: start range settings */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
/* block 3: end range settings */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
}
@@ -568,11 +568,11 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
/* get layout-row + UI-block for this */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row); // err...
/* left-align -------------------------------------------- */
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
uiBlockSetEmboss(block, UI_EMBOSSN);
@@ -590,7 +590,7 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
/* right-align ------------------------------------------- */
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
@@ -652,28 +652,28 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
box = uiLayoutBox(layout);
/* restricted range ----------------------------------------------------- */
- col = uiLayoutColumn(box, TRUE);
+ col = uiLayoutColumn(box, true);
/* top row: use restricted range */
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
/* second row: settings */
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
/* third row: blending influence */
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
}
/* influence -------------------------------------------------------------- */
- col = uiLayoutColumn(box, TRUE);
+ col = uiLayoutColumn(box, true);
/* top row: use influence */
uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
@@ -705,9 +705,9 @@ void free_fmodifiers_copybuf(void)
* assuming that the buffer has been cleared already with free_fmodifiers_copybuf()
* - active: only copy the active modifier
*/
-short ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, short active)
+bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
{
- short ok = 1;
+ bool ok = true;
/* sanity checks */
if (ELEM(NULL, modifiers, modifiers->first))
@@ -734,10 +734,10 @@ short ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, short active)
/* 'Paste' the F-Modifier(s) from the buffer to the specified list
* - replace: free all the existing modifiers to leave only the pasted ones
*/
-short ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, short replace)
+bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace)
{
FModifier *fcm;
- short ok = 0;
+ bool ok = false;
/* sanity checks */
if (modifiers == NULL)
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index c95afe0bd8c..f7e07959c5a 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -40,32 +40,16 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_dlrbTree.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_material_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_node_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_speaker_types.h"
-#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_mask_types.h"
-#include "BKE_key.h"
-#include "BKE_material.h"
-#include "BKE_global.h" // XXX remove me!
-
+#include "BKE_fcurve.h"
#include "GPU_blender_aspect.h"
#include "GPU_colors.h"
#include "GPU_matrix.h"
@@ -87,11 +71,15 @@
short compare_ak_cfraPtr(void *node, void *data)
{
ActKeyColumn *ak = (ActKeyColumn *)node;
- float *cframe = data;
+ const float *cframe = data;
+ float val = *cframe;
+
+ if (IS_EQT(val, ak->cfra, BEZT_BINARYSEARCH_THRESH))
+ return 0;
- if (*cframe < ak->cfra)
+ if (val < ak->cfra)
return -1;
- else if (*cframe > ak->cfra)
+ else if (val > ak->cfra)
return 1;
else
return 0;
@@ -261,110 +249,6 @@ static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *mas
BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape);
}
-/* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
-
-/* maximum size of default buffer for BezTriple columns */
-#define MAX_ABK_BUFSIZE 4
-
-/* BezTriple Container Node */
-// NOTE: only used internally while building Long Keyframes for now, but may be useful externally?
-typedef struct ActBeztColumn {
- /* Tree Node interface ---------------- */
- /* ListBase linkage */
- struct ActBeztColumn *next, *prev;
-
- /* sorting-tree linkage */
- struct ActBeztColumn *left, *right; /* 'children' of this node, less than and greater than it (respectively) */
- struct ActBeztColumn *parent; /* parent of this node in the tree */
- char tree_col; /* DLRB_BLACK or DLRB_RED */
- char pad;
-
- /* BezTriple Store -------------------- */
- short numBezts; /* number of BezTriples on this frame */
- float cfra; /* frame that the BezTriples occur on */
-
- BezTriple *bezts[MAX_ABK_BUFSIZE]; /* buffer of pointers to BezTriples on the same frame */
- //BezTriple **bezts_extra; /* secondary buffer of pointers if need be */
-} ActBeztColumn;
-
-/* --------------- */
-
-/* Comparator callback used for ActBeztColumns and BezTriple */
-static short compare_abk_bezt(void *node, void *data)
-{
- ActBeztColumn *abk = (ActBeztColumn *)node;
- BezTriple *bezt = (BezTriple *)data;
-
- if (bezt->vec[1][0] < abk->cfra)
- return -1;
- else if (bezt->vec[1][0] > abk->cfra)
- return 1;
- else
- return 0;
-}
-
-/* New node callback used for building ActBeztColumns from BezTriples */
-static DLRBT_Node *nalloc_abk_bezt(void *data)
-{
- ActBeztColumn *abk = MEM_callocN(sizeof(ActBeztColumn), "ActKeyColumn");
- BezTriple *bezt = (BezTriple *)data;
-
- /* store the BeztTriple in the buffer, and keep track of its frame number */
- abk->cfra = bezt->vec[1][0];
- abk->bezts[abk->numBezts++] = bezt;
-
- return (DLRBT_Node *)abk;
-}
-
-/* Node updater callback used for building ActBeztColumns from BezTriples */
-static void nupdate_abk_bezt(void *node, void *data)
-{
- ActBeztColumn *abk = (ActBeztColumn *)node;
- BezTriple *bezt = (BezTriple *)data;
-
- /* just add the BezTriple to the buffer if there's space, or allocate a new one */
- if (abk->numBezts >= MAX_ABK_BUFSIZE) {
- // TODO: need to allocate new array to cater...
- //bezts_extra = MEM_callocN(...);
- if (G.debug & G_DEBUG)
- printf("FIXME: nupdate_abk_bezt() missing case for too many overlapping BezTriples\n");
- }
- else {
- /* just store an extra one */
- abk->bezts[abk->numBezts++] = bezt;
- }
-}
-
-/* --------------- */
-
-/* Return the BezTriple in the given ActBeztColumn that matches the requested value */
-static BezTriple *abk_get_bezt_with_value(ActBeztColumn *abk, float value)
-{
- BezTriple *bezt;
- int i;
-
- /* sanity checks */
- if (abk == NULL)
- return NULL;
-
- /* look over each BezTriple in this container */
- for (i = 0; i < abk->numBezts; i++) {
- /* only do exact match for now... */
- if (/*i >= MAX_ABK_BUFSIZE*/ 0) {
- // TODO: this case needs special handling
- }
- else {
- /* just use the default buffer */
- bezt = abk->bezts[i];
-
- if (bezt->vec[1][1] == value)
- return bezt;
- }
- }
-
- return NULL;
-}
-
/* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
/* Comparator callback used for ActKeyBlock and cframe float-value pointer */
@@ -372,11 +256,12 @@ static BezTriple *abk_get_bezt_with_value(ActBeztColumn *abk, float value)
short compare_ab_cfraPtr(void *node, void *data)
{
ActKeyBlock *ab = (ActKeyBlock *)node;
- float *cframe = data;
+ const float *cframe = data;
+ float val = *cframe;
- if (*cframe < ab->start)
+ if (val < ab->start)
return -1;
- else if (*cframe > ab->start)
+ else if (val > ab->start)
return 1;
else
return 0;
@@ -399,17 +284,25 @@ static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn)
return ab;
}
-static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree, BezTriple *beztn)
+static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt, BezTriple *beztn)
{
ActKeyBlock *new_ab = NULL;
- ActBeztColumn *abk;
- BezTriple *prev;
+ BezTriple *prev = NULL;
/* get the BezTriple immediately before the given one which has the same value */
- /* the keyframes immediately before the ones containing the specified keyframe */
- abk = (ActBeztColumn *)BLI_dlrbTree_search_prev(beztTree, compare_abk_bezt, beztn);
- /* if applicable, the BezTriple with the same value */
- prev = (abk) ? abk_get_bezt_with_value(abk, beztn->vec[1][1]) : NULL;
+ if (beztn != first_bezt) {
+ /* XXX: Unless I'm overlooking some details from the past, this should be sufficient?
+ * The old code did some elaborate stuff trying to find keyframe columns for
+ * the given BezTriple, then step backwards to the column before that, and find
+ * an appropriate BezTriple with matching values there. Maybe that was warranted
+ * in the past, but now, that list is only ever filled with keyframes from the
+ * current FCurve.
+ *
+ * -- Aligorith (20140415)
+ */
+ prev = beztn - 1;
+ }
+
/* check if block needed - same value(s)?
* -> firstly, handles must have same central value as each other
@@ -417,6 +310,7 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree,
*/
if (prev == NULL) return;
if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return;
+
if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return;
if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return;
@@ -431,6 +325,7 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree,
ActKeyBlock *ab, *abn = NULL;
/* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there
+ * Note: we perform a tree traversal here NOT a standard linked-list traversal...
* Note: we can't search from end to try to optimize this as it causes errors there's
* an A ___ B |---| B situation
*/
@@ -439,17 +334,19 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree,
// A|------------------------------------------------|A
// A|----|A|---|A|-----------------------------------|A
for (ab = blocks->root; ab; ab = abn) {
- /* check if this is a match, or whether we go left or right */
- if (ab->start == prev->vec[1][0]) {
+ /* check if this is a match, or whether we go left or right
+ * NOTE: we now use a float threshold to prevent precision errors causing problems with summaries
+ */
+ if (IS_EQT(ab->start, prev->vec[1][0], BEZT_BINARYSEARCH_THRESH)) {
/* set selection status and 'touched' status */
if (BEZSELECTED(beztn)) ab->sel = SELECT;
- ab->modified += 1;
+ ab->modified++;
/* done... no need to insert */
return;
}
else {
- ActKeyBlock **abnp = NULL;
+ ActKeyBlock **abnp = NULL; /* branch to go down - used to hook new blocks to parents */
/* check if go left or right, but if not available, add new node */
if (ab->start < prev->vec[1][0])
@@ -652,7 +549,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
glEnable(GL_BLEND);
/* get View2D scaling factor */
- UI_view2d_getscale(v2d, &xscale, NULL);
+ UI_view2d_scale_get(v2d, &xscale, NULL);
/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
/* TODO: allow this opacity factor to be themed? */
@@ -660,18 +557,23 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
/* draw keyblocks */
if (blocks) {
+ float sel_color[4], unsel_color[4];
+
+ /* cache colours first */
+ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color);
+ UI_GetThemeColor4fv(TH_STRIP, unsel_color);
+
+ sel_color[3] *= alpha;
+ unsel_color[3] *= alpha;
+
+ /* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */
for (ab = blocks->first; ab; ab = ab->next) {
if (actkeyblock_is_valid(ab, keys)) {
- float color[4];
-
/* draw block */
if (ab->sel)
- UI_GetThemeColor4fv(TH_STRIP_SELECT, color);
+ gpuColor4fv(sel_color);
else
- UI_GetThemeColor4fv(TH_STRIP, color);
-
- color[3] *= alpha;
- gpuColor4fv(color);
+ gpuColor4fv(unsel_color);
gpuSingleFilledRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize);
}
@@ -861,7 +763,6 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
/* loop through each F-Curve, grabbing the keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
-
/* Why not use all #eAnim_KeyType here?
* All of the other key types are actually "summaries" themselves, and will just end up duplicating stuff
* that comes up through standard filtering of just F-Curves.
@@ -882,7 +783,7 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
break;
}
}
-
+
BLI_freelistN(&anim_data);
}
}
@@ -958,7 +859,6 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *bl
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree *blocks)
{
- DLRBT_Tree *beztTree = NULL;
BezTriple *bezt;
unsigned int v;
@@ -967,25 +867,10 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
- /* if getting long keyframes too, grab the BezTriples in a BST for
- * accelerated searching...
- */
- if (blocks) {
- /* init new tree */
- beztTree = BLI_dlrbTree_new();
-
- /* populate tree with the BezTriples */
- for (v = 0, bezt = fcu->bezt; v < fcu->totvert; v++, bezt++)
- BLI_dlrbTree_add(beztTree, compare_abk_bezt, nalloc_abk_bezt, nupdate_abk_bezt, bezt);
-
- /* make sure that it is suitable for linked-list searching too */
- BLI_dlrbTree_linkedlist_sync(beztTree);
- }
-
/* loop through beztriples, making ActKeysColumns and ActKeyBlocks */
for (v = 0, bezt = fcu->bezt; v < fcu->totvert; v++, bezt++) {
add_bezt_to_keycolumns_list(keys, bezt);
- if (blocks) add_bezt_to_keyblocks_list(blocks, beztTree, bezt);
+ if (blocks) add_bezt_to_keyblocks_list(blocks, fcu->bezt, bezt);
}
/* update the number of curves that elements have appeared in */
@@ -993,12 +878,6 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree
set_touched_actkeycolumn(keys->root);
if (blocks)
set_touched_actkeyblock(blocks->root);
-
- /* free temp data for building long keyframes */
- if (blocks && beztTree) {
- BLI_dlrbTree_free(beztTree);
- MEM_freeN(beztTree);
- }
/* unapply NLA-mapping if applicable */
if (adt)
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 6010a64bd06..7e7453487b8 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -35,29 +35,16 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_lasso.h"
#include "DNA_anim_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_material_types.h"
#include "DNA_object_types.h"
-#include "DNA_meta_types.h"
#include "DNA_node_types.h"
-#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
-#include "DNA_world_types.h"
#include "BKE_fcurve.h"
-#include "BKE_key.h"
-#include "BKE_material.h"
-
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
@@ -427,6 +414,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
*/
#define KEYFRAME_OK_CHECKS(check) \
{ \
+ CHECK_TYPE(ok, short); \
if (check(1)) \
ok |= KEYFRAME_OK_KEY; \
\
@@ -523,6 +511,45 @@ static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt)
return 0;
}
+/**
+ * only called from #ok_bezier_region_lasso
+ */
+static bool bezier_region_lasso_test(
+ const struct KeyframeEdit_LassoData *data_lasso,
+ const float xy[2])
+{
+ if (BLI_rctf_isect_pt_v(data_lasso->rectf_scaled, xy)) {
+ float xy_view[2];
+
+ BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy);
+
+ if (BLI_lasso_is_point_inside(data_lasso->mcords, data_lasso->mcords_tot, xy_view[0], xy_view[1], INT_MAX)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt)
+{
+ /* rect is stored in data property (it's of type rectf, but may not be set) */
+ if (ked->data) {
+ short ok = 0;
+
+#define KEY_CHECK_OK(_index) bezier_region_lasso_test(ked->data, bezt->vec[_index])
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+#undef KEY_CHECK_OK
+
+ /* check for lasso */
+
+ /* return ok flags */
+ return ok;
+ }
+ else
+ return 0;
+}
+
KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
{
@@ -540,6 +567,8 @@ KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
return ok_bezier_valuerange;
case BEZT_OK_REGION: /* only if bezier falls within the specified rect (data -> rectf) */
return ok_bezier_region;
+ case BEZT_OK_REGION_LASSO: /* only if the point falls within KeyframeEdit_LassoData defined data */
+ return ok_bezier_region_lasso;
default: /* nothing was ok */
return NULL;
}
@@ -880,15 +909,109 @@ static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
return 0;
}
+static short set_bezt_back(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BACK;
+ return 0;
+}
+
+static short set_bezt_bounce(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BOUNCE;
+ return 0;
+}
+
+static short set_bezt_circle(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CIRC;
+ return 0;
+}
+
+static short set_bezt_cubic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CUBIC;
+ return 0;
+}
+
+static short set_bezt_elastic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_ELASTIC;
+ return 0;
+}
+
+static short set_bezt_expo(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_EXPO;
+ return 0;
+}
+
+static short set_bezt_quad(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUAD;
+ return 0;
+}
+
+static short set_bezt_quart(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUART;
+ return 0;
+}
+
+static short set_bezt_quint(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUINT;
+ return 0;
+}
+
+static short set_bezt_sine(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_SINE;
+ return 0;
+}
+
/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
// ANIM_editkeyframes_ipocurve_ipotype() !
KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
{
switch (code) {
+ /* interpolation */
case BEZT_IPO_CONST: /* constant */
return set_bezt_constant;
case BEZT_IPO_LIN: /* linear */
return set_bezt_linear;
+
+ /* easing */
+ case BEZT_IPO_BACK:
+ return set_bezt_back;
+ case BEZT_IPO_BOUNCE:
+ return set_bezt_bounce;
+ case BEZT_IPO_CIRC:
+ return set_bezt_circle;
+ case BEZT_IPO_CUBIC:
+ return set_bezt_cubic;
+ case BEZT_IPO_ELASTIC:
+ return set_bezt_elastic;
+ case BEZT_IPO_EXPO:
+ return set_bezt_expo;
+ case BEZT_IPO_QUAD:
+ return set_bezt_quad;
+ case BEZT_IPO_QUART:
+ return set_bezt_quart;
+ case BEZT_IPO_QUINT:
+ return set_bezt_quint;
+ case BEZT_IPO_SINE:
+ return set_bezt_sine;
+
default: /* bezier */
return set_bezt_bezier;
}
@@ -943,6 +1066,54 @@ KeyframeEditFunc ANIM_editkeyframes_keytype(short code)
}
}
+/* ------- */
+
+static short set_easingtype_easein(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN;
+ return 0;
+}
+
+static short set_easingtype_easeout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_OUT;
+ return 0;
+}
+
+static short set_easingtype_easeinout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN_OUT;
+ return 0;
+}
+
+static short set_easingtype_easeauto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_AUTO;
+ return 0;
+}
+
+/* Set the easing type of the selected BezTriples in each F-Curve to the specified one */
+KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
+{
+ switch (mode) {
+ case BEZT_IPO_EASE_IN: /* ease in */
+ return set_easingtype_easein;
+
+ case BEZT_IPO_EASE_OUT: /* ease out */
+ return set_easingtype_easeout;
+
+ case BEZT_IPO_EASE_IN_OUT: /* both */
+ return set_easingtype_easeinout;
+
+ default: /* auto */
+ return set_easingtype_easeauto;
+ }
+}
+
/* ******************************************* */
/* Selection */
@@ -1116,7 +1287,7 @@ KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode)
/* flush selection map values to the given beztriple */
short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
{
- char *map = ked->data;
+ const char *map = ked->data;
short on = map[ked->curIndex];
/* select or deselect based on whether the map allows it or not */
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 6a359b0e6d0..c610595c4ba 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
@@ -359,7 +358,7 @@ void smooth_fcurve(FCurve *fcu)
/* round 2: apply new values */
tsb = tarray;
for (i = 0; i < totSel; i++, tsb++) {
- /* don't touch end points, as their values were't touched above */
+ /* don't touch end points, as their values weren't touched above */
if (ELEM(i, 0, (totSel - 1)) == 0) {
/* y2 takes the average of the 2 points */
*tsb->h2 = tsb->y2;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 41f39c1d33a..78c87d58766 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -40,7 +40,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -59,7 +58,6 @@
#include "BKE_armature.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
-#include "BKE_main.h"
#include "BKE_idcode.h"
#include "BKE_nla.h"
#include "BKE_global.h"
@@ -72,6 +70,7 @@
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -228,7 +227,7 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
return fcu;
}
-/* Helper */
+/* Helper for update_autoflags_fcurve() */
static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
{
/* set additional flags for the F-Curve (i.e. only integer values) */
@@ -251,8 +250,8 @@ static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
}
}
-/* Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
- * but also through RNA when editing an ID prop, see T37103).
+/* Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
+ * but also through RNA when editing an ID prop, see T37103).
*/
void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, PointerRNA *ptr)
{
@@ -276,9 +275,10 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin
idname, fcu->rna_path);
return;
}
-
+
+ /* update F-Curve flags */
update_autoflags_fcurve_direct(fcu, prop);
-
+
if (old_flag != fcu->flag) {
/* Same as if keyframes had been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
@@ -394,11 +394,18 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, short flag)
beztr.vec[2][0] = x + 1.0f;
beztr.vec[2][1] = y;
beztr.f1 = beztr.f2 = beztr.f3 = SELECT;
- beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
- //BEZKEYTYPE(&beztr)= scene->keytype; /* default keyframe type */
- /* use default interpolation mode, with exceptions for int/discrete values */
- beztr.ipo = U.ipo_new;
+ if (flag & INSERTKEY_NO_USERPREF) {
+ beztr.h1 = beztr.h2 = HD_AUTO_ANIM;
+ beztr.ipo = BEZT_IPO_BEZ;
+ }
+ else {
+ beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
+ //BEZKEYTYPE(&beztr)= scene->keytype; /* default keyframe type */
+
+ /* use default interpolation mode, with exceptions for int/discrete values */
+ beztr.ipo = U.ipo_new;
+ }
if (fcu->flag & FCURVE_DISCRETE_VALUES)
beztr.ipo = BEZT_IPO_CONST;
@@ -760,7 +767,7 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
int rotmode;
/* handle for Objects or PoseChannels only
- * - only Location, Rotation or Scale keyframes are supported curently
+ * - only Location, Rotation or Scale keyframes are supported currently
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
@@ -842,7 +849,7 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
* and extra keyframe filtering.
*/
-short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag)
+bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag)
{
float curval = 0.0f;
@@ -884,6 +891,7 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p
}
}
+ /* update F-Curve flags to ensure proper behaviour for property type */
update_autoflags_fcurve_direct(fcu, prop);
/* obtain value to give keyframe */
@@ -1263,6 +1271,8 @@ static int modify_key_op_poll(bContext *C)
static int insert_key_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ bool ob_edit_mode = false;
KeyingSet *ks = NULL;
int type = RNA_enum_get(op->ptr, "type");
float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
@@ -1285,12 +1295,25 @@ static int insert_key_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active keying set");
return OPERATOR_CANCELLED;
}
+
+ /* exit the edit mode to make sure that those object data properties that have been
+ * updated since the last switching to the edit mode will be keyframed correctly
+ */
+ if (obedit && ANIM_keyingset_find_id(ks, (ID *)obedit->data)) {
+ ED_object_toggle_modes(C, OB_MODE_EDIT);
+ ob_edit_mode = true;
+ }
/* try to insert keyframes for the channels specified by KeyingSet */
success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
if (G.debug & G_DEBUG)
BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes", ks->name, success);
+ /* restore the edit mode if necessary */
+ if (ob_edit_mode) {
+ ED_object_toggle_modes(C, OB_MODE_EDIT);
+ }
+
/* report failure or do updates? */
if (success == MODIFYKEY_INVALID_CONTEXT) {
BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
@@ -1302,7 +1325,7 @@ static int insert_key_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
@@ -1365,7 +1388,7 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN
else {
/* just call the exec() on the active keyingset */
RNA_enum_set(op->ptr, "type", 0);
- RNA_boolean_set(op->ptr, "confirm_success", TRUE);
+ RNA_boolean_set(op->ptr, "confirm_success", true);
return op->type->exec(C, op);
}
@@ -1454,7 +1477,7 @@ static int delete_key_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
@@ -1509,7 +1532,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
FCurve *fcu, *fcn;
for (fcu = act->curves.first; fcu; fcu = fcn) {
- short can_delete = FALSE;
+ bool can_delete = false;
fcn = fcu->next;
@@ -1527,13 +1550,13 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
/* delete if bone is selected*/
if ((pchan) && (pchan->bone)) {
if (pchan->bone->flag & BONE_SELECTED)
- can_delete = TRUE;
+ can_delete = true;
}
}
}
else {
/* object mode - all of Object's F-Curves are affected */
- can_delete = TRUE;
+ can_delete = true;
}
/* delete F-Curve completely */
@@ -1707,7 +1730,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
uiContextAnimUpdate(C);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
@@ -1778,7 +1801,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
uiContextAnimUpdate(C);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
@@ -1848,7 +1871,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
uiContextAnimUpdate(C);
/* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
@@ -1928,7 +1951,7 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
/* Checks whether an Action has a keyframe for a given frame
* Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
*/
-static short action_frame_has_keyframe(bAction *act, float frame, short filter)
+static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
{
FCurve *fcu;
@@ -1956,7 +1979,7 @@ static short action_frame_has_keyframe(bAction *act, float frame, short filter)
}
/* Checks whether an Object has a keyframe for a given frame */
-static short object_frame_has_keyframe(Object *ob, float frame, short filter)
+static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
{
/* error checking */
if (ob == NULL)
@@ -2014,7 +2037,7 @@ static short object_frame_has_keyframe(Object *ob, float frame, short filter)
/* --------------- API ------------------- */
/* Checks whether a keyframe exists for the given ID-block one the given frame */
-short id_frame_has_keyframe(ID *id, float frame, short filter)
+bool id_frame_has_keyframe(ID *id, float frame, short filter)
{
/* sanity checks */
if (id == NULL)
@@ -2024,8 +2047,6 @@ short id_frame_has_keyframe(ID *id, float frame, short filter)
switch (GS(id->name)) {
case ID_OB: /* object */
return object_frame_has_keyframe((Object *)id, frame, filter);
- break;
-
#if 0
// XXX TODO... for now, just use 'normal' behavior
case ID_SCE: /* scene */
@@ -2049,7 +2070,7 @@ short id_frame_has_keyframe(ID *id, float frame, short filter)
/* ************************************************** */
-int ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
+bool ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
{
/* auto keyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
@@ -2064,14 +2085,14 @@ int ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
BLI_freelistN(&dsources);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
-int ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
+bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
{
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
ListBase dsources = {NULL, NULL};
@@ -2090,7 +2111,7 @@ int ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *p
pchan->bone->flag &= ~BONE_UNKEYED;
}
- return TRUE;
+ return true;
}
else {
/* add unkeyed tags */
@@ -2098,6 +2119,6 @@ int ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *p
pchan->bone->flag |= BONE_UNKEYED;
}
- return FALSE;
+ return false;
}
}
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 74bd4960838..ad2db0d9c66 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -39,8 +39,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
@@ -641,6 +639,16 @@ void ANIM_keyingset_infos_exit(void)
BKE_keyingsets_free(&builtin_keyingsets);
}
+/* Check if the ID appears in the paths specified by the KeyingSet */
+bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id)
+{
+ /* sanity checks */
+ if (ELEM(NULL, ks, id))
+ return false;
+
+ return BLI_findptr(&ks->paths, id, offsetof(KS_Path, id)) != NULL;
+}
+
/* ******************************************* */
/* KEYING SETS API (for UI) */
@@ -783,7 +791,7 @@ EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNUSED(pt
/* Polling API ----------------------------------------------- */
/* Check if KeyingSet can be used in the current context */
-short ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
+bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
{
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
@@ -797,7 +805,7 @@ short ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
return (ksi->poll(ksi, C));
}
- return 1;
+ return true;
}
/* Special 'Overrides' Iterator for Relative KeyingSets ------ */
@@ -916,7 +924,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
ReportList *reports = CTX_wm_reports(C);
KS_Path *ksp;
int kflag = 0, success = 0;
- char *groupname = NULL;
+ const char *groupname = NULL;
/* sanity checks */
if (ks == NULL)
@@ -927,7 +935,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
/* use KeyingSet's flags as base */
kflag = ks->keyingflag;
- /* suppliment with info from the context */
+ /* supplement with info from the context */
kflag |= ANIM_get_keyframing_flags(scene, 1);
}
else if (mode == MODIFYKEY_MODE_DELETE)
@@ -1009,7 +1017,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
}
/* send notifiers for updates (this doesn't require context to work!) */
- WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
/* return the number of channels successfully affected */
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 456dd802086..16975eed75e 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -312,7 +312,7 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
/* does this constraint have a subtarget in
* this armature?
*/
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -548,9 +548,9 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
for (ebone = arm->edbo->first; ((ebone) && (ebone != first)); ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone)) {
/* we extrude per definition the tip */
- do_extrude = FALSE;
+ do_extrude = false;
if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
- do_extrude = TRUE;
+ do_extrude = true;
}
else if (ebone->flag & BONE_ROOTSEL) {
/* but, a bone with parent deselected we do the root... */
@@ -589,7 +589,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
totbone++;
newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
- if (do_extrude == TRUE) {
+ if (do_extrude == true) {
copy_v3_v3(newbone->head, ebone->tail);
copy_v3_v3(newbone->tail, newbone->head);
newbone->parent = ebone;
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index db57e762848..c5aa81c3a37 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -200,39 +200,45 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente
/* adjust bone roll to align Z axis with vector
* vec is in local space and is normalized
*/
-float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const short axis_only)
+float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const bool axis_only)
{
float mat[3][3], nor[3];
+ float vec[3], align_axis_proj[3], roll = 0.0f;
+
+ BLI_ASSERT_UNIT_V3(align_axis);
sub_v3_v3v3(nor, bone->tail, bone->head);
+
+ /* if tail == head! */
+ if (is_zero_v3(nor)) {
+ return roll;
+ }
+
vec_roll_to_mat3(nor, 0.0f, mat);
-
+
/* check the bone isn't aligned with the axis */
- if (!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) {
- float vec[3], align_axis_proj[3], roll;
-
- /* project the new_up_axis along the normal */
- project_v3_v3v3(vec, align_axis, nor);
- sub_v3_v3v3(align_axis_proj, align_axis, vec);
-
- if (axis_only) {
- if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI / 2.0)) {
- negate_v3(align_axis_proj);
- }
- }
-
- roll = angle_v3v3(align_axis_proj, mat[2]);
-
- cross_v3_v3v3(vec, mat[2], align_axis_proj);
-
- if (dot_v3v3(vec, nor) < 0) {
- roll = -roll;
- }
-
+ if (dot_v3v3(align_axis, mat[2]) >= (1.0f - FLT_EPSILON)) {
return roll;
}
- return 0.0f;
+ /* project the new_up_axis along the normal */
+ project_v3_v3v3(vec, align_axis, nor);
+ sub_v3_v3v3(align_axis_proj, align_axis, vec);
+
+ if (axis_only) {
+ if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI_2)) {
+ negate_v3(align_axis_proj);
+ }
+ }
+
+ roll = angle_v3v3(align_axis_proj, mat[2]);
+
+ cross_v3_v3v3(vec, mat[2], align_axis_proj);
+
+ if (dot_v3v3(vec, nor) < 0.0f) {
+ return -roll;
+ }
+ return roll;
}
@@ -253,9 +259,9 @@ static EnumPropertyItem prop_calc_roll_types[] = {
{CALC_ROLL_TAN_X, "X", 0, "Local X Tangent", ""},
{CALC_ROLL_TAN_Z, "Z", 0, "Local Z Tangent", ""},
- {CALC_ROLL_X, "X", 0, "Global X Axis", ""},
- {CALC_ROLL_Y, "Y", 0, "Global Y Axis", ""},
- {CALC_ROLL_Z, "Z", 0, "Global Z Axis", ""},
+ {CALC_ROLL_X, "GLOBAL_X", 0, "Global X Axis", ""},
+ {CALC_ROLL_Y, "GLOBAL_Y", 0, "Global Y Axis", ""},
+ {CALC_ROLL_Z, "GLOBAL_Z", 0, "Global Z Axis", ""},
{CALC_ROLL_ACTIVE, "ACTIVE", 0, "Active Bone", ""},
{CALC_ROLL_VIEW, "VIEW", 0, "View Axis", ""},
@@ -268,8 +274,8 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
const short type = RNA_enum_get(op->ptr, "type");
- const short axis_only = RNA_boolean_get(op->ptr, "axis_only");
- const short axis_flip = RNA_boolean_get(op->ptr, "axis_flip");
+ const bool axis_only = RNA_boolean_get(op->ptr, "axis_only");
+ const bool axis_flip = RNA_boolean_get(op->ptr, "axis_flip");
float imat[3][3];
@@ -1221,7 +1227,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index f3db9042879..1d054ffc2e9 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -133,7 +133,6 @@ void POSE_OT_rotation_mode_set(struct wmOperatorType *ot);
void POSE_OT_quaternions_flip(struct wmOperatorType *ot);
-void POSE_OT_armature_layers(struct wmOperatorType *ot);
void POSE_OT_bone_layers(struct wmOperatorType *ot);
/* ******************************************************* */
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index a6b27d4925f..bef0a4f6152 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -105,7 +105,7 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *
bConstraintTarget *ct;
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
ListBase targets = {NULL, NULL};
/* constraint targets */
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index be23c285cf7..b7e38546ca2 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -139,7 +139,6 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_quaternions_flip);
- WM_operatortype_append(POSE_OT_armature_layers);
WM_operatortype_append(POSE_OT_bone_layers);
WM_operatortype_append(POSE_OT_propagate);
@@ -179,7 +178,7 @@ void ED_operatormacros_armature(void)
"Create new bones from the selected joints and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude");
- RNA_boolean_set(otmacro->ptr, "forked", FALSE);
+ RNA_boolean_set(otmacro->ptr, "forked", false);
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
@@ -189,7 +188,7 @@ void ED_operatormacros_armature(void)
"Create new bones from the selected joints and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
otmacro = WM_operatortype_macro_define(ot, "ARMATURE_OT_extrude");
- RNA_boolean_set(otmacro->ptr, "forked", TRUE);
+ RNA_boolean_set(otmacro->ptr, "forked", true);
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
}
@@ -215,16 +214,16 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SKETCH_OT_gesture", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "snap", TRUE);
+ RNA_boolean_set(kmi->ptr, "snap", true);
WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "snap", TRUE);
+ RNA_boolean_set(kmi->ptr, "snap", true);
/* only set in editmode armature, by space_view3d listener */
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "ARMATURE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_align", AKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
@@ -243,21 +242,21 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
WM_keymap_add_item(keymap, "ARMATURE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -284,7 +283,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_disable", WKEY, KM_PRESS, KM_ALT, 0);
-
+
/* armature/bone layers */
WM_keymap_add_item(keymap, "ARMATURE_OT_layers_show_all", ACCENTGRAVEKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
@@ -315,9 +314,9 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "POSE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
@@ -334,16 +333,16 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "flipped", FALSE);
+ RNA_boolean_set(kmi->ptr, "flipped", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "flipped", TRUE);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#ifdef __APPLE__
WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
- RNA_boolean_set(kmi->ptr, "flipped", FALSE);
+ RNA_boolean_set(kmi->ptr, "flipped", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_OSKEY | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "flipped", TRUE);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#endif
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_all", AKEY, KM_PRESS, 0, 0);
@@ -355,17 +354,17 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
@@ -385,7 +384,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
/* armature/bone layers */
WM_keymap_add_item(keymap, "ARMATURE_OT_layers_show_all", ACCENTGRAVEKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "POSE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_bone_layers", MKEY, KM_PRESS, 0, 0);
/* special transforms: */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 3e261806e62..cc6e39240e4 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -42,7 +42,6 @@
#include "BLF_translation.h"
#include "BKE_action.h"
-#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -75,7 +74,7 @@ static void joined_armature_fix_links_constraints(
bConstraint *con;
for (con = lb->first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -302,7 +301,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
if (ob->type == OB_ARMATURE) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -340,7 +339,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
/* fix object-level constraints */
if (ob != origArm) {
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 0b2ce5b947e..c8041ece883 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -80,13 +80,15 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
EditBone *ebone;
void *firstunSel = NULL, *firstSel = NULL, *data;
unsigned int hitresult;
- short i, takeNext = 0, sel;
+ short i;
+ bool takeNext = false;
for (i = 0; i < hits; i++) {
hitresult = buffer[3 + (i * 4)];
- if (!(hitresult & BONESEL_NOSEL)) { // -1
- if (hitresult & BONESEL_ANY) { // to avoid including objects in selection
+ if (!(hitresult & BONESEL_NOSEL)) {
+ if (hitresult & BONESEL_ANY) { /* to avoid including objects in selection */
+ bool sel;
hitresult &= ~(BONESEL_ANY);
/* Determine what the current bone is */
@@ -256,7 +258,7 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
}
/* does bones and points */
@@ -305,7 +307,7 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
if (hits > 0) {
if (hits == 1) {
- if (!(buffer[3] & BONESEL_NOSEL))
+ if (!(buffer[3] & BONESEL_NOSEL))
besthitresult = buffer[3];
}
else {
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 7ec0acf12d1..e898e600e9b 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -113,7 +113,7 @@ static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
{
/* This group creates a vertex group to ob that has the
* same name as bone (provided the bone is skinnable).
- * If such a vertex group aleady exist the routine exits.
+ * If such a vertex group already exist the routine exits.
*/
if (!(bone->flag & BONE_NO_DEFORM)) {
if (!defgroup_find_name(ob, bone->name)) {
@@ -191,7 +191,7 @@ static void add_vgroups__mapFunc(void *userData, int index, const float co[3],
static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist,
bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
- float (*root)[3], float (*tip)[3], int *selected, float scale)
+ float (*root)[3], float (*tip)[3], const int *selected, float scale)
{
/* Create vertex group weights from envelopes */
@@ -235,7 +235,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
}
}
-static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, Object *par, int heat, int mirror)
+static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, Object *par, int heat, bool mirror)
{
/* This functions implements the automatic computation of vertex group
* weights, either through envelopes or using a heat equilibrium.
@@ -272,7 +272,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
if (numbones == 0)
return;
- if (ED_vgroup_data_create(ob->data) == FALSE)
+ if (ED_vgroup_data_create(ob->data) == false)
return;
/* create an array of pointer to bones that are skinnable
@@ -403,7 +403,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
}
/* only generated in some cases but can call anyway */
- mesh_octree_table(ob, NULL, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e');
/* free the memory allocated */
MEM_freeN(bonelist);
@@ -415,7 +415,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
MEM_freeN(verts);
}
-void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, Object *par, int mode, int mirror)
+void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, Object *par, int mode, bool mirror)
{
/* Lets try to create some vertex groups
* based on the bones of the parent armature.
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 853d957cf26..7689fdda90a 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -218,6 +218,31 @@ void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4])
copy_v3_v3(mat[3], ebone->head);
}
+void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3])
+{
+ float vec[3], roll;
+ const float len = len_v3v3(ebone->head, ebone->tail);
+
+ mat3_to_vec_roll(mat, vec, &roll);
+
+ madd_v3_v3v3fl(ebone->tail, ebone->head, vec, len);
+ ebone->roll = roll;
+}
+
+void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4])
+{
+ float mat3[3][3];
+
+ copy_m3_m4(mat3, mat);
+ /* We want normalized matrix here, to be consistent with ebone_to_mat. */
+ BLI_ASSERT_UNIT_M3(mat3);
+
+ sub_v3_v3(ebone->tail, ebone->head);
+ copy_v3_v3(ebone->head, mat[3]);
+ add_v3_v3(ebone->tail, mat[3]);
+ ED_armature_ebone_from_mat3(ebone, mat3);
+}
+
/**
* Return a pointer to the bone of the given name
*/
@@ -484,7 +509,7 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist)
print_m4("difmat", difmat);
printf("Roll = %f\n", RAD2DEGF(-atan2(difmat[2][0], difmat[2][2])));
#endif
- curBone->roll = (float)-atan2(difmat[2][0], difmat[2][2]);
+ curBone->roll = -atan2f(difmat[2][0], difmat[2][2]);
/* and set restposition again */
BKE_armature_where_is_bone(curBone, curBone->parent);
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index 41ec144bd98..4eb9e3ecc79 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -39,7 +39,7 @@ void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invma
copy_v3_v3(normal, no);
mul_m3_v3(tmat, normal);
- bone->roll = ED_rollBoneToVector(bone, normal, FALSE);
+ bone->roll = ED_rollBoneToVector(bone, normal, false);
}
}
@@ -203,7 +203,7 @@ int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int st
c = dot_v3v3(off, off) - (lengthLimit * lengthLimit);
- f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
+ f = (-b + sqrtf(b * b - 4 * a * c)) / (2 * a);
//printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index a0411f246c8..647b640ee61 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -40,7 +40,6 @@
#include "BKE_constraint.h"
#include "BKE_armature.h"
#include "BKE_context.h"
-#include "BKE_scene.h"
#include "ED_armature.h"
#include "ED_util.h"
@@ -159,11 +158,11 @@ static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float q
if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis)) {
rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */
- return ED_rollBoneToVector(bone, x_axis, FALSE);
+ return ED_rollBoneToVector(bone, x_axis, false);
}
else {
rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */
- return ED_rollBoneToVector(bone, z_axis, FALSE);
+ return ED_rollBoneToVector(bone, z_axis, false);
}
}
@@ -208,7 +207,7 @@ static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4]
/* real qroll between normal and up_axis */
rotation_between_vecs_to_quat(qroll, new_up_axis, normal);
- return ED_rollBoneToVector(edge->bone, normal, FALSE);
+ return ED_rollBoneToVector(edge->bone, normal, false);
}
}
@@ -219,7 +218,7 @@ float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
copy_v3_v3(new_up_axis, old_up_axis);
mul_qt_v3(qrot, new_up_axis);
- return ED_rollBoneToVector(bone, new_up_axis, FALSE);
+ return ED_rollBoneToVector(bone, new_up_axis, false);
}
/************************************ DESTRUCTORS ******************************************************/
@@ -708,7 +707,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -833,7 +832,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1129,7 +1128,7 @@ static void RIG_removeUneededOffsets(RigGraph *rg)
}
}
-static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, int selected)
+static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, bool selected)
{
EditBone *bone, *last_bone = root_bone;
RigArc *arc = NULL;
@@ -1684,7 +1683,7 @@ static RetargetMode detectArcRetargetMode(RigArc *iarc)
if (nb_edges > 2) {
for (edge = iarc->edges.first; edge; edge = edge->next) {
- if (fabs(edge->angle - avg_angle) > M_PI / 6) {
+ if (fabsf(edge->angle - avg_angle) > (float)(M_PI / 6)) {
large_angle = 1;
}
}
@@ -1795,7 +1794,7 @@ static float costLength(float original_length, float current_length, float lengt
return MAX_COST;
}
else {
- float length_ratio = fabs((current_length - original_length) / original_length);
+ float length_ratio = fabsf((current_length - original_length) / original_length);
return length_weight * length_ratio * length_ratio;
}
}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 36ab09f26c2..dd77bb20ac0 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -169,6 +169,7 @@ void BIF_makeListTemplates(const bContext *C)
}
}
+#if 0 /* UNUSED */
const char *BIF_listTemplates(const bContext *UNUSED(C))
{
GHashIterator ghi;
@@ -198,6 +199,7 @@ const char *BIF_listTemplates(const bContext *UNUSED(C))
return TEMPLATES_MENU;
}
+#endif
int BIF_currentTemplate(const bContext *C)
{
@@ -933,7 +935,6 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr
zfac = ED_view3d_calc_zfac(ar->regiondata, fp, NULL);
- /* method taken from editview.c - mouse_cursor() */
if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, cval, dd->mval);
ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 017d2783c1d..56e7bde0081 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -140,22 +140,6 @@ static int laplacian_edge_count(EdgeHash *edgehash, int v1, int v2)
return (int)(intptr_t)BLI_edgehash_lookup(edgehash, v1, v2);
}
-static float cotan_weight(float *v1, float *v2, float *v3)
-{
- float a[3], b[3], c[3], clen;
-
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
-
- clen = len_v3(c);
-
- if (clen == 0.0f)
- return 0.0f;
-
- return dot_v3v3(a, b) / clen;
-}
-
static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3)
{
float t1, t2, t3, len1, len2, len3, area;
@@ -166,9 +150,9 @@ static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3
v2 = sys->verts[i2];
v3 = sys->verts[i3];
- t1 = cotan_weight(v1, v2, v3);
- t2 = cotan_weight(v2, v3, v1);
- t3 = cotan_weight(v3, v1, v2);
+ t1 = cotangent_tri_weight_v3(v1, v2, v3);
+ t2 = cotangent_tri_weight_v3(v2, v3, v1);
+ t3 = cotangent_tri_weight_v3(v3, v1, v2);
if (angle_v3v3v3(v2, v1, v3) > DEG2RADF(90.0f)) obtuse = 1;
else if (angle_v3v3v3(v1, v2, v3) > DEG2RADF(90.0f)) obtuse = 2;
@@ -207,9 +191,9 @@ static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int
/* instead of *0.5 we divided by the number of faces of the edge, it still
* needs to be verified that this is indeed the correct thing to do! */
- t1 = cotan_weight(v1, v2, v3) / laplacian_edge_count(sys->edgehash, i2, i3);
- t2 = cotan_weight(v2, v3, v1) / laplacian_edge_count(sys->edgehash, i3, i1);
- t3 = cotan_weight(v3, v1, v2) / laplacian_edge_count(sys->edgehash, i1, i2);
+ t1 = cotangent_tri_weight_v3(v1, v2, v3) / laplacian_edge_count(sys->edgehash, i2, i3);
+ t2 = cotangent_tri_weight_v3(v2, v3, v1) / laplacian_edge_count(sys->edgehash, i3, i1);
+ t3 = cotangent_tri_weight_v3(v3, v1, v2) / laplacian_edge_count(sys->edgehash, i1, i2);
nlMatrixAdd(i1, i1, (t2 + t3) * varea[i1]);
nlMatrixAdd(i2, i2, (t1 + t3) * varea[i2]);
@@ -651,8 +635,8 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
MVert *mvert = me->mvert;
- int use_vert_sel = FALSE;
- int use_face_sel = FALSE;
+ bool use_vert_sel = false;
+ bool use_face_sel = false;
*err_str = NULL;
@@ -678,9 +662,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
if (use_vert_sel) {
for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
- if (use_vert_sel) {
- mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
- }
+ mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
}
}
}
@@ -1227,7 +1209,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
}
}
-static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2)
+static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const float co1[3], const float co2[3])
{
MDefBoundIsect *isect;
BVHTreeRayHit hit;
@@ -1236,14 +1218,23 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
void *data[3] = {mdb->cagedm->getTessFaceArray(mdb->cagedm), mdb, &isect_mdef};
MFace *mface1 = data[0], *mface;
float vert[4][3], len, end[3];
- static float epsilon[3] = {0, 0, 0}; //1e-4, 1e-4, 1e-4};
+ // static float epsilon[3] = {1e-4, 1e-4, 1e-4};
+
+ /* happens binding when a cage has no faces */
+ if (UNLIKELY(mdb->bvhtree == NULL))
+ return NULL;
/* setup isec */
memset(&isect_mdef, 0, sizeof(isect_mdef));
isect_mdef.lambda = 1e10f;
+#if 0
add_v3_v3v3(isect_mdef.start, co1, epsilon);
add_v3_v3v3(end, co2, epsilon);
+#else
+ copy_v3_v3(isect_mdef.start, co1);
+ copy_v3_v3(end, co2);
+#endif
sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start);
hit.index = -1;
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index d1c096e6cf5..de8b2e36d5b 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -36,12 +36,10 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
-#include "DNA_constraint_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "BKE_anim.h"
-#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_deform.h"
@@ -124,7 +122,7 @@ void ED_armature_exit_posemode(bContext *C, Base *base)
/* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
/* only_selected == 1: the active bone is allowed to be protected */
#if 0 /* UNUSED 2.5 */
-static short pose_has_protected_selected(Object *ob, short warn)
+static bool pose_has_protected_selected(Object *ob, short warn)
{
/* check protection */
if (ob->proxy) {
@@ -424,7 +422,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- BKE_copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
+ BKE_constraints_copy(&tmp_constraints, &pchanact->constraints, true);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
@@ -536,7 +534,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- BKE_copy_constraints(&tmp_constraints, &const_copy, TRUE);
+ BKE_constraints_copy(&tmp_constraints, &const_copy, true);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
/* add proxy-local tags */
for (con = tmp_constraints.first; con; con = con->next)
@@ -707,17 +705,37 @@ void POSE_OT_rotation_mode_set(wmOperatorType *ot)
/* ********************************************** */
-/* Show all armature layers */
-static int pose_armature_layers_showall_poll(bContext *C)
+static int armature_layers_poll(bContext *C)
{
- /* this single operator can be used in posemode OR editmode for armatures */
+ /* Armature layers operators can be used in posemode OR editmode for armatures */
return ED_operator_posemode(C) || ED_operator_editarmature(C);
}
+static bArmature *armature_layers_get_data(Object **ob)
+{
+ bArmature *arm = NULL;
+
+ /* Sanity checking and handling of posemode. */
+ if (*ob) {
+ Object *tob = BKE_object_pose_armature_get(*ob);
+ if (tob) {
+ *ob = tob;
+ arm = (*ob)->data;
+ }
+ else if ((*ob)->type == OB_ARMATURE) {
+ arm = (*ob)->data;
+ }
+ }
+
+ return arm;
+}
+
+/* Show all armature layers */
+
static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
{
- Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
- bArmature *arm = (ob) ? ob->data : NULL;
+ Object *ob = CTX_data_active_object(C);
+ bArmature *arm = armature_layers_get_data(&ob);
PointerRNA ptr;
int maxLayers = (RNA_boolean_get(op->ptr, "all")) ? 32 : 16;
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -754,7 +772,7 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
/* callbacks */
ot->exec = pose_armature_layers_showall_exec;
- ot->poll = pose_armature_layers_showall_poll;
+ ot->poll = armature_layers_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -766,10 +784,10 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
- bArmature *arm = (ob) ? ob->data : NULL;
+ Object *ob = CTX_data_active_object(C);
+ bArmature *arm = armature_layers_get_data(&ob);
PointerRNA ptr;
int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -787,13 +805,14 @@ static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEven
}
/* Set the visible layers for the active armature (edit and pose modes) */
-static int pose_armature_layers_exec(bContext *C, wmOperator *op)
+static int armature_layers_exec(bContext *C, wmOperator *op)
{
- Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ Object *ob = CTX_data_active_object(C);
+ bArmature *arm = armature_layers_get_data(&ob);
PointerRNA ptr;
int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
- if (ELEM(NULL, ob, ob->data)) {
+ if (arm == NULL) {
return OPERATOR_CANCELLED;
}
@@ -801,7 +820,7 @@ static int pose_armature_layers_exec(bContext *C, wmOperator *op)
RNA_boolean_get_array(op->ptr, "layers", layers);
/* get pointer for armature, and write data there... */
- RNA_id_pointer_create((ID *)ob->data, &ptr);
+ RNA_id_pointer_create((ID *)arm, &ptr);
RNA_boolean_set_array(&ptr, "layers", layers);
/* note, notifier might evolve */
@@ -810,26 +829,6 @@ static int pose_armature_layers_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-
-void POSE_OT_armature_layers(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Change Armature Layers";
- ot->idname = "POSE_OT_armature_layers";
- ot->description = "Change the visible armature layers";
-
- /* callbacks */
- ot->invoke = pose_armature_layers_invoke;
- ot->exec = pose_armature_layers_exec;
- ot->poll = ED_operator_posemode;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
-}
-
void ARMATURE_OT_armature_layers(wmOperatorType *ot)
{
/* identifiers */
@@ -838,9 +837,9 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
ot->description = "Change the visible armature layers";
/* callbacks */
- ot->invoke = pose_armature_layers_invoke;
- ot->exec = pose_armature_layers_exec;
- ot->poll = ED_operator_editarmature;
+ ot->invoke = armature_layers_invoke;
+ ot->exec = armature_layers_exec;
+ ot->poll = armature_layers_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index d2d48fce8e6..376c1bc0838 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -176,7 +176,7 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_pose_object_from_context(C);
bPose *pose;
- short done = FALSE;
+ bool done = false;
/* only continue if there's an object, and a pose there too */
if (ELEM(NULL, ob, ob->pose))
@@ -195,7 +195,7 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
pchan->agrp_index = pose->active_group;
- done = TRUE;
+ done = true;
}
CTX_DATA_END;
@@ -232,7 +232,7 @@ void POSE_OT_group_assign(wmOperatorType *ot)
static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_pose_object_from_context(C);
- short done = FALSE;
+ bool done = false;
/* only continue if there's an object, and a pose there too */
if (ELEM(NULL, ob, ob->pose))
@@ -243,7 +243,7 @@ static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
{
if (pchan->agrp_index) {
pchan->agrp_index = 0;
- done = TRUE;
+ done = true;
}
}
CTX_DATA_END;
@@ -438,7 +438,7 @@ void POSE_OT_group_sort(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void pose_group_select(bContext *C, Object *ob, int select)
+static void pose_group_select(bContext *C, Object *ob, bool select)
{
bPose *pose = ob->pose;
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 4f421fad57a..d22b368bf58 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -611,6 +611,7 @@ void POSELIB_OT_pose_remove(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to remove");
RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -700,6 +701,7 @@ void POSELIB_OT_pose_rename(wmOperatorType *ot)
ot->prop = RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to rename");
RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
/* ************************************************************* */
@@ -879,7 +881,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
pchan = BKE_pose_channel_find_name(pose, agrp->name);
if (pchan) {
- short ok = 0;
+ bool ok = 0;
/* check if this bone should get any animation applied */
if (pld->selcount == 0) {
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 4038200d0a0..d783c1dcfde 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -43,7 +43,6 @@
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
-#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
@@ -332,7 +331,7 @@ void POSE_OT_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
}
/* -------------------------------------- */
@@ -464,7 +463,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
{
if (pchan->bone->flag & BONE_SELECTED) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -846,7 +845,7 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
}
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index ec49dad69b5..375cbb0fe2b 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -300,7 +300,7 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
*/
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
- char *bPtr, *pPtr;
+ const char *bPtr, *pPtr;
if (fcu->rna_path == NULL)
continue;
@@ -1013,11 +1013,11 @@ static float pose_propagate_get_boneHoldEndFrame(Object *ob, tPChanFCurveLink *p
}
/* get reference value from F-Curve using RNA */
-static short pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
+static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
- short found = FALSE;
+ bool found = false;
/* base pointer is always the object -> id_ptr */
RNA_id_pointer_create(&ob->id, &id_ptr);
@@ -1027,7 +1027,7 @@ static short pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
if (RNA_property_array_check(prop)) {
/* array */
if (fcu->array_index < RNA_property_array_length(&ptr, prop)) {
- found = TRUE;
+ found = true;
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
*value = (float)RNA_property_boolean_get_index(&ptr, prop, fcu->array_index);
@@ -1039,14 +1039,14 @@ static short pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
*value = RNA_property_float_get_index(&ptr, prop, fcu->array_index);
break;
default:
- found = FALSE;
+ found = false;
break;
}
}
}
else {
/* not an array */
- found = TRUE;
+ found = true;
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
*value = (float)RNA_property_boolean_get(&ptr, prop);
@@ -1061,7 +1061,7 @@ static short pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
*value = RNA_property_float_get(&ptr, prop);
break;
default:
- found = FALSE;
+ found = false;
break;
}
}
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 5fba6554b8c..094af99776b 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -78,7 +78,7 @@ static void applyarmature_fix_boneparents(Scene *scene, Object *armob)
/* apply current transform from parent (not yet destroyed),
* then calculate new parent inverse matrix
*/
- BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
+ BKE_object_apply_mat4(ob, ob->obmat, false, false);
BKE_object_workob_calc_parent(scene, ob, &workob);
invert_m4_m4(ob->parentinv, workob.obmat);
@@ -218,7 +218,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
*/
BKE_armature_mat_pose_to_bone(pchan, pchan->pose_mat, delta_mat);
- BKE_pchan_apply_mat4(pchan, delta_mat, TRUE);
+ BKE_pchan_apply_mat4(pchan, delta_mat, true);
}
CTX_DATA_END;
@@ -521,10 +521,10 @@ void POSE_OT_paste(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_boolean(ot->srna, "flipped", FALSE, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose");
+ prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- RNA_def_boolean(ot->srna, "selected_mask", FALSE, "On Selected Only", "Only paste the stored pose on to selected bones in the current pose");
+ RNA_def_boolean(ot->srna, "selected_mask", false, "On Selected Only", "Only paste the stored pose on to selected bones in the current pose");
}
/* ********************************************** */
@@ -812,7 +812,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
float cframe = (float)CFRA;
- const short only_select = RNA_boolean_get(op->ptr, "only_selected");
+ const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
if ((ob->adt) && (ob->adt->action)) {
/* XXX: this is just like this to avoid contaminating anything else;
@@ -879,5 +879,5 @@ void POSE_OT_user_transforms_clear(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "only_selected", TRUE, "Only Selected", "Only visible/selected bones");
+ RNA_def_boolean(ot->srna, "only_selected", true, "Only Selected", "Only visible/selected bones");
}
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 205012a6679..075e6811136 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -1796,7 +1796,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold))
static void filterGraph(ReebGraph *rg, short options, float threshold_internal, float threshold_external)
{
- int done = TRUE;
+ bool done = true;
calculateGraphLength(rg);
@@ -1810,8 +1810,8 @@ static void filterGraph(ReebGraph *rg, short options, float threshold_internal,
if (threshold_internal > 0 || threshold_external > 0) {
/* filter until there's nothing more to do */
- while (done == 1) {
- done = FALSE; /* no work done yet */
+ while (done == true) {
+ done = false; /* no work done yet */
done = filterInternalExternalReebGraph(rg, threshold_internal, threshold_external);
}
@@ -2497,32 +2497,16 @@ int weightFromLoc(EditMesh *em, int axis)
return 1;
}
-static float cotan_weight(float *v1, float *v2, float *v3)
-{
- float a[3], b[3], c[3], clen;
-
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
-
- clen = len_v3(c);
-
- if (clen == 0.0f)
- return 0.0f;
-
- return dot_v3v3(a, b) / clen;
-}
-
static void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2, int e3)
{
/* Angle opposite e1 */
- float t1 = cotan_weight(v1->co, v2->co, v3->co) / e2;
+ float t1 = cotangent_tri_weight_v3(v1->co, v2->co, v3->co) / e2;
/* Angle opposite e2 */
- float t2 = cotan_weight(v2->co, v3->co, v1->co) / e3;
+ float t2 = cotangent_tri_weight_v3(v2->co, v3->co, v1->co) / e3;
/* Angle opposite e3 */
- float t3 = cotan_weight(v3->co, v1->co, v2->co) / e1;
+ float t3 = cotangent_tri_weight_v3(v3->co, v1->co, v2->co) / e1;
int i1 = indexData(v1);
int i2 = indexData(v2);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 4f95bceddb3..f1b34182439 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -155,14 +155,14 @@ void ED_operatormacros_curve(void)
WM_operatortype_macro_define(ot, "CURVE_OT_duplicate");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
- RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
ot = WM_operatortype_append_macro("CURVE_OT_extrude_move", "Extrude Curve and Move",
"Extrude curve and move result", OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "CURVE_OT_extrude");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
- RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
}
void ED_keymap_curve(wmKeyConfig *keyconf)
@@ -225,7 +225,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "FONT_OT_line_break", RETKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FONT_OT_text_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
kmi = WM_keymap_add_item(keymap, "FONT_OT_text_insert", BACKSPACEKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "accent", TRUE); /* accented characters */
+ RNA_boolean_set(kmi->ptr, "accent", true); /* accented characters */
/* only set in editmode curve, by space_view3d listener */
keymap = WM_keymap_find(keyconf, "Curve", 0, 0);
@@ -248,9 +248,9 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CURVE_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "CURVE_OT_separate", PKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_split", YKEY, KM_PRESS, 0, 0);
@@ -268,9 +268,9 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CURVE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "CURVE_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
@@ -282,5 +282,5 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
- ED_keymap_proportional_editmode(keyconf, keymap, TRUE);
+ ED_keymap_proportional_editmode(keyconf, keymap, true);
}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 8d4321588cb..241b572c6f0 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -55,6 +55,7 @@
#include "BKE_report.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_modifier.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -91,8 +92,8 @@ typedef struct {
/* Definitions needed for shape keys */
typedef struct {
void *orig_cv;
- int key_index, nu_index, pt_index;
- int switched;
+ int key_index, nu_index, pt_index, vertex_index;
+ bool switched;
Nurb *orig_nu;
} CVKeyIndex;
@@ -256,7 +257,7 @@ void printknots(Object *obedit)
/* ********************* Shape keys *************** */
-static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, Nurb *orig_nu)
+static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index, Nurb *orig_nu)
{
CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), "init_cvKeyIndex");
@@ -264,7 +265,8 @@ static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt
cvIndex->key_index = key_index;
cvIndex->nu_index = nu_index;
cvIndex->pt_index = pt_index;
- cvIndex->switched = 0;
+ cvIndex->vertex_index = vertex_index;
+ cvIndex->switched = false;
cvIndex->orig_nu = orig_nu;
return cvIndex;
@@ -278,7 +280,7 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
BezTriple *bezt, *origbezt;
BPoint *bp, *origbp;
CVKeyIndex *keyIndex;
- int a, key_index = 0, nu_index = 0, pt_index = 0;
+ int a, key_index = 0, nu_index = 0, pt_index = 0, vertex_index = 0;
if (editnurb->keyindex) return;
@@ -291,9 +293,10 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
origbezt = orignu->bezt;
pt_index = 0;
while (a--) {
- keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, orignu);
+ keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, vertex_index, orignu);
BLI_ghash_insert(gh, bezt, keyIndex);
key_index += 12;
+ vertex_index += 3;
bezt++;
origbezt++;
pt_index++;
@@ -305,12 +308,13 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
origbp = orignu->bp;
pt_index = 0;
while (a--) {
- keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, orignu);
+ keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, vertex_index, orignu);
BLI_ghash_insert(gh, bp, keyIndex);
key_index += 4;
bp++;
origbp++;
pt_index++;
+ vertex_index++;
}
}
@@ -895,7 +899,7 @@ static void calc_shapeKeys(Object *obedit)
}
else {
int index;
- float *curofp;
+ const float *curofp;
if (oldkey) {
if (nu->bezt) {
@@ -1109,7 +1113,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
next = fcu->next;
if (!strncmp(fcu->rna_path, "splines", 7)) {
- char *ch = strchr(fcu->rna_path, '.');
+ const char *ch = strchr(fcu->rna_path, '.');
if (ch && (!strncmp(ch, ".bezier_points", 14) || !strncmp(ch, ".points", 7)))
fcurve_remove(adt, orig_curves, fcu);
@@ -1163,6 +1167,144 @@ int ED_curve_updateAnimPaths(Curve *cu)
/* ********************* LOAD and MAKE *************** */
+static int *initialize_index_map(Object *obedit, int *r_old_totvert)
+{
+ Curve *curve = (Curve *) obedit->data;
+ EditNurb *editnurb = curve->editnurb;
+ Nurb *nu;
+ CVKeyIndex *keyIndex;
+ int *old_to_new_map;
+ int old_totvert, i;
+ int vertex_index;
+
+ for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) {
+ if (nu->bezt) {
+ old_totvert += nu->pntsu * 3;
+ }
+ else {
+ old_totvert += nu->pntsu * nu->pntsv;
+ }
+ }
+
+ old_to_new_map = MEM_mallocN(old_totvert * sizeof(int), "curve old to new index map");
+ for (i = 0; i < old_totvert; i++) {
+ old_to_new_map[i] = -1;
+ }
+
+ for (nu = editnurb->nurbs.first, vertex_index = 0;
+ nu != NULL;
+ nu = nu->next, vertex_index++)
+ {
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ int a = nu->pntsu;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bezt);
+ if (keyIndex) {
+ if (keyIndex->switched) {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index + 2;
+ old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+ old_to_new_map[keyIndex->vertex_index + 2] = vertex_index;
+ }
+ else {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index;
+ old_to_new_map[keyIndex->vertex_index + 1] = vertex_index + 1;
+ old_to_new_map[keyIndex->vertex_index + 2] = vertex_index + 2;
+ }
+ }
+ vertex_index += 3;
+ bezt++;
+ }
+ }
+ else {
+ BPoint *bp = nu->bp;
+ int a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ keyIndex = getCVKeyIndex(editnurb, bp);
+ if (keyIndex) {
+ old_to_new_map[keyIndex->vertex_index] = vertex_index;
+ }
+ vertex_index++;
+ bp++;
+ }
+ }
+ }
+
+ *r_old_totvert = old_totvert;
+ return old_to_new_map;
+}
+
+static void remap_hooks_and_vertex_parents(Object *obedit)
+{
+ Object *object;
+ Curve *curve = (Curve *) obedit->data;
+ int *old_to_new_map = NULL;
+ int old_totvert;
+
+ for (object = G.main->object.first; object; object = object->id.next) {
+ ModifierData *md;
+ int index;
+ if ((object->parent) &&
+ (object->parent->data == curve) &&
+ ELEM(object->partype, PARVERT1, PARVERT3))
+ {
+ if (old_to_new_map == NULL) {
+ old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ }
+
+ if (object->par1 < old_totvert) {
+ index = old_to_new_map[object->par1];
+ if (index != -1) {
+ object->par1 = index;
+ }
+ }
+ if (object->par2 < old_totvert) {
+ index = old_to_new_map[object->par2];
+ if (index != -1) {
+ object->par2 = index;
+ }
+ }
+ if (object->par3 < old_totvert) {
+ index = old_to_new_map[object->par3];
+ if (index != -1) {
+ object->par3 = index;
+ }
+ }
+ }
+ if (object->data == curve) {
+ for (md = object->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *) md;
+ int i, j;
+
+ if (old_to_new_map == NULL) {
+ old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ }
+
+ for (i = j = 0; i < hmd->totindex; i++) {
+ if (hmd->indexar[i] < old_totvert) {
+ index = old_to_new_map[hmd->indexar[i]];
+ if (index != -1) {
+ hmd->indexar[j++] = index;
+ }
+ }
+ else {
+ j++;
+ }
+ }
+
+ hmd->totindex = j;
+ }
+ }
+ }
+ }
+ if (old_to_new_map != NULL) {
+ MEM_freeN(old_to_new_map);
+ }
+}
+
/* load editNurb in object */
void load_editNurb(Object *obedit)
{
@@ -1175,6 +1317,8 @@ void load_editNurb(Object *obedit)
Nurb *nu, *newnu;
ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
+ remap_hooks_and_vertex_parents(obedit);
+
for (nu = editnurb->first; nu; nu = nu->next) {
newnu = BKE_nurb_duplicate(nu);
BLI_addtail(&newnurb, newnu);
@@ -1231,7 +1375,7 @@ void make_editNurb(Object *obedit)
if (actkey)
editnurb->shapenr = obedit->shapenr;
- /* animation could be added in editmode even if there was no animdata i
+ /* animation could be added in editmode even if there was no animdata in
* object mode hence we always need CVs index be created */
init_editNurb_keyIndex(editnurb, &cu->nurb);
}
@@ -1662,7 +1806,7 @@ static void ed_surf_delete_selected(Object *obedit)
BPoint *bp, *bpn, *newbp;
int a, b, newu, newv;
- BLI_assert(obedit->type != OB_SURF);
+ BLI_assert(obedit->type == OB_SURF);
nu = editnurb->first;
while (nu) {
@@ -2423,55 +2567,128 @@ void CURVE_OT_radius_set(wmOperatorType *ot)
/********************* smooth operator ********************/
+static void smooth_single_bezt(
+ BezTriple *bezt,
+ const BezTriple *bezt_orig_prev, const BezTriple *bezt_orig_next,
+ float factor)
+{
+ int i;
+
+ BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+
+ for (i = 0; i < 3; i++) {
+ float val_old, val_new, offset;
+
+ /* get single dimension pos of the mid handle */
+ val_old = bezt->vec[1][i];
+
+ /* get the weights of the previous/next mid handles and calc offset */
+ val_new = (bezt_orig_prev->vec[1][i] * 0.5f) + (bezt_orig_next->vec[1][i] * 0.5f);
+ offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+
+ /* offset midpoint and 2 handles */
+ bezt->vec[1][i] += offset;
+ bezt->vec[0][i] += offset;
+ bezt->vec[2][i] += offset;
+ }
+}
+
+/**
+ * Same as smooth_single_bezt(), keep in sync
+ */
+static void smooth_single_bp(
+ BPoint *bp,
+ const BPoint *bp_orig_prev, const BPoint *bp_orig_next,
+ float factor)
+{
+ int i;
+
+ BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+
+ for (i = 0; i < 3; i++) {
+ float val_old, val_new, offset;
+
+ val_old = bp->vec[i];
+ val_new = (bp_orig_prev->vec[i] * 0.5f) + (bp_orig_next->vec[i] * 0.5f);
+ offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+
+ bp->vec[i] += offset;
+ }
+}
+
static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
+ const float factor = 1.0f / 6.0f;
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
- BezTriple *bezt, *beztOrig;
- BPoint *bp, *bpOrig;
- float val, newval, offset;
- int a, i;
+
+ int a, a_end;
bool changed = false;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->bezt) {
+ /* duplicate the curve to use in weight calculation */
+ const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
+ BezTriple *bezt;
changed = false;
- beztOrig = MEM_dupallocN(nu->bezt);
- for (bezt = &nu->bezt[1], a = 1; a < nu->pntsu - 1; a++, bezt++) {
+
+ /* check whether its cyclic or not, and set initial & final conditions */
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
+
+ /* for all the curve points */
+ for (; a < a_end; a++) {
+ /* respect selection */
+ bezt = &nu->bezt[a];
if (bezt->f2 & SELECT) {
- for (i = 0; i < 3; i++) {
- val = bezt->vec[1][i];
- newval = ((beztOrig + (a - 1))->vec[1][i] * 0.5f) + ((beztOrig + (a + 1))->vec[1][i] * 0.5f);
- offset = (val * ((1.0f / 6.0f) * 5.0f)) + (newval * (1.0f / 6.0f)) - val;
- /* offset handles */
- bezt->vec[1][i] += offset;
- bezt->vec[0][i] += offset;
- bezt->vec[2][i] += offset;
- }
+ const BezTriple *bezt_orig_prev, *bezt_orig_next;
+
+ bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
+ bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
+
+ smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
+
changed = true;
}
}
- MEM_freeN(beztOrig);
+ MEM_freeN((void *)bezt_orig);
if (changed) {
BKE_nurb_handles_calc(nu);
}
}
else if (nu->bp) {
- bpOrig = MEM_dupallocN(nu->bp);
/* Same as above, keep these the same! */
- for (bp = &nu->bp[1], a = 1; a < nu->pntsu - 1; a++, bp++) {
+ const BPoint *bp_orig = MEM_dupallocN(nu->bp);
+ BPoint *bp;
+
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
+
+ for (; a < a_end; a++) {
+ bp = &nu->bp[a];
if (bp->f1 & SELECT) {
- for (i = 0; i < 3; i++) {
- val = bp->vec[i];
- newval = ((bpOrig + (a - 1))->vec[i] * 0.5f) + ((bpOrig + (a + 1))->vec[i] * 0.5f);
- offset = (val * ((1.0f / 6.0f) * 5.0f)) + (newval * (1.0f / 6.0f)) - val;
-
- bp->vec[i] += offset;
- }
+ const BPoint *bp_orig_prev, *bp_orig_next;
+
+ bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
+ bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
+
+ smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
}
}
- MEM_freeN(bpOrig);
+ MEM_freeN((void *)bp_orig);
}
}
@@ -2756,7 +2973,7 @@ static void select_adjacent_cp(ListBase *editnurb, short next,
BezTriple *bezt;
BPoint *bp;
int a;
- short lastsel = false;
+ bool lastsel = false;
if (next == 0) return;
@@ -2926,7 +3143,7 @@ void CURVE_OT_de_select_last(wmOperatorType *ot)
/******************* de select all operator ***************/
-static short nurb_has_selected_cps(ListBase *editnurb)
+static bool nurb_has_selected_cps(ListBase *editnurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -3615,7 +3832,7 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2],
/* return 0 1 2: handlepunt */
struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL};
- data.dist = 100;
+ data.dist = ED_view3d_select_dist_px();
data.hpoint = 0;
data.select = sel;
data.mval_fl[0] = mval[0];
@@ -3866,7 +4083,7 @@ static void switchdirection_knots(float *base, int tot)
fp1 = base;
fp2 = tempf = MEM_mallocN(sizeof(float) * a, "switchdirect");
while (a--) {
- fp2[0] = fabs(fp1[1] - fp1[0]);
+ fp2[0] = fabsf(fp1[1] - fp1[0]);
fp1++;
fp2++;
}
@@ -3918,11 +4135,11 @@ static bool is_u_selected(Nurb *nu, int u)
bp = &nu->bp[u];
for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) {
if ((v != 0) && (bp->f1 & SELECT)) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
typedef struct NurbSort {
@@ -4001,7 +4218,7 @@ static void make_selection_list_nurb(ListBase *editnurb)
}
}
-static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu2)
+static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu1, Nurb *nu2)
{
BPoint *bp, *bp1, *bp2, *temp;
float len1, len2;
@@ -4116,10 +4333,12 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
for (u = 0; u < nu1->pntsu; u++, bp++) {
if (u < origu) {
+ keyIndex_updateBP(cu->editnurb, bp1, bp, 1);
*bp = *bp1; bp1++;
select_bpoint(bp, SELECT, SELECT, HIDDEN);
}
else {
+ keyIndex_updateBP(cu->editnurb, bp2, bp, 1);
*bp = *bp2; bp2++;
}
}
@@ -4141,9 +4360,10 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
static int merge_nurb(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
ListBase *editnurb = object_editcurve_get(obedit);
NurbSort *nus1, *nus2;
- int ok = 1;
+ bool ok = true;
make_selection_list_nurb(editnurb);
@@ -4190,7 +4410,7 @@ static int merge_nurb(bContext *C, wmOperator *op)
}
while (nus2) {
- merge_2_nurb(op, editnurb, nus1->nu, nus2->nu);
+ merge_2_nurb(op, cu, editnurb, nus1->nu, nus2->nu);
nus2 = nus2->next;
}
@@ -4212,7 +4432,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
ListBase *nubase = object_editcurve_get(obedit);
Nurb *nu, *nu1 = NULL, *nu2 = NULL;
BPoint *bp;
- int ok = 0;
+ bool ok = false;
/* int a; */ /* UNUSED */
/* first decide if this is a surface merge! */
@@ -4227,7 +4447,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if (isNurbsel_count(cu, nu) == 1) {
/* only 1 selected, not first or last, a little complex, but intuitive */
if (nu->pntsv == 1) {
- if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
+ if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
/* pass */
}
else {
@@ -4337,6 +4557,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
nu1->bezt = bezt;
nu1->pntsu += nu2->pntsu;
BLI_remlink(nubase, nu2);
+ keyIndex_delNurb(cu->editnurb, nu2);
BKE_nurb_free(nu2); nu2 = NULL;
BKE_nurb_handles_calc(nu1);
}
@@ -4361,6 +4582,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
BKE_nurb_knot_calc_u(nu1);
}
+ keyIndex_delNurb(cu->editnurb, nu2);
BKE_nurb_free(nu2); nu2 = NULL;
}
@@ -4368,7 +4590,11 @@ static int make_segment_exec(bContext *C, wmOperator *op)
ok = 1;
}
}
- else if (nu1 && !nu2) {
+ else if ((nu1 && !nu2) || (!nu1 && nu2)) {
+ if (nu2) {
+ SWAP(Nurb *, nu1, nu2);
+ }
+
if (!(nu1->flagu & CU_NURB_CYCLIC) && nu1->pntsu > 1) {
if (nu1->type == CU_BEZIER && BEZSELECTED_HIDDENHANDLES(cu, nu1->bezt) &&
BEZSELECTED_HIDDENHANDLES(cu, &nu1->bezt[nu1->pntsu - 1]))
@@ -4694,7 +4920,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
BezTriple *bezt, *newbezt = NULL;
BPoint *bp, *newbp = NULL;
float imat[4][4], temp[3];
- int ok = 0;
+ bool ok = false;
BezTriple *bezt_recalc[3] = {NULL};
invert_m4_m4(imat, obedit->obmat);
@@ -6795,7 +7021,7 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op))
int a;
if (object->curve_cache == NULL) {
- BKE_displist_make_curveTypes(scene, object, FALSE);
+ BKE_displist_make_curveTypes(scene, object, false);
}
INIT_MINMAX(min, max);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 00195eb2f88..5c448effcd5 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -34,12 +34,6 @@
#include <wchar.h>
#include <errno.h>
-#ifndef WIN32
-# include <unistd.h>
-#else
-# include <io.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -57,7 +51,6 @@
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_font.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -72,6 +65,7 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_util.h"
+#include "ED_view3d.h"
#include "UI_interface.h"
@@ -715,7 +709,7 @@ static EnumPropertyItem style_items[] = {
{0, NULL, 0, NULL, NULL}
};
-static int set_style(bContext *C, const int style, const int clear)
+static int set_style(bContext *C, const int style, const bool clear)
{
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
@@ -741,7 +735,7 @@ static int set_style(bContext *C, const int style, const int clear)
static int set_style_exec(bContext *C, wmOperator *op)
{
const int style = RNA_enum_get(op->ptr, "style");
- const int clear = RNA_boolean_get(op->ptr, "clear");
+ const bool clear = RNA_boolean_get(op->ptr, "clear");
return set_style(C, style, clear);
}
@@ -972,7 +966,7 @@ static EnumPropertyItem move_type_items[] = {
{NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""},
{0, NULL, 0, NULL, NULL}};
-static int move_cursor(bContext *C, int type, int select)
+static int move_cursor(bContext *C, int type, const bool select)
{
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
@@ -1082,7 +1076,7 @@ static int move_exec(bContext *C, wmOperator *op)
{
int type = RNA_enum_get(op->ptr, "type");
- return move_cursor(C, type, 0);
+ return move_cursor(C, type, false);
}
void FONT_OT_move(wmOperatorType *ot)
@@ -1109,7 +1103,7 @@ static int move_select_exec(bContext *C, wmOperator *op)
{
int type = RNA_enum_get(op->ptr, "type");
- return move_cursor(C, type, 1);
+ return move_cursor(C, type, true);
}
void FONT_OT_move_select(wmOperatorType *ot)
@@ -1789,7 +1783,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
VFont *vfont = NULL;
- char *path;
+ const char *path;
PointerRNA idptr;
PropertyPointerRNA *pprop;
@@ -1878,7 +1872,7 @@ static void undoFont_to_editFont(void *strv, void *ecu, void *UNUSED(obdata))
{
Curve *cu = (Curve *)ecu;
EditFont *ef = cu->editfont;
- char *str = strv;
+ const char *str = strv;
ef->pos = *((short *)str);
ef->len = *((short *)(str + 2));
@@ -1928,3 +1922,89 @@ void undo_push_font(bContext *C, const char *name)
{
undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
}
+
+/**
+ * TextBox selection
+ */
+bool mouse_font(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ ViewContext vc;
+ /* bias against the active, in pixels, allows cycling */
+ const float active_bias_px = 4.0f;
+ const float mval_fl[2] = {UNPACK2(mval)};
+ const int i_actbox = max_ii(0, cu->actbox - 1);
+ int i_iter, actbox_select = -1;
+ const float dist = ED_view3d_select_dist_px();
+ float dist_sq_best = dist * dist;
+
+ view3d_set_viewcontext(C, &vc);
+
+ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+
+ /* currently only select active */
+ (void)extend;
+ (void)deselect;
+ (void)toggle;
+
+ for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
+ int i = (i_iter + i_actbox) % cu->totbox;
+ float dist_sq_min;
+ int j, j_prev;
+
+ float obedit_co[4][3];
+ float screen_co[4][2];
+ rctf rect;
+ int project_ok = 0;
+
+
+ BKE_curve_rect_from_textbox(cu, &cu->tb[i], &rect);
+
+ copy_v3_fl3(obedit_co[0], rect.xmin, rect.ymin, 0.0f);
+ copy_v3_fl3(obedit_co[1], rect.xmin, rect.ymax, 0.0f);
+ copy_v3_fl3(obedit_co[2], rect.xmax, rect.ymax, 0.0f);
+ copy_v3_fl3(obedit_co[3], rect.xmax, rect.ymin, 0.0f);
+
+ for (j = 0; j < 4; j++) {
+ if (ED_view3d_project_float_object(vc.ar, obedit_co[j], screen_co[j],
+ V3D_PROJ_TEST_CLIP_BB) == V3D_PROJ_RET_OK)
+ {
+ project_ok |= (1 << j);
+ }
+ }
+
+ dist_sq_min = dist_sq_best;
+ for (j = 0, j_prev = 3; j < 4; j_prev = j++) {
+ if ((project_ok & (1 << j)) &&
+ (project_ok & (1 << j_prev)))
+ {
+ const float dist_test_sq = dist_squared_to_line_segment_v2(mval_fl, screen_co[j_prev], screen_co[j]);
+ if (dist_sq_min > dist_test_sq) {
+ dist_sq_min = dist_test_sq;
+ }
+ }
+ }
+
+ /* bias in pixels to cycle seletion */
+ if (i_iter == 0) {
+ dist_sq_min += active_bias_px;
+ }
+
+ if (dist_sq_min < dist_sq_best) {
+ dist_sq_best = dist_sq_min;
+ actbox_select = i + 1;
+ }
+ }
+
+ if (actbox_select != -1) {
+ if (cu->actbox != actbox_select) {
+ cu->actbox = actbox_select;
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 35a669175df..3fc6e2e6f0d 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -33,10 +33,10 @@ set(SRC
data_to_c_simple(../../../../release/datafiles/bfont.pfb SRC)
data_to_c_simple(../../../../release/datafiles/bfont.ttf SRC)
+data_to_c_simple(../../../../release/datafiles/bmonofont.ttf SRC)
if(WITH_BLENDER)
# blender only (not player)
- data_to_c_simple(../../../../release/datafiles/bmonofont.ttf SRC)
if(NOT WITH_HEADLESS)
# blender UI only
@@ -47,6 +47,7 @@ if(WITH_BLENDER)
# images
data_to_c_simple(../../../../release/datafiles/splash.png SRC)
+ data_to_c_simple(../../../../release/datafiles/splash_2x.png SRC)
# XXX These are handy, but give nasty "false changes" in svn :/
#svg_to_png(../../../../release/datafiles/blender_icons.svg
#../../../../release/datafiles/blender_icons16.png
diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript
index dadd4bd1f19..47819d0e33c 100644
--- a/source/blender/editors/datafiles/SConscript
+++ b/source/blender/editors/datafiles/SConscript
@@ -41,6 +41,7 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
os.path.join(env['DATA_SOURCES'], "splash.png.c"),
+ os.path.join(env['DATA_SOURCES'], "splash_2x.png.c"),
os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 3bfa5e6b088..e701be0e63b 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -36,7 +36,6 @@
#include "BLI_sys_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -44,10 +43,9 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
@@ -57,7 +55,6 @@
#include "BIF_glutil.h"
#include "ED_gpencil.h"
-#include "ED_sequencer.h"
#include "ED_view3d.h"
#include "GPU_blender_aspect.h"
@@ -475,7 +472,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
/* draw a set of strokes */
static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
- short debug, short lthick, float color[4])
+ short debug, short lthick, const float color[4])
{
bGPDstroke *gps;
@@ -745,7 +742,7 @@ void draw_gpencil_2dimage(const bContext *C)
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
* Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes,
* second time with onlyv2d=0 for screen-aligned strokes */
-void draw_gpencil_view2d(const bContext *C, short onlyv2d)
+void draw_gpencil_view2d(const bContext *C, bool onlyv2d)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -790,7 +787,7 @@ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
* deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, TRUE); /* no shift */
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */
offsx = iroundf(rectf.xmin);
offsy = iroundf(rectf.ymin);
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 8fcbee6f758..f5bf1422488 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_gpencil_types.h"
@@ -46,7 +45,6 @@
#include "BKE_fcurve.h"
#include "BKE_gpencil.h"
-#include "ED_anim_api.h"
#include "ED_gpencil.h"
#include "ED_keyframes_edit.h"
#include "ED_markers.h"
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 5f829a1cb27..0fe4d7e7157 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -33,7 +33,6 @@
#include <stdlib.h>
#include <stddef.h>
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLF_translation.h"
@@ -134,14 +133,14 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* get layout-row + UI-block for header */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
block = uiLayoutGetBlock(row); /* err... */
uiBlockSetEmboss(block, UI_EMBOSSN);
/* left-align ............................... */
- sub = uiLayoutRow(row, FALSE);
+ sub = uiLayoutRow(row, false);
/* active */
block = uiLayoutGetBlock(sub);
@@ -172,7 +171,7 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* delete button (only if hidden but not locked!) */
if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) {
/* right-align ............................... */
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
block = uiLayoutGetBlock(sub); /* XXX... err... */
@@ -216,7 +215,7 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* delete 'button' */
uiBlockSetEmboss(block, UI_EMBOSSN);
/* right-align ............................... */
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
block = uiLayoutGetBlock(sub); /* XXX... err... */
@@ -227,14 +226,14 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* new backdrop ----------------------------------- */
box = uiLayoutBox(layout);
- split = uiLayoutSplit(box, 0.5f, FALSE);
+ split = uiLayoutSplit(box, 0.5f, false);
/* draw settings ---------------------------------- */
/* left column ..................... */
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
/* color */
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiItemR(sub, &ptr, "color", 0, "", ICON_NONE);
uiItemR(sub, &ptr, "alpha", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -247,10 +246,10 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
}
/* right column ................... */
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
/* onion-skinning */
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiItemR(sub, &ptr, "use_onion_skinning", 0, NULL, ICON_NONE);
uiItemR(sub, &ptr, "ghost_range_max", 0, IFACE_("Frames"), ICON_NONE);
@@ -273,14 +272,14 @@ static void draw_gpencil_space_specials(const bContext *C, uiLayout *layout)
uiLayout *col, *row;
SpaceClip *sc = CTX_wm_space_clip(C);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
if (sc) {
bScreen *screen = CTX_wm_screen(C);
PointerRNA sc_ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr);
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
}
@@ -299,7 +298,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
/* draw gpd settings first ------------------------------------- */
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
/* current Grease Pencil block */
/* TODO: show some info about who owns this? */
@@ -307,7 +306,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
/* add new layer button - can be used even when no data, since it can add a new block too */
uiItemO(col, IFACE_("New Layer"), ICON_NONE, "GPENCIL_OT_layer_add");
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemO(row, IFACE_("Delete Frame"), ICON_NONE, "GPENCIL_OT_active_frame_delete");
uiItemO(row, IFACE_("Convert"), ICON_NONE, "GPENCIL_OT_convert");
@@ -317,12 +316,12 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
/* draw each layer --------------------------------------------- */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
gp_drawui_layer(col, gpd, gpl, is_v3d);
}
/* draw gpd drawing settings first ------------------------------------- */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
/* label */
uiItemL(col, IFACE_("Drawing Settings:"), ICON_NONE);
@@ -335,17 +334,17 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
}
/* drawing space options */
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE);
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE);
if (sc == NULL) {
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiLayoutSetActive(row, v3d_stroke_opts);
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE);
uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON);
uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 94400682f9e..d25de906e31 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -52,7 +52,6 @@
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
-#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -456,10 +455,8 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
/* get screen coordinate */
if (gps->flag & GP_STROKE_2DSPACE) {
- int mvali[2];
View2D *v2d = &ar->v2d;
- UI_view2d_view_to_region(v2d, pt->x, pt->y, mvali, mvali + 1);
- VECCOPY2D(mvalf, mvali);
+ UI_view2d_view_to_region_fl(v2d, pt->x, pt->y, &mvalf[0], &mvalf[1]);
}
else {
if (subrect) {
@@ -472,9 +469,6 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
}
}
- /* convert screen coordinate to 3d coordinates
- * - method taken from editview.c - mouse_cursor()
- */
ED_view3d_win_to_3d(ar, fp, mvalf, p3d);
}
}
@@ -757,8 +751,8 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
prop = RNA_struct_find_property(&ptr, "eval_time");
/* Ensure we have an F-Curve to add keyframes to */
- act = verify_adt_action((ID *)cu, TRUE);
- fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, TRUE);
+ act = verify_adt_action((ID *)cu, true);
+ fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, true);
if (G.debug & G_DEBUG) {
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
@@ -1392,7 +1386,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
Scene *scene = CTX_data_scene(C);
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, subrect, TRUE); /* no shift */
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, subrect, true); /* no shift */
return 1;
}
}
@@ -1673,7 +1667,7 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
/* Never show this prop */
if (strcmp(prop_id, "use_timing_data") == 0)
- return FALSE;
+ return false;
if (link_strokes) {
/* Only show when link_stroke is true */
@@ -1749,11 +1743,11 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
- RNA_def_boolean(ot->srna, "use_normalize_weights", TRUE, "Normalize Weight",
+ RNA_def_boolean(ot->srna, "use_normalize_weights", true, "Normalize Weight",
"Normalize weight (set from stroke width)");
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
- RNA_def_boolean(ot->srna, "use_link_strokes", TRUE, "Link Strokes",
+ RNA_def_boolean(ot->srna, "use_link_strokes", true, "Link Strokes",
"Whether to link strokes with zero-radius sections of curves");
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
@@ -1764,7 +1758,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
"The duration of evaluation of the path control curve", 1, 1000);
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
"The start frame of the path control curve", 1, 100000);
- RNA_def_boolean(ot->srna, "use_realtime", FALSE, "Realtime",
+ RNA_def_boolean(ot->srna, "use_realtime", false, "Realtime",
"Whether the path control curve reproduces the drawing in realtime, starting from Start Frame");
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
@@ -1779,7 +1773,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
"Custom Gap mode: Random generator seed", 0, 100);
/* Note: Internal use, this one will always be hidden by UI code... */
- prop = RNA_def_boolean(ot->srna, "use_timing_data", FALSE, "Has Valid Timing",
+ prop = RNA_def_boolean(ot->srna, "use_timing_data", false, "Has Valid Timing",
"Whether the converted Grease Pencil layer has valid timing data (internal use)");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 8e40fc19671..0df6dcc6cc2 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -279,9 +279,9 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
*/
}
else {
- int mval_prj[2];
+ float mval_prj[2];
float rvec[3], dvec[3];
- float mval_f[2];
+ float mval_f[2] = {UNPACK2(mval)};
float zfac;
/* Current method just converts each point in screen-coordinates to
@@ -295,11 +295,9 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
gp_get_3d_reference(p, rvec);
zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
-
- /* method taken from editview.c - mouse_cursor() */
- /* TODO, use ED_view3d_project_float_global */
- if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- VECSUB2D(mval_f, mval_prj, mval);
+
+ if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ sub_v2_v2v2(mval_f, mval_prj, mval_f);
ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
sub_v3_v3v3(out, rvec, dvec);
}
@@ -672,16 +670,16 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) &&
(i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0)))
{
- interp_depth = TRUE;
+ interp_depth = true;
}
else {
- found_depth = TRUE;
+ found_depth = true;
}
copy_v2_v2_int(mval_prev, mval);
}
- if (found_depth == FALSE) {
+ if (found_depth == false) {
/* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */
for (i = gpd->sbuffer_size - 1; i >= 0; i--)
depth_arr[i] = 0.9999f;
@@ -708,7 +706,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
for (i = first_valid + 1; i < last_valid; i++)
depth_arr[i] = FLT_MAX;
- interp_depth = TRUE;
+ interp_depth = true;
}
if (interp_depth) {
@@ -890,11 +888,11 @@ static short gp_stroke_eraser_strokeinside(const int mval[2], const int UNUSED(m
const float screen_co_b[2] = {x1, y1};
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
- return TRUE;
+ return true;
}
/* not inside */
- return FALSE;
+ return false;
}
static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt,
@@ -913,7 +911,7 @@ static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *
}
}
else if (gps->flag & GP_STROKE_2DSPACE) {
- UI_view2d_view_to_region(v2d, pt->x, pt->y, r_x, r_y);
+ UI_view2d_view_to_region_clip(v2d, pt->x, pt->y, r_x, r_y);
}
else {
if (subrect == NULL) { /* normal 3D view */
@@ -1149,7 +1147,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
MovieClip *clip = ED_space_clip_get_clip(sc);
int framenr = ED_space_clip_get_clip_frame_number(sc);
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
- MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
p->imat[3][0] -= marker->pos[0];
p->imat[3][1] -= marker->pos[1];
@@ -1284,7 +1282,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, TRUE); /* no shift */
+ ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */
p->subrect = &p->subrect_data;
}
}
@@ -1440,7 +1438,7 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
/* check size of buffer before cleanup, to determine if anything happened here */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* turn off radial brush cursor */
- gpencil_draw_toggle_eraser_cursor(C, p, FALSE);
+ gpencil_draw_toggle_eraser_cursor(C, p, false);
/* if successful, store the new eraser size to be used again next time */
if (p->status == GP_STATUS_DONE)
@@ -1760,7 +1758,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
/* if eraser is on, draw radial aid */
if (p->paintmode == GP_PAINTMODE_ERASER) {
- gpencil_draw_toggle_eraser_cursor(C, p, TRUE);
+ gpencil_draw_toggle_eraser_cursor(C, p, true);
}
/* set cursor */
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index a3d3d8f05a2..477a7c0ce17 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -38,9 +38,12 @@
#ifdef __APPLE__
/* hacking pointsize and linewidth */
-#define glPointSize(f) glPointSize(U.pixelsize*(f))
-#define glLineWidth(f) glLineWidth(U.pixelsize*(f))
-
+# define glPointSize(f) glPointSize(U.pixelsize * (f))
+# define glLineWidth(f) glLineWidth(U.pixelsize * (f))
+#else
+ /* avoid include mismatch by referencing 'U' from both */
+# define glPointSize(f) glPointSize(((void)U.pixelsize, (f)))
+# define glLineWidth(f) glLineWidth(((void)U.pixelsize, (f)))
#endif
/*
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 72902c601f3..0342e7a7435 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -50,6 +50,7 @@ struct Object;
struct bDopeSheet;
+struct bAction;
struct bActionGroup;
struct FCurve;
struct FModifier;
@@ -164,7 +165,7 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_GPDATABLOCK,
ANIMTYPE_GPLAYER,
-
+
ANIMTYPE_MASKDATABLOCK,
ANIMTYPE_MASKLAYER,
@@ -363,6 +364,13 @@ bool ANIM_animdata_context_getdata(bAnimContext *ac);
/* ------------------------ Drawing TypeInfo -------------------------- */
+/* role or level of animchannel in the hierarchy */
+typedef enum eAnimChannel_Role {
+ ACHANNEL_ROLE_EXPANDER = -1, /* datablock expander - a "composite" channel type */
+ ACHANNEL_ROLE_SPECIAL = 0, /* special purposes - not generally for hierarchy processing */
+ ACHANNEL_ROLE_CHANNEL = 1 /* data channel - a channel representing one of the actual building blocks of channels */
+} eAnimChannel_Role;
+
/* flag-setting behavior */
typedef enum eAnimChannels_SetFlag {
ACHANNEL_SETFLAG_CLEAR = 0, /* turn off */
@@ -378,17 +386,20 @@ typedef enum eAnimChannel_Settings {
ACHANNEL_SETTING_MUTE = 2,
ACHANNEL_SETTING_EXPAND = 3,
ACHANNEL_SETTING_VISIBLE = 4, /* only for Graph Editor */
- ACHANNEL_SETTING_SOLO = 5 /* only for NLA Tracks */
+ ACHANNEL_SETTING_SOLO = 5, /* only for NLA Tracks */
+ ACHANNEL_SETTING_PINNED = 6 /* only for NLA Actions */
} eAnimChannel_Settings;
/* Drawing, mouse handling, and flag setting behavior... */
typedef struct bAnimChannelType {
- /* type data */
+ /* -- Type data -- */
/* name of the channel type, for debugging */
const char *channel_type_name;
+ /* "level" or role in hierarchy - for finding the active channel */
+ eAnimChannel_Role channel_role;
- /* drawing */
+ /* -- Drawing -- */
/* get RGB color that is used to draw the majority of the backdrop */
void (*get_backdrop_color)(bAnimContext *ac, bAnimListElem *ale, float r_color[3]);
/* draw backdrop strip for channel */
@@ -405,16 +416,16 @@ typedef struct bAnimChannelType {
/* get icon (for channel lists) */
int (*icon)(bAnimListElem *ale);
- /* settings */
+ /* -- Settings -- */
/* check if the given setting is valid in the current context */
- bool (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting);
+ bool (*has_setting)(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting);
/* get the flag used for this setting */
- int (*setting_flag)(bAnimContext *ac, int setting, bool *neg);
+ int (*setting_flag)(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg);
/* get the pointer to int/short where data is stored,
* with type being sizeof(ptr_data) which should be fine for runtime use...
* - assume that setting has been checked to be valid for current context
*/
- void *(*setting_ptr)(bAnimListElem *ale, int setting, short *type);
+ void *(*setting_ptr)(bAnimListElem *ale, eAnimChannel_Settings setting, short *type);
} bAnimChannelType;
/* ------------------------ Drawing API -------------------------- */
@@ -456,7 +467,7 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting,
* - setting: type of setting to set
* - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short on);
+void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, int setting, short mode);
/* Deselect all animation channels */
@@ -513,12 +524,12 @@ void free_fmodifiers_copybuf(void);
* assuming that the buffer has been cleared already with free_fmodifiers_copybuf()
* - active: only copy the active modifier
*/
-short ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, short active);
+bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active);
/* 'Paste' the F-Modifier(s) from the buffer to the specified list
* - replace: free all the existing modifiers to leave only the pasted ones
*/
-short ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, short replace);
+bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace);
/* ************************************************* */
/* ASSORTED TOOLS */
@@ -532,6 +543,14 @@ int getname_anim_fcurve(char *name, struct ID *id, struct FCurve *fcu);
/* Automatically determine a color for the nth F-Curve */
void getcolor_fcurve_rainbow(int cur, int tot, float out[3]);
+/* ----------------- NLA Drawing ----------------------- */
+/* NOTE: Technically, this is not in the animation module (it's in space_nla)
+ * but these are sometimes needed by various animation apis.
+ */
+
+/* Get color to use for NLA Action channel's background */
+void nla_action_get_color(struct AnimData *adt, struct bAction *act, float color[4]);
+
/* ----------------- NLA-Mapping ----------------------- */
/* anim_draw.c */
@@ -539,7 +558,7 @@ void getcolor_fcurve_rainbow(int cur, int tot, float out[3]);
struct AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale);
/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve */
-void ANIM_nla_mapping_apply_fcurve(struct AnimData *adt, struct FCurve *fcu, short restore, short only_keys);
+void ANIM_nla_mapping_apply_fcurve(struct AnimData *adt, struct FCurve *fcu, bool restore, bool only_keys);
/* ..... */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 704a64b9633..4d48974832f 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -90,7 +90,7 @@ typedef struct EditBone {
#define BONESEL_BONE (1 << 30)
#define BONESEL_ANY (BONESEL_TIP | BONESEL_ROOT | BONESEL_BONE)
-#define BONESEL_NOSEL (1 << 31) /* Indicates a negative number */
+#define BONESEL_NOSEL (1u << 31u)
/* useful macros */
#define EBONE_VISIBLE(arm, ebone) ( \
@@ -127,7 +127,7 @@ int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int
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);
-float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const short axis_only);
+float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only);
EditBone *ED_armature_bone_find_name(const struct ListBase *edbo, const char *name);
EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo);
void ED_armature_sync_selection(struct ListBase *edbo);
@@ -143,6 +143,9 @@ EditBone *ED_armature_bone_find_shared_parent(EditBone *ebone_child[], const uns
void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]);
void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]);
+void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
+void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
+
void transform_armature_mirror_update(struct Object *obedit);
void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
@@ -154,7 +157,7 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4]);
#define ARM_GROUPS_ENVELOPE 2
#define ARM_GROUPS_AUTO 3
-void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct Object *par, int mode, int mirror);
+void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct Object *par, int mode, bool mirror);
void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */
void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep);
@@ -187,7 +190,6 @@ void BIF_deleteSketch(struct bContext *C);
void BIF_selectAllSketch(struct bContext *C, int mode); /* -1: deselect, 0: select, 1: toggle */
void BIF_makeListTemplates(const struct bContext *C);
-const char *BIF_listTemplates(const struct bContext *C);
int BIF_currentTemplate(const struct bContext *C);
void BIF_freeTemplates(struct bContext *C);
void BIF_setTemplate(struct bContext *C, int index);
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 5cc399fdcee..64c16605dec 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -34,6 +34,7 @@ bool ED_texture_context_check_world(const struct bContext *C);
bool ED_texture_context_check_material(const struct bContext *C);
bool ED_texture_context_check_lamp(const struct bContext *C);
bool ED_texture_context_check_particles(const struct bContext *C);
+bool ED_texture_context_check_linestyle(const struct bContext *C);
bool ED_texture_context_check_others(const struct bContext *C);
#endif /* __ED_BUTTONS_H__ */
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 91f8b39f7b9..5f8ebd87d19 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -63,7 +63,7 @@ int ED_space_clip_get_clip_frame_number(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
-bool ED_space_clip_color_sample(struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_clip_color_sample(struct Scene *scene, struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
void ED_clip_update_frame(const struct Main *mainp, int cfra);
bool ED_clip_view_selection(const struct bContext *C, struct ARegion *ar, bool fit);
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 2a04840a5b1..330147db077 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -89,6 +89,8 @@ int ED_curve_updateAnimPaths(struct Curve *cu);
bool ED_curve_active_center(struct Curve *cu, float center[3]);
+bool mouse_font(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
+
/* debug only */
void printknots(struct Object *obedit);
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 81dbb8e9aa5..9022a1481aa 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -54,6 +54,9 @@ extern char datatoc_prvicons_png[];
extern int datatoc_splash_png_size;
extern char datatoc_splash_png[];
+extern int datatoc_splash_2x_png_size;
+extern char datatoc_splash_2x_png[];
+
extern int datatoc_bfont_pfb_size;
extern char datatoc_bfont_pfb[];
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 1eca5f91d40..ea479f8bada 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -78,7 +78,7 @@ void ED_operatortypes_gpencil(void);
/* drawgpencil.c */
void draw_gpencil_2dimage(const struct bContext *C);
-void draw_gpencil_view2d(const struct bContext *C, short onlyv2d);
+void draw_gpencil_view2d(const struct bContext *C, bool onlyv2d);
void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, bool only3d);
void gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 36f31897c7d..b15a83809f5 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -47,7 +47,7 @@ void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, s
struct Mask *ED_space_image_get_mask(struct SpaceImage *sima);
void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
-bool ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_image_color_sample(struct Scene *scene, struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
bool ED_space_image_has_buffer(struct SpaceImage *sima);
@@ -75,7 +75,7 @@ bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *
int ED_space_image_maskedit_poll(struct bContext *C);
int ED_space_image_maskedit_mask_poll(struct bContext *C);
-void ED_image_draw_info(struct Scene *scene, struct ARegion *ar, int color_manage, int use_default_view, int channels, int x, int y,
+void ED_image_draw_info(struct Scene *scene, struct ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf);
#endif /* __ED_IMAGE_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index c99c70377ab..c8365689803 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -56,7 +56,8 @@ typedef enum eEditKeyframes_Validate {
BEZT_OK_SELECTED,
BEZT_OK_VALUE,
BEZT_OK_VALUERANGE,
- BEZT_OK_REGION
+ BEZT_OK_REGION,
+ BEZT_OK_REGION_LASSO,
} eEditKeyframes_Validate;
/* ------------ */
@@ -98,6 +99,15 @@ typedef enum eEditKeyframes_Mirror {
MIRROR_KEYS_VALUE
} eEditKeyframes_Mirror;
+/* use with BEZT_OK_REGION_LASSO */
+struct KeyframeEdit_LassoData {
+ const rctf *rectf_scaled;
+ const rctf *rectf_view;
+ const int (*mcords)[2];
+ int mcords_tot;
+};
+
+
/* ************************************************ */
/* Non-Destuctive Editing API (keyframes_edit.c) */
@@ -207,6 +217,7 @@ KeyframeEditFunc ANIM_editkeyframes_select(short mode);
KeyframeEditFunc ANIM_editkeyframes_handles(short mode);
KeyframeEditFunc ANIM_editkeyframes_ipo(short mode);
KeyframeEditFunc ANIM_editkeyframes_keytype(short mode);
+KeyframeEditFunc ANIM_editkeyframes_easing(short mode);
/* -------- BezTriple Callbacks (Selection Map) ---------- */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 31b2c0673da..2065ae36351 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -108,7 +108,7 @@ int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
* Use this to insert a keyframe using the current value being keyframed, in the
* nominated F-Curve (no creation of animation data performed). Returns success.
*/
-short insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag);
+bool insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag);
/* -------- */
@@ -202,6 +202,9 @@ struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, con
/* Find KeyingSet type info given a name */
KeyingSetInfo *ANIM_keyingset_info_find_name(const char name[]);
+/* Find a given ID in the KeyingSet */
+bool ANIM_keyingset_find_id(struct KeyingSet *ks, ID *id);
+
/* for RNA type registrations... */
void ANIM_keyingset_info_register(struct KeyingSetInfo *ksi);
void ANIM_keyingset_info_unregister(struct Main *bmain, KeyingSetInfo *ksi);
@@ -224,7 +227,7 @@ struct KeyingSet *ANIM_get_keyingset_for_autokeying(struct Scene *scene, const c
struct EnumPropertyItem *ANIM_keying_sets_enum_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free);
/* Check if KeyingSet can be used in the current context */
-short ANIM_keyingset_context_ok_poll(struct bContext *C, struct KeyingSet *ks);
+bool ANIM_keyingset_context_ok_poll(struct bContext *C, struct KeyingSet *ks);
/* ************ Drivers ********************** */
@@ -244,28 +247,28 @@ struct FCurve *verify_driver_fcurve(struct ID *id, const char rna_path[], const
/* -------- */
/* Returns whether there is a driver in the copy/paste buffer to paste */
-short ANIM_driver_can_paste(void);
+bool ANIM_driver_can_paste(void);
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
*/
-short ANIM_add_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag, int type);
+int ANIM_add_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag, int type);
/* Main Driver Management API calls:
* Remove the driver for the specified property on the given ID block (if available)
*/
-short ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
+bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
/* Main Driver Management API calls:
* Make a copy of the driver for the specified property on the given ID block
*/
-short ANIM_copy_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
+bool ANIM_copy_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block or replace an existing one
* with the driver + driver-curve data from the buffer
*/
-short ANIM_paste_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
+bool ANIM_paste_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
/* ************ Auto-Keyframing ********************** */
/* Notes:
@@ -305,7 +308,7 @@ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter);
* in case some detail of the implementation changes...
* - frame: the value of this is quite often result of BKE_scene_frame_get()
*/
-short id_frame_has_keyframe(struct ID *id, float frame, short filter);
+bool id_frame_has_keyframe(struct ID *id, float frame, short filter);
/* filter flags for id_cfra_has_keyframe
*
@@ -324,8 +327,8 @@ typedef enum eAnimFilterFlags {
} eAnimFilterFlags;
/* utility funcs for auto keyframe */
-int ED_autokeyframe_object(struct bContext *C, struct Scene *scene, struct Object *ob, struct KeyingSet *ks);
-int ED_autokeyframe_pchan(struct bContext *C, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, struct KeyingSet *ks);
+bool ED_autokeyframe_object(struct bContext *C, struct Scene *scene, struct Object *ob, struct KeyingSet *ks);
+bool ED_autokeyframe_pchan(struct bContext *C, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, struct KeyingSet *ks);
/* Names for builtin keying sets so we don't confuse these with labels/text,
* defined in python script: keyingsets_builtins.py */
diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h
index cb065646f0a..76d36623b60 100644
--- a/source/blender/editors/include/ED_markers.h
+++ b/source/blender/editors/include/ED_markers.h
@@ -69,7 +69,7 @@ struct TimeMarker *ED_markers_get_first_selected(ListBase *markers);
/* called in screen_ops.c:ED_operatortypes_screen() */
void ED_operatortypes_marker(void);
/* called in screen_ops.c:ED_keymap_screen() */
-void ED_marker_keymap(struct wmKeyConfig *keyconf);
+void ED_keymap_marker(struct wmKeyConfig *keyconf);
/* called in animation editors - keymap defines */
void ED_marker_keymap_animedit_conflictfree(struct wmKeyMap *keymap);
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index d8fe14282e3..97fd553ea19 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -72,9 +72,9 @@ bool ED_mask_layer_shape_auto_key_all(struct Mask *mask, const int frame);
bool ED_mask_layer_shape_auto_key_select(struct Mask *mask, const int frame);
/* ----------- Mask AnimEdit API ------------------ */
-short ED_masklayer_frames_looper(struct MaskLayer *masklay, struct Scene *scene,
- short (*masklay_shape_cb)(struct MaskLayerShape *, struct Scene *));
-void ED_masklayer_make_cfra_list(struct MaskLayer *masklay, ListBase *elems, short onlysel);
+bool ED_masklayer_frames_looper(struct MaskLayer *masklay, struct Scene *scene,
+ short (*masklay_shape_cb)(struct MaskLayerShape *, struct Scene *));
+void ED_masklayer_make_cfra_list(struct MaskLayer *masklay, ListBase *elems, bool onlysel);
bool ED_masklayer_frame_select_check(struct MaskLayer *masklay);
void ED_masklayer_frame_select_set(struct MaskLayer *masklay, short mode);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 04f8dfc2d1b..ebc97c58e24 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -166,7 +166,7 @@ bool EDBM_selectmode_disable(struct Scene *scene, struct BMEditMesh *em,
const short selectmode_disable,
const short selectmode_fallback);
-void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
+void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const bool select);
void EDBM_select_toggle_all(struct BMEditMesh *em);
@@ -300,8 +300,9 @@ void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalcte
int join_mesh_exec(struct bContext *C, struct wmOperator *op);
int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
-intptr_t mesh_octree_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode);
-int mesh_mirrtopo_table(struct Object *ob, char mode);
+/* mirror lookup api */
+int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode);
+int ED_mesh_mirror_topo_table(struct Object *ob, char mode);
/* retrieves mirrored cache vert, or NULL if there isn't one.
* note: calling this without ensuring the mirror cache state
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 39d7ff3bc25..92dfe0c1805 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -107,7 +107,7 @@ void ED_node_composite_job(const struct bContext *C, struct bNodeTree *nodetree,
void ED_operatormacros_node(void);
/* node_view.c */
-int ED_space_node_color_sample(struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_node_color_sample(struct Scene *scene, struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
#endif /* __ED_NODE_H__ */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index e44dab7bff0..e7b52a49e8c 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -51,6 +51,7 @@ typedef struct NumInput {
/* NumInput.flag */
enum {
NUM_AFFECT_ALL = (1 << 0),
+ /* (1 << 9) and above are reserved for internal flags! */
};
/* NumInput.val_flag[] */
@@ -65,10 +66,19 @@ enum {
/*********************** NumInput ********************************/
+/* There are important things to note here for code using numinput:
+ * * Values passed to applyNumInput() should be valid and are stored as default ones (val_org), if it is not EDITED.
+ * * bool returned by applyNumInput should be used to decide whether to apply numinput-specific post-process to data.
+ * * *Once applyNumInput has been called*, hasNumInput returns a valid value to decide whether to use numinput
+ * as drawstr source or not (i.e. to call outputNumInput).
+ *
+ * Those two steps have to be separated (so do not use a common call to hasNumInput() to do both in the same time!).
+ */
+
void initNumInput(NumInput *n);
void outputNumInput(NumInput *n, char *str);
bool hasNumInput(const NumInput *n);
-void applyNumInput(NumInput *n, float *vec);
+bool applyNumInput(NumInput *n, float *vec);
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event);
#define NUM_MODAL_INCREMENT_UP 18
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index dae53213afb..5504b7e0352 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -110,7 +110,7 @@ void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *
void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap,
- const short do_connected);
+ const bool do_connected);
/* send your own notifier for select! */
void ED_base_object_select(struct Base *base, short mode);
@@ -162,7 +162,7 @@ void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene);
/* constraints */
struct ListBase *get_active_constraints(struct Object *ob);
-struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **pchan_r);
+struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan);
struct bConstraint *get_active_constraint(struct Object *ob);
void object_test_constraints(struct Object *ob);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5826bbc0d5b..cf3974c527c 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -56,6 +56,7 @@ void ED_region_do_draw(struct bContext *C, struct ARegion *ar);
void ED_region_exit(struct bContext *C, struct ARegion *ar);
void ED_region_pixelspace(struct ARegion *ar);
void ED_region_set(const struct bContext *C, struct ARegion *ar);
+void ED_region_update_rect(struct bContext *C, struct ARegion *ar);
void ED_region_init(struct bContext *C, struct ARegion *ar);
void ED_region_tag_redraw(struct ARegion *ar);
void ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
@@ -145,6 +146,7 @@ int ED_operator_node_active(struct bContext *C);
int ED_operator_node_editable(struct bContext *C);
int ED_operator_graphedit_active(struct bContext *C);
int ED_operator_sequencer_active(struct bContext *C);
+int ED_operator_sequencer_active_editable(struct bContext *C);
int ED_operator_image_active(struct bContext *C);
int ED_operator_nla_active(struct bContext *C);
int ED_operator_logic_active(struct bContext *C);
@@ -177,6 +179,12 @@ int ED_operator_posemode(struct bContext *C);
int ED_operator_mask(struct bContext *C);
+/* Cache display helpers */
+
+void ED_region_cache_draw_background(const struct ARegion *ar);
+void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y);
+void ED_region_cache_draw_cached_segments(const struct ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra);
+
/* default keymaps, bitflags */
#define ED_KEYMAP_UI 1
#define ED_KEYMAP_VIEW2D 2
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index ba69be5b4c0..8fcb228803b 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -45,16 +45,9 @@ void ED_operatortypes_sculpt(void);
void sculpt_get_redraw_planes(float planes[4][4], struct ARegion *ar,
struct RegionView3D *rv3d, struct Object *ob);
void ED_sculpt_get_average_stroke(struct Object *ob, float stroke[3]);
-int ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]);
-int ED_sculpt_mask_layers_ensure(struct Object *ob,
- struct MultiresModifierData *mmd);
+bool ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]);
int do_sculpt_mask_box_select(struct ViewContext *vc, struct rcti *rect, bool select, bool extend);
-enum {
- ED_SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
- ED_SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1)
-};
-
/* paint_ops.c */
void ED_operatortypes_paint(void);
void ED_keymap_paint(struct wmKeyConfig *keyconf);
@@ -67,8 +60,11 @@ typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
typedef void (*UndoFreeCb)(struct ListBase *lb);
int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
+void ED_undo_paint_step_num(struct bContext *C, int type, int num);
+const char *ED_undo_paint_get_name(int type, int nr, int *active);
void ED_undo_paint_free(void);
int ED_undo_paint_valid(int type, const char *name);
+bool ED_undo_paint_empty(int type);
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free);
void ED_undo_paint_push_end(int type);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 35f12a47f82..41ff9b88da9 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -103,7 +103,7 @@ enum TfmMode {
* returns 1 if successful, 0 otherwise (usually means there's no selection)
* (if 0 is returns, *vec is unmodified)
* */
-int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
+bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
struct TransInfo;
struct ScrArea;
diff --git a/source/blender/editors/include/ED_transverts.h b/source/blender/editors/include/ED_transverts.h
index 1df89b0a8f9..9005d55feff 100644
--- a/source/blender/editors/include/ED_transverts.h
+++ b/source/blender/editors/include/ED_transverts.h
@@ -36,19 +36,21 @@ struct Object;
typedef struct TransVert {
float *loc;
float oldloc[3], maploc[3];
- float *val, oldval;
+ float normal[3];
int flag;
} TransVert;
typedef struct TransVertStore {
struct TransVert *transverts;
int transverts_tot;
+ int mode;
} TransVertStore;
void ED_transverts_create_from_obedit(TransVertStore *tvs, struct Object *obedit, const int mode);
void ED_transverts_update_obedit(TransVertStore *tvs, struct Object *obedit);
void ED_transverts_free(TransVertStore *tvs);
bool ED_transverts_check_obedit(Object *obedit);
+int ED_transverts_poll(struct bContext *C);
/* currently only used for bmesh index values */
enum {
@@ -59,12 +61,15 @@ enum {
/* mode flags: */
enum {
- TM_ALL_JOINTS = 1, /* all joints (for bones only) */
- TM_SKIP_HANDLES = 2 /* skip handles when control point is selected (for curves only) */
+ TM_ALL_JOINTS = (1 << 0), /* all joints (for bones only) */
+ TM_SKIP_HANDLES = (1 << 1), /* skip handles when control point is selected (for curves only) */
+ TM_CALC_NORMALS = (1 << 2), /* fill in normals when available */
};
-
- /* SELECT == (1 << 0) */
-#define TX_VERT_USE_MAPLOC (1 << 1)
+enum {
+ /* SELECT == (1 << 0) */
+ TX_VERT_USE_MAPLOC = (1 << 1),
+ TX_VERT_USE_NORMAL = (1 << 2), /* avoid nonzero check */
+};
#endif /* __ED_TRANSVERTS_H__ */
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index a3a4e80b3a6..366421722ba 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -80,13 +80,6 @@ void undo_editmode_push(struct bContext *C, const char *name,
void undo_editmode_clear(void);
-/* crazyspace.c */
-float (*crazyspace_get_mapped_editverts(struct Scene *scene, struct Object *obedit))[3];
-void crazyspace_set_quats_editmesh(struct BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4]);
-void crazyspace_set_quats_mesh(struct Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4]);
-int sculpt_get_first_deform_matrices(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
-void crazyspace_build_sculpt(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]);
-
/* cut-paste buffer free */
void ED_clipboard_posebuf_free(void);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 3eb8a41d95d..74c3a6339c8 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -57,7 +57,8 @@ void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]);
-bool ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **ima, struct ImageUser **iuser, struct bNode **node);
+bool ED_object_get_active_image(struct Object *ob, int mat_nr,
+ struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node);
void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int mat_nr, struct Image *ima);
bool ED_uvedit_test(struct Object *obedit);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 0fc31afb4f6..f9df2ead79d 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -96,6 +96,8 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist
void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
+void ED_view3d_lastview_store(struct RegionView3D *rv3d);
+
/* Depth buffer */
void ED_view3d_depth_update(struct ARegion *ar);
float ED_view3d_depth_read_cached(struct ViewContext *vc, int x, int y);
@@ -270,6 +272,8 @@ bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], con
#define MAXPICKBUF 10000
short view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, struct rcti *input);
+/* view3d_select.c */
+float ED_view3d_select_dist_px(void);
void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc);
void view3d_operator_needs_opengl(const struct bContext *C);
void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
@@ -310,6 +314,7 @@ struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
+char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
char ED_view3d_lock_view_from_index(int index);
bool ED_view3d_lock(struct RegionView3D *rv3d);
@@ -323,8 +328,9 @@ bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d);
/* camera lock functions */
bool ED_view3d_camera_lock_check(struct View3D *v3d, struct RegionView3D *rv3d);
/* copy the camera to the view before starting a view transformation */
+void ED_view3d_camera_lock_init_ex(struct View3D *v3d, struct RegionView3D *rv3d, const bool calc_dist);
void ED_view3d_camera_lock_init(struct View3D *v3d, struct RegionView3D *rv3d);
-/* copy the view to the camera, return TRUE if */
+/* copy the view to the camera, return true if */
bool ED_view3d_camera_lock_sync(struct View3D *v3d, struct RegionView3D *rv3d);
void ED_view3D_lock_clear(struct View3D *v3d);
@@ -336,6 +342,7 @@ void ED_view3D_background_image_clear(struct View3D *v3d);
#define VIEW3D_MARGIN 1.4f
#define VIEW3D_DIST_FALLBACK 1.0f
float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback);
+void ED_view3d_distance_set(struct RegionView3D *rv3d, const float dist);
float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit);
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index dcc526b81d2..c776026a811 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -258,8 +258,8 @@ DEF_ICON(BOIDS)
DEF_ICON(STRANDS)
DEF_ICON(LIBRARY_DATA_INDIRECT)
DEF_ICON(GREASEPENCIL)
+DEF_ICON(LINE_DATA)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK083)
DEF_ICON(BLANK084)
#endif
DEF_ICON(GROUP_BONE)
@@ -616,9 +616,7 @@ DEF_ICON(NEXT_KEYFRAME)
DEF_ICON(PLAY_AUDIO)
DEF_ICON(PLAY_REVERSE)
DEF_ICON(PREVIEW_RANGE)
-#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK180)
-#endif
+DEF_ICON(ACTION_TWEAK)
DEF_ICON(PMARKER_ACT)
DEF_ICON(PMARKER_SEL)
DEF_ICON(PMARKER)
@@ -640,25 +638,25 @@ DEF_ICON(SOLO_OFF)
DEF_ICON(SOLO_ON)
DEF_ICON(FRAME_PREV)
DEF_ICON(FRAME_NEXT)
+DEF_ICON(NLA_PUSHDOWN)
+DEF_ICON(IPO_CONSTANT)
+DEF_ICON(IPO_LINEAR)
+DEF_ICON(IPO_BEZIER)
+DEF_ICON(IPO_SINE)
+DEF_ICON(IPO_QUAD)
+DEF_ICON(IPO_CUBIC)
+DEF_ICON(IPO_QUART)
+DEF_ICON(IPO_QUINT)
+DEF_ICON(IPO_EXPO)
+DEF_ICON(IPO_CIRC)
+DEF_ICON(IPO_BOUNCE)
+DEF_ICON(IPO_ELASTIC)
+DEF_ICON(IPO_BACK)
+DEF_ICON(IPO_EASE_IN)
+DEF_ICON(IPO_EASE_OUT)
+DEF_ICON(IPO_EASE_IN_OUT)
#ifndef DEF_ICON_BLANK_SKIP
/* available */
- DEF_ICON(BLANK186)
- DEF_ICON(BLANK187)
- DEF_ICON(BLANK188)
- DEF_ICON(BLANK189)
- DEF_ICON(BLANK190)
- DEF_ICON(BLANK191)
- DEF_ICON(BLANK192)
- DEF_ICON(BLANK193)
- DEF_ICON(BLANK194)
- DEF_ICON(BLANK195)
- DEF_ICON(BLANK196)
- DEF_ICON(BLANK197)
- DEF_ICON(BLANK198)
- DEF_ICON(BLANK199)
- DEF_ICON(BLANK200)
- DEF_ICON(BLANK201)
- DEF_ICON(BLANK202)
DEF_ICON(BLANK203)
DEF_ICON(BLANK204)
DEF_ICON(BLANK205)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 0fa123291b7..bbe9d054928 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -176,6 +176,8 @@ enum {
UI_BUT_COLOR_CUBIC = (1 << 23), /* cubic saturation for the color wheel */
UI_BUT_LIST_ITEM = (1 << 24), /* This but is "inside" a list item (currently used to change theme colors). */
UI_BUT_DRAG_MULTI = (1 << 25), /* edit this button as well as the active button (not just dragging) */
+ UI_BUT_SCA_LINK_GREY = (1 << 26), /* used to flag if sca links shoud be grey out */
+ UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
};
#define UI_PANEL_WIDTH 340
@@ -188,8 +190,6 @@ enum {
* (except for the 'align' ones)!
*/
enum {
- /* draw enum-like up/down arrows for button */
- UI_BUT_DRAW_ENUM_ARROWS = (1 << 0),
/* Text and icon alignment (by default, they are centered). */
UI_BUT_TEXT_LEFT = (1 << 1),
UI_BUT_ICON_LEFT = (1 << 2),
@@ -275,6 +275,7 @@ typedef enum {
SEARCH_MENU_UNLINK = (52 << 9),
NODESOCKET = (53 << 9),
SEPRLINE = (54 << 9),
+ GRIP = (55 << 9),
} eButType;
#define BUTTYPE (63 << 9)
@@ -288,6 +289,7 @@ typedef enum {
#define UI_GRAD_V 5
#define UI_GRAD_V_ALT 9
+#define UI_GRAD_L_ALT 10
/* Drawing
*
@@ -435,7 +437,7 @@ void uiButSetDragName(uiBut *but, const char *name);
void uiButSetDragValue(uiBut *but);
void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
-int UI_but_active_drop_name(struct bContext *C);
+bool UI_but_active_drop_name(struct bContext *C);
void uiButSetFlag(uiBut *but, int flag);
void uiButClearFlag(uiBut *but, int flag);
@@ -836,7 +838,8 @@ void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char
struct PointerRNA *root_ptr, const char *text);
uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
-void uiTemplatePreview(uiLayout *layout, struct ID *id, int show_buttons, struct ID *parent, struct MTex *slot);
+void uiTemplatePreview(uiLayout *layout, struct bContext *C, struct ID *id, int show_buttons, struct ID *parent,
+ struct MTex *slot, const char *preview_id);
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int expand);
void uiTemplateIconView(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 1d4d61afef9..0f11994e2d1 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -275,7 +275,8 @@ enum {
TH_INFO_INFO,
TH_INFO_INFO_TEXT,
TH_INFO_DEBUG,
- TH_INFO_DEBUG_TEXT
+ TH_INFO_DEBUG_TEXT,
+ TH_VIEW_OVERLAY,
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 3bae255f297..cb7cf3ee404 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -34,6 +34,8 @@
#ifndef __UI_VIEW2D_H__
#define __UI_VIEW2D_H__
+#include "BLI_compiler_attrs.h"
+
/* ------------------------------------------ */
/* Settings and Defines: */
@@ -190,31 +192,44 @@ void UI_view2d_listview_visible_cells(struct View2D *v2d, float columnwidth, flo
int *row_min, int *row_max);
/* coordinate conversion */
-void UI_view2d_region_to_view(struct View2D *v2d, float x, float y, float *viewx, float *viewy);
-void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *regionx, int *regiony);
-void UI_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, int *regionx, int *region_y);
-void UI_view2d_to_region_float(struct View2D *v2d, float x, float y, float *regionx, float *regiony);
+float UI_view2d_region_to_view_x(struct View2D *v2d, float x);
+float UI_view2d_region_to_view_y(struct View2D *v2d, float y);
+void UI_view2d_region_to_view(struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL();
+void UI_view2d_region_to_view_rctf(struct View2D *v2d, const struct rctf *rect_src, struct rctf *rect_dst) ATTR_NONNULL();
+
+float UI_view2d_view_to_region_x(struct View2D *v2d, float x);
+float UI_view2d_view_to_region_y(struct View2D *v2d, float y);
+bool UI_view2d_view_to_region_clip(struct View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL();
+
+void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL();
+void UI_view2d_view_to_region_fl(struct View2D *v2d, float x, float y, float *r_region_x, float *r_region_y) ATTR_NONNULL();
+void UI_view2d_view_to_region_rcti(struct View2D *v2d, const struct rctf *rect_src, struct rcti *rect_dst) ATTR_NONNULL();
+bool UI_view2d_view_to_region_rcti_clip(struct View2D *v2d, const struct rctf *rect_src, struct rcti *rect_dst) ATTR_NONNULL();
/* utilities */
struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
-void UI_view2d_getscale(struct View2D *v2d, float *x, float *y);
-void UI_view2d_getscale_inverse(struct View2D *v2d, float *x, float *y);
+void UI_view2d_scale_get(struct View2D *v2d, float *x, float *y);
+void UI_view2d_scale_get_inverse(struct View2D *v2d, float *x, float *y);
+
+void UI_view2d_center_get(struct View2D *v2d, float *x, float *y);
+void UI_view2d_center_set(struct View2D *v2d, float x, float y);
-void UI_view2d_getcenter(struct View2D *v2d, float *x, float *y);
-void UI_view2d_setcenter(struct View2D *v2d, float x, float y);
+void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac);
short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y);
/* cached text drawing in v2d, to allow pixel-aligned draw as post process */
-void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, const char col[4]);
-void UI_view2d_text_cache_rectf(struct View2D *v2d, const struct rctf *rect, const char *str, const char col[4]);
+void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y,
+ const char *str, size_t str_len, const char col[4]);
+void UI_view2d_text_cache_add_rectf(struct View2D *v2d, const struct rctf *rect_view,
+ const char *str, size_t str_len, const char col[4]);
void UI_view2d_text_cache_draw(struct ARegion *ar);
/* operators */
-void UI_view2d_operatortypes(void);
-void UI_view2d_keymap(struct wmKeyConfig *keyconf);
+void ED_operatortypes_view2d(void);
+void ED_keymap_view2d(struct wmKeyConfig *keyconf);
void UI_view2d_smooth_view(struct bContext *C, struct ARegion *ar,
const struct rctf *cur, const int smooth_viewtx);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 9f93f2aa6f4..3f8e643988f 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -45,7 +45,6 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
-#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -100,6 +99,19 @@ bool ui_block_is_menu(const uiBlock *block)
((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
}
+static bool ui_is_but_unit_radians_ex(UnitSettings *unit, const int unit_type)
+{
+ return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION);
+}
+
+static bool ui_is_but_unit_radians(const uiBut *but)
+{
+ UnitSettings *unit = but->block->unit;
+ const int unit_type = uiButGetUnitType(but);
+
+ return ui_is_but_unit_radians_ex(unit, unit_type);
+}
+
/* ************* window matrix ************** */
void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y)
@@ -209,43 +221,41 @@ void ui_block_translate(uiBlock *block, int x, int y)
static void ui_text_bounds_block(uiBlock *block, float offset)
{
uiStyle *style = UI_GetStyle();
- uiBut *bt;
- int i = 0, j, x1addval = offset, nextcol;
- int lastcol = 0, col = 0;
-
+ uiBut *bt, *init_col_bt, *col_bt;
+ int i = 0, j, x1addval = offset;
+
uiStyleFontSet(&style->widget);
-
- for (bt = block->buttons.first; bt; bt = bt->next) {
+
+ for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) {
if (!ELEM(bt->type, SEPR, SEPRLINE)) {
j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
- if (j > i) i = j;
+ if (j > i)
+ i = j;
}
- if (bt->next && bt->rect.xmin < bt->next->rect.xmin)
- lastcol++;
- }
+ if (bt->next && bt->rect.xmin < bt->next->rect.xmin) {
+ /* End of this column, and it’s not the last one. */
+ for (col_bt = init_col_bt; col_bt->prev != bt; col_bt = col_bt->next) {
+ col_bt->rect.xmin = x1addval;
+ col_bt->rect.xmax = x1addval + i + block->bounds;
- /* cope with multi collumns */
- bt = block->buttons.first;
- while (bt) {
- nextcol = (bt->next && bt->rect.xmin < bt->next->rect.xmin);
-
- bt->rect.xmin = x1addval;
- bt->rect.xmax = bt->rect.xmin + i + block->bounds;
-
- if (col == lastcol) {
- bt->rect.xmax = max_ff(bt->rect.xmax, offset + block->minbounds);
- }
+ ui_check_but(col_bt); /* clips text again */
+ }
- ui_check_but(bt); /* clips text again */
-
- if (nextcol) {
+ /* And we prepare next column. */
x1addval += i + block->bounds;
- col++;
+ i = 0;
+ init_col_bt = col_bt;
}
-
- bt = bt->next;
+ }
+
+ /* Last column. */
+ for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) {
+ col_bt->rect.xmin = x1addval;
+ col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds);
+
+ ui_check_but(col_bt); /* clips text again */
}
}
@@ -433,10 +443,15 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max
static int ui_but_float_precision(uiBut *but, double value)
{
- int prec;
+ int prec = (int)but->a2;
- /* first check if prec is 0 and fallback to a simple default */
- if ((prec = (int)but->a2) == -1) {
+ /* first check for various special cases:
+ * * If button is radians, we want additional precision (see T39861).
+ * * If prec is not set, we fallback to a simple default */
+ if (ui_is_but_unit_radians(but) && prec < 5) {
+ prec = 5;
+ }
+ else if (prec == -1) {
prec = (but->hardmax < 10.001f) ? 3 : 2;
}
@@ -447,7 +462,7 @@ static int ui_but_float_precision(uiBut *but, double value)
/* link line drawing is not part of buttons or theme.. so we stick with it here */
-static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines)
+static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines, int dashInactiveLines)
{
rcti rect;
@@ -458,11 +473,12 @@ static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines)
rect.xmax = BLI_rctf_cent_x(&line->to->rect);
rect.ymax = BLI_rctf_cent_y(&line->to->rect);
- if (line->flag & UI_SELECT)
- gpuGray3f(0.392f);
+ if (dashInactiveLines)
+ UI_ThemeColor(TH_GRID);
+ else if (line->flag & UI_SELECT)
else if (highlightActiveLines && ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE)))
UI_ThemeColor(TH_TEXT_HI);
- else
+ else
gpuColor3P(CPACK_BLACK);
ui_draw_link_bezier(&rect);
@@ -473,7 +489,8 @@ static void ui_draw_links(uiBlock *block)
uiBut *but;
uiLinkLine *line;
- /* Draw the inactive lines (lines with neither button being hovered over).
+ /* Draw the grey out lines. Do this first so they appear at the
+ * bottom of inactive or active lines.
* As we go, remember if we see any active or selected lines. */
bool found_selectline = false;
bool found_activeline = false;
@@ -481,8 +498,10 @@ static void ui_draw_links(uiBlock *block)
for (but = block->buttons.first; but; but = but->next) {
if (but->type == LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
- if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE))
- ui_draw_linkline(line, 0);
+ if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) {
+ if (line->deactive)
+ ui_draw_linkline(line, 0, true);
+ }
else
found_activeline = true;
@@ -492,14 +511,26 @@ static void ui_draw_links(uiBlock *block)
}
}
+ /* Draw the inactive lines (lines with neither button being hovered over) */
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->type == LINK && but->link) {
+ for (line = but->link->lines.first; line; line = line->next) {
+ if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) {
+ if (!line->deactive)
+ ui_draw_linkline(line, 0, false);
+ }
+ }
+ }
+ }
+
/* Draw any active lines (lines with either button being hovered over).
- * Do this last so they appear on top of inactive lines. */
+ * Do this last so they appear on top of inactive and grey out lines. */
if (found_activeline) {
for (but = block->buttons.first; but; but = but->next) {
if (but->type == LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
if ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE))
- ui_draw_linkline(line, !found_selectline);
+ ui_draw_linkline(line, !found_selectline, false);
}
}
}
@@ -856,11 +887,12 @@ static void ui_menu_block_set_keyaccels(uiBlock *block)
void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_strip)
{
- if (do_strip) {
- char *cpoin = strchr(but->str, UI_SEP_CHAR);
+ if (do_strip && (but->flag & UI_BUT_HAS_SEP_CHAR)) {
+ char *cpoin = strrchr(but->str, UI_SEP_CHAR);
if (cpoin) {
*cpoin = '\0';
}
+ but->flag &= ~UI_BUT_HAS_SEP_CHAR;
}
/* without this, just allow stripping of the shortcut */
@@ -879,6 +911,7 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
butstr_orig, shortcut_str);
MEM_freeN(butstr_orig);
but->str = but->strdata;
+ but->flag |= UI_BUT_HAS_SEP_CHAR;
ui_check_but(but);
}
}
@@ -1271,7 +1304,7 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
*/
int ui_is_but_push_ex(uiBut *but, double *value)
{
- int is_push = false;
+ int is_push = 0;
if (but->bit) {
const bool state = ELEM3(but->type, TOGN, ICONTOGN, OPTIONN) ? false : true;
@@ -1357,7 +1390,7 @@ static uiBut *ui_find_inlink(uiBlock *block, void *poin)
return NULL;
}
-static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt)
+static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deactive)
{
uiLinkLine *line;
@@ -1365,6 +1398,7 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt)
BLI_addtail(listb, line);
line->from = but;
line->to = bt;
+ line->deactive = deactive;
}
uiBut *uiFindInlink(uiBlock *block, void *poin)
@@ -1391,14 +1425,25 @@ void uiComposeLinks(uiBlock *block)
for (a = 0; a < *(link->totlink); a++) {
bt = ui_find_inlink(block, (*ppoin)[a]);
if (bt) {
- ui_add_link_line(&link->lines, but, bt);
+ if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) {
+ ui_add_link_line(&link->lines, but, bt, true);
+ }
+ else {
+ ui_add_link_line(&link->lines, but, bt, false);
+ }
+
}
}
}
else if (link->poin) {
bt = ui_find_inlink(block, *(link->poin) );
if (bt) {
- ui_add_link_line(&link->lines, but, bt);
+ if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) {
+ ui_add_link_line(&link->lines, but, bt, true);
+ }
+ else {
+ ui_add_link_line(&link->lines, but, bt, false);
+ }
}
}
}
@@ -1496,14 +1541,14 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
}
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
- char *cp = (char *)but->poin;
+ const char *cp = (char *)but->poin;
vec[0] = ((float)cp[0]) / 255.0f;
vec[1] = ((float)cp[1]) / 255.0f;
vec[2] = ((float)cp[2]) / 255.0f;
}
else if (but->pointype == UI_BUT_POIN_FLOAT) {
- float *fp = (float *)but->poin;
+ const float *fp = (float *)but->poin;
copy_v3_v3(vec, fp);
}
else {
@@ -1591,7 +1636,7 @@ bool ui_is_but_unit(const uiBut *but)
return false;
#if 1 /* removed so angle buttons get correct snapping */
- if (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION)
+ if (ui_is_but_unit_radians_ex(unit, unit_type))
return false;
#endif
@@ -1802,6 +1847,21 @@ int ui_get_but_string_max_length(uiBut *but)
return UI_MAX_DRAW_STR;
}
+uiBut *ui_get_but_drag_multi_edit(uiBut *but)
+{
+ uiBut *but_iter;
+
+ BLI_assert(but->flag & UI_BUT_DRAG_MULTI);
+
+ for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) {
+ if (but_iter->editstr) {
+ break;
+ }
+ }
+
+ return but_iter;
+}
+
static double ui_get_but_scale_unit(uiBut *but, double value)
{
UnitSettings *unit = but->block->unit;
@@ -1854,7 +1914,7 @@ void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, bool pad, int float_precision)
{
UnitSettings *unit = but->block->unit;
- int do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
+ const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
int unit_type = uiButGetUnitType(but);
int precision;
@@ -1865,7 +1925,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va
/* Sanity checks */
precision = (int)but->a2;
if (precision > UI_PRECISION_FLOAT_MAX) precision = UI_PRECISION_FLOAT_MAX;
- else if (precision == -1) precision = 2;
+ else if (precision == -1) precision = 2;
}
else {
precision = float_precision;
@@ -1893,7 +1953,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
}
/**
- * \param float_precision For number buttons the precission to use or -1 to fallback to the button default.
+ * \param float_precision For number buttons the precision to use or -1 to fallback to the button default.
*/
void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
{
@@ -2422,8 +2482,8 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
/* window matrix and aspect */
if (region && region->swinid) {
- wm_subwindow_getmatrix(window, region->swinid, block->winmat);
- wm_subwindow_getsize(window, region->swinid, &getsizex, &getsizey);
+ wm_subwindow_matrix_get(window, region->swinid, block->winmat);
+ wm_subwindow_size_get(window, region->swinid, &getsizex, &getsizey);
block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
}
@@ -2431,8 +2491,8 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
/* no subwindow created yet, for menus for example, so we
* use the main window instead, since buttons are created
* there anyway */
- wm_subwindow_getmatrix(window, window->screen->mainwin, block->winmat);
- wm_subwindow_getsize(window, window->screen->mainwin, &getsizex, &getsizey);
+ wm_subwindow_matrix_get(window, window->screen->mainwin, block->winmat);
+ wm_subwindow_size_get(window, window->screen->mainwin, &getsizex, &getsizey);
block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
block->auto_open = true;
@@ -2498,6 +2558,25 @@ void ui_check_but(uiBut *but)
/* name: */
switch (but->type) {
+
+ case MENU:
+ if (BLI_rctf_size_x(&but->rect) > 24.0f) {
+ /* only needed for menus in popup blocks that don't recreate buttons on redraw */
+ if (but->block->flag & UI_BLOCK_LOOP) {
+ if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) {
+ int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ const char *buf;
+ if (RNA_property_enum_name_gettexted(but->block->evil_C,
+ &but->rnapoin, but->rnaprop, value, &buf))
+ {
+ BLI_strncpy(but->str, buf, sizeof(but->strdata));
+ }
+ }
+ }
+ BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr));
+ }
+ break;
+
case NUM:
case NUMSLI:
@@ -2624,7 +2703,7 @@ void ui_check_but(uiBut *but)
/* if we are doing text editing, this will override the drawstr */
if (but->editstr)
- BLI_strncpy(but->drawstr, but->editstr, UI_MAX_DRAW_STR);
+ but->drawstr[0] = '\0';
/* text clipping moved to widget drawing code itself */
}
@@ -2644,9 +2723,17 @@ void uiBlockBeginAlign(uiBlock *block)
static bool buts_are_horiz(uiBut *but1, uiBut *but2)
{
float dx, dy;
-
- dx = fabs(but1->rect.xmax - but2->rect.xmin);
- dy = fabs(but1->rect.ymin - but2->rect.ymax);
+
+ /* simple case which can fail if buttons shift apart
+ * with proportional layouts, see: [#38602] */
+ if ((but1->rect.ymin == but2->rect.ymin) &&
+ (but1->rect.xmin != but2->rect.xmin))
+ {
+ return true;
+ }
+
+ dx = fabsf(but1->rect.xmax - but2->rect.xmin);
+ dy = fabsf(but1->rect.ymin - but2->rect.ymax);
return (dx <= dy);
}
@@ -2959,7 +3046,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
/* keep track of UI_interface.h */
- if (ELEM10(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR, SEPRLINE)) {}
+ if (ELEM11(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR, SEPRLINE, GRIP)) {}
else if (but->type >= SEARCH_MENU) {}
else but->flag |= UI_BUT_UNDO;
@@ -3054,7 +3141,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
column_end = totitems;
for (b = a + 1; b < totitems; b++) {
- item = &item_array[ b];
+ item = &item_array[b];
/* new column on N rows or on separation label */
if (((b - a) % rows == 0) || (!item->identifier[0] && item->name)) {
@@ -3129,59 +3216,58 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
}
/* use rna values if parameters are not specified */
- if (!str) {
- if (type == MENU && proptype == PROP_ENUM) {
- EnumPropertyItem *item;
- int totitem, value;
- bool free;
- int i;
+ if ((proptype == PROP_ENUM) && ELEM3(type, MENU, ROW, LISTROW)) {
+ /* MENU is handled a little differently here */
+ EnumPropertyItem *item;
+ int value;
+ bool free;
+ int i;
- RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free);
+
+ if (type == MENU) {
value = RNA_property_enum_get(ptr, prop);
- i = RNA_enum_from_value(item, value);
- if (i != -1) {
- str = item[i].name;
- icon = item[i].icon;
- }
- else {
- str = "";
- }
+ }
+ else {
+ value = (int)max;
+ }
- if (free) {
- MEM_freeN(item);
- }
+ i = RNA_enum_from_value(item, value);
+ if (i != -1) {
+ if (!str) {
+ str = item[i].name;
#ifdef WITH_INTERNATIONAL
- str = CTX_IFACE_(RNA_property_translation_context(prop), str);
+ str = CTX_IFACE_(RNA_property_translation_context(prop), str);
#endif
+ }
- func = ui_def_but_rna__menu;
+ icon = item[i].icon;
}
- else if (ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) {
- EnumPropertyItem *item, *item_array = NULL;
- bool free;
-
- /* get untranslated, then translate the single string we need */
- RNA_property_enum_items(block->evil_C, ptr, prop, &item_array, NULL, &free);
- for (item = item_array; item->identifier; item++) {
- if (item->identifier[0] && item->value == (int)max) {
- str = CTX_IFACE_(RNA_property_translation_context(prop), item->name);
- icon = item->icon;
- break;
+ else {
+ if (!str) {
+ if (type == MENU) {
+ str = "";
+ }
+ else {
+ str = RNA_property_ui_name(prop);
}
}
+ }
- if (!str) {
- str = RNA_property_ui_name(prop);
- }
- if (free) {
- MEM_freeN(item_array);
- }
+ if (type == MENU) {
+ func = ui_def_but_rna__menu;
}
- else {
+
+ if (free) {
+ MEM_freeN(item);
+ }
+ }
+ else {
+ if (!str) {
str = RNA_property_ui_name(prop);
- icon = RNA_property_ui_icon(prop);
}
+ icon = RNA_property_ui_icon(prop);
}
if (!tip && proptype != PROP_ENUM)
@@ -3240,9 +3326,15 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
if (icon) {
but->icon = (BIFIconID)icon;
but->flag |= UI_HAS_ICON;
- but->drawflag |= UI_BUT_ICON_LEFT;
+ if (str[0]) {
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
}
+ if ((type == MENU) && (but->dt == UI_EMBOSSP)) {
+ but->flag |= UI_ICON_SUBMENU;
+ }
+
if (!RNA_property_editable(&but->rnapoin, prop)) {
ui_def_but_rna__disable(but);
}
@@ -4175,22 +4267,11 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
if (type == BUT_GET_LABEL) {
if (but->str) {
- /* Menu labels can have some complex formating stuff marked by pipes or %t, we don't want those here! */
- const char *tc1, *tc2;
-
- tc1 = strstr(but->str, "%t");
- tc2 = strstr(but->str, UI_SEP_CHAR_S);
-
- if (tc2 && (!tc1 || tc1 > tc2))
- tc1 = tc2;
-
- if (tc1)
- tmp = BLI_strdupn(but->str, tc1 - but->str);
- else
- tmp = BLI_strdup(but->str);
+ tmp = BLI_strdup(but->str);
}
- else
+ else {
type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */
+ }
}
else if (type == BUT_GET_TIP) {
if (but->tip && but->tip[0])
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index d44802803da..f0f08358013 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -117,10 +117,19 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str)
if (fcu && driven) {
driver = fcu->driver;
- if (driver && driver->type == DRIVER_TYPE_PYTHON) {
+ if (driver && (driver->type == DRIVER_TYPE_PYTHON)) {
BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
+
+ /* tag driver as needing to be recompiled */
driver->flag |= DRIVER_FLAG_RECOMPILE;
+
+ /* clear invalid flags which may prevent this from working */
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ fcu->flag &= ~FCURVE_DISABLED;
+
+ /* this notifier should update the Graph Editor and trigger depsgraph refresh? */
WM_event_add_notifier(but->block->evil_C, NC_ANIMATION | ND_KEYFRAME, NULL);
+
return true;
}
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 1ebf3e8f6c4..80e4b75315b 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -478,28 +478,9 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
static void draw_scope_end(const rctf *rect, GLint *scissor)
{
- float scaler_x1, scaler_x2;
-
/* restore scissortest */
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
- /* scale widget */
- scaler_x1 = rect->xmin + BLI_rctf_size_x(rect) / 2 - SCOPE_RESIZE_PAD;
- scaler_x2 = rect->xmin + BLI_rctf_size_x(rect) / 2 + SCOPE_RESIZE_PAD;
-
- gpuImmediateFormat_C4_V2(); // DOODLE: fixed number of colored lines
- gpuBegin(GL_LINES);
-
- gpuColor4P(CPACK_BLACK, 0.250f);
- gpuAppendLinef(scaler_x1, rect->ymin - 4, scaler_x2, rect->ymin - 4);
- gpuAppendLinef(scaler_x1, rect->ymin - 7, scaler_x2, rect->ymin - 7);
-
- gpuColor4P(CPACK_WHITE, 0.250f);
- gpuAppendLinef(scaler_x1, rect->ymin - 5, scaler_x2, rect->ymin - 5);
- gpuAppendLinef(scaler_x1, rect->ymin - 8, scaler_x2, rect->ymin - 8);
-
- gpuEnd();
- gpuImmediateUnformat();
/* outline */
gpuColor4P(CPACK_BLACK, 0.500f);
@@ -508,7 +489,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
}
static void histogram_draw_one(float r, float g, float b, float alpha,
- float x, float y, float w, float h, float *data, int res, const bool is_line)
+ float x, float y, float w, float h, const float *data, int res, const bool is_line)
{
int i;
@@ -592,7 +573,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
rect.xmin = (float)recti->xmin + 1;
rect.xmax = (float)recti->xmax - 1;
- rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
+ rect.ymin = (float)recti->ymin + 1;
rect.ymax = (float)recti->ymax - 1;
w = BLI_rctf_size_x(&rect);
@@ -646,7 +627,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
gpuImmediateUnformat();
- /* outline, scale gripper */
+ /* outline */
draw_scope_end(&rect, scissor);
}
@@ -668,7 +649,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
rect.xmin = (float)recti->xmin + 1;
rect.xmax = (float)recti->xmax - 1;
- rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
+ rect.ymin = (float)recti->ymin + 1;
rect.ymax = (float)recti->ymax - 1;
if (scopes->wavefrm_yfac < 0.5f)
@@ -693,7 +674,6 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
gpuColor4P(CPACK_BLACK, 0.300f);
uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_TRIANGLE_FAN, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
-
/* need scissor test, waveform can draw outside of boundary */
gpuGetViewport(scissor);
@@ -828,24 +808,23 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
gpuDrawLinef(rect.xmin + w + 2 + c * 2, min, rect.xmin + w + 2 + c * 2, max); // DOODLE: single line
}
}
-
gpuImmediateUnformat();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* reset blender default */
}
- /* outline, scale gripper */
+ /* outline */
draw_scope_end(&rect, scissor);
}
static float polar_to_x(float center, float diam, float ampli, float angle)
{
- return center + diam *ampli * cosf(angle);
+ return center + diam * ampli * cosf(angle);
}
static float polar_to_y(float center, float diam, float ampli, float angle)
{
- return center + diam *ampli * sinf(angle);
+ return center + diam * ampli * sinf(angle);
}
static void vectorscope_draw_target(float centerx, float centery, float diam, const float colf[3])
@@ -917,7 +896,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
rect.xmin = (float)recti->xmin + 1;
rect.xmax = (float)recti->xmax - 1;
- rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
+ rect.ymin = (float)recti->ymin + 1;
rect.ymax = (float)recti->ymax - 1;
w = BLI_rctf_size_x(&rect);
@@ -998,19 +977,174 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
}
gpuImmediateUnformat();
-
- /* outline, scale gripper */
+
+ /* outline */
draw_scope_end(&rect, scissor);
glDisable(GL_BLEND);
}
+static void ui_draw_colorband_handle_tri_hlight(float x1, float y1, float halfwidth, float height)
+{
+ float v[2];
+
+ glEnable(GL_LINE_SMOOTH);
+
+ glBegin(GL_LINE_STRIP);
+ copy_v2_fl2(v, x1 + halfwidth, y1);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x1, y1 + height);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x1 - halfwidth, y1);
+ glVertex2fv(v);
+ glEnd();
+
+ glDisable(GL_LINE_SMOOTH);
+}
+
+static void ui_draw_colorband_handle_tri(float x1, float y1, float halfwidth, float height, bool fill)
+{
+ float v[2];
+
+ if (fill) {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glEnable(GL_POLYGON_SMOOTH);
+ }
+ else {
+ glPolygonMode(GL_FRONT, GL_LINE);
+ glEnable(GL_LINE_SMOOTH);
+ }
+
+ glBegin(GL_TRIANGLES);
+ copy_v2_fl2(v, x1 + halfwidth, y1);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x1, y1 + height);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x1 - halfwidth, y1);
+ glVertex2fv(v);
+ glEnd();
+
+ if (fill) {
+ glDisable(GL_POLYGON_SMOOTH);
+ }
+ else {
+ glDisable(GL_LINE_SMOOTH);
+ glPolygonMode(GL_FRONT, GL_FILL);
+ }
+}
+
+static void ui_draw_colorband_handle_box(float x1, float y1, float x2, float y2, bool fill)
+{
+ float v[2];
+
+ if (fill) {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ }
+ else {
+ glPolygonMode(GL_FRONT, GL_LINE);
+ }
+
+ glBegin(GL_QUADS);
+ copy_v2_fl2(v, x1, y1);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x1, y2);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x2, y2);
+ glVertex2fv(v);
+ copy_v2_fl2(v, x2, y1);
+ glVertex2fv(v);
+ glEnd();
+
+ if (!fill) {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ }
+}
+
+static void ui_draw_colorband_handle(
+ const rcti *rect, float x,
+ const float rgb[3], struct ColorManagedDisplay *display,
+ bool active)
+{
+ const float sizey = BLI_rcti_size_y(rect);
+ const float min_width = 3.0f;
+ float half_width, height, y1, y2;
+ float colf[3] = {UNPACK3(rgb)};
+
+ half_width = floorf(sizey / 3.5f);
+ height = half_width * 1.4f;
+
+ y1 = rect->ymin + (sizey * 0.16f);
+ y2 = rect->ymax;
+
+ /* align to pixels */
+ x = floorf(x + 0.5f);
+ y1 = floorf(y1 + 0.5f);
+
+ if (active || half_width < min_width) {
+ glBegin(GL_LINES);
+ glColor3ub(0, 0, 0);
+ glVertex2f(x, y1);
+ glVertex2f(x, y2);
+ glEnd();
+ setlinestyle(active ? 2 : 1);
+ glBegin(GL_LINES);
+ glColor3ub(200, 200, 200);
+ glVertex2f(x, y1);
+ glVertex2f(x, y2);
+ glEnd();
+ setlinestyle(0);
+
+ /* hide handles when zoomed out too far */
+ if (half_width < min_width) {
+ return;
+ }
+ }
+
+ /* shift handle down */
+ y1 = y1 - half_width;
+
+ glColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_box(x - half_width, y1 - 1, x + half_width, y1 + height, false);
+
+ /* draw all triangles blended */
+ glEnable(GL_BLEND);
+
+ ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true);
+
+ if (active)
+ glColor3ub(196, 196, 196);
+ else
+ glColor3ub(128, 128, 128);
+ ui_draw_colorband_handle_tri(x, y1 + height, half_width, half_width, true);
+
+ if (active)
+ glColor3ub(255, 255, 255);
+ else
+ glColor3ub(196, 196, 196);
+ ui_draw_colorband_handle_tri_hlight(x, y1 + height - 1, (half_width - 1), (half_width - 1));
+
+ glColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_tri_hlight(x, y1 + height, half_width, half_width);
+
+ glDisable(GL_BLEND);
+
+ glColor3ub(128, 128, 128);
+ ui_draw_colorband_handle_box(x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true);
+
+ if (display) {
+ IMB_colormanagement_scene_linear_to_display_v3(colf, display);
+ }
+
+ glColor3fv(colf);
+ ui_draw_colorband_handle_box(x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true);
+}
+
void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
{
ColorBand *coba;
CBData *cbd;
- float x1, y1, sizex, sizey;
- float v3[2], v1[2], v2[2], v1a[2], v2a[2];
+ float x1, y1, sizex, sizey, sizey_solid;
+ float v1[2], v2[2];
int a;
float pos, colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
struct ColorManagedDisplay *display = NULL;
@@ -1022,23 +1156,24 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
display = ui_block_display_get(but->block);
x1 = rect->xmin;
- y1 = rect->ymin;
sizex = rect->xmax - x1;
- sizey = rect->ymax - y1;
-
+ sizey = BLI_rcti_size_y(rect);
+ sizey_solid = sizey / 4;
+ y1 = rect->ymin;
+
gpuImmediateFormat_C4_V2();
- /* first background, to show tranparency */
+ /* layer: background, to show tranparency */
gpuColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
- gpuDrawFilledRectf(x1, y1, x1 + sizex, y1 + sizey);
+ gpuDrawFilledRectf(x1, y1, x1 + sizex, rect->ymax);
GPU_raster_begin();
GPU_aspect_enable(GPU_ASPECT_RASTER, GPU_RASTER_POLYGON|GPU_RASTER_STIPPLE);
gpuPolygonStipple(stipple_checker_8px);
gpuColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
- gpuDrawFilledRectf(x1, y1, x1 + sizex, y1 + sizey);
+ gpuDrawFilledRectf(x1, y1, x1 + sizex, rect->ymax);
GPU_aspect_disable(GPU_ASPECT_RASTER, GPU_RASTER_POLYGON|GPU_RASTER_STIPPLE);
GPU_raster_end();
@@ -1046,22 +1181,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
+ /* layer: color ramp */
glEnable(GL_BLEND);
cbd = coba->data;
- v1[0] = v2[0] = x1;
- v1[1] = y1;
- v2[1] = y1 + sizey;
+ v1[1] = y1 + sizey_solid;
+ v2[1] = rect->ymax;
gpuBegin(GL_TRIANGLE_STRIP);
-
- gpuColor4fv(&cbd->r);
- gpuVertex2fv(v1);
- gpuVertex2fv(v2);
-
- for (a = 1; a <= sizex; a++) {
- pos = ((float)a) / (sizex - 1);
+ for (a = 0; a <= sizex; a++) {
+ pos = ((float)a) / sizex;
do_colorband(coba, pos, colf);
if (display)
IMB_colormanagement_scene_linear_to_display_v3(colf, display);
@@ -1072,80 +1202,60 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
gpuVertex2fv(v1);
gpuVertex2fv(v2);
}
-
gpuEnd();
-
// SSS Disable Smooth
GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
- glDisable(GL_BLEND);
- /* outline */
- gpuColor3P(CPACK_BLACK);
- gpuDrawWireRectf(x1, y1, x1 + sizex, y1 + sizey);
-
- /* help lines */
- v1[0] = v2[0] = v3[0] = x1;
+ /* layer: color ramp without alpha for reference when manipulating ramp properties */
v1[1] = y1;
- v1a[1] = y1 + 0.25f * sizey;
- v2[1] = y1 + 0.5f * sizey;
- v2a[1] = y1 + 0.75f * sizey;
- v3[1] = y1 + sizey;
-
- GPU_raster_begin();
-
- cbd = coba->data;
- gpuBegin(GL_LINES);
- for (a = 0; a < coba->tot; a++, cbd++) {
- v1[0] = v2[0] = v3[0] = v1a[0] = v2a[0] = x1 + cbd->pos * sizex;
-
- if (a == coba->cur) {
- gpuColor3P(CPACK_BLACK);
- gpuVertex2fv(v1);
- gpuVertex2fv(v3);
- gpuEnd();
-
- GPU_raster_set_line_style(2);
- gpuBegin(GL_LINES);
- gpuColor3P(CPACK_WHITE);
- gpuVertex2fv(v1);
- gpuVertex2fv(v3);
- gpuEnd();
- GPU_raster_set_line_style(0);
- gpuBegin(GL_LINES);
+ v2[1] = y1 + sizey_solid;
-#if 0
- gpuColor3P(CPACK_BLACK);
-
- gpuVertex2fv(v1);
- gpuVertex2fv(v1a);
-
- gpuVertex2fv(v2);
- gpuVertex2fv(v2a);
+ gpuBegin(GL_TRIANGLE_STRIP);
+ for (a = 0; a <= sizex; a++) {
+ pos = ((float)a) / sizex;
+ do_colorband(coba, pos, colf);
+ if (display)
+ IMB_colormanagement_scene_linear_to_display_v3(colf, display);
- gpuColor3P(CPACK_WHITE);
+ v1[0] = v2[0] = x1 + a;
- gpuVertex2fv(v1a);
- gpuVertex2fv(v2);
+ gpuColor4f(colf[0], colf[1], colf[2], 1.0f);
+ gpuVertex2fv(v1);
+ gpuVertex2fv(v2);
+ }
+ gpuEnd();
- gpuVertex2fv(v2a);
- gpuVertex2fv(v3);
-#endif
- }
- else {
- gpuColor3P(CPACK_BLACK);
- gpuVertex2fv(v1);
- gpuVertex2fv(v2);
+ glDisable(GL_BLEND);
+
+ // SSS Enable Smooth
+ GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
- gpuColor3P(CPACK_WHITE);
- gpuVertex2fv(v2);
- gpuVertex2fv(v3);
+ /* layer: box outline */
+ gpuColor4f(0.0, 0.0, 0.0, 1.0);
+ fdrawbox(x1, y1, x1 + sizex, rect->ymax);
+
+ /* layer: box outline */
+ glEnable(GL_BLEND);
+ gpuColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+ fdrawline(x1, y1, x1 + sizex, y1);
+ gpuColor4f(1.0f, 1.0f, 1.0f, 0.25f);
+ fdrawline(x1, y1 - 1, x1 + sizex, y1 - 1);
+ glDisable(GL_BLEND);
+
+ /* layer: draw handles */
+ for (a = 0; a < coba->tot; a++, cbd++) {
+ if (a != coba->cur) {
+ pos = x1 + cbd->pos * (sizex - 1) + 1;
+ ui_draw_colorband_handle(rect, pos, &cbd->r, display, false);
}
}
- gpuEnd();
-
- GPU_raster_end();
+ /* layer: active handle */
+ cbd = &coba->data[coba->cur];
+ pos = x1 + cbd->pos * (sizex - 1) + 1;
+ ui_draw_colorband_handle(rect, pos, &cbd->r, display, true);
+
gpuImmediateUnformat();
}
@@ -1505,13 +1615,14 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
rctf rect;
- int ok = 0, width, height;
+ bool ok = false;
+ int width, height;
GLint scissor[4];
MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
rect.xmin = (float)recti->xmin + 1;
rect.xmax = (float)recti->xmax - 1;
- rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
+ rect.ymin = (float)recti->ymin + 1;
rect.ymax = (float)recti->ymax - 1;
width = BLI_rctf_size_x(&rect) + 1;
@@ -1543,9 +1654,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
IMB_freeImBuf(scopes->track_preview);
tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height,
- scopes->track_search, scopes->track,
- &scopes->undist_marker, true, scopes->use_track_mask,
- width, height, scopes->track_pos);
+ scopes->track_search, scopes->track,
+ &scopes->undist_marker, true, scopes->use_track_mask,
+ width, height, scopes->track_pos);
if (tmpibuf) {
if (tmpibuf->rect_float)
@@ -1626,7 +1737,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
uiDrawBox(GL_TRIANGLE_FAN, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
}
- /* outline, scale gripper */
+ /* outline */
draw_scope_end(&rect, scissor);
glDisable(GL_BLEND);
@@ -1637,14 +1748,14 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
static const float size = 5.0f;
/* 16 values of sin function */
- static float si[16] = {
+ const float si[16] = {
0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
-0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
-0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
};
/* 16 values of cos function */
- static float co[16] = {
+ const float co[16] = {
1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
-0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
-0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 023a0cd6fcb..5b7915e20c5 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -149,7 +149,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
+ if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) {
return;
}
}
@@ -161,7 +161,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
+ if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) {
return;
}
}
@@ -173,7 +173,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
+ if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) {
return;
}
}
@@ -476,8 +476,9 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
+ const int mval[2] = {
+ mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
Base *base;
CTX_wm_area_set(C, sa);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index cfdc0c87fed..2da04ed56f3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -96,6 +96,9 @@
/* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */
#define USE_KEYNAV_LIMIT
+/* drag popups by their header */
+#define USE_DRAG_POPUP
+
/* proto */
static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
@@ -114,7 +117,7 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
#define BUTTON_AUTO_OPEN_THRESH 0.3
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
/* pixels to move the cursor to get out of keyboard navigation */
-#define BUTTON_KEYNAV_PX_LIMIT 4
+#define BUTTON_KEYNAV_PX_LIMIT 8
#define MENU_TOWARDS_MARGIN 20 /* margin in pixels */
#define MENU_TOWARDS_WIGGLE_ROOM 64 /* tolerance in pixels */
@@ -728,15 +731,15 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
uiBut *bt;
-
+
ui_set_but_val(but, but->hardmax);
-
+
+ ui_apply_but_func(C, but);
+
/* states of other row buttons */
for (bt = block->buttons.first; bt; bt = bt->next)
if (bt != but && bt->poin == but->poin && ELEM(bt->type, ROW, LISTROW))
ui_check_but(bt);
-
- ui_apply_but_func(C, but);
data->retval = but->retval;
data->applied = true;
@@ -1564,6 +1567,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
ui_apply_but_ROW(C, block, but, data);
break;
case SCROLL:
+ case GRIP:
case NUM:
case NUMSLI:
ui_apply_but_NUM(C, but, data);
@@ -1671,22 +1675,35 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
/* c = copy, v = paste */
static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, char mode)
{
- char buf[UI_MAX_DRAW_STR + 1] = {0};
+ int buf_paste_len = 0;
+ const char *buf_paste = "";
+ bool buf_paste_alloc = false;
if (mode == 'v' && but->lock == true) {
return;
}
+ if (mode == 'c') {
+ /* disallow copying from any passwords */
+ if (but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) {
+ return;
+ }
+ }
+
if (mode == 'v') {
/* extract first line from clipboard in case of multi-line copies */
- int pbuf_len;
- char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
- if (pbuf) {
- BLI_strncpy(buf, pbuf, sizeof(buf));
- MEM_freeN(pbuf);
+ const char *buf_paste_test;
+
+ buf_paste_test = WM_clipboard_text_get_firstline(false, &buf_paste_len);
+ if (buf_paste_test) {
+ buf_paste = buf_paste_test;
+ buf_paste_alloc = true;
}
}
-
+
+ /* No return from here down */
+
+
/* numeric value */
if (ELEM(but->type, NUM, NUMSLI)) {
@@ -1696,18 +1713,19 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else if (mode == 'c') {
/* Get many decimal places, then strip trailing zeros.
* note: too high values start to give strange results (6 or so is ok) */
- ui_get_but_string_ex(but, buf, sizeof(buf), 6);
- BLI_str_rstrip_float_zero(buf, '\0');
+ char buf_copy[UI_MAX_DRAW_STR];
+ ui_get_but_string_ex(but, buf_copy, sizeof(buf_copy), 6);
+ BLI_str_rstrip_float_zero(buf_copy, '\0');
- WM_clipboard_text_set(buf, 0);
+ WM_clipboard_text_set(buf_copy, 0);
}
else {
double val;
- if (ui_set_but_string_eval_num(C, but, buf, &val)) {
+ if (ui_set_but_string_eval_num(C, but, buf_paste, &val)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
data->value = val;
- ui_set_but_string(C, but, buf);
+ ui_set_but_string(C, but, buf_paste);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
@@ -1721,12 +1739,13 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* pass */
}
else if (mode == 'c') {
+ char buf_copy[UI_MAX_DRAW_STR];
ui_get_but_vectorf(but, xyz);
- BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f]", xyz[0], xyz[1], xyz[2]);
- WM_clipboard_text_set(buf, 0);
+ BLI_snprintf(buf_copy, sizeof(buf_copy), "[%f, %f, %f]", xyz[0], xyz[1], xyz[2]);
+ WM_clipboard_text_set(buf_copy, 0);
}
else {
- if (sscanf(buf, "[%f, %f, %f]", &xyz[0], &xyz[1], &xyz[2]) == 3) {
+ if (sscanf(buf_paste, "[%f, %f, %f]", &xyz[0], &xyz[1], &xyz[2]) == 3) {
if (normalize_v3(xyz) == 0.0f) {
/* better set Z up then have a zero vector */
xyz[2] = 1.0;
@@ -1747,7 +1766,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* pass */
}
else if (mode == 'c') {
- if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ char buf_copy[UI_MAX_DRAW_STR];
+
+ if (but->rnaprop && RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
else
rgba[3] = 1.0f;
@@ -1757,19 +1778,19 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
srgb_to_linearrgb_v3_v3(rgba, rgba);
- BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f, %f]", rgba[0], rgba[1], rgba[2], rgba[3]);
- WM_clipboard_text_set(buf, 0);
+ BLI_snprintf(buf_copy, sizeof(buf_copy), "[%f, %f, %f, %f]", rgba[0], rgba[1], rgba[2], rgba[3]);
+ WM_clipboard_text_set(buf_copy, 0);
}
else {
- if (sscanf(buf, "[%f, %f, %f, %f]", &rgba[0], &rgba[1], &rgba[2], &rgba[3]) == 4) {
+ if (sscanf(buf_paste, "[%f, %f, %f, %f]", &rgba[0], &rgba[1], &rgba[2], &rgba[3]) == 4) {
/* assume linear colors in buffer */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
linearrgb_to_srgb_v3_v3(rgba, rgba);
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
ui_set_but_vectorf(but, rgba);
- if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ if (but->rnaprop && RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]);
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -1786,7 +1807,6 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
else if (mode == 'c') {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR);
WM_clipboard_text_set(active_data->str, 0);
active_data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -1794,8 +1814,10 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen);
- else BLI_strncpy(active_data->str, buf, active_data->maxlen);
+ if (ui_is_but_utf8(but))
+ BLI_strncpy_utf8(active_data->str, buf_paste, active_data->maxlen);
+ else
+ BLI_strncpy(active_data->str, buf_paste, active_data->maxlen);
if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
@@ -1808,43 +1830,39 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* colorband (not supported by system clipboard) */
else if (but->type == BUT_COLORBAND) {
if (mode == 'c') {
- if (but->poin == NULL)
- return;
-
- memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand));
+ if (but->poin != NULL) {
+ memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand));
+ }
}
else {
- if (but_copypaste_coba.tot == 0)
- return;
-
- if (!but->poin)
- but->poin = MEM_callocN(sizeof(ColorBand), "colorband");
+ if (but_copypaste_coba.tot != 0) {
+ if (!but->poin)
+ but->poin = MEM_callocN(sizeof(ColorBand), "colorband");
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- memcpy(data->coba, &but_copypaste_coba, sizeof(ColorBand));
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ memcpy(data->coba, &but_copypaste_coba, sizeof(ColorBand));
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
}
}
else if (but->type == BUT_CURVE) {
if (mode == 'c') {
- if (but->poin == NULL)
- return;
-
- but_copypaste_curve_alive = true;
- curvemapping_free_data(&but_copypaste_curve);
- curvemapping_copy_data(&but_copypaste_curve, (CurveMapping *) but->poin);
+ if (but->poin != NULL) {
+ but_copypaste_curve_alive = true;
+ curvemapping_free_data(&but_copypaste_curve);
+ curvemapping_copy_data(&but_copypaste_curve, (CurveMapping *) but->poin);
+ }
}
else {
- if (!but_copypaste_curve_alive)
- return;
+ if (but_copypaste_curve_alive) {
+ if (!but->poin)
+ but->poin = MEM_callocN(sizeof(CurveMapping), "curvemapping");
- if (!but->poin)
- but->poin = MEM_callocN(sizeof(CurveMapping), "curvemapping");
-
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- curvemapping_free_data((CurveMapping *) but->poin);
- curvemapping_copy_data((CurveMapping *) but->poin, &but_copypaste_curve);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ curvemapping_free_data((CurveMapping *) but->poin);
+ curvemapping_copy_data((CurveMapping *) but->poin, &but_copypaste_curve);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
}
}
/* operator button (any type) */
@@ -1870,6 +1888,10 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
WM_clipboard_text_set(str, 0);
}
}
+
+ if (buf_paste_alloc) {
+ MEM_freeN((void *)buf_paste);
+ }
}
/* ************************ password text ******************************
@@ -1953,7 +1975,11 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
return changed;
}
-/* note, but->block->aspect is used here, when drawing button style is getting scaled too */
+/**
+ * \param x Screen space cursor location - #wmEvent.x
+ *
+ * \note ``but->block->aspect`` is used here, so drawing button style is getting scaled too.
+ */
static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x)
{
uiStyle *style = UI_GetStyle(); // XXX pass on as arg
@@ -1962,8 +1988,11 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
const short fstyle_points_prev = fstyle->points;
float startx = but->rect.xmin;
+ float starty_dummy = 0.0f;
char *origstr, password_str[UI_MAX_DRAW_STR];
+ ui_block_to_window_fl(data->region, but->block, &startx, &starty_dummy);
+
ui_fontscale(&fstyle->points, aspect);
uiStyleFontSet(fstyle);
@@ -1975,19 +2004,15 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
- BLI_strncpy(origstr, but->drawstr, data->maxlen);
+ BLI_strncpy(origstr, but->editstr, data->maxlen);
- /* XXX solve generic, see: #widget_draw_text_icon */
- if (but->type == NUM || but->type == NUMSLI) {
- startx += (int)(UI_TEXT_MARGIN_X * U.widget_unit);
- }
- else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (but->flag & UI_HAS_ICON) {
- startx += UI_DPI_ICON_SIZE;
+ startx += UI_DPI_ICON_SIZE / aspect;
}
- /* but this extra .05 makes clicks inbetween characters feel nicer */
- startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit);
}
+ /* but this extra .05 makes clicks inbetween characters feel nicer */
+ startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit) / aspect;
/* mouse dragged outside the widget to the left */
if (x < startx) {
@@ -1998,7 +2023,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
while (i > 0) {
if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &i)) {
/* 0.25 == scale factor for less sensitivity */
- if (BLF_width(fstyle->uifont_id, origstr + i, BLF_DRAW_STR_DUMMY_MAX) * aspect > (startx - x) * 0.25f) {
+ if (BLF_width(fstyle->uifont_id, origstr + i, BLF_DRAW_STR_DUMMY_MAX) > (startx - x) * 0.25f) {
break;
}
}
@@ -2020,12 +2045,12 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
but->pos = pos_prev = strlen(origstr) - but->ofs;
while (true) {
- cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs, BLF_DRAW_STR_DUMMY_MAX) * aspect;
+ cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs, BLF_DRAW_STR_DUMMY_MAX);
/* check if position is found */
if (cdist < x) {
/* check is previous location was in fact closer */
- if (((float)x - cdist) > (cdist_prev - (float)x)) {
+ if ((x - cdist) > (cdist_prev - x)) {
but->pos = pos_prev;
}
break;
@@ -2364,6 +2389,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->selextend = 0;
data->selstartx = 0.0f;
+#ifdef USE_DRAG_MULTINUM
+ /* this can happen from multi-drag */
+ data->applied_interactive = false;
+#endif
+
/* set cursor pos to the end of the text */
but->editstr = data->str;
but->pos = len;
@@ -2521,9 +2551,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_window_to_block_fl(data->region, block, &mx, &my);
if (ui_but_contains_pt(but, mx, my)) {
- ui_textedit_set_cursor_pos(but, data, mx);
+ ui_textedit_set_cursor_pos(but, data, event->x);
but->selsta = but->selend = but->pos;
- data->selstartx = mx;
+ data->selstartx = event->x;
button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING);
retval = WM_UI_HANDLER_BREAK;
@@ -2735,7 +2765,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
- ui_textedit_set_cursor_select(but, data, mx);
+ ui_textedit_set_cursor_select(but, data, event->x);
retval = WM_UI_HANDLER_BREAK;
break;
}
@@ -2901,7 +2931,7 @@ static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleBut
ARegion *ar = CTX_wm_region(C);
uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
- if (labelbut && labelbut->type == TEX) {
+ if (labelbut && labelbut->type == TEX && !(labelbut->flag & UI_BUT_DISABLED)) {
/* exit listrow */
data->cancel = true;
button_activate_exit(C, but, data, false, false);
@@ -3354,11 +3384,11 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
if ((is_float == true) && (softrange > 11)) {
/* non linear change in mouse input- good for high precicsion */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 500.0f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * ((float)abs(mx - data->dragstartx) / 500.0f);
}
else if ((is_float == false) && (softrange > 129)) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 250.0f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * ((float)abs(mx - data->dragstartx) / 250.0f);
}
else {
/*no scaling */
@@ -3467,18 +3497,29 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
- if (data->dragchange)
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- else
+ if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+ /* if we started multibutton but didnt drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
+#endif
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
click = 1;
+ }
}
else if (event->type == MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
float fac;
#ifdef USE_DRAG_MULTINUM
- data->multi_data.drag_dir[0] += fabsf(data->draglastx - mx);
- data->multi_data.drag_dir[1] += fabsf(data->draglasty - my);
+ data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
+ data->multi_data.drag_dir[1] += abs(data->draglasty - my);
#endif
fac = 1.0f;
@@ -3510,13 +3551,16 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* we can click on the side arrows to increment/decrement,
* or click inside to edit the value directly */
float tempf, softmin, softmax;
+ float handlewidth;
int temp;
softmin = but->softmin;
softmax = but->softmax;
+ handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect));
+
if (!ui_is_but_float(but)) {
- if (mx < (but->rect.xmin + BLI_rctf_size_x(&but->rect) / 3 - 3)) {
+ if (mx < (but->rect.xmin + handlewidth)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value - 1;
@@ -3527,7 +3571,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- else if (mx > (but->rect.xmin + (2 * BLI_rctf_size_x(&but->rect) / 3) + 3)) {
+ else if (mx > (but->rect.xmax - handlewidth)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp = (int)data->value + 1;
@@ -3543,7 +3587,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
}
else {
- if (mx < (but->rect.xmin + BLI_rctf_size_x(&but->rect) / 3 - 3)) {
+ if (mx < (but->rect.xmin + handlewidth)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value - 0.01f * but->a1;
@@ -3552,7 +3596,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
- else if (mx > but->rect.xmin + (2 * (BLI_rctf_size_x(&but->rect) / 3) + 3)) {
+ else if (mx > but->rect.xmax - handlewidth) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf = (float)data->value + 0.01f * but->a1;
@@ -3750,15 +3794,26 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
- if (data->dragchange)
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- else
+ if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+ /* if we started multibutton but didnt drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
+#endif
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
click = 1;
+ }
}
else if (event->type == MOUSEMOVE) {
#ifdef USE_DRAG_MULTINUM
- data->multi_data.drag_dir[0] += fabsf(data->draglastx - mx);
- data->multi_data.drag_dir[1] += fabsf(data->draglasty - my);
+ data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
+ data->multi_data.drag_dir[1] += abs(data->draglasty - my);
#endif
if (ui_numedit_but_SLI(but, data, mx, true, event->ctrl != 0, event->shift != 0))
ui_numedit_apply(C, block, but, data);
@@ -3897,112 +3952,75 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
return retval;
}
-static int ui_do_but_LISTROW(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* hack to pass on ctrl+click and double click to overlapping text
- * editing field for editing list item names
- */
- if ((ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS && event->ctrl) ||
- (event->type == LEFTMOUSE && event->val == KM_DBL_CLICK))
- {
- uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING);
- if (labelbut) {
- /* Nothing else to do. */
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
-
- return ui_do_but_EXIT(C, but, data, event);
-}
-
-
-static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+static int ui_do_but_GRIP(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
- uiList *ui_list = but->custom_data;
- int *size = (int *)but->poin;
- int mx, my, dragx, dragy;
+ int mx, my;
int retval = WM_UI_HANDLER_CONTINUE;
+ const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
/* Note: Having to store org point in window space and recompute it to block "space" each time
* is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which
* returns different results when the block is inside a panel or not...
* See T37739.
*/
- dragx = data->dragstartx;
- dragy = data->dragstarty;
- ui_window_to_block(data->region, block, &dragx, &dragy);
mx = event->x;
my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
- if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->val == KM_PRESS) {
+ if (event->type == LEFTMOUSE) {
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
if (event->type == ESCKEY) {
if (event->val == KM_PRESS) {
data->cancel = true;
data->escapecancel = true;
- *size = (int)data->origvalue;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_list->flag &= ~UILST_RESIZING;
- ED_region_tag_redraw(data->region);
}
}
else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_list->flag &= ~UILST_RESIZING;
- ED_region_tag_redraw(data->region);
}
else if (event->type == MOUSEMOVE) {
- /* If we switched from dragged to auto size, suspend shrinking dragging and set dragstarty to a temp
- * refpoint.
- */
- if (data->draglastvalue > 0 && *size == 0) {
- data->draglastvalue = *size;
- data->dragstartx = data->dragstarty; /* draglasty already used... */
- data->dragstarty = event->y;
- }
- else {
- int newsize = *size;
- int diff = dragy - my;
-
- diff = iroundf((float)diff / (float)UI_UNIT_Y);
-
- /* If we are not in autosize mode, default behavior... */
- if (*size > 0) {
- /* list template will clamp, but we do not want to reach 0 aka autosize mode! */
- newsize = data->dragstartvalue + diff;
- }
- /* If we are leaving autosize mode (growing dragging), restore to minimal size. */
- else if (diff > 0) {
- /* We can't use ui_numedit_apply()... */
- newsize = ui_list->dyn_data->visual_height_min;
-
- /* Restore real dragstarty value! */
- data->dragstarty = data->dragstartx;
- }
-
- /* Used to detect switch to/from autosize mode. */
- data->draglastvalue = newsize;
+ int dragstartx = data->dragstartx;
+ int dragstarty = data->dragstarty;
+ ui_window_to_block(data->region, block, &dragstartx, &dragstarty);
+ data->value = data->origvalue + (horizontal ? mx - dragstartx : dragstarty - my);
+ ui_numedit_apply(C, block, but, data);
+ }
- if (newsize != *size) {
- *size = newsize;
+ retval = WM_UI_HANDLER_BREAK;
+ }
- /* We can't use ui_numedit_apply()... */
- data->dragchange = true;
- data->applied = data->applied_interactive = true;
+ return retval;
+}
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
- ED_region_tag_redraw(data->region);
- }
+static int ui_do_but_LISTROW(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ /* hack to pass on ctrl+click and double click to overlapping text
+ * editing field for editing list item names
+ */
+ if ((ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS && event->ctrl) ||
+ (event->type == LEFTMOUSE && event->val == KM_DBL_CLICK))
+ {
+ uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING);
+ if (labelbut) {
+ /* Nothing else to do. */
+ return WM_UI_HANDLER_BREAK;
}
}
-
- retval = WM_UI_HANDLER_BREAK;
}
- return retval;
+ return ui_do_but_EXIT(C, but, data, event);
}
static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
@@ -4129,7 +4147,7 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data,
if (mrad < radsq) { /* inner circle */
fp[0] = dx;
fp[1] = dy;
- fp[2] = sqrt(radsq - dx * dx - dy * dy);
+ fp[2] = sqrtf(radsq - dx * dx - dy * dy);
}
else { /* outer circle */
@@ -4142,7 +4160,7 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data,
if (mrad < radsq) {
fp[0] = dx;
fp[1] = dy;
- fp[2] = -sqrt(radsq - dx * dx - dy * dy);
+ fp[2] = -sqrtf(radsq - dx * dx - dy * dy);
}
}
normalize_v3(fp);
@@ -4260,6 +4278,30 @@ static void clamp_axis_max_v3(float v[3], const float max)
}
}
+static void ui_rgb_to_color_picker_HSVCUBE_compat_v(uiBut *but, const float rgb[3], float hsv[3])
+{
+ if (but->a1 == UI_GRAD_L_ALT)
+ rgb_to_hsl_compat_v(rgb, hsv);
+ else
+ rgb_to_hsv_compat_v(rgb, hsv);
+}
+
+static void ui_rgb_to_color_picker_HSVCUBE_v(uiBut *but, const float rgb[3], float hsv[3])
+{
+ if (but->a1 == UI_GRAD_L_ALT)
+ rgb_to_hsl_v(rgb, hsv);
+ else
+ rgb_to_hsv_v(rgb, hsv);
+}
+
+static void ui_color_picker_to_rgb_HSVCUBE_v(uiBut *but, const float hsv[3], float rgb[3])
+{
+ if (but->a1 == UI_GRAD_L_ALT)
+ hsl_to_rgb_v(hsv, rgb);
+ else
+ hsv_to_rgb_v(hsv, rgb);
+}
+
static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
int mx, int my,
const enum eSnapType snap, const bool shift)
@@ -4269,7 +4311,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
float x, y;
float mx_fl, my_fl;
bool changed = true;
- bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
@@ -4287,7 +4329,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
if (use_display_colorspace)
ui_block_to_display_space_v3(but->block, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
/* only apply the delta motion, not absolute */
if (shift) {
@@ -4302,7 +4344,8 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
ui_block_to_display_space_v3(but->block, rgb);
copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
- rgb_to_hsv_compat_v(rgb, hsvo);
+
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsvo);
/* and original position */
ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
@@ -4339,12 +4382,14 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
case UI_GRAD_V:
hsv[2] = x;
break;
+ case UI_GRAD_L_ALT:
+ hsv[2] = y;
+ break;
case UI_GRAD_V_ALT:
/* vertical 'value' strip */
/* exception only for value strip - use the range set in but->min/max */
hsv[2] = y * (but->softmax - but->softmin) + but->softmin;
-
break;
default:
BLI_assert(0);
@@ -4357,13 +4402,13 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
}
}
- hsv_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
if (use_display_colorspace)
ui_block_to_scene_linear_v3(but->block, rgb);
/* clamp because with color conversion we can exceed range [#34295] */
- if ((int)but->a1 == UI_GRAD_V_ALT) {
+ if (but->a1 == UI_GRAD_V_ALT) {
clamp_axis_max_v3(rgb, but->softmax);
}
@@ -4376,49 +4421,50 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
}
static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
- wmNDOFMotionData *ndof,
+ const wmNDOFMotionData *ndof,
const enum eSnapType snap, const bool shift)
{
float *hsv = ui_block_hsv_get(but->block);
const float hsv_v_max = max_ff(hsv[2], but->softmax);
float rgb[3];
float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt;
- bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
ui_get_but_vectorf(but, rgb);
if (use_display_colorspace)
ui_block_to_display_space_v3(but->block, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
-
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
+
switch ((int)but->a1) {
case UI_GRAD_SV:
- hsv[2] += ndof->ry * sensitivity;
- hsv[1] += ndof->rx * sensitivity;
+ hsv[2] += ndof->rvec[2] * sensitivity;
+ hsv[1] += ndof->rvec[0] * sensitivity;
break;
case UI_GRAD_HV:
- hsv[0] += ndof->ry * sensitivity;
- hsv[2] += ndof->rx * sensitivity;
+ hsv[0] += ndof->rvec[2] * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
break;
case UI_GRAD_HS:
- hsv[0] += ndof->ry * sensitivity;
- hsv[1] += ndof->rx * sensitivity;
+ hsv[0] += ndof->rvec[2] * sensitivity;
+ hsv[1] += ndof->rvec[0] * sensitivity;
break;
case UI_GRAD_H:
- hsv[0] += ndof->ry * sensitivity;
+ hsv[0] += ndof->rvec[2] * sensitivity;
break;
case UI_GRAD_S:
- hsv[1] += ndof->ry * sensitivity;
+ hsv[1] += ndof->rvec[2] * sensitivity;
break;
case UI_GRAD_V:
- hsv[2] += ndof->ry * sensitivity;
+ hsv[2] += ndof->rvec[2] * sensitivity;
break;
case UI_GRAD_V_ALT:
+ case UI_GRAD_L_ALT:
/* vertical 'value' strip */
/* exception only for value strip - use the range set in but->min/max */
- hsv[2] += ndof->rx * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
CLAMP(hsv[2], but->softmin, but->softmax);
break;
@@ -4436,7 +4482,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
/* ndof specific: the changes above aren't clamping */
hsv_clamp_v(hsv, hsv_v_max);
- hsv_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
if (use_display_colorspace)
ui_block_to_scene_linear_v3(but->block, rgb);
@@ -4470,7 +4516,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
return WM_UI_HANDLER_BREAK;
}
else if (event->type == NDOF_MOTION) {
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
const enum eSnapType snap = ui_event_to_snap(event);
ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0);
@@ -4482,35 +4528,32 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
}
/* XXX hardcoded keymap check.... */
else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
- if (but->a1 == UI_GRAD_V_ALT) {
+ if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
int len;
/* reset only value */
len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
- if (len >= 3) {
+ if (ELEM(len, 3, 4)) {
float rgb[3], def_hsv[3];
- float *def;
+ float def[4];
float *hsv = ui_block_hsv_get(but->block);
- def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
- rgb_to_hsv_v(def, def_hsv);
-
+ ui_rgb_to_color_picker_HSVCUBE_v(but, def, def_hsv);
+
ui_get_but_vectorf(but, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
def_hsv[0] = hsv[0];
def_hsv[1] = hsv[1];
- hsv_to_rgb_v(def_hsv, rgb);
+ ui_color_picker_to_rgb_HSVCUBE_v(but, def_hsv, rgb);
ui_set_but_vectorf(but, rgb);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
-
- MEM_freeN(def);
+ return WM_UI_HANDLER_BREAK;
}
- return WM_UI_HANDLER_BREAK;
}
}
}
@@ -4548,8 +4591,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
bool changed = true;
float mx_fl, my_fl;
float rgb[3];
- float hsv[3];
-
+ float *hsv = ui_block_hsv_get(but->block);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+
ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
#ifdef USE_CONT_MOUSE_CORRECT
@@ -4571,25 +4615,38 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
BLI_rcti_rctf_copy(&rect, &but->rect);
ui_get_but_vectorf(but, rgb);
- copy_v3_v3(hsv, ui_block_hsv_get(but->block));
- rgb_to_hsv_compat_v(rgb, hsv);
-
+ if (use_display_colorspace)
+ ui_block_to_display_space_v3(but->block, rgb);
+
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
/* exception, when using color wheel in 'locked' value state:
* allow choosing a hue for black values, by giving a tiny increment */
- if (but->flag & UI_BUT_COLOR_LOCK) { // lock
- if (hsv[2] == 0.f) hsv[2] = 0.0001f;
+ if (but->flag & UI_BUT_COLOR_LOCK) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
+ if (hsv[2] == 0.f) hsv[2] = 0.0001f;
+ }
+ else {
+ if (hsv[2] == 0.f) hsv[2] = 0.0001f;
+ if (hsv[2] == 1.f) hsv[2] = 0.9999f;
+ }
}
/* only apply the delta motion, not absolute */
if (shift) {
- float xpos, ypos, hsvo[3];
+ float xpos, ypos, hsvo[3], rgbo[3];
/* calculate original hsv again */
copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
- rgb_to_hsv_compat_v(data->origvec, hsvo);
+ copy_v3_v3(rgbo, data->origvec);
+ if (use_display_colorspace)
+ ui_block_to_display_space_v3(but->block, rgbo);
+
+ ui_rgb_to_color_picker_compat_v(rgbo, hsvo);
+
/* and original position */
ui_hsvcircle_pos_from_vals(but, &rect, hsvo, &xpos, &ypos);
-
+
mx_fl = xpos - (data->dragstartx - mx_fl);
my_fl = ypos - (data->dragstarty - my_fl);
@@ -4597,20 +4654,23 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
ui_hsvcircle_vals_from_pos(hsv, hsv + 1, &rect, mx_fl, my_fl);
- if (but->flag & UI_BUT_COLOR_CUBIC)
+ if ((but->flag & UI_BUT_COLOR_CUBIC) && (U.color_picker_type == USER_CP_CIRCLE_HSV))
hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
if (snap != SNAP_OFF) {
ui_color_snap_hue(snap, &hsv[0]);
}
- hsv_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_v(hsv, rgb);
if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (rgb[0] || rgb[1] || rgb[2])) {
normalize_v3(rgb);
mul_v3_fl(rgb, but->a2);
}
+ if (use_display_colorspace)
+ ui_block_to_scene_linear_v3(but->block, rgb);
+
ui_set_but_vectorf(but, rgb);
data->draglastx = mx;
@@ -4620,16 +4680,19 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
}
static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
- wmNDOFMotionData *ndof,
+ const wmNDOFMotionData *ndof,
const enum eSnapType snap, const bool shift)
{
float *hsv = ui_block_hsv_get(but->block);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
float rgb[3];
float phi, r /*, sqr */ /* UNUSED */, v[2];
float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt;
ui_get_but_vectorf(but, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
+ if (use_display_colorspace)
+ ui_block_to_display_space_v3(but->block, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
/* Convert current color on hue/sat disc to circular coordinates phi, r */
phi = fmodf(hsv[0] + 0.25f, 1.0f) * -2.0f * (float)M_PI;
@@ -4641,14 +4704,14 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
v[1] = r * sinf(phi);
/* Use ndof device y and x rotation to move the vector in 2d space */
- v[0] += ndof->rz * sensitivity;
- v[1] += ndof->rx * sensitivity;
+ v[0] += ndof->rvec[2] * sensitivity;
+ v[1] += ndof->rvec[0] * sensitivity;
/* convert back to polar coords on circle */
phi = atan2f(v[0], v[1]) / (2.0f * (float)M_PI) + 0.5f;
- /* use ndof z rotation to additionally rotate hue */
- phi += ndof->ry * sensitivity * 0.5f;
+ /* use ndof Y rotation to additionally rotate hue */
+ phi += ndof->rvec[1] * sensitivity * 0.5f;
r = len_v2(v);
/* convert back to hsv values, in range [0,1] */
@@ -4657,8 +4720,14 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
/* exception, when using color wheel in 'locked' value state:
* allow choosing a hue for black values, by giving a tiny increment */
- if (but->flag & UI_BUT_COLOR_LOCK) { // lock
- if (hsv[2] == 0.0f) hsv[2] = 0.0001f;
+ if (but->flag & UI_BUT_COLOR_LOCK) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
+ if (hsv[2] == 0.f) hsv[2] = 0.0001f;
+ }
+ else {
+ if (hsv[2] == 0.f) hsv[2] = 0.0001f;
+ if (hsv[2] == 1.f) hsv[2] = 0.9999f;
+ }
}
if (snap != SNAP_OFF) {
@@ -4667,12 +4736,15 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
hsv_clamp_v(hsv, FLT_MAX);
- hsv_to_rgb_v(hsv, data->vec);
+ ui_color_picker_to_rgb_v(hsv, data->vec);
if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (data->vec[0] || data->vec[1] || data->vec[2])) {
normalize_v3(data->vec);
mul_v3_fl(data->vec, but->a2);
}
+
+ if (use_display_colorspace)
+ ui_block_to_scene_linear_v3(but->block, data->vec);
ui_set_but_vectorf(but, data->vec);
}
@@ -4702,7 +4774,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
}
else if (event->type == NDOF_MOTION) {
const enum eSnapType snap = ui_event_to_snap(event);
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0);
@@ -4725,10 +4797,10 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
- rgb_to_hsv_v(def, def_hsv);
+ ui_color_picker_to_rgb_v(def, def_hsv);
ui_get_but_vectorf(but, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
def_hsv[0] = hsv[0];
def_hsv[2] = hsv[2];
@@ -5126,40 +5198,22 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
return WM_UI_HANDLER_CONTINUE;
}
-static bool in_scope_resize_zone(uiBut *but, int UNUSED(x), int y)
-{
- /* bottom corner return (x > but->rect.xmax - SCOPE_RESIZE_PAD) && (y < but->rect.ymin + SCOPE_RESIZE_PAD); */
- return (y < but->rect.ymin + SCOPE_RESIZE_PAD);
-}
-
static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
Histogram *hist = (Histogram *)but->poin;
- /* rcti rect; */
bool changed = true;
- float /* dx, */ dy; /* UNUSED */
-
- /* BLI_rcti_rctf_copy(&rect, &but->rect); */
-
- /* dx = mx - data->draglastx; */ /* UNUSED */
- dy = my - data->draglasty;
+ float dy = my - data->draglasty;
+
+ /* scale histogram values (dy / 10 for better control) */
+ const float yfac = min_ff(powf(hist->ymax, 2.0f), 1.0f) * 0.5f;
+ hist->ymax += (dy * 0.1f) * yfac;
+
+ /* 0.1 allows us to see HDR colors up to 10 */
+ CLAMP(hist->ymax, 0.1f, 100.f);
- if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
- /* resize histogram widget itself */
- hist->height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
- }
- else {
- /* scale histogram values (dy / 10 for better control) */
- const float yfac = min_ff(powf(hist->ymax, 2.0f), 1.0f) * 0.5f;
- hist->ymax += (dy * 0.1f) * yfac;
-
- /* 0.1 allows us to see HDR colors up to 10 */
- CLAMP(hist->ymax, 0.1f, 100.f);
- }
-
data->draglastx = mx;
data->draglasty = my;
-
+
return changed;
}
@@ -5220,27 +5274,15 @@ static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandle
static bool ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
Scopes *scopes = (Scopes *)but->poin;
- /* rcti rect; */
bool changed = true;
- float /* dx, */ dy /* , yfac =1.0f */; /* UNUSED */
-
- /* BLI_rcti_rctf_copy(&rect, &but->rect); */
+ float dy;
- /* dx = mx - data->draglastx; */ /* UNUSED */
dy = my - data->draglasty;
+ /* scale waveform values */
+ scopes->wavefrm_yfac += dy / 200.0f;
- if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
- /* resize waveform widget itself */
- scopes->wavefrm_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
- }
- else {
- /* scale waveform values */
- /* yfac = scopes->wavefrm_yfac; */ /* UNUSED */
- scopes->wavefrm_yfac += dy / 200.0f;
-
- CLAMP(scopes->wavefrm_yfac, 0.5f, 2.f);
- }
+ CLAMP(scopes->wavefrm_yfac, 0.5f, 2.0f);
data->draglastx = mx;
data->draglasty = my;
@@ -5302,75 +5344,6 @@ static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleB
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int mx, int my)
-{
- Scopes *scopes = (Scopes *)but->poin;
- /* rcti rect; */
- bool changed = true;
- /* float dx, dy; */
-
- /* BLI_rcti_rctf_copy(&rect, &but->rect); */
-
- /* dx = mx - data->draglastx; */
- /* dy = my - data->draglasty; */
-
- if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
- /* resize vectorscope widget itself */
- scopes->vecscope_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
- }
-
- data->draglastx = mx;
- data->draglasty = my;
-
- return changed;
-}
-
-static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_VECTORSCOPE(but, data, mx, my))
- ui_numedit_apply(C, block, but, data);
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_VECTORSCOPE(but, data, mx, my))
- ui_numedit_apply(C, block, but, data);
- }
- }
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
VECCOPY2D(but->linkto, event->mval);
@@ -5414,25 +5387,19 @@ static bool ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonD
dy /= 5.0f;
}
- if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
- /* resize preview widget itself */
- scopes->track_preview_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
- }
- else {
- if (!scopes->track_locked) {
- if (scopes->marker->framenr != scopes->framenr)
- scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr);
+ if (!scopes->track_locked) {
+ if (scopes->marker->framenr != scopes->framenr)
+ scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr);
- scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
- scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_rctf_size_x(&but->block->rect);
- scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_rctf_size_y(&but->block->rect);
+ scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_rctf_size_x(&but->block->rect);
+ scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_rctf_size_y(&but->block->rect);
- WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
- }
-
- scopes->ok = 0;
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
}
+ scopes->ok = 0;
+
data->draglastx = mx;
data->draglasty = my;
@@ -5627,7 +5594,17 @@ void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa)
pup = uiPupMenuBegin(C, IFACE_("Panel"), ICON_NONE);
layout = uiPupMenuLayout(pup);
if (UI_panel_category_is_visible(ar)) {
- uiItemR(layout, &ptr, "use_pin", 0, "Pin" UI_SEP_CHAR_S "Shift+Left Mouse", ICON_NONE);
+ char tmpstr[80];
+ BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse"));
+ uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE);
+
+ /* evil, force shortcut flag */
+ {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but = block->buttons.last;
+ but->flag |= UI_BUT_HAS_SEP_CHAR;
+ }
+
}
uiPupMenuEnd(C, pup);
}
@@ -6085,6 +6062,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case SCROLL:
retval = ui_do_but_SCROLL(C, block, but, data, event);
break;
+ case GRIP:
+ retval = ui_do_but_GRIP(C, block, but, data, event);
+ break;
case NUM:
retval = ui_do_but_NUM(C, block, but, data, event);
break;
@@ -6092,7 +6072,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_SLI(C, block, but, data, event);
break;
case LISTBOX:
- retval = ui_do_but_LISTBOX(C, block, but, data, event);
+ /* Nothing to do! */
break;
case LISTROW:
retval = ui_do_but_LISTROW(C, but, data, event);
@@ -6112,7 +6092,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_WAVEFORM(C, block, but, data, event);
break;
case VECTORSCOPE:
- retval = ui_do_but_VECTORSCOPE(C, block, but, data, event);
+ /* Nothing to do! */
break;
case TEX:
case SEARCH_MENU:
@@ -6287,7 +6267,7 @@ void uiFreeActiveButtons(const bContext *C, bScreen *screen)
/* returns true if highlighted button allows drop of names */
/* called in region context */
-int UI_but_active_drop_name(bContext *C)
+bool UI_but_active_drop_name(bContext *C)
{
ARegion *ar = CTX_wm_region(C);
uiBut *but = ui_but_find_activated(ar);
@@ -6379,7 +6359,7 @@ static bool ui_is_but_interactive(const uiBut *but, const bool labeledit)
return false;
if (but->flag & UI_SCROLLED)
return false;
- if ((but->type == TEX) && (but->dt & UI_EMBOSSN) && !labeledit)
+ if ((but->type == TEX) && (but->dt == UI_EMBOSSN) && !labeledit)
return false;
if ((but->type == LISTROW) && labeledit)
return false;
@@ -6712,6 +6692,11 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
else if (type == BUTTON_ACTIVATE_APPLY)
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
+
+ if (but->type == GRIP) {
+ const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
+ WM_cursor_modal_set(data->window, horizontal ? BC_EW_ARROWCURSOR : BC_NS_ARROWCURSOR);
+ }
}
static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
@@ -6720,6 +6705,10 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
uiBlock *block = but->block;
uiBut *bt;
+ if (but->type == GRIP) {
+ WM_cursor_modal_restore(data->window);
+ }
+
/* ensure we are in the exit state */
if (data->state != BUTTON_STATE_EXIT)
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -7254,7 +7243,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
}
else {
/* XXX issue is because WM_event_add_mousemove(C) is a bad hack and not reliable,
- *if that gets coded better this bypass can go away too.
+ * if that gets coded better this bypass can go away too.
*
* This is needed to make sure if a button was active,
* it stays active while the mouse is over it.
@@ -7272,13 +7261,12 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
{
- uiBut *but, *dragbut;
+ uiBut *but;
uiList *ui_list;
uiListDyn *dyn_data;
int retval = WM_UI_HANDLER_CONTINUE;
int type = event->type, val = event->val;
int mx, my;
- bool is_over_dragbut = false;
but = ui_list_find_mouse_over(ar, event->x, event->y);
if (!but) {
@@ -7295,145 +7283,108 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
my = event->y;
ui_window_to_block(ar, but->block, &mx, &my);
- /* Find our "dragging" button. */
- for (dragbut = but->block->buttons.first; dragbut; dragbut = dragbut->next) {
- if (dragbut->poin == (void *)ui_list) {
- break;
- }
- }
- if (dragbut && dragbut == ui_but_find_mouse_over(ar, event)) {
- is_over_dragbut = true;
- }
-
- if (is_over_dragbut && type == LEFTMOUSE && val == KM_PRESS && !(but->flag & UI_BUT_DISABLED)) {
- uiHandleButtonData *data;
- int *size = (int *)but->poin;
-
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
- button_activate_state(C, but, BUTTON_STATE_INIT);
-
- data = but->active;
- data->dragstarty = event->y;
-
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
- /* Again, have to override values set by ui_numedit_begin, because our listbox button also has a rnapoin... */
- *size = data->origvalue = (double)dyn_data->visual_height;
- data->dragstartvalue = *size;
- ui_list->flag |= UILST_RESIZING;
-
- retval = WM_UI_HANDLER_BREAK;
+ /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* also see wm_event_system.c do_wheel_ui hack */
+ if (type == MOUSEPAN)
+ retval = WM_UI_HANDLER_BREAK;
}
- else {
- /* convert pan to scrollwheel */
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- /* if type still is mousepan, we call it handled, since delta-y accumulate */
- /* also see wm_event_system.c do_wheel_ui hack */
- if (type == MOUSEPAN)
- retval = WM_UI_HANDLER_BREAK;
- }
+ if (val == KM_PRESS) {
+ if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ {
+ const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ int value, min, max, inc;
- if (val == KM_PRESS) {
- if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
- {
- const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
- int value, min, max, inc;
+ /* activate up/down the list */
+ value = value_orig;
+ if ((ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0) {
+ inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? 1 : -1;
+ }
+ else {
+ inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? -1 : 1;
+ }
- /* activate up/down the list */
- value = value_orig;
- if ((ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0) {
- inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? 1 : -1;
- }
- else {
- inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? -1 : 1;
- }
+ if (dyn_data->items_filter_neworder || dyn_data->items_filter_flags) {
+ /* If we have a display order different from collection order, we have some work! */
+ int *org_order = MEM_mallocN(dyn_data->items_shown * sizeof(int), __func__);
+ const int *new_order = dyn_data->items_filter_neworder;
+ int i, org_idx = -1, len = dyn_data->items_len;
+ int current_idx = -1;
+ int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
- if (dyn_data->items_filter_neworder || dyn_data->items_filter_flags) {
- /* If we have a display order different from collection order, we have some work! */
- int *org_order = MEM_mallocN(dyn_data->items_shown * sizeof(int), __func__);
- int *new_order = dyn_data->items_filter_neworder;
- int i, org_idx = -1, len = dyn_data->items_len;
- int current_idx = -1;
- int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
-
- for (i = 0; i < len; i++) {
- if (!dyn_data->items_filter_flags ||
- ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude))
- {
- org_order[new_order ? new_order[++org_idx] : ++org_idx] = i;
- if (i == value) {
- current_idx = new_order ? new_order[org_idx] : org_idx;
- }
- }
- else if (i == value && org_idx >= 0) {
- current_idx = -(new_order ? new_order[org_idx] : org_idx) - 1;
+ for (i = 0; i < len; i++) {
+ if (!dyn_data->items_filter_flags ||
+ ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude))
+ {
+ org_order[new_order ? new_order[++org_idx] : ++org_idx] = i;
+ if (i == value) {
+ current_idx = new_order ? new_order[org_idx] : org_idx;
}
}
- /* Now, org_order maps displayed indices to real indices,
- * and current_idx either contains the displayed index of active value (positive),
- * or its more-nearest one (negated).
- */
- if (current_idx < 0) {
- current_idx = (current_idx * -1) + (inc < 0 ? inc : inc - 1);
- }
- else {
- current_idx += inc;
+ else if (i == value && org_idx >= 0) {
+ current_idx = -(new_order ? new_order[org_idx] : org_idx) - 1;
}
- CLAMP(current_idx, 0, dyn_data->items_shown - 1);
- value = org_order[current_idx];
- MEM_freeN(org_order);
+ }
+ /* Now, org_order maps displayed indices to real indices,
+ * and current_idx either contains the displayed index of active value (positive),
+ * or its more-nearest one (negated).
+ */
+ if (current_idx < 0) {
+ current_idx = (current_idx * -1) + (inc < 0 ? inc : inc - 1);
}
else {
- value += inc;
+ current_idx += inc;
}
+ CLAMP(current_idx, 0, dyn_data->items_shown - 1);
+ value = org_order[current_idx];
+ MEM_freeN(org_order);
+ }
+ else {
+ value += inc;
+ }
- CLAMP(value, 0, dyn_data->items_len - 1);
+ CLAMP(value, 0, dyn_data->items_len - 1);
- RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
- CLAMP(value, min, max);
+ RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
+ CLAMP(value, min, max);
- if (value != value_orig) {
- RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ if (value != value_orig) {
+ RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
- ui_apply_undo(but);
+ ui_apply_undo(but);
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
- ED_region_tag_redraw(ar);
- }
- retval = WM_UI_HANDLER_BREAK;
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ ED_region_tag_redraw(ar);
}
- else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
- /* We now have proper grip, but keep this anyway! */
- if (ui_list->list_grip == 0)
- ui_list->list_grip = dyn_data->visual_height;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ /* We now have proper grip, but keep this anyway! */
+ if (ui_list->list_grip < (dyn_data->visual_height_min - UI_LIST_AUTO_SIZE_THRESHOLD)) {
+ ui_list->list_grip = dyn_data->visual_height;
+ }
+ ui_list->list_grip += (type == WHEELUPMOUSE) ? -1 : 1;
+
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ ED_region_tag_redraw(ar);
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ if (dyn_data->height > dyn_data->visual_height) {
/* list template will clamp */
- if (type == WHEELUPMOUSE)
- ui_list->list_grip--;
- else
- ui_list->list_grip++;
+ ui_list->list_scroll += (type == WHEELUPMOUSE) ? -1 : 1;
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
ED_region_tag_redraw(ar);
retval = WM_UI_HANDLER_BREAK;
}
- else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- if (dyn_data->height > dyn_data->visual_height) {
- /* list template will clamp */
- if (type == WHEELUPMOUSE)
- ui_list->list_scroll--;
- else
- ui_list->list_scroll++;
-
- ED_region_tag_redraw(ar);
-
- retval = WM_UI_HANDLER_BREAK;
- }
- }
}
}
@@ -7757,14 +7708,16 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
return retval;
}
-static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
- int level, const bool is_parent_inside)
+static int ui_handle_menu_event(
+ bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside, const bool is_parent_menu, const bool is_floating)
{
ARegion *ar;
uiBlock *block;
uiBut *but, *bt;
int mx, my, retval;
bool inside;
+ bool inside_title; /* check for title dragging */
ar = menu->region;
block = ar->uiblocks.first;
@@ -7777,10 +7730,31 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
/* check if mouse is inside block */
inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+ inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax);
/* if there's an active modal button, don't check events or outside, except for search menu */
but = ui_but_find_activated(ar);
+#ifdef USE_DRAG_POPUP
+ if (menu->is_grab) {
+ if (event->type == LEFTMOUSE) {
+ menu->is_grab = false;
+ }
+ else {
+ if (event->type == MOUSEMOVE) {
+ int mdiff[2];
+
+ sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
+ copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+
+ ui_popup_translate(C, ar, mdiff);
+ }
+
+ return retval;
+ }
+ }
+#endif
+
if (but && button_modal_state(but->active->state)) {
if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
/* if a button is activated modal, always reset the start mouse
@@ -7971,16 +7945,17 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
count++;
/* exception for rna layer buts */
- if (but->rnapoin.data && but->rnaprop) {
- if (ELEM(RNA_property_subtype(but->rnaprop), PROP_LAYER, PROP_LAYER_MEMBER)) {
- if (but->rnaindex == act - 1)
- doit = true;
+ if (but->rnapoin.data && but->rnaprop &&
+ ELEM(RNA_property_subtype(but->rnaprop), PROP_LAYER, PROP_LAYER_MEMBER))
+ {
+ if (but->rnaindex == act - 1) {
+ doit = true;
}
}
else if (count == act) {
doit = true;
}
-
+
if (doit) {
/* activate buttons but open menu's */
uiButtonActivateType activate;
@@ -8080,9 +8055,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
if (ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) &&
ELEM(event->val, KM_PRESS, KM_DBL_CLICK))
{
- if ((level == 0) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
+ if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
/* for root menus, allow clicking to close */
- menu->menuretval = UI_RETURN_OUT;
+ if (block->flag & (UI_BLOCK_OUT_1))
+ menu->menuretval = UI_RETURN_OK;
+ else
+ menu->menuretval = UI_RETURN_OUT;
}
else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
if (block->flag & (UI_BLOCK_OUT_1))
@@ -8112,6 +8090,16 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
if (!ui_but_find_activated(ar))
menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
}
+#ifdef USE_DRAG_POPUP
+ else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) &&
+ (inside && is_floating && inside_title))
+ {
+ if (!ui_but_find_activated(ar)) {
+ menu->is_grab = true;
+ copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+ }
+ }
+#endif
else {
/* check mouse moving outside of the menu */
@@ -8219,8 +8207,9 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
- int level, const bool is_parent_inside)
+static int ui_handle_menus_recursive(
+ bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside, const bool is_parent_menu, const bool is_floating)
{
uiBut *but;
uiHandleButtonData *data;
@@ -8234,11 +8223,12 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
submenu = (data) ? data->menu : NULL;
if (submenu) {
+ uiBlock *block = menu->region->uiblocks.first;
+ const bool is_menu = ui_block_is_menu(block);
bool inside = false;
if (is_parent_inside == false) {
int mx, my;
- uiBlock *block = menu->region->uiblocks.first;
mx = event->x;
my = event->y;
@@ -8246,7 +8236,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
inside = BLI_rctf_isect_pt(&block->rect, mx, my);
}
- retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside);
+ retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
}
/* now handle events for our own menu */
@@ -8279,7 +8269,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
}
}
else {
- retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside);
+ retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_parent_menu, is_floating);
}
}
@@ -8376,7 +8366,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
if (data->menu)
- retval = ui_handle_menus_recursive(C, event, data->menu, 0, false);
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false, false);
/* handle events for the activated button */
if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
@@ -8422,7 +8412,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
retval = WM_UI_HANDLER_CONTINUE;
}
- ui_handle_menus_recursive(C, event, menu, 0, false);
+ ui_handle_menus_recursive(C, event, menu, 0, false, false, true);
/* free if done, does not free handle itself */
if (menu->menuretval) {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 585e8e97bfe..53152050b5e 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -29,12 +29,10 @@
/* my interface */
#include "interface_intern.h"
-
/* my library */
#include "ED_datafiles.h"
#include "ED_render.h"
-
#include "UI_interface.h"
#include "UI_interface_icons.h"
@@ -46,7 +44,6 @@
#include "BKE_global.h"
#include "BKE_icons.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
@@ -536,13 +533,13 @@ static void init_brush_icons(void)
#define INIT_BRUSH_ICON(icon_id, name) \
{ \
- unsigned char *rect = (unsigned char *)datatoc_ ##name## _png; \
- int size = datatoc_ ##name## _png_size; \
- DrawInfo *di; \
+ unsigned char *rect = (unsigned char *)datatoc_ ##name## _png; \
+ int size = datatoc_ ##name## _png_size; \
+ DrawInfo *di; \
\
- di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
- di->data.buffer.image->datatoc_rect = rect; \
- di->data.buffer.image->datatoc_size = size; \
+ di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
+ di->data.buffer.image->datatoc_rect = rect; \
+ di->data.buffer.image->datatoc_size = size; \
}
/* end INIT_BRUSH_ICON */
@@ -671,13 +668,13 @@ static void init_internal_icons(void)
#endif
if (b16buf == NULL)
b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png,
- datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
+ datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
if (b16buf)
IMB_premultiply_alpha(b16buf);
if (b32buf == NULL)
b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png,
- datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
+ datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
if (b32buf)
IMB_premultiply_alpha(b32buf);
@@ -779,7 +776,7 @@ static void init_iconfile_list(struct ListBase *list)
for (i = 0; i < totfile; i++) {
if ((dir[i].type & S_IFREG)) {
- char *filename = dir[i].relname;
+ const char *filename = dir[i].relname;
if (BLI_testextensie(filename, ".png")) {
/* loading all icons on file start is overkill & slows startup
@@ -1220,7 +1217,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
#endif
if (!iimg->rect) return; /* something has gone wrong! */
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index eb0895840e8..9efa7bb3c66 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -154,7 +154,7 @@ enum {
typedef struct uiLinkLine { /* only for draw/edit */
struct uiLinkLine *next, *prev;
struct uiBut *from, *to;
- short flag, pad;
+ short flag, deactive;
} uiLinkLine;
typedef struct {
@@ -393,7 +393,7 @@ extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rc
const float mx, const float my);
extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos);
extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
-bool ui_hsvcube_use_display_colorspace(struct uiBut *but);
+bool ui_color_picker_use_display_colorspace(struct uiBut *but);
extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL();
extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
@@ -401,6 +401,7 @@ extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) AT
extern bool ui_set_but_string(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
extern bool ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL();
extern int ui_get_but_string_max_length(uiBut *but);
+extern uiBut *ui_get_but_drag_multi_edit(uiBut *but);
extern void ui_set_but_default(struct bContext *C, const bool all, const bool use_afterfunc);
@@ -466,6 +467,11 @@ struct uiPopupBlockHandle {
/* menu direction */
int direction;
+
+/* #ifdef USE_DRAG_POPUP */
+ bool is_grab;
+ int grab_xy_prev[2];
+/* #endif */
};
uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
@@ -474,11 +480,17 @@ struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion,
void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
uiBut *ui_popup_menu_memory_get(struct uiBlock *block);
-void ui_popup_menu_memory_set(struct uiBlock *block, struct uiBut *but);
+void ui_popup_menu_memory_set(uiBlock *block, struct uiBut *but);
+
+void ui_popup_translate(struct bContext *C, struct ARegion *ar, const int mdiff[2]);
float *ui_block_hsv_get(struct uiBlock *block);
void ui_popup_block_scrolltest(struct uiBlock *block);
+void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]);
+void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3]);
+void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3]);
+void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b);
/* searchbox for string button */
ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
@@ -546,7 +558,7 @@ void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
uiWidgetColors *ui_tooltip_get_theme(void);
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *UNUSED(block), rcti *rect);
void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
-int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol);
+bool ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol);
void ui_draw_link_bezier(const rcti *rect);
extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 57e7ebfd800..0bc679dede0 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -222,18 +222,25 @@ static int ui_layout_vary_direction(uiLayout *layout)
}
/* estimated size of text + icon */
-static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int compact)
+static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool compact)
{
- float f5 = 0.25f * UI_UNIT_X;
- float f10 = 0.5f * UI_UNIT_X;
- int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X;
+ bool variable;
if (icon && !name[0])
return UI_UNIT_X; /* icon only */
- else if (icon)
- return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */
- else
- return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
+
+ variable = (ui_layout_vary_direction(layout) == UI_ITEM_VARY_X);
+
+ if (variable) {
+ /* it may seem odd that the icon only adds (UI_UNIT_X / 4)
+ * but taking margins into account its fine */
+ return (UI_GetStringWidth(name) +
+ (UI_UNIT_X * ((compact ? 1.25f : 1.50f) +
+ (icon ? 0.25f : 0.0f))));
+ }
+ else {
+ return UI_UNIT_X * 10;
+ }
}
static void ui_item_size(uiItem *item, int *r_w, int *r_h)
@@ -403,8 +410,8 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
uiBlockBeginAlign(block);
for (a = 0; a < colbuts; a++) {
- int layer_num = a + b * colbuts;
- int layer_flag = 1 << layer_num;
+ const int layer_num = a + b * colbuts;
+ const unsigned int layer_flag = (1u << layer_num);
if (layer_used & layer_flag) {
if (layer_active & layer_flag)
@@ -421,8 +428,8 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num));
}
for (a = 0; a < colbuts; a++) {
- int layer_num = a + len / 2 + b * colbuts;
- int layer_flag = 1 << layer_num;
+ const int layer_num = a + len / 2 + b * colbuts;
+ const unsigned int layer_flag = (1u << layer_num);
if (layer_used & layer_flag) {
if (layer_active & layer_flag)
@@ -881,7 +888,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
EnumPropertyItem *item, *item_array = NULL;
bool free;
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
- uiLayout *column = uiLayoutColumn(split, false);
+ uiLayout *column = uiLayoutColumn(split, layout->align);
RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free);
for (item = item_array; item->identifier; item++) {
@@ -905,7 +912,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
if (item->name) {
uiBut *but;
if (item != item_array) {
- column = uiLayoutColumn(split, false);
+ column = uiLayoutColumn(split, layout->align);
/* inconsistent, but menus with labels do not look good flipped */
block->flag |= UI_BLOCK_NO_FLIP;
}
@@ -1104,7 +1111,7 @@ static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, Point
RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item_array, NULL, &free);
for (item = item_array; item->identifier; item++) {
if (item->identifier[0]) {
- w = max_ii(w, ui_text_icon_width(layout, item->name, icon, 0));
+ w = max_ii(w, ui_text_icon_width(layout, item->name, item->icon, 0));
}
}
if (free) {
@@ -1125,7 +1132,7 @@ static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, Point
if (ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER))
h += 2 * UI_UNIT_Y;
else if (subtype == PROP_MATRIX)
- h += ceil(sqrt(len)) * UI_UNIT_Y;
+ h += ceilf(sqrtf(len)) * UI_UNIT_Y;
else
h += len * UI_UNIT_Y;
}
@@ -1171,12 +1178,18 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
if (icon == ICON_NONE)
icon = RNA_property_ui_icon(prop);
- if (ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER))
+ if (flag & UI_ITEM_R_ICON_ONLY) {
+ /* pass */
+ }
+ else if (ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER)) {
name = ui_item_name_add_colon(name, namestr);
- else if (type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX)
+ }
+ else if (type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX) {
name = ui_item_name_add_colon(name, namestr);
- else if (type == PROP_ENUM && index != RNA_ENUM_VALUE)
+ }
+ else if (type == PROP_ENUM && index != RNA_ENUM_VALUE) {
name = ui_item_name_add_colon(name, namestr);
+ }
if (layout->root->type == UI_LAYOUT_MENU) {
if (type == PROP_BOOLEAN && ((is_array == false) || (index != RNA_NO_INDEX))) {
@@ -1250,6 +1263,12 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
if (no_bg)
uiBlockSetEmboss(block, UI_EMBOSS);
+
+ /* ensure text isn't added to icon_only buttons */
+ if (but && icon_only) {
+ BLI_assert(but->str[0] == '\0');
+ }
+
}
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
@@ -1605,8 +1624,8 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
CTX_store_set(C, NULL);
}
-static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
- const char *tip, bool force_menu)
+static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
+ const char *tip, bool force_menu)
{
uiBlock *block = layout->root->block;
uiBut *but;
@@ -1656,6 +1675,8 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre
{
uiButSetMenuFromPulldown(but);
}
+
+ return but;
}
void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const char *name, int icon)
@@ -1802,8 +1823,7 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch
{
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
MenuItemLevel *lvl;
- char namestr_buf[UI_MAX_NAME_STR], keybuf[128];
- char *namestr = namestr_buf;
+ uiBut *but;
UI_OPERATOR_ERROR_RET(ot, opname, return );
@@ -1813,10 +1833,9 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch
return;
}
- if (name)
- namestr += BLI_strncpy_rlen(namestr, name, sizeof(namestr_buf));
- else
- namestr += BLI_strncpy_rlen(namestr, RNA_struct_ui_name(ot->srna), sizeof(namestr_buf));
+ if (name == NULL) {
+ name = RNA_struct_ui_name(ot->srna);
+ }
if (layout->root->type == UI_LAYOUT_MENU && !icon)
icon = ICON_BLANK1;
@@ -1826,17 +1845,20 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch
BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname));
lvl->opcontext = layout->root->opcontext;
+ but = ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl,
+ RNA_struct_ui_description(ot->srna), true);
+
/* add hotkey here, lower UI code can't detect it */
- if (layout->root->block->flag & UI_BLOCK_LOOP) {
- if (ot->prop && ot->invoke &&
- WM_key_event_operator_string(C, ot->idname, layout->root->opcontext, NULL, false, keybuf, sizeof(keybuf)))
+ if ((layout->root->block->flag & UI_BLOCK_LOOP) &&
+ (ot->prop && ot->invoke))
+ {
+ char keybuf[128];
+ if (WM_key_event_operator_string(C, ot->idname, layout->root->opcontext, NULL, false,
+ keybuf, sizeof(keybuf)))
{
- namestr += BLI_snprintf(namestr, sizeof(namestr_buf) - (namestr - namestr_buf), "|%s", keybuf);
+ ui_but_add_shortcut(but, keybuf, false);
}
}
-
- ui_item_menu(layout, namestr_buf, icon, menu_item_enum_opname_menu, NULL, lvl, RNA_struct_ui_description(ot->srna),
- true);
}
static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
@@ -2509,15 +2531,6 @@ uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, Pr
but->rnapoin = *actptr;
but->rnaprop = actprop;
- /* Resizing data. */
- /* Note: we can't use usual "num button" value handling, as it only tries rnapoin when it is non-NULL... :/
- * So just setting but->poin, not but->pointype.
- */
- but->poin = (void *)&ui_list->list_grip;
- but->hardmin = but->softmin = 0.0f;
- but->hardmax = but->softmax = 1000.0f; /* Should be more than enough! */
- but->a1 = 0.0f;
-
/* only for the undo string */
if (but->flag & UI_BUT_UNDO) {
but->tip = RNA_property_description(actprop);
@@ -3011,7 +3024,7 @@ void uiLayoutContextCopy(uiLayout *layout, bContextStore *context)
static void ui_intro_button(DynStr *ds, uiButtonItem *bitem)
{
uiBut *but = bitem->but;
- BLI_dynstr_appendf(ds, "'type':%d, ", but->type); /* see ~ UI_interface.h:200 */
+ BLI_dynstr_appendf(ds, "'type':%d, ", (int)but->type);
BLI_dynstr_appendf(ds, "'draw_string':'''%s''', ", but->drawstr);
BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : ""); /* not exactly needed, rna has this */
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 8f065d75151..8982b3e9c11 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -234,8 +234,9 @@ static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
uiContextActiveProperty(C, &ptr, &prop, &index);
/* if there is a valid property that is editable... */
- if (ptr.data && prop && RNA_property_editable(&ptr, prop)
- /*&& RNA_property_is_idprop(prop)*/ && RNA_property_is_set(&ptr, prop))
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop) &&
+ /* RNA_property_is_idprop(prop) && */
+ RNA_property_is_set(&ptr, prop))
{
RNA_property_unset(&ptr, prop);
return operator_button_property_finish(C, &ptr, prop);
@@ -286,14 +287,24 @@ static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, bo
return true;
}
-static int copy_to_selected_button_poll(bContext *C)
+/**
+ * called from both exec & poll
+ *
+ * \note: normally we wouldn't call a loop from within a poll function,
+ * However this is a special case, and for regular poll calls, getting
+ * the context from the button will fail early.
+ */
+static bool copy_to_selected_button(bContext *C, bool all, bool poll)
{
PointerRNA ptr, lptr, idptr;
PropertyRNA *prop, *lprop;
- int index, success = 0;
+ bool success = false;
+ int index;
+ /* try to reset the nominated setting to its default value */
uiContextActiveProperty(C, &ptr, &prop, &index);
+ /* if there is a valid property that is editable... */
if (ptr.data && prop) {
char *path = NULL;
bool use_path;
@@ -317,8 +328,18 @@ static int copy_to_selected_button_poll(bContext *C)
}
if (lprop == prop) {
- if (RNA_property_editable(&lptr, prop))
- success = 1;
+ if (RNA_property_editable(&lptr, lprop)) {
+ if (poll) {
+ success = true;
+ break;
+ }
+ else {
+ if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
+ RNA_property_update(C, &lptr, prop);
+ success = true;
+ }
+ }
+ }
}
}
}
@@ -333,58 +354,19 @@ static int copy_to_selected_button_poll(bContext *C)
return success;
}
-static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
+static int copy_to_selected_button_poll(bContext *C)
{
- PointerRNA ptr, lptr, idptr;
- PropertyRNA *prop, *lprop;
- int success = 0;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to reset the nominated setting to its default value */
- uiContextActiveProperty(C, &ptr, &prop, &index);
-
- /* if there is a valid property that is editable... */
- if (ptr.data && prop) {
- char *path = NULL;
- bool use_path;
- CollectionPointerLink *link;
- ListBase lb;
-
- if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
- return success;
+ return copy_to_selected_button(C, false, true);
+}
- if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
- for (link = lb.first; link; link = link->next) {
- if (link->ptr.data != ptr.data) {
- if (use_path) {
- lprop = NULL;
- RNA_id_pointer_create(link->ptr.id.data, &idptr);
- RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
- }
- else {
- lptr = link->ptr;
- lprop = prop;
- }
+static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
+{
+ bool success;
- if (lprop == prop) {
- if (RNA_property_editable(&lptr, lprop)) {
- if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
- RNA_property_update(C, &lptr, prop);
- success = 1;
- }
- }
- }
- }
- }
+ const bool all = RNA_boolean_get(op->ptr, "all");
- if (path)
- MEM_freeN(path);
- }
+ success = copy_to_selected_button(C, all, false);
- BLI_freelistN(&lb);
- }
-
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -681,7 +663,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch
/* Now try without the second iso code part (_ES in es_ES). */
{
- char *tc = NULL;
+ const char *tc = NULL;
size_t szt = 0;
tstr[0] = '\0';
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 427109272dc..fc3ef1a27cd 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -41,7 +41,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_math_color_blend.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -66,6 +65,7 @@
#include "ED_screen.h"
+#include "UI_view2d.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
@@ -176,21 +176,24 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
/****************************** panels ******************************/
-static void panels_collapse_all(ScrArea *sa, ARegion *ar, Panel *from_pa)
+static void panels_collapse_all(ScrArea *sa, ARegion *ar, const Panel *from_pa)
{
+ const bool has_category_tabs = UI_panel_category_is_visible(ar);
+ const char *category = has_category_tabs ? UI_panel_category_active_get(ar, false) : NULL;
+ const int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
+ const PanelType *from_pt = from_pa->type;
Panel *pa;
- PanelType *pt, *from_pt;
- int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
for (pa = ar->panels.first; pa; pa = pa->next) {
- pt = pa->type;
- from_pt = from_pa->type;
+ PanelType *pt = pa->type;
/* close panels with headers in the same context */
if (pt && from_pt && !(pt->flag & PNL_NO_HEADER)) {
- if (!pt->context[0] || strcmp(pt->context, from_pt->context) == 0) {
- pa->flag &= ~PNL_CLOSED;
- pa->flag |= flag;
+ if (!pt->context[0] || !from_pt->context[0] || STREQ(pt->context, from_pt->context)) {
+ if ((pa->flag & PNL_PIN) || !category || !pt->category[0] || STREQ(pt->category, category)) {
+ pa->flag &= ~PNL_CLOSED;
+ pa->flag |= flag;
+ }
}
}
}
@@ -213,8 +216,8 @@ Panel *uiPanelFindByType(ARegion *ar, PanelType *pt)
const char *tabname = pt->idname;
for (pa = ar->panels.first; pa; pa = pa->next) {
- if (STREQLEN(pa->panelname, idname, UI_MAX_NAME_STR)) {
- if (STREQLEN(pa->tabname, tabname, UI_MAX_NAME_STR)) {
+ if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
+ if (STREQLEN(pa->tabname, tabname, sizeof(pa->panelname))) {
return pa;
}
}
@@ -230,9 +233,9 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Pan
{
Panel *patab, *palast, *panext;
const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
- char *idname = pt->idname;
- char *tabname = pt->idname;
- char *hookname = NULL;
+ const char *idname = pt->idname;
+ const char *tabname = pt->idname;
+ const char *hookname = NULL;
const bool newpanel = (pa == NULL);
int align = panel_aligned(sa, ar);
@@ -243,8 +246,8 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Pan
/* new panel */
pa = MEM_callocN(sizeof(Panel), "new panel");
pa->type = pt;
- BLI_strncpy(pa->panelname, idname, UI_MAX_NAME_STR);
- BLI_strncpy(pa->tabname, tabname, UI_MAX_NAME_STR);
+ BLI_strncpy(pa->panelname, idname, sizeof(pa->panelname));
+ BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
if (pt->flag & PNL_DEFAULT_CLOSED) {
if (align == BUT_VERTICAL)
@@ -265,8 +268,8 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Pan
if (hookname) {
for (patab = ar->panels.first; patab; patab = patab->next) {
if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
- if (strncmp(hookname, patab->panelname, UI_MAX_NAME_STR) == 0) {
- if (strncmp(tabname, patab->tabname, UI_MAX_NAME_STR) == 0) {
+ if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
+ if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
pa->paneltab = patab;
ui_panel_copy_offset(pa, patab);
break;
@@ -932,7 +935,7 @@ static void ui_do_animate(const bContext *C, Panel *panel)
float fac;
fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
- fac = min_ff(sqrt(fac), 1.0f);
+ fac = min_ff(sqrtf(fac), 1.0f);
/* for max 1 second, interpolate positions */
if (uiAlignPanelStep(sa, ar, fac, false)) {
@@ -1355,9 +1358,6 @@ static void ui_panel_category_draw_tab(int mode, float minx, float miny, float m
mul_v2_fl(vec[a], rad);
}
- (void)use_shadow;
- (void)use_highlight;
-
gpuImmediateFormat_V2();
gpuBegin(mode);
@@ -1686,6 +1686,31 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
if (pc_dyn) {
UI_panel_category_active_set(ar, pc_dyn->idname);
ED_region_tag_redraw(ar);
+
+ /* reset scroll to the top [#38348] */
+ UI_view2d_offset(&ar->v2d, -1.0f, 1.0f);
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ /* mouse wheel cycle tabs */
+
+ /* first check if the mouse is in the tab region */
+ if (event->ctrl || (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax)) {
+ const char *category = UI_panel_category_active_get(ar, false);
+ if (LIKELY(category)) {
+ PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
+ if (LIKELY(pc_dyn)) {
+ pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
+ if (pc_dyn) {
+ /* intentionally don't reset scroll in this case,
+ * this allows for quick browsing between tabs */
+ UI_panel_category_active_set(ar, pc_dyn->idname);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ }
retval = WM_UI_HANDLER_BREAK;
}
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index c45ba28979b..13d44e3d38a 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -41,12 +41,10 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "BKE_idcode.h"
#include "BKE_report.h"
#include "BKE_global.h"
@@ -336,12 +334,15 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
- /* full string */
- ui_get_but_string(but, buf, sizeof(buf));
- if (buf[0]) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf);
- data->color_id[data->totline] = UI_TIP_LC_NORMAL;
- data->totline++;
+ /* better not show the value of a password */
+ if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) {
+ /* full string */
+ ui_get_but_string(but, buf, sizeof(buf));
+ if (buf[0]) {
+ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf);
+ data->color_id[data->totline] = UI_TIP_LC_NORMAL;
+ data->totline++;
+ }
}
}
@@ -673,8 +674,7 @@ int uiSearchBoxHeight(void)
int uiSearchBoxWidth(void)
{
- /* was hardcoded at 150 */
- return 9 * UI_UNIT_X;
+ return 12 * UI_UNIT_X;
}
int uiSearchItemFindIndex(uiSearchItems *items, const char *name)
@@ -778,7 +778,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
if (data->active != -1) {
const char *name = data->items.names[data->active];
- const char *name_sep = data->use_sep ? strchr(name, UI_SEP_CHAR) : NULL;
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
@@ -884,7 +884,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset)
for (a = 0; a < data->items.totitem; a++) {
const char *name = data->items.names[a];
- const char *name_sep = data->use_sep ? strchr(name, UI_SEP_CHAR) : NULL;
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
data->active = a;
break;
@@ -1101,8 +1101,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
BLI_rcti_rctf_copy(&rect_i, &rect_fl);
if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmin, rect_fl.ymin, &rect_i.xmin, &rect_i.ymin);
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmax, rect_fl.ymax, &rect_i.xmax, &rect_i.ymax);
+ UI_view2d_view_to_region_rcti(&butregion->v2d, &rect_fl, &rect_i);
}
BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
@@ -1127,7 +1126,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
int newy1 = but->rect.ymax + ofsy;
if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax)
- UI_view2d_to_region_no_clip(&butregion->v2d, 0, newy1, NULL, &newy1);
+ newy1 = UI_view2d_view_to_region_y(&butregion->v2d, newy1);
newy1 += butregion->winrct.ymin;
@@ -1232,10 +1231,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
short dir1 = 0, dir2 = 0;
/* transform to window coordinates, using the source button region/block */
- butrct = but->rect;
-
- ui_block_to_window_fl(butregion, but->block, &butrct.xmin, &butrct.ymin);
- ui_block_to_window_fl(butregion, but->block, &butrct.xmax, &butrct.ymax);
+ ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);
/* widget_roundbox_set has this correction too, keep in sync */
if (but->type != PULLDOWN) {
@@ -1262,8 +1258,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
}
/* aspect = (float)(BLI_rcti_size_x(&block->rect) + 4);*/ /*UNUSED*/
- ui_block_to_window_fl(butregion, but->block, &block->rect.xmin, &block->rect.ymin);
- ui_block_to_window_fl(butregion, but->block, &block->rect.xmax, &block->rect.ymax);
+ ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect);
//block->rect.xmin -= 2.0; block->rect.ymin -= 2.0;
//block->rect.xmax += 2.0; block->rect.ymax += 2.0;
@@ -1385,8 +1380,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* apply offset, buttons in window coords */
for (bt = block->buttons.first; bt; bt = bt->next) {
- ui_block_to_window_fl(butregion, but->block, &bt->rect.xmin, &bt->rect.ymin);
- ui_block_to_window_fl(butregion, but->block, &bt->rect.xmax, &bt->rect.ymax);
+ ui_block_to_window_rctf(butregion, but->block, &bt->rect, &bt->rect);
BLI_rctf_translate(&bt->rect, xof, yof);
@@ -1615,7 +1609,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* get winmat now that we actually have the subwindow */
wmSubWindowSet(window, ar->swinid);
- wm_subwindow_getmatrix(window, ar->swinid, block->winmat);
+ wm_subwindow_matrix_get(window, ar->swinid, block->winmat);
/* notify change and redraw */
ED_region_tag_redraw(ar);
@@ -1653,23 +1647,33 @@ static void ui_warp_pointer(int x, int y)
void ui_set_but_hsv(uiBut *but)
{
float col[3];
- float *hsv = ui_block_hsv_get(but->block);
+ const float *hsv = ui_block_hsv_get(but->block);
- hsv_to_rgb_v(hsv, col);
+ ui_color_picker_to_rgb_v(hsv, col);
+
ui_set_but_vectorf(but, col);
}
/* also used by small picker, be careful with name checks below... */
-static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
+static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is_display_space)
{
uiBut *bt;
float *hsv = ui_block_hsv_get(block);
struct ColorManagedDisplay *display = NULL;
-
/* this is to keep the H and S value when V is equal to zero
* and we are working in HSV mode, of course!
*/
- rgb_to_hsv_compat_v(rgb, hsv);
+ if (is_display_space) {
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+ }
+ else {
+ /* we need to convert to display space to use hsv, because hsv is stored in display space */
+ float rgb_display[3];
+
+ copy_v3_v3(rgb_display, rgb);
+ ui_block_to_display_space_v3(block, rgb_display);
+ ui_rgb_to_color_picker_compat_v(rgb_display, hsv);
+ }
if (block->color_profile)
display = ui_block_display_get(block);
@@ -1683,6 +1687,7 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
}
else if (strcmp(bt->str, "Hex: ") == 0) {
float rgb_gamma[3];
+ unsigned char rgb_gamma_uchar[3];
double intpart;
char col[16];
@@ -1699,8 +1704,8 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
if (rgb_gamma[1] > 1.0f) rgb_gamma[1] = modf(rgb_gamma[1], &intpart);
if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart);
- BLI_snprintf(col, sizeof(col), "%02X%02X%02X",
- FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
+ rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma);
+ BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3OP((unsigned int), rgb_gamma_uchar));
strcpy(bt->poin, col);
}
@@ -1723,6 +1728,9 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
else if (bt->str[0] == 'V') {
ui_set_but_val(bt, hsv[2]);
}
+ else if (bt->str[0] == 'L') {
+ ui_set_but_val(bt, hsv[2]);
+ }
}
ui_check_but(bt);
@@ -1739,23 +1747,29 @@ static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
if (prop) {
RNA_property_float_get_array(&ptr, prop, rgb);
- ui_update_block_buts_rgb(but->block, rgb);
+ ui_update_block_buts_rgb(but->block, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA));
}
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
}
-static void do_hsv_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void do_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
float rgb[3];
- float *hsv = ui_block_hsv_get(but->block);
-
- hsv_to_rgb_v(hsv, rgb);
-
- ui_update_block_buts_rgb(but->block, rgb);
+ const float *hsv = ui_block_hsv_get(but->block);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+
+ ui_color_picker_to_rgb_v(hsv, rgb);
+
+ /* hsv is saved in display space so convert back */
+ if (use_display_colorspace) {
+ ui_block_to_scene_linear_v3(but->block, rgb);
+ }
+
+ ui_update_block_buts_rgb(but->block, rgb, !use_display_colorspace);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -1776,7 +1790,7 @@ static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
ui_block_to_scene_linear_v3(but->block, rgb);
}
- ui_update_block_buts_rgb(but->block, rgb);
+ ui_update_block_buts_rgb(but->block, rgb, false);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -1797,12 +1811,12 @@ static void picker_new_hide_reveal(uiBlock *block, short colormode)
/* tag buttons */
for (bt = block->buttons.first; bt; bt = bt->next) {
- if (bt->func == do_picker_rna_cb && bt->type == NUMSLI && bt->rnaindex != 3) {
+ if ((bt->func == do_picker_rna_cb) && bt->type == NUMSLI && bt->rnaindex != 3) {
/* RGB sliders (color circle and alpha are always shown) */
if (colormode == 0) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
}
- else if (bt->func == do_hsv_rna_cb) {
+ else if (bt->func == do_color_wheel_rna_cb) {
/* HSV sliders */
if (colormode == 1) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
@@ -1834,12 +1848,18 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
uiBut *bt;
/* HS circle */
- bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0, 0, "Color");
+ bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
-
+
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness");
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ }
+ else {
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value"));
+ uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ }
}
@@ -1849,11 +1869,11 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in
int bartype = type + 3;
/* HS square */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, "Color");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, "Value");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -1867,12 +1887,11 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
static char tip[50];
static char hexcol[128];
float rgb_gamma[3];
+ unsigned char rgb_gamma_uchar[3];
float softmin, softmax, hardmin, hardmax, step, precision;
float *hsv = ui_block_hsv_get(block);
int yco;
-
- ui_block_hsv_get(block);
-
+
width = PICKER_TOTAL_W;
butwidth = width - 1.5f * UI_UNIT_X;
@@ -1898,9 +1917,6 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
RNA_property_float_get_array(ptr, prop, rgba);
switch (U.color_picker_type) {
- case USER_CP_CIRCLE:
- circle_picker(block, ptr, prop);
- break;
case USER_CP_SQUARE_SV:
square_picker(block, ptr, prop, UI_GRAD_SV);
break;
@@ -1910,6 +1926,13 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
case USER_CP_SQUARE_HV:
square_picker(block, ptr, prop, UI_GRAD_HV);
break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ case USER_CP_CIRCLE_HSL:
+ default:
+ circle_picker(block, ptr, prop);
+ break;
}
/* mode */
@@ -1917,7 +1940,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
uiBlockBeginAlign(block);
bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
- bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ if (U.color_picker_type == USER_CP_CIRCLE_HSL)
+ bt = uiDefButS(block, ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ else
+ bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
@@ -1945,30 +1971,36 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
yco = -3.0f * UI_UNIT_Y;
uiBlockBeginAlign(block);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
- uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+ uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
- uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
+ uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
+ if (U.color_picker_type == USER_CP_CIRCLE_HSL)
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness"));
+ else
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
+
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
- uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+ uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
+
uiBlockEndAlign(block);
if (rgba[3] != FLT_MAX) {
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha"));
+ bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
else {
rgba[3] = 1.0f;
}
- BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
+ rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma);
+ BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3OP((unsigned int), rgb_gamma_uchar));
yco = -3.0f * UI_UNIT_Y;
bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- rgb_to_hsv_v(rgba, hsv);
+ ui_rgb_to_color_picker_v(rgb_gamma, hsv);
picker_new_hide_reveal(block, colormode);
}
@@ -1991,16 +2023,24 @@ static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, c
uiPopupBlockHandle *popup = block->handle;
float rgb[3];
float *hsv = ui_block_hsv_get(block);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
ui_get_but_vectorf(but, rgb);
-
- rgb_to_hsv_compat_v(rgb, hsv);
+
+ if (use_display_colorspace)
+ ui_block_to_display_space_v3(block, rgb);
+
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
hsv[2] = CLAMPIS(hsv[2] + add, 0.0f, 1.0f);
- hsv_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_v(hsv, rgb);
+
+ if (use_display_colorspace)
+ ui_block_to_scene_linear_v3(block, rgb);
ui_set_but_vectorf(but, rgb);
- ui_update_block_buts_rgb(block, rgb);
+ ui_update_block_buts_rgb(block, rgb, !use_display_colorspace);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -2052,11 +2092,14 @@ static unsigned int ui_popup_string_hash(const char *str)
{
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
int hash;
- char *delimit = strchr(str, UI_SEP_CHAR);
+ const char *delimit = strrchr(str, UI_SEP_CHAR);
- if (delimit) *delimit = '\0';
- hash = BLI_ghashutil_strhash(str);
- if (delimit) *delimit = UI_SEP_CHAR;
+ if (delimit) {
+ hash = BLI_ghashutil_strhash_n(str, delimit - str);
+ }
+ else {
+ hash = BLI_ghashutil_strhash(str);
+ }
return hash;
}
@@ -2106,6 +2149,29 @@ void ui_popup_menu_memory_set(uiBlock *block, uiBut *but)
ui_popup_menu_memory__internal(block, but);
}
+/**
+ * Translate any popup regions (so we can drag them).
+ */
+void ui_popup_translate(bContext *C, ARegion *ar, const int mdiff[2])
+{
+ uiBlock *block;
+
+ BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff));
+
+ ED_region_update_rect(C, ar);
+
+ ED_region_tag_redraw(ar);
+
+ /* update blocks */
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ uiSafetyRct *saferct;
+ for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
+ BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff));
+ BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff));
+ }
+ }
+}
+
/******************** Popup Menu with callback or string **********************/
struct uiPopupMenu {
@@ -2408,7 +2474,7 @@ bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports)
MenuType *mt = WM_menutype_find(idname, true);
if (mt == NULL) {
- BKE_reportf(reports, RPT_ERROR, "menu \"%s\" not found", idname);
+ BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname);
return false;
}
@@ -2509,3 +2575,51 @@ float *ui_block_hsv_get(uiBlock *block)
{
return block->_hsv;
}
+
+void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3])
+{
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ rgb_to_hsl_compat_v(rgb, r_cp);
+ break;
+ default:
+ rgb_to_hsv_compat_v(rgb, r_cp);
+ break;
+ }
+}
+
+void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3])
+{
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ rgb_to_hsl_v(rgb, r_cp);
+ break;
+ default:
+ rgb_to_hsv_v(rgb, r_cp);
+ break;
+ }
+}
+
+void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3])
+{
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ hsl_to_rgb_v(r_cp, rgb);
+ break;
+ default:
+ hsv_to_rgb_v(r_cp, rgb);
+ break;
+ }
+}
+
+void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b)
+{
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ hsl_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
+ break;
+ default:
+ hsv_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
+ break;
+ }
+}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index f9595edf616..fa31c20eb74 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -38,7 +38,6 @@
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_string.h"
@@ -56,6 +55,9 @@
#include "interface_intern.h"
+#ifdef WIN32
+# include "BLI_math_base.h" /* M_PI */
+#endif
/* style + theme + layout-engine = UI */
@@ -430,7 +432,7 @@ void uiStyleInit(void)
if (blf_mono_font_render == -1)
blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
- BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 );
+ BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72);
}
void uiStyleFontSet(uiFontStyle *fs)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index e11055fe278..e4c26d86044 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -48,24 +48,20 @@
#include "BLF_api.h"
#include "BLF_translation.h"
-#include "BKE_animsys.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
-#include "BKE_dynamicpaint.h"
#include "BKE_global.h"
+#include "BKE_idcode.h"
#include "BKE_library.h"
+#include "BKE_linestyle.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_modifier.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_packedFile.h"
#include "BKE_particle.h"
#include "BKE_report.h"
#include "BKE_sca.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_texture.h"
@@ -311,6 +307,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
Scene *scene = CTX_data_scene(C);
ED_object_single_user(bmain, scene, (struct Object *)id);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ DAG_relations_tag_update(bmain);
}
else {
if (id) {
@@ -435,8 +432,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
TIP_(template_id_browse_tip(type)));
- uiButSetDrawFlag(but, UI_BUT_DRAW_ENUM_ARROWS);
-
if (type) {
but->icon = RNA_struct_ui_icon(type);
/* default dragging of icon for id browse buttons */
@@ -452,7 +447,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
/* text button with name */
if (id) {
char name[UI_MAX_NAME_STR];
- const short user_alert = (id->us <= 0);
+ const bool user_alert = (id->us <= 0);
//text_idbutton(id, name);
name[0] = '\0';
@@ -906,7 +901,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiButSetFlag(but, UI_BUT_DISABLED);
uiButSetFunc(but, modifiers_setOnCage, ob, md);
}
- else if (modifier_supportsCage(scene, md)) {
+ else if (modifier_supportsCage(scene, md) && (index <= lastCageIndex)) {
uiBlockEndAlign(block);
/* place holder button */
@@ -943,9 +938,9 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiBlockSetEmboss(block, UI_EMBOSSN);
/* When Modifier is a simulation, show button to switch to context rather than the delete button. */
- if (modifier_can_delete(md) && !modifier_is_simulation(md))
+ if (modifier_can_delete(md) && (!modifier_is_simulation(md) || STREQ(scene->r.engine, "BLENDER_GAME")))
uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
- if (modifier_is_simulation(md) == 1)
+ else if (modifier_is_simulation(md) == 1)
uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PHYSICS");
else if (modifier_is_simulation(md) == 2)
uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PARTICLES");
@@ -1113,7 +1108,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
// int rb_col; // UNUSED
/* get constraint typeinfo */
- cti = BKE_constraint_get_typeinfo(con);
+ cti = BKE_constraint_typeinfo_get(con);
if (cti == NULL) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"), sizeof(typestr));
@@ -1122,7 +1117,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
/* determine whether constraint is proxy protected or not */
- if (BKE_proxylocked_constraints_owner(ob, pchan))
+ if (BKE_constraints_proxylocked_owner(ob, pchan))
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
else
proxy_protected = 0;
@@ -1185,7 +1180,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
*
* Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
*/
- if (BKE_proxylocked_constraints_owner(ob, pchan)) {
+ if (BKE_constraints_proxylocked_owner(ob, pchan)) {
if (con->prev) {
prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
}
@@ -1292,10 +1287,14 @@ static void do_preview_buttons(bContext *C, void *arg, int event)
}
}
-void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, MTex *slot)
+void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons, ID *parent, MTex *slot,
+ const char *preview_id)
{
uiLayout *row, *col;
uiBlock *block;
+ uiPreview *ui_preview = NULL;
+ ARegion *ar;
+
Material *ma = NULL;
Tex *tex = (Tex *)id;
ID *pid, *pparent;
@@ -1303,8 +1302,10 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
PointerRNA material_ptr;
PointerRNA texture_ptr;
- if (id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
- RNA_warning("Expected ID of type material, texture, lamp or world");
+ char _preview_id[UI_MAX_NAME_STR];
+
+ if (id && !ELEM5(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
+ RNA_warning("Expected ID of type material, texture, lamp, world or line style");
return;
}
@@ -1319,6 +1320,8 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
pr_texture = &((World *)parent)->pr_texture;
else if (parent && (GS(parent->name) == ID_LA))
pr_texture = &((Lamp *)parent)->pr_texture;
+ else if (parent && (GS(parent->name) == ID_LS))
+ pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
if (pr_texture) {
if (*pr_texture == TEX_PR_OTHER)
@@ -1328,17 +1331,44 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
}
}
+ if (!preview_id || (preview_id[0] == '\0')) {
+ /* If no identifier given, generate one from ID type. */
+ BLI_snprintf(_preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idcode_to_name(GS(id->name)));
+ preview_id = _preview_id;
+ }
+
+ /* Find or add the uiPreview to the current Region. */
+ ar = CTX_wm_region(C);
+ ui_preview = BLI_findstring(&ar->ui_previews, preview_id, offsetof(uiPreview, preview_id));
+
+ if (!ui_preview) {
+ ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
+ BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
+ ui_preview->height = (short)(UI_UNIT_Y * 5.6f);
+ BLI_addtail(&ar->ui_previews, ui_preview);
+ }
+
+ if (ui_preview->height < UI_UNIT_Y) {
+ ui_preview->height = UI_UNIT_Y;
+ }
+ else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
+ ui_preview->height = UI_UNIT_Y * 50;
+ }
+
/* layout */
block = uiLayoutGetBlock(layout);
row = uiLayoutRow(layout, false);
col = uiLayoutColumn(row, false);
uiLayoutSetKeepAspect(col, true);
-
+
/* add preview */
- uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, pid, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, "");
uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent, slot);
uiBlockSetHandleFunc(block, do_preview_buttons, NULL);
-
+
+ uiDefIconButS(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height,
+ UI_UNIT_Y, UI_UNIT_Y * 50.0f, 0.0f, 0.0f, "");
+
/* add buttons */
if (pid && show_buttons) {
if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
@@ -1372,6 +1402,10 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
+ else if (GS(parent->name) == ID_LS) {
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+ }
uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
@@ -1463,7 +1497,7 @@ static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
}
static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr,
- RNAUpdateCb *cb, int expand)
+ RNAUpdateCb *cb, int expand)
{
uiLayout *row, *split, *subsplit;
uiBut *bt;
@@ -1524,6 +1558,8 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
row = uiLayoutRow(layout, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
+ bt = block->buttons.last;
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
}
else {
split = uiLayoutSplit(layout, 0.5f, false);
@@ -1539,6 +1575,8 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
+ bt = block->buttons.last;
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
}
}
}
@@ -1669,39 +1707,33 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
PointerRNA cptr;
- RNAUpdateCb *cb;
uiBlock *block;
- uiBut *bt;
+ uiLayout *col;
Histogram *hist;
- rctf rect;
-
+
if (!prop || RNA_property_type(prop) != PROP_POINTER)
return;
-
+
cptr = RNA_property_pointer_get(ptr, prop);
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram))
return;
-
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
- rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
-
- block = uiLayoutAbsoluteBlock(layout);
- //colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
-
hist = (Histogram *)cptr.data;
- hist->height = (hist->height <= 20) ? 20 : hist->height;
+ if (hist->height < UI_UNIT_Y) {
+ hist->height = UI_UNIT_Y;
+ }
+ else if (hist->height > UI_UNIT_Y * 20) {
+ hist->height = UI_UNIT_Y * 20;
+ }
- bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height,
- hist, 0, 0, 0, 0, "");
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ uiDefBut(block, HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
- MEM_freeN(cb);
+ /* Resize grip. */
+ uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height,
+ UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
/********************* Waveform Template ************************/
@@ -1710,36 +1742,33 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
PointerRNA cptr;
- RNAUpdateCb *cb;
uiBlock *block;
- uiBut *bt;
+ uiLayout *col;
Scopes *scopes;
- rctf rect;
-
+
if (!prop || RNA_property_type(prop) != PROP_POINTER)
return;
-
+
cptr = RNA_property_pointer_get(ptr, prop);
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
return;
scopes = (Scopes *)cptr.data;
-
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
- rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
-
- block = uiLayoutAbsoluteBlock(layout);
-
- scopes->wavefrm_height = (scopes->wavefrm_height <= 20) ? 20 : scopes->wavefrm_height;
- bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height,
- scopes, 0, 0, 0, 0, "");
- (void)bt; /* UNUSED */
-
- MEM_freeN(cb);
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (scopes->wavefrm_height < UI_UNIT_Y) {
+ scopes->wavefrm_height = UI_UNIT_Y;
+ }
+ else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
+ scopes->wavefrm_height = UI_UNIT_Y * 20;
+ }
+
+ uiDefBut(block, WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
+
+ /* Resize grip. */
+ uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height,
+ UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
/********************* Vectorscope Template ************************/
@@ -1748,36 +1777,33 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
PointerRNA cptr;
- RNAUpdateCb *cb;
uiBlock *block;
- uiBut *bt;
+ uiLayout *col;
Scopes *scopes;
- rctf rect;
-
+
if (!prop || RNA_property_type(prop) != PROP_POINTER)
return;
-
+
cptr = RNA_property_pointer_get(ptr, prop);
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
return;
scopes = (Scopes *)cptr.data;
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
- rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
- rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
-
- block = uiLayoutAbsoluteBlock(layout);
+ if (scopes->vecscope_height < UI_UNIT_Y) {
+ scopes->vecscope_height = UI_UNIT_Y;
+ }
+ else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
+ scopes->vecscope_height = UI_UNIT_Y * 20;
+ }
- scopes->vecscope_height = (scopes->vecscope_height <= 20) ? 20 : scopes->vecscope_height;
-
- bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
- UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- MEM_freeN(cb);
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiDefBut(block, VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
+
+ /* Resize grip. */
+ uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height,
+ UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
/********************* CurveMapping Template ************************/
@@ -2238,10 +2264,6 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
row = uiLayoutRow(col, true);
switch (U.color_picker_type) {
- case USER_CP_CIRCLE:
- but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
- -1, 0.0, 0.0, 0, 0, "");
- break;
case USER_CP_SQUARE_SV:
but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, UI_GRAD_SV, 0, "");
@@ -2254,6 +2276,15 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, UI_GRAD_HV, 0, "");
break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ case USER_CP_CIRCLE_HSL:
+ default:
+ but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ -1, 0.0, 0.0, 0, 0, "");
+ break;
+
}
if (lock) {
@@ -2273,10 +2304,10 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
if (value_slider) {
switch (U.color_picker_type) {
- case USER_CP_CIRCLE:
+ case USER_CP_CIRCLE_HSL:
uiItemS(row);
uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
- -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+ -1, softmin, softmax, UI_GRAD_L_ALT, 0, "");
break;
case USER_CP_SQUARE_SV:
uiItemS(col);
@@ -2293,6 +2324,14 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
-1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ default:
+ uiItemS(row);
+ uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+ break;
}
}
}
@@ -2393,7 +2432,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname,
}
void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propname,
- PointerRNA *used_ptr, const char *used_propname, int active_state)
+ PointerRNA *used_ptr, const char *used_propname, int active_state)
{
uiLayout *uRow, *uCol;
PropertyRNA *prop, *used_prop = NULL;
@@ -2646,30 +2685,17 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma
{
uiListDyn *dyn_data = ui_list->dyn_data;
int activei_row, max_scroll;
+ const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD));
/* default rows */
- if (rows == 0)
+ if (rows <= 0)
rows = 5;
dyn_data->visual_height_min = rows;
- if (maxrows == 0)
- maxrows = 5;
- if (columns == 0)
+ if (maxrows < rows)
+ maxrows = max_ii(rows, 5);
+ if (columns <= 0)
columns = 9;
- if (ui_list->list_grip >= (rows - 1) && ui_list->list_grip != 0) {
- /* Only enable auto-size mode when we have dragged one row away from minimum size.
- * Avoids to switch too easily to auto-size mode when resizing to minimum size...
- */
- maxrows = rows = max_ii(ui_list->list_grip, rows);
- }
- else {
- ui_list->list_grip = 0; /* Reset to auto-size mode. */
- /* Prevent auto-size mode to take effect while grab-resizing! */
- if (ui_list->flag & UILST_RESIZING) {
- maxrows = rows;
- }
- }
-
if (columns > 1) {
dyn_data->height = (int)ceil((double)len / (double)columns);
activei_row = (int)floor((double)activei / (double)columns);
@@ -2679,8 +2705,12 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma
activei_row = activei;
}
- /* Expand size if needed and possible. */
- if ((ui_list->list_grip == 0) && (rows != maxrows) && (dyn_data->height > rows)) {
+ if (!use_auto_size) {
+ /* No auto-size, yet we clamp at min size! */
+ maxrows = rows = max_ii(ui_list->list_grip, rows);
+ }
+ else if ((rows != maxrows) && (dyn_data->height > rows)) {
+ /* Expand size if needed and possible. */
rows = min_ii(dyn_data->height, maxrows);
}
@@ -2704,6 +2734,21 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma
layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
}
+static void ui_list_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2))
+{
+ uiList *ui_list = arg1;
+ uiListDyn *dyn_data = ui_list->dyn_data;
+
+ /* This way we get diff in number of additional items to show (positive) or hide (negative). */
+ const int diff = iroundf((float)(dyn_data->resize - dyn_data->resize_prev) / (float)UI_UNIT_Y);
+
+ if (diff != 0) {
+ ui_list->list_grip += diff;
+ dyn_data->resize_prev += diff * UI_UNIT_Y;
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ }
+}
+
void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
int rows, int maxrows, int layout_type, int columns)
@@ -2810,6 +2855,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
if (!ui_list->dyn_data) {
ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data");
+ ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
}
dyn_data = ui_list->dyn_data;
@@ -2931,7 +2977,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
sub = uiLayoutRow(overlap, false);
but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- active_dataptr, activeprop, 0, 0, org_i, 0, 0, "Double click to rename");
+ active_dataptr, activeprop, 0, 0, org_i, 0, 0, TIP_("Double click to rename"));
sub = uiLayoutRow(overlap, false);
@@ -3055,19 +3101,31 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
}
if (glob) {
+ /* About GRIP drag-resize:
+ * We can't directly use results from GRIP button, since we have a rather complex behavior here
+ * (sizing by discrete steps and, overall, autosize feature).
+ * Since we *never* know whether we are grip-resizing or not (because there is no callback for when a
+ * button enters/leaves its "edit mode"), we use the fact that grip-controlled value (dyn_data->resize)
+ * is completely handled by the grip during the grab resize, so settings its value here has no effect
+ * at all.
+ * It is only meaningful when we are not resizing, in which case this gives us the correct "init drag" value.
+ * Note we cannot affect dyn_data->resize_prev here, since this value is not controlled by the grip!
+ */
+ dyn_data->resize = dyn_data->resize_prev + (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
+
row = uiLayoutRow(glob, true);
subblock = uiLayoutGetBlock(row);
uiBlockSetEmboss(subblock, UI_EMBOSSN);
if (ui_list->filter_flag & UILST_FLT_SHOW) {
but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0,
- UI_UNIT_X, UI_UNIT_Y * 0.8f, &(ui_list->filter_flag), 0, 0, 0, 0,
+ UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
TIP_("Hide filtering options"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.8f, ui_list,
- 0.0, 0.0, 0, -1, "");
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+ but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
+ &dyn_data->resize, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL);
uiBlockSetEmboss(subblock, UI_EMBOSS);
@@ -3079,13 +3137,13 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
}
else {
but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0,
- UI_UNIT_X, UI_UNIT_Y * 0.8f, &(ui_list->filter_flag), 0, 0, 0, 0,
+ UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
TIP_("Show filtering options"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconBut(subblock, BUT, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.8f, ui_list,
- 0.0, 0.0, 0, -1, "");
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+ but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
+ &dyn_data->resize, 0.0, 0.0, 0, 0, "");
+ uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL);
uiBlockSetEmboss(subblock, UI_EMBOSS);
}
@@ -3232,7 +3290,9 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
handle_event = B_STOPCOMPO;
break;
}
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) {
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE) ||
+ WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE))
+ {
/* Skip bake jobs in compositor to avoid compo header displaying
* progress bar which is not being updated (bake jobs only need
* to update NC_IMAGE context.
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index fc87801d6a3..2c958c5028a 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -43,7 +43,6 @@
#include "BLF_translation.h"
-#include "BKE_context.h"
#include "BKE_report.h"
#include "MEM_guardedalloc.h"
@@ -99,7 +98,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
else if (icon)
but = uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but = uiDefButR_prop(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
case PROP_STRING:
if (icon && name && name[0] == '\0')
@@ -172,16 +171,14 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr,
if (!is_boolean)
uiItemL(col, name, ICON_NONE);
}
- else if (label_align == 'H') {
+ else { /* (label_align == 'H') */
+ BLI_assert(label_align == 'H');
split = uiLayoutSplit(layout, 0.5f, false);
col = uiLayoutColumn(split, false);
uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
col = uiLayoutColumn(split, false);
}
- else {
- col = NULL;
- }
/* may meed to add more cases here.
* don't override enum flag names */
@@ -325,7 +322,7 @@ struct uiButStoreElem {
};
/**
- * Create a new button sture, the caller must manage and run #UI_butstore_free
+ * Create a new button store, the caller must manage and run #UI_butstore_free
*/
uiButStore *UI_butstore_create(uiBlock *block)
{
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index b8dd2eadd21..b91f330c730 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -38,7 +38,6 @@
#include "BIF_glutil.h"
#include "BLI_math.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
@@ -638,15 +637,15 @@ static void shadecolors4(char coltop[4], char coldown[4], const char *color, sho
coldown[3] = color[3];
}
-static void round_box_shade_col4_r(unsigned char col_r[4], const char col1[4], const char col2[4], const float fac)
+static void round_box_shade_col4_r(unsigned char r_col[4], const char col1[4], const char col2[4], const float fac)
{
const int faci = FTOCHAR(fac);
const int facm = 255 - faci;
- col_r[0] = (faci * col1[0] + facm * col2[0]) >> 8;
- col_r[1] = (faci * col1[1] + facm * col2[1]) >> 8;
- col_r[2] = (faci * col1[2] + facm * col2[2]) >> 8;
- col_r[3] = (faci * col1[3] + facm * col2[3]) >> 8;
+ r_col[0] = (faci * col1[0] + facm * col2[0]) >> 8;
+ r_col[1] = (faci * col1[1] + facm * col2[1]) >> 8;
+ r_col[2] = (faci * col1[2] + facm * col2[2]) >> 8;
+ r_col[3] = (faci * col1[3] + facm * col2[3]) >> 8;
}
static void widget_verts_to_quad_strip(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2])
@@ -888,7 +887,9 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
float aspect, height;
if (but->flag & UI_ICON_PREVIEW) {
+ glEnable(GL_BLEND);
widget_draw_preview(icon, alpha, rect);
+ glDisable(GL_BLEND);
return;
}
@@ -956,18 +957,18 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
glDisable(GL_BLEND);
}
-static void ui_text_clip_give_prev_off(uiBut *but)
+static void ui_text_clip_give_prev_off(uiBut *but, const char *str)
{
- char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + but->ofs);
- int bytes = but->drawstr + but->ofs - prev_utf8;
+ const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs);
+ int bytes = str + but->ofs - prev_utf8;
but->ofs -= bytes;
}
-static void ui_text_clip_give_next_off(uiBut *but)
+static void ui_text_clip_give_next_off(uiBut *but, const char *str)
{
- char *next_utf8 = BLI_str_find_next_char_utf8(but->drawstr + but->ofs, NULL);
- int bytes = next_utf8 - (but->drawstr + but->ofs);
+ const char *next_utf8 = BLI_str_find_next_char_utf8(str + but->ofs, NULL);
+ int bytes = next_utf8 - (str + but->ofs);
but->ofs += bytes;
}
@@ -993,7 +994,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
but->ofs = 0;
but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr));
- if (but->strwidth > okwidth) {
+ if ((okwidth > 0.0f) && (but->strwidth > okwidth)) {
float strwidth;
but->ofs = BLF_width_to_rstrlen(fstyle->uifont_id, but->drawstr,
sizeof(but->drawstr), okwidth, &strwidth);
@@ -1009,66 +1010,68 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
* This func assumes things like kerning handling have already been handled!
* Return the length of modified (right-clipped + ellipsis) string.
*/
-static void ui_text_clip_right_ex(uiFontStyle *fstyle, uiBut *but, const size_t max_len, const float okwidth,
+static void ui_text_clip_right_ex(uiFontStyle *fstyle, char *str, const size_t max_len, const float okwidth,
const char *sep, const int sep_len, const float sep_strwidth)
{
float tmp;
int l_end;
+ BLI_assert(str[0]);
+
/* If the trailing ellipsis takes more than 20% of all available width, just cut the string
* (as using the ellipsis would remove even more useful chars, and we cannot show much already!).
*/
if (sep_strwidth / okwidth > 0.2f) {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth, &tmp);
- but->drawstr[l_end] = '\0';
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
+ str[l_end] = '\0';
}
else {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth - sep_strwidth, &tmp);
- memcpy(but->drawstr + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
+ memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
}
}
/**
- * Cut off the middle of the text to fit into the width of \a rect.
+ * Cut off the middle of the text to fit into the given width.
* Note in case this middle clipping would just remove a few chars, it rather clips right, which is more readable.
*/
-static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
+static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, const float okwidth, const float minwidth,
+ const size_t max_len)
{
- /* No margin for labels! */
- const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
- const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
float strwidth;
- const size_t max_len = sizeof(but->drawstr);
+
+ BLI_assert(str[0]);
/* need to set this first */
uiStyleFontSet(fstyle);
- if (fstyle->kerning == 1) /* for BLF_width */
+ if (fstyle->kerning == 1) { /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
- but->ofs = 0;
- strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
+ strwidth = BLF_width(fstyle->uifont_id, str, max_len);
- if (strwidth > okwidth) {
- const char sep[] = "…";
+ if ((okwidth > 0.0f) && (strwidth > okwidth)) {
+ /* utf8 ellipsis '...', some compilers complain */
+ const char sep[] = {0xe2, 0x80, 0xa6, 0x0};
const int sep_len = sizeof(sep) - 1;
size_t l_end;
const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);
const float parts_strwidth = ((float)okwidth - sep_strwidth) / 2.0f;
- if (min_ff(parts_strwidth, strwidth - okwidth) < (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f) {
+ if (min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
/* If we really have no place, or we would clip a very small piece of string in the middle,
* only show start of string.
*/
- ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
+ ui_text_clip_right_ex(fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth);
}
else {
size_t r_offset, r_len;
- l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, parts_strwidth, &strwidth);
- r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, but->drawstr, max_len, parts_strwidth, &strwidth);
- r_len = strlen(but->drawstr + r_offset) + 1; /* +1 for the trailing '\0'... */
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, &strwidth);
+ r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, &strwidth);
+ r_len = strlen(str + r_offset) + 1; /* +1 for the trailing '\0'... */
if (l_end + sep_len + r_len > max_len) {
/* Corner case, the str already takes all available mem, and the ellipsis chars would actually
@@ -1076,21 +1079,33 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
* Better to just trim one or two letters to the right in this case...
* Note: with a single-char ellipsis, this should never happen! But better be safe here...
*/
- ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
+ ui_text_clip_right_ex(fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth);
}
else {
- memmove(but->drawstr + l_end + sep_len, but->drawstr + r_offset, r_len);
- memcpy(but->drawstr + l_end, sep, sep_len);
+ memmove(str + l_end + sep_len, str + r_offset, r_len);
+ memcpy(str + l_end, sep, sep_len);
}
}
- strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
+ strwidth = BLF_width(fstyle->uifont_id, str, max_len);
}
- but->strwidth = strwidth;
-
if (fstyle->kerning == 1) {
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
+
+ return strwidth;
+}
+
+static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
+{
+ /* No margin for labels! */
+ const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
+ const size_t max_len = sizeof(but->drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
+
+ but->ofs = 0;
+ but->strwidth = ui_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len);
}
/**
@@ -1113,36 +1128,39 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec
if (but->ofs > but->pos)
but->ofs = but->pos;
- if (BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr)) <= okwidth)
+ if (BLF_width(fstyle->uifont_id, but->editstr, INT_MAX) <= okwidth)
but->ofs = 0;
- but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
+ but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, INT_MAX);
- while (but->strwidth > okwidth) {
- float width;
+ if (but->strwidth > okwidth) {
+ int len = strlen(but->editstr);
- /* string position of cursor */
- width = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, but->pos - but->ofs);
+ while (but->strwidth > okwidth) {
+ float width;
- /* if cursor is at 20 pixels of right side button we clip left */
- if (width > okwidth - 20) {
- ui_text_clip_give_next_off(but);
- }
- else {
- int len, bytes;
- /* shift string to the left */
- if (width < 20 && but->ofs > 0)
- ui_text_clip_give_prev_off(but);
- len = strlen(but->drawstr);
- bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + len));
- if (bytes < 0)
- bytes = 1;
- but->drawstr[len - bytes] = 0;
- }
+ /* string position of cursor */
+ width = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, (but->pos - but->ofs));
- but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
+ /* if cursor is at 20 pixels of right side button we clip left */
+ if (width > okwidth - 20) {
+ ui_text_clip_give_next_off(but, but->editstr);
+ }
+ else {
+ int bytes;
+ /* shift string to the left */
+ if (width < 20 && but->ofs > 0)
+ ui_text_clip_give_prev_off(but, but->editstr);
+ bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->editstr, but->editstr + len));
+ if (bytes == -1)
+ bytes = 1;
+ len -= bytes;
+ }
+
+ but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, len - but->ofs);
- if (but->strwidth < 10) break;
+ if (but->strwidth < 10) break;
+ }
}
if (fstyle->kerning == 1) {
@@ -1161,7 +1179,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
char *cpoin = NULL;
int drawstr_len = strlen(but->drawstr);
- char *cpend = but->drawstr + drawstr_len;
+ const char *cpend = but->drawstr + drawstr_len;
/* need to set this first */
uiStyleFontSet(fstyle);
@@ -1173,7 +1191,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
but->ofs = 0;
- /* First shorten num-buttopns eg,
+ /* First shorten num-buttons eg,
* Translucency: 0.000
* becomes
* Trans: 0.000
@@ -1187,7 +1205,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
/* chop off the leading text, starting from the right */
while (but->strwidth > okwidth && cp2 > but->drawstr) {
- char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2);
+ const char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2);
int bytes = cp2 - prev_utf8;
/* shift the text after and including cp2 back by 1 char, +1 to include null terminator */
@@ -1204,7 +1222,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
/* after the leading text is gone, chop off the : and following space, with ofs */
while ((but->strwidth > okwidth) && (but->ofs < 2)) {
- ui_text_clip_give_next_off(but);
+ ui_text_clip_give_next_off(but, but->drawstr);
but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
if (but->strwidth < 10) break;
}
@@ -1226,7 +1244,6 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
-
static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
int drawstr_left_len = UI_MAX_DRAW_STR;
@@ -1250,13 +1267,18 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* Special case: when we're entering text for multiple buttons,
* don't draw the text for any of the multi-editing buttons */
if (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI)) {
- uiBut *but_iter;
- for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) {
- if (but_iter->editstr) {
- drawstr = but_iter->editstr;
- fstyle->align = UI_STYLE_TEXT_LEFT;
- break;
- }
+ uiBut *but_edit = ui_get_but_drag_multi_edit(but);
+ if (but_edit) {
+ drawstr = but_edit->editstr;
+ fstyle->align = UI_STYLE_TEXT_LEFT;
+ }
+ }
+ else {
+ if (but->editstr) {
+ /* max length isn't used in this case,
+ * we rely on string being NULL terminated. */
+ drawstr_left_len = INT_MAX;
+ drawstr = but->editstr;
}
}
@@ -1309,9 +1331,11 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
#endif
/* cut string in 2 parts - only for menu entries */
- if ((but->block->flag & UI_BLOCK_LOOP)) {
- if (ELEM3(but->type, NUM, TEX, NUMSLI) == 0) {
- drawstr_right = strchr(drawstr, UI_SEP_CHAR);
+ if ((but->block->flag & UI_BLOCK_LOOP) &&
+ (but->editstr == NULL))
+ {
+ if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+ drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
if (drawstr_right) {
drawstr_left_len = (drawstr_right - drawstr);
drawstr_right++;
@@ -1352,7 +1376,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
if (but->menu_key != '\0') {
char fixedbuf[128];
- char *str;
+ const char *str;
BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawstr_left_len));
@@ -1394,12 +1418,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* draws text and icons for buttons */
static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
+ const bool show_menu_icon = ui_but_draw_menu_icon(but);
float alpha = (float)wcol->text[3] / 255.0f;
char password_str[UI_MAX_DRAW_STR];
- if (but == NULL)
- return;
-
ui_button_text_password_hide(password_str, but, false);
/* check for button text label */
@@ -1412,8 +1434,8 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
/* If there's an icon too (made with uiDefIconTextBut) then draw the icon
* and offset the text label to accommodate it */
- if (but->flag & UI_HAS_ICON) {
- const bool show_menu_icon = ui_but_draw_menu_icon(but);
+ if (but->flag & UI_HAS_ICON || show_menu_icon) {
+ const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
const float icon_size = ICON_SIZE_FROM_BUTRECT(rect);
/* menu item - add some more padding so menus don't feel cramped. it must
@@ -1421,7 +1443,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
if (ui_block_is_menu(but->block))
rect->xmin += 0.3f * U.widget_unit;
- widget_draw_icon(but, but->icon + but->iconadd, alpha, rect, show_menu_icon);
+ widget_draw_icon(but, icon, alpha, rect, show_menu_icon);
rect->xmin += icon_size;
/* without this menu keybindings will overlap the arrow icon [#38083] */
@@ -1450,6 +1472,11 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
if (but->editstr && but->pos >= 0) {
ui_text_clip_cursor(fstyle, but, rect);
}
+ else if (but->drawstr[0] == '\0') {
+ /* bypass text clipping on icon buttons */
+ but->ofs = 0;
+ but->strwidth = 0;
+ }
else if (ELEM(but->type, NUM, NUMSLI)) {
ui_text_clip_right_label(fstyle, but, rect);
}
@@ -2065,7 +2092,7 @@ void ui_hsvcircle_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float
ang = 2.0f * (float)M_PI * hsv[0] + 0.5f * (float)M_PI;
- if (but->flag & UI_BUT_COLOR_CUBIC)
+ if ((but->flag & UI_BUT_COLOR_CUBIC) && (U.color_picker_type == USER_CP_CIRCLE_HSV))
radius_t = (1.0f - powf(1.0f - hsv[1], 3.0f));
else
radius_t = hsv[1];
@@ -2088,13 +2115,10 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
float xpos, ypos, ang = 0.0f;
float rgb[3], hsvo[3], hsv[3], col[3], colcent[3];
int a;
- bool color_profile = but->block->color_profile;
-
+ bool color_profile = ui_color_picker_use_display_colorspace(but);
+
gpuImmediateFormat_C4_V3();
- if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- color_profile = false;
-
/* color */
ui_get_but_vectorf(but, rgb);
@@ -2103,20 +2127,25 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
hsvo[1] = hsv[1] = hsv_ptr[1];
hsvo[2] = hsv[2] = hsv_ptr[2];
- rgb_to_hsv_compat_v(rgb, hsvo);
-
if (color_profile)
ui_block_to_display_space_v3(but->block, rgb);
- rgb_to_hsv_compat_v(rgb, hsv);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+ copy_v3_v3(hsvo, hsv);
+
+ CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
/* exception: if 'lock' is set
* lock the value of the color wheel to 1.
* Useful for color correction tools where you're only interested in hue. */
- if (but->flag & UI_BUT_COLOR_LOCK)
- hsv[2] = 1.f;
+ if (but->flag & UI_BUT_COLOR_LOCK) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV)
+ hsv[2] = 1.f;
+ else
+ hsv[2] = 0.5f;
+ }
- hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent + 1, colcent + 2);
+ ui_color_picker_to_rgb(0.f, 0.f, hsv[2], colcent, colcent + 1, colcent + 2);
// SSS Enable Smooth
GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
@@ -2130,9 +2159,9 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
float co = cos(ang);
ui_hsvcircle_vals_from_pos(hsv, hsv + 1, rect, centx + co * radius, centy + si * radius);
- CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
- hsv_to_rgb_v(hsv, col);
+ ui_color_picker_to_rgb_v(hsv, col);
+
gpuColor3fv(col);
gpuVertex2f(centx + co * radius, centy + si * radius);
}
@@ -2311,7 +2340,7 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_SMOOTH);
}
-bool ui_hsvcube_use_display_colorspace(uiBut *but)
+bool ui_color_picker_use_display_colorspace(uiBut *but)
{
bool color_profile = but->block->color_profile;
@@ -2320,8 +2349,7 @@ bool ui_hsvcube_use_display_colorspace(uiBut *but)
color_profile = false;
}
- /* SV+H gradient does not use display colorspace */
- return color_profile && !ELEM((int)but->a1, UI_GRAD_SV, UI_GRAD_H);
+ return color_profile;
}
void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp)
@@ -2341,10 +2369,15 @@ void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *x
x = hsv[1]; y = 0.5; break;
case UI_GRAD_V:
x = hsv[2]; y = 0.5; break;
+ case UI_GRAD_L_ALT:
+ x = 0.5f;
+ /* exception only for value strip - use the range set in but->min/max */
+ y = hsv[2];
+ break;
case UI_GRAD_V_ALT:
x = 0.5f;
/* exception only for value strip - use the range set in but->min/max */
- y = (hsv[2] - but->softmin ) / (but->softmax - but->softmin);
+ y = (hsv[2] - but->softmin) / (but->softmax - but->softmin);
break;
}
@@ -2358,9 +2391,9 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
{
float rgb[3];
float x = 0.0f, y = 0.0f;
- float *hsv = ui_block_hsv_get(but->block);
+ const float *hsv = ui_block_hsv_get(but->block);
float hsv_n[3];
- bool use_display_colorspace = ui_hsvcube_use_display_colorspace(but);
+ bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
gpuImmediateFormat_C4_V3();
@@ -2394,7 +2427,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
uiWidgetBase wtb;
const float rad = 0.5f * BLI_rcti_size_x(rect);
float x, y;
- float rgb[3], hsv[3], v, range;
+ float rgb[3], hsv[3], v;
bool color_profile = but->block->color_profile;
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
@@ -2405,12 +2438,17 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
if (color_profile)
ui_block_to_display_space_v3(but->block, rgb);
- rgb_to_hsv_v(rgb, hsv);
+ if (but->a1 == UI_GRAD_L_ALT)
+ rgb_to_hsl_v(rgb, hsv);
+ else
+ rgb_to_hsv_v(rgb, hsv);
v = hsv[2];
/* map v from property range to [0,1] */
- range = but->softmax - but->softmin;
- v = (v - but->softmin) / range;
+ if (but->a1 == UI_GRAD_V_ALT) {
+ float range = but->softmax - but->softmin;
+ v = (v - but->softmin) / range;
+ }
widget_init(&wtb);
@@ -2478,9 +2516,11 @@ static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int
widgetbase_draw(&wtb, wcol);
- /* text space */
- rect->xmin += textofs;
- rect->xmax -= textofs;
+ if (!(state & UI_TEXTINPUT)) {
+ /* text space */
+ rect->xmin += textofs;
+ rect->xmax -= textofs;
+ }
}
static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
@@ -2496,7 +2536,7 @@ static void widget_numbut_embossn(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
widget_numbut_draw(wcol, rect, state, roundboxalign, true);
}
-int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
+bool ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
{
float dist, vec[4][2];
@@ -2513,9 +2553,9 @@ int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
vec[2][0] = vec[3][0] - dist;
vec[2][1] = vec[3][1];
- BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float) * 2);
- BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0] + 1, resol, sizeof(float) * 2);
-
+ BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], &coord_array[0][0], resol, sizeof(float[2]));
+ BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], &coord_array[0][1], resol, sizeof(float[2]));
+
return 1;
}
@@ -2795,8 +2835,10 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
widgetbase_draw(&wtb, wcol);
/* add space at either side of the button so text aligns with numbuttons (which have arrow icons) */
- rect->xmax -= toffs;
- rect->xmin += toffs;
+ if (!(state & UI_TEXTINPUT)) {
+ rect->xmax -= toffs;
+ rect->xmin += toffs;
+ }
}
@@ -3483,20 +3525,26 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case MENU:
case BLOCK:
- /* new node-link button, not active yet XXX */
- if (but->flag & UI_BUT_NODE_LINK)
+ if (but->flag & UI_BUT_NODE_LINK) {
+ /* new node-link button, not active yet XXX */
wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
-
- /* no text, with icon */
- else if (!but->str[0] && but->icon) {
- if (but->drawflag & UI_BUT_DRAW_ENUM_ARROWS)
- wt = widget_type(UI_WTYPE_MENU_RADIO); /* with arrows */
- else
- wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */
}
- /* with menu arrows */
- else
- wt = widget_type(UI_WTYPE_MENU_RADIO);
+ else {
+ /* with menu arrows */
+
+ /* we could use a flag for this, but for now just check size,
+ * add updown arrows if there is room. */
+ if ((!but->str[0] && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
+ /* disable for brushes also */
+ (but->flag & UI_ICON_PREVIEW))
+ {
+ /* no arrows */
+ wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
+ }
+ else {
+ wt = widget_type(UI_WTYPE_MENU_RADIO);
+ }
+ }
break;
case PULLDOWN:
@@ -3528,7 +3576,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case HSVCUBE:
- if (but->a1 == UI_GRAD_V_ALT) { /* vertical V slider, uses new widget draw now */
+ if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) { /* vertical V slider, uses new widget draw now */
ui_draw_but_HSV_v(but, rect);
}
else { /* other HSV pickers... */
@@ -3577,6 +3625,10 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
wt = widget_type(UI_WTYPE_SCROLL);
break;
+ case GRIP:
+ wt = widget_type(UI_WTYPE_ICON);
+ break;
+
case TRACKPREVIEW:
ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect);
break;
@@ -3599,8 +3651,13 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
roundboxalign = widget_roundbox_set(but, rect);
state = but->flag;
- if (but->editstr) state |= UI_TEXTINPUT;
-
+
+ if ((but->editstr) ||
+ (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_get_but_drag_multi_edit(but)))
+ {
+ state |= UI_TEXTINPUT;
+ }
+
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE))
if (but->dt != UI_EMBOSSP)
disabled = true;
@@ -3687,7 +3744,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
{
uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
rcti _rect = *rect;
- char *cpoin;
+ char *cpoin = NULL;
wt->state(wt, state);
wt->draw(&wt->wcol, rect, 0, 0);
@@ -3704,13 +3761,35 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
cpoin = strchr(name, UI_SEP_CHAR);
if (cpoin) {
*cpoin = 0;
- rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + 10;
+
+ /* need to set this first */
+ uiStyleFontSet(fstyle);
+
+ if (fstyle->kerning == 1) { /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
}
-
- gpuColor4ubv((unsigned char *)wt->wcol.text);
- uiStyleFontDraw(fstyle, rect, name);
-
+
+ {
+ char drawstr[UI_MAX_DRAW_STR];
+ const float okwidth = (float)BLI_rcti_size_x(rect);
+ const size_t max_len = sizeof(drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE);
+
+ BLI_strncpy(drawstr, name, sizeof(drawstr));
+ ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len);
+
+ gpuColor4ubv((unsigned char *)wt->wcol.text);
+ uiStyleFontDraw(fstyle, rect, drawstr);
+ }
+
/* part text right aligned */
if (use_sep) {
if (cpoin) {
@@ -3747,6 +3826,7 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
wt->state(wt, state);
wt->draw(&wt->wcol, rect, 0, 0);
+ glEnable(GL_BLEND);
widget_draw_preview(iconid, 1.0f, rect);
BLF_width_and_height(fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
@@ -3769,11 +3849,19 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
bg_rect.xmax = rect->xmax - PREVIEW_PAD;
gpuColor4ubv((unsigned char *)wt->wcol_theme->inner_sel);
- glEnable(GL_BLEND);
gpuSingleFilledRecti(bg_rect.xmin, bg_rect.ymin, bg_rect.xmax, bg_rect.ymax);
glDisable(GL_BLEND);
-
- gpuColor3ubv((unsigned char *)wt->wcol.text);
- uiStyleFontDraw(fstyle, &trect, name);
+ {
+ char drawstr[UI_MAX_DRAW_STR];
+ const float okwidth = (float)BLI_rcti_size_x(&trect);
+ const size_t max_len = sizeof(drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE);
+
+ BLI_strncpy(drawstr, name, sizeof(drawstr));
+ ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len);
+
+ gpuColor4ubv((unsigned char *)wt->wcol.text);
+ uiStyleFontDraw(fstyle, &trect, drawstr);
+ }
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 00e30546ca5..f1ebff5e0e4 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -92,6 +92,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
static char setting = 0;
const char *cp = error;
+ /* ensure we're not getting a color after running BKE_userdef_free */
+ BLI_assert(BLI_findindex(&U.themes, theme_active) != -1);
+
if (btheme) {
/* first check for ui buttons theme */
@@ -267,6 +270,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_GRID:
cp = ts->grid; break;
+ case TH_VIEW_OVERLAY:
+ cp = ts->view_overlay; break;
case TH_WIRE:
cp = ts->wire; break;
case TH_WIRE_EDIT:
@@ -746,8 +751,8 @@ static void ui_theme_init_new_do(ThemeSpace *ts)
rgba_char_args_set(ts->list_text_hi, 255, 255, 255, 255);
rgba_char_args_set(ts->tab_active, 114, 114, 114, 255);
- rgba_char_args_set(ts->tab_inactive, 100, 100, 100, 255);
- rgba_char_args_set(ts->tab_back, 70, 70, 70, 255);
+ rgba_char_args_set(ts->tab_inactive, 83, 83, 83, 255);
+ rgba_char_args_set(ts->tab_back, 64, 64, 64, 255);
rgba_char_args_set(ts->tab_outline, 60, 60, 60, 255);
}
@@ -760,6 +765,18 @@ static void ui_theme_init_new(bTheme *btheme)
}
}
+static void ui_theme_space_init_handles_color(ThemeSpace *theme_space)
+{
+ rgba_char_args_set(theme_space->handle_free, 0, 0, 0, 255);
+ rgba_char_args_set(theme_space->handle_auto, 0x90, 0x90, 0x00, 255);
+ rgba_char_args_set(theme_space->handle_vect, 0x40, 0x90, 0x30, 255);
+ rgba_char_args_set(theme_space->handle_align, 0x80, 0x30, 0x60, 255);
+ rgba_char_args_set(theme_space->handle_sel_free, 0, 0, 0, 255);
+ rgba_char_args_set(theme_space->handle_sel_auto, 0xf0, 0xff, 0x40, 255);
+ rgba_char_args_set(theme_space->handle_sel_vect, 0x40, 0xc0, 0x30, 255);
+ rgba_char_args_set(theme_space->handle_sel_align, 0xf0, 0x90, 0xa0, 255);
+ rgba_char_args_set(theme_space->act_spline, 0xdb, 0x25, 0x12, 255);
+}
/* initialize default theme
* Note: when you add new colors, created & saved themes need initialized
@@ -818,6 +835,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.shade2, 0x7f, 0x70, 0x70, 100);
rgba_char_args_set_fl(btheme->tv3d.grid, 0.251, 0.251, 0.251, 1.0);
+ rgba_char_args_set(btheme->tv3d.view_overlay, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.wire, 0x0, 0x0, 0x0, 255);
rgba_char_args_set(btheme->tv3d.wire_edit, 0x0, 0x0, 0x0, 255);
rgba_char_args_set(btheme->tv3d.lamp, 0, 0, 0, 40);
@@ -869,14 +887,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.nurb_sel_uline, 0xf0, 0xff, 0x40, 255);
rgba_char_args_set(btheme->tv3d.nurb_sel_vline, 0xf0, 0x90, 0xa0, 255);
- rgba_char_args_set(btheme->tv3d.handle_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tv3d.handle_auto, 0x90, 0x90, 0x00, 255);
- rgba_char_args_set(btheme->tv3d.handle_vect, 0x40, 0x90, 0x30, 255);
- rgba_char_args_set(btheme->tv3d.handle_align, 0x80, 0x30, 0x60, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_auto, 0xf0, 0xff, 0x40, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_vect, 0x40, 0xc0, 0x30, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_align, 0xf0, 0x90, 0xa0, 255);
+ ui_theme_space_init_handles_color(&btheme->tv3d);
rgba_char_args_set(btheme->tv3d.act_spline, 0xdb, 0x25, 0x12, 255);
rgba_char_args_set(btheme->tv3d.lastsel_point, 0xff, 0xff, 0xff, 255);
@@ -941,7 +952,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tact.keytype_jitter, 148, 229, 117, 255);
rgba_char_args_set(btheme->tact.keytype_jitter_select, 97, 192, 66, 255);
- rgba_char_args_set(btheme->tact.keyborder, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tact.keyborder, 0, 0, 0, 255);
rgba_char_args_set(btheme->tact.keyborder_select, 0, 0, 0, 255);
/* space nla */
@@ -960,7 +971,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tnla.nla_sound, 43, 61, 61, 255);
rgba_char_args_set(btheme->tnla.nla_sound_sel, 31, 122, 122, 255);
- rgba_char_args_set(btheme->tnla.keyborder, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tnla.keyborder, 0, 0, 0, 255);
rgba_char_args_set(btheme->tnla.keyborder_select, 0, 0, 0, 255);
/* space file */
@@ -1019,6 +1030,9 @@ void ui_theme_init_default(void)
rgba_char_args_test_set(btheme->tima.uv_others, 96, 96, 96, 255);
rgba_char_args_test_set(btheme->tima.uv_shadow, 112, 112, 112, 255);
+ ui_theme_space_init_handles_color(&btheme->tima);
+ btheme->tima.handle_vertex_size = 5;
+
/* space text */
btheme->text = btheme->tv3d;
rgba_char_args_set(btheme->text.back, 153, 153, 153, 255);
@@ -1079,7 +1093,7 @@ void ui_theme_init_default(void)
/* space node, re-uses syntax and console color storage */
btheme->tnode = btheme->tv3d;
- rgba_char_args_set(btheme->tnode.edge_select, 255, 255, 255, 255); /* wire selected */
+ rgba_char_args_set(btheme->tnode.edge_select, 255, 255, 255, 255); /* wire selected */
rgba_char_args_set(btheme->tnode.syntaxl, 155, 155, 155, 160); /* TH_NODE, backdrop */
rgba_char_args_set(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in */
rgba_char_args_set(btheme->tnode.nodeclass_output, 100, 100, 100, 255); /* output */
@@ -1121,7 +1135,8 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tclip.list, 0x66, 0x66, 0x66, 0xff);
rgba_char_args_set(btheme->tclip.strip, 0x0c, 0x0a, 0x0a, 0x80);
rgba_char_args_set(btheme->tclip.strip_select, 0xff, 0x8c, 0x00, 0xff);
- btheme->tclip.handle_vertex_size = 4;
+ btheme->tclip.handle_vertex_size = 5;
+ ui_theme_space_init_handles_color(&btheme->tclip);
}
void ui_style_init_default(void)
@@ -1724,7 +1739,7 @@ void init_userdef_do_versions(void)
/* adjust themes */
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
- char *col;
+ const char *col;
/* IPO Editor: Handles/Vertices */
col = btheme->tipo.vertex;
@@ -1883,27 +1898,9 @@ void init_userdef_do_versions(void)
/* init new curve colors */
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
- /* init colors used for handles in 3D-View */
- rgba_char_args_set(btheme->tv3d.handle_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tv3d.handle_auto, 0x90, 0x90, 0x00, 255);
- rgba_char_args_set(btheme->tv3d.handle_vect, 0x40, 0x90, 0x30, 255);
- rgba_char_args_set(btheme->tv3d.handle_align, 0x80, 0x30, 0x60, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_auto, 0xf0, 0xff, 0x40, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_vect, 0x40, 0xc0, 0x30, 255);
- rgba_char_args_set(btheme->tv3d.handle_sel_align, 0xf0, 0x90, 0xa0, 255);
- rgba_char_args_set(btheme->tv3d.act_spline, 0xdb, 0x25, 0x12, 255);
-
- /* same colors again for Graph Editor... */
- rgba_char_args_set(btheme->tipo.handle_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tipo.handle_auto, 0x90, 0x90, 0x00, 255);
- rgba_char_args_set(btheme->tipo.handle_vect, 0x40, 0x90, 0x30, 255);
- rgba_char_args_set(btheme->tipo.handle_align, 0x80, 0x30, 0x60, 255);
- rgba_char_args_set(btheme->tipo.handle_sel_free, 0, 0, 0, 255);
- rgba_char_args_set(btheme->tipo.handle_sel_auto, 0xf0, 0xff, 0x40, 255);
- rgba_char_args_set(btheme->tipo.handle_sel_vect, 0x40, 0xc0, 0x30, 255);
- rgba_char_args_set(btheme->tipo.handle_sel_align, 0xf0, 0x90, 0xa0, 255);
-
+ ui_theme_space_init_handles_color(&btheme->tv3d);
+ ui_theme_space_init_handles_color(&btheme->tipo);
+
/* edge crease */
rgba_char_args_set_fl(btheme->tv3d.edge_crease, 0.8, 0, 0.6, 1.0);
}
@@ -2008,7 +2005,7 @@ void init_userdef_do_versions(void)
rgba_char_args_set(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255);
rgba_char_args_set(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff);
rgba_char_args_set(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff);
- btheme->tclip.handle_vertex_size = 4;
+ btheme->tclip.handle_vertex_size = 5;
}
/* auto-clamped handles -> based on auto */
@@ -2388,12 +2385,12 @@ void init_userdef_do_versions(void)
rgba_char_args_set(btheme->tact.keytype_jitter_select, 97, 192, 66, 255);
/* key border */
- rgba_char_args_set(btheme->tact.keyborder, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tact.keyborder, 0, 0, 0, 255);
rgba_char_args_set(btheme->tact.keyborder_select, 0, 0, 0, 255);
/* NLA ............................ */
/* key border */
- rgba_char_args_set(btheme->tnla.keyborder, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tnla.keyborder, 0, 0, 0, 255);
rgba_char_args_set(btheme->tnla.keyborder_select, 0, 0, 0, 255);
/* Graph Editor ................... */
@@ -2415,13 +2412,23 @@ void init_userdef_do_versions(void)
for (ts = UI_THEMESPACE_START(btheme); ts != UI_THEMESPACE_END(btheme); ts++) {
rgba_char_args_set(ts->tab_active, 114, 114, 114, 255);
- rgba_char_args_set(ts->tab_inactive, 100, 100, 100, 255);
- rgba_char_args_set(ts->tab_back, 70, 70, 70, 255);
+ rgba_char_args_set(ts->tab_inactive, 83, 83, 83, 255);
+ rgba_char_args_set(ts->tab_back, 64, 64, 64, 255);
rgba_char_args_set(ts->tab_outline, 60, 60, 60, 255);
}
}
}
-
+
+ {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ ui_theme_space_init_handles_color(&btheme->tclip);
+ ui_theme_space_init_handles_color(&btheme->tima);
+ btheme->tima.handle_vertex_size = 5;
+ btheme->tclip.handle_vertex_size = 5;
+ }
+ }
+
if (U.pixelsize == 0.0f)
U.pixelsize = 1.0f;
@@ -2447,8 +2454,6 @@ void init_userdef_factory(void)
U.uiflag |= USER_QUIT_PROMPT;
U.uiflag |= USER_CONTINUOUS_MOUSE;
- U.ogl_multisamples = USER_MULTISAMPLE_4;
-
U.versions = 1;
U.savetime = 2;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index ac579c0bf87..2f15d0ca112 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -38,9 +38,11 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_link_utils.h"
+#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_timecode.h"
#include "BKE_context.h"
@@ -55,7 +57,6 @@
#include "BLF_api.h"
-#include "ED_anim_api.h"
#include "ED_screen.h"
#include "UI_interface.h"
@@ -67,6 +68,35 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_
/* *********************************************************************** */
+BLI_INLINE int clamp_float_to_int(const float f)
+{
+ const float min = INT_MIN;
+ const float max = INT_MAX;
+
+ if (UNLIKELY(f < min)) {
+ return min;
+ }
+ else if (UNLIKELY(f > max)) {
+ return max;
+ }
+ else {
+ return (int)f;
+ }
+}
+
+/**
+ * use instead of #BLI_rcti_rctf_copy so we have consistent behavior
+ * with users of #clamp_float_to_int.
+ */
+BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
+{
+ dst->xmin = clamp_float_to_int(src->xmin);
+ dst->xmax = clamp_float_to_int(src->xmax);
+ dst->ymin = clamp_float_to_int(src->ymin);
+ dst->ymax = clamp_float_to_int(src->ymax);
+}
+
+
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
/* XXX there's V2D_SCROLL_HORIZONTAL_HIDE and V2D_SCROLL_HORIZONTAL_FULLR ... */
@@ -1953,7 +1983,7 @@ void UI_view2d_listview_visible_cells(View2D *v2d, float columnwidth, float rowh
/* min */
UI_view2d_listview_view_to_cell(v2d, columnwidth, rowheight, startx, starty,
v2d->cur.xmin, v2d->cur.ymin, column_min, row_min);
-
+
/* max*/
UI_view2d_listview_view_to_cell(v2d, columnwidth, rowheight, startx, starty,
v2d->cur.xmax, v2d->cur.ymax, column_max, row_max);
@@ -1963,28 +1993,44 @@ void UI_view2d_listview_visible_cells(View2D *v2d, float columnwidth, float rowh
/* *********************************************************************** */
/* Coordinate Conversions */
+float UI_view2d_region_to_view_x(struct View2D *v2d, float x)
+{
+ return (v2d->cur.xmin + (BLI_rctf_size_x(&v2d->cur) * (x - v2d->mask.xmin) / BLI_rcti_size_x(&v2d->mask)));
+}
+float UI_view2d_region_to_view_y(struct View2D *v2d, float y)
+{
+ return (v2d->cur.ymin + (BLI_rctf_size_y(&v2d->cur) * (y - v2d->mask.ymin) / BLI_rcti_size_y(&v2d->mask)));
+}
+
/* Convert from screen/region space to 2d-View space
*
* - x,y = coordinates to convert
* - viewx,viewy = resultant coordinates
*/
-void UI_view2d_region_to_view(View2D *v2d, float x, float y, float *r_viewx, float *r_viewy)
+void UI_view2d_region_to_view(View2D *v2d, float x, float y, float *r_view_x, float *r_view_y)
{
- float div, ofs;
+ *r_view_x = UI_view2d_region_to_view_x(v2d, x);
+ *r_view_y = UI_view2d_region_to_view_y(v2d, y);
+}
- if (r_viewx) {
- div = (float)BLI_rcti_size_x(&v2d->mask);
- ofs = (float)v2d->mask.xmin;
-
- *r_viewx = v2d->cur.xmin + BLI_rctf_size_x(&v2d->cur) * ((float)x - ofs) / div;
- }
+void UI_view2d_region_to_view_rctf(View2D *v2d, const rctf *rect_src, rctf *rect_dst)
+{
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
- if (r_viewy) {
- div = (float)BLI_rcti_size_y(&v2d->mask);
- ofs = (float)v2d->mask.ymin;
-
- *r_viewy = v2d->cur.ymin + BLI_rctf_size_y(&v2d->cur) * ((float)y - ofs) / div;
- }
+ rect_dst->xmin = (v2d->cur.xmin + (cur_size[0] * (rect_src->xmin - v2d->mask.xmin) / mask_size[0]));
+ rect_dst->xmax = (v2d->cur.xmin + (cur_size[0] * (rect_src->xmax - v2d->mask.xmin) / mask_size[0]));
+ rect_dst->ymin = (v2d->cur.ymin + (cur_size[1] * (rect_src->ymin - v2d->mask.ymin) / mask_size[1]));
+ rect_dst->ymax = (v2d->cur.ymin + (cur_size[1] * (rect_src->ymax - v2d->mask.ymin) / mask_size[1]));
+}
+
+float UI_view2d_view_to_region_x(View2D *v2d, float x)
+{
+ return (v2d->mask.xmin + (((x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur)) * BLI_rcti_size_x(&v2d->mask)));
+}
+float UI_view2d_view_to_region_y(View2D *v2d, float y)
+{
+ return (v2d->mask.ymin + (((y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur)) * BLI_rcti_size_y(&v2d->mask)));
}
/* Convert from 2d-View space to screen/region space
@@ -1993,24 +2039,24 @@ void UI_view2d_region_to_view(View2D *v2d, float x, float y, float *r_viewx, flo
* - x,y = coordinates to convert
* - regionx,regiony = resultant coordinates
*/
-void UI_view2d_view_to_region(View2D *v2d, float x, float y, int *regionx, int *regiony)
+bool UI_view2d_view_to_region_clip(View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
- /* set initial value in case coordinate lies outside of bounds */
- if (regionx)
- *regionx = V2D_IS_CLIPPED;
- if (regiony)
- *regiony = V2D_IS_CLIPPED;
-
/* express given coordinates as proportional values */
x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
/* check if values are within bounds */
if ((x >= 0.0f) && (x <= 1.0f) && (y >= 0.0f) && (y <= 1.0f)) {
- if (regionx)
- *regionx = (int)(v2d->mask.xmin + x * BLI_rcti_size_x(&v2d->mask));
- if (regiony)
- *regiony = (int)(v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask));
+ *r_region_x = (int)(v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask)));
+ *r_region_y = (int)(v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask)));
+
+ return true;
+ }
+ else {
+ /* set initial value in case coordinate lies outside of bounds */
+ *r_region_x = *r_region_y = V2D_IS_CLIPPED;
+
+ return false;
}
}
@@ -2020,38 +2066,86 @@ void UI_view2d_view_to_region(View2D *v2d, float x, float y, int *regionx, int *
* - x,y = coordinates to convert
* - regionx,regiony = resultant coordinates
*/
-void UI_view2d_to_region_no_clip(View2D *v2d, float x, float y, int *regionx, int *regiony)
+void UI_view2d_view_to_region(View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
/* step 1: express given coordinates as proportional values */
x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
-
+
/* step 2: convert proportional distances to screen coordinates */
- x = v2d->mask.xmin + x * BLI_rcti_size_x(&v2d->mask);
- y = v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask);
-
+ x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
+ y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
+
/* although we don't clamp to lie within region bounds, we must avoid exceeding size of ints */
- if (regionx) {
- if (x < INT_MIN) *regionx = INT_MIN;
- else if (x > INT_MAX) *regionx = INT_MAX;
- else *regionx = (int)x;
- }
- if (regiony) {
- if (y < INT_MIN) *regiony = INT_MIN;
- else if (y > INT_MAX) *regiony = INT_MAX;
- else *regiony = (int)y;
- }
+ *r_region_x = clamp_float_to_int(x);
+ *r_region_y = clamp_float_to_int(y);
}
-void UI_view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
+void UI_view2d_view_to_region_fl(View2D *v2d, float x, float y, float *r_region_x, float *r_region_y)
{
/* express given coordinates as proportional values */
- x = -v2d->cur.xmin / BLI_rctf_size_x(&v2d->cur);
- y = -v2d->cur.ymin / BLI_rctf_size_y(&v2d->cur);
+ x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
+ y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
/* convert proportional distances to screen coordinates */
- *regionx = v2d->mask.xmin + x * BLI_rcti_size_x(&v2d->mask);
- *regiony = v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask);
+ *r_region_x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
+ *r_region_y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
+}
+
+void UI_view2d_view_to_region_rcti(View2D *v2d, const rctf *rect_src, rcti *rect_dst)
+{
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
+ rctf rect_tmp;
+
+ /* step 1: express given coordinates as proportional values */
+ rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
+ rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
+
+
+ /* step 2: convert proportional distances to screen coordinates */
+ rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
+ rect_tmp.xmax = v2d->mask.xmin + (rect_tmp.xmax * mask_size[0]);
+ rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
+ rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
+
+ clamp_rctf_to_rcti(rect_dst, &rect_tmp);
+}
+
+bool UI_view2d_view_to_region_rcti_clip(View2D *v2d, const rctf *rect_src, rcti *rect_dst)
+{
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
+ rctf rect_tmp;
+
+ BLI_assert(rect_src->xmin <= rect_src->xmax && rect_src->ymin <= rect_src->ymax);
+
+ /* step 1: express given coordinates as proportional values */
+ rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
+ rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
+
+ if (((rect_tmp.xmax < 0.0f) || (rect_tmp.xmin > 1.0f) ||
+ (rect_tmp.ymax < 0.0f) || (rect_tmp.ymin > 1.0f)) == 0)
+ {
+ /* step 2: convert proportional distances to screen coordinates */
+ rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
+ rect_tmp.xmax = v2d->mask.ymin + (rect_tmp.xmax * mask_size[0]);
+ rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
+ rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
+
+ clamp_rctf_to_rcti(rect_dst, &rect_tmp);
+
+ return true;
+ }
+ else {
+ rect_dst->xmin = rect_dst->xmax = rect_dst->ymin = rect_dst->ymax = V2D_IS_CLIPPED;
+
+ return false;
+ }
}
/* *********************************************************************** */
@@ -2090,13 +2184,13 @@ View2D *UI_view2d_fromcontext_rwin(const bContext *C)
*
* - x,y = scale on each axis
*/
-void UI_view2d_getscale(View2D *v2d, float *x, float *y)
+void UI_view2d_scale_get(View2D *v2d, float *x, float *y)
{
if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
}
-/* Same as UI_view2d_getscale() - 1.0f / x, y */
-void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y)
+/* Same as UI_view2d_scale_get() - 1.0f / x, y */
+void UI_view2d_scale_get_inverse(View2D *v2d, float *x, float *y)
{
if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
@@ -2105,13 +2199,13 @@ void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y)
/* Simple functions for consistent center offset access.
* Used by node editor to shift view center for each individual node tree.
*/
-void UI_view2d_getcenter(struct View2D *v2d, float *x, float *y)
+void UI_view2d_center_get(struct View2D *v2d, float *x, float *y)
{
/* get center */
if (x) *x = BLI_rctf_cent_x(&v2d->cur);
if (y) *y = BLI_rctf_cent_y(&v2d->cur);
}
-void UI_view2d_setcenter(struct View2D *v2d, float x, float y)
+void UI_view2d_center_set(struct View2D *v2d, float x, float y)
{
BLI_rctf_recenter(&v2d->cur, x, y);
@@ -2119,6 +2213,35 @@ void UI_view2d_setcenter(struct View2D *v2d, float x, float y)
UI_view2d_curRect_validate(v2d);
}
+/**
+ * Simple pan function
+ * (0.0, 0.0) bottom left
+ * (0.5, 0.5) center
+ * (1.0, 1.0) top right.
+ */
+void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac)
+{
+ if (xfac != -1.0f) {
+ const float xsize = BLI_rctf_size_x(&v2d->cur);
+ const float xmin = v2d->tot.xmin;
+ const float xmax = v2d->tot.xmax - xsize;
+
+ v2d->cur.xmin = (xmin * (1.0f - xfac)) + (xmax * xfac);
+ v2d->cur.xmax = v2d->cur.xmin + xsize;
+ }
+
+ if (yfac != -1.0f) {
+ const float ysize = BLI_rctf_size_y(&v2d->cur);
+ const float ymin = v2d->tot.ymin;
+ const float ymax = v2d->tot.ymax - ysize;
+
+ v2d->cur.ymin = (ymin * (1.0f - yfac)) + (ymax * yfac);
+ v2d->cur.ymax = v2d->cur.ymin + ysize;
+ }
+
+ UI_view2d_curRect_validate(v2d);
+}
+
/* Check if mouse is within scrollers
* - Returns appropriate code for match
* 'h' = in horizontal scroller
@@ -2151,56 +2274,79 @@ short UI_view2d_mouse_in_scrollers(const bContext *C, View2D *v2d, int x, int y)
/* ******************* view2d text drawing cache ******************** */
-/* assumes caches are used correctly, so for time being no local storage in v2d */
-static ListBase strings = {NULL, NULL};
-
typedef struct View2DString {
- struct View2DString *next, *prev;
+ struct View2DString *next;
union {
unsigned char ub[4];
int pack;
} col;
- int mval[2];
rcti rect;
+ int mval[2];
} View2DString;
+/* assumes caches are used correctly, so for time being no local storage in v2d */
+static MemArena *g_v2d_strings_arena = NULL;
+static View2DString *g_v2d_strings = NULL;
-void UI_view2d_text_cache_add(View2D *v2d, float x, float y, const char *str, const char col[4])
+void UI_view2d_text_cache_add(View2D *v2d, float x, float y,
+ const char *str, size_t str_len, const char col[4])
{
int mval[2];
- UI_view2d_view_to_region(v2d, x, y, mval, mval + 1);
-
- if (mval[0] != V2D_IS_CLIPPED && mval[1] != V2D_IS_CLIPPED) {
- int len = strlen(str) + 1;
- /* use calloc, rect has to be zeroe'd */
- View2DString *v2s = MEM_callocN(sizeof(View2DString) + len, "View2DString");
- char *v2s_str = (char *)(v2s + 1);
- memcpy(v2s_str, str, len);
+ BLI_assert(str_len == strlen(str));
+
+ if (UI_view2d_view_to_region_clip(v2d, x, y, &mval[0], &mval[1])) {
+ int alloc_len = str_len + 1;
+ View2DString *v2s;
+
+ if (g_v2d_strings_arena == NULL) {
+ g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
+ }
+
+ v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
+
+ BLI_LINKS_PREPEND(g_v2d_strings, v2s);
- BLI_addtail(&strings, v2s);
v2s->col.pack = *((int *)col);
+
+ memset(&v2s->rect, 0, sizeof(v2s->rect));
+
v2s->mval[0] = mval[0];
v2s->mval[1] = mval[1];
+
+ memcpy(v2s + 1, str, alloc_len);
}
}
/* no clip (yet) */
-void UI_view2d_text_cache_rectf(View2D *v2d, const rctf *rect, const char *str, const char col[4])
+void UI_view2d_text_cache_add_rectf(View2D *v2d, const rctf *rect_view,
+ const char *str, size_t str_len, const char col[4])
{
- int len = strlen(str) + 1;
- View2DString *v2s = MEM_callocN(sizeof(View2DString) + len, "View2DString");
- char *v2s_str = (char *)(v2s + 1);
- memcpy(v2s_str, str, len);
+ rcti rect;
- UI_view2d_to_region_no_clip(v2d, rect->xmin, rect->ymin, &v2s->rect.xmin, &v2s->rect.ymin);
- UI_view2d_to_region_no_clip(v2d, rect->xmax, rect->ymax, &v2s->rect.xmax, &v2s->rect.ymax);
+ BLI_assert(str_len == strlen(str));
- v2s->col.pack = *((int *)col);
- v2s->mval[0] = v2s->rect.xmin;
- v2s->mval[1] = v2s->rect.ymin;
+ if (UI_view2d_view_to_region_rcti_clip(v2d, rect_view, &rect)) {
+ int alloc_len = str_len + 1;
+ View2DString *v2s;
- BLI_addtail(&strings, v2s);
+ if (g_v2d_strings_arena == NULL) {
+ g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
+ }
+
+ v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
+
+ BLI_LINKS_PREPEND(g_v2d_strings, v2s);
+
+ v2s->col.pack = *((int *)col);
+
+ v2s->rect = rect;
+
+ v2s->mval[0] = v2s->rect.xmin;
+ v2s->mval[1] = v2s->rect.ymin;
+
+ memcpy(v2s + 1, str, alloc_len);
+ }
}
@@ -2210,7 +2356,7 @@ void UI_view2d_text_cache_draw(ARegion *ar)
int col_pack_prev = 0;
/* investigate using BLF_ascender() */
- const float default_height = strings.first ? BLF_height_default("28", 3) : 0.0f;
+ const float default_height = g_v2d_strings ? BLF_height_default("28", 3) : 0.0f;
// gpuMatrixMode(GL_PROJECTION);
// gpuPushMatrix();
@@ -2218,7 +2364,7 @@ void UI_view2d_text_cache_draw(ARegion *ar)
// gpuPushMatrix();
ED_region_pixelspace(ar);
- for (v2s = strings.first; v2s; v2s = v2s->next) {
+ for (v2s = g_v2d_strings; v2s; v2s = v2s->next) {
const char *str = (const char *)(v2s + 1);
int xofs = 0, yofs;
@@ -2239,14 +2385,17 @@ void UI_view2d_text_cache_draw(ARegion *ar)
BLF_disable_default(BLF_CLIPPING);
}
}
-
+ g_v2d_strings = NULL;
+
+ if (g_v2d_strings_arena) {
+ BLI_memarena_free(g_v2d_strings_arena);
+ g_v2d_strings_arena = NULL;
+ }
+
// gpuMatrixMode(GL_PROJECTION);
// gpuPopMatrix();
// gpuMatrixMode(GL_MODELVIEW);
// gpuPopMatrix();
-
- if (strings.first)
- BLI_freelistN(&strings);
}
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index a332e5bbcd7..e30c6ca61ba 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -126,16 +126,32 @@ static int view_pan_init(bContext *C, wmOperator *op)
return 1;
}
+static int view_pan_poll(bContext *C)
+{
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d;
+
+ /* check if there's a region in context to work with */
+ if (ar == NULL)
+ return 0;
+ v2d = &ar->v2d;
+
+ /* check that 2d-view can pan */
+ if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y))
+ return 0;
+
+ /* view can pan */
+ return 1;
+}
+
/* apply transform to view (i.e. adjust 'cur' rect) */
-static void view_pan_apply(bContext *C, wmOperator *op)
+static void view_pan_apply_ex(bContext *C, v2dViewPanData *vpd, float dx, float dy)
{
- v2dViewPanData *vpd = op->customdata;
View2D *v2d = vpd->v2d;
- float dx, dy;
/* calculate amount to move view by */
- dx = vpd->facx * (float)RNA_int_get(op->ptr, "deltax");
- dy = vpd->facy * (float)RNA_int_get(op->ptr, "deltay");
+ dx *= vpd->facx;
+ dy *= vpd->facy;
/* only move view on an axis if change is allowed */
if ((v2d->keepofs & V2D_LOCKOFS_X) == 0) {
@@ -164,6 +180,16 @@ static void view_pan_apply(bContext *C, wmOperator *op)
}
}
+static void view_pan_apply(bContext *C, wmOperator *op)
+{
+ v2dViewPanData *vpd = op->customdata;
+
+ view_pan_apply_ex(C, vpd,
+ RNA_int_get(op->ptr, "deltax"),
+ RNA_int_get(op->ptr, "deltay"));
+
+}
+
/* cleanup temp customdata */
static void view_pan_exit(wmOperator *op)
{
@@ -527,6 +553,25 @@ typedef struct v2dViewZoomData {
float mx_2d, my_2d; /* initial mouse location in v2d coords */
} v2dViewZoomData;
+/**
+ * Clamp by convention rather then locking flags,
+ * for ndof and +/- keys
+ */
+static void view_zoom_axis_lock_defaults(bContext *C, bool r_do_zoom_xy[2])
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ r_do_zoom_xy[0] = true;
+ r_do_zoom_xy[1] = true;
+
+ /* default not to zoom the sequencer vertically */
+ if (sa && sa->spacetype == SPACE_SEQ) {
+ ARegion *ar = CTX_wm_region(C);
+
+ if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
+ r_do_zoom_xy[1] = false;
+ }
+}
/* initialize panning customdata */
static int view_zoomdrag_init(bContext *C, wmOperator *op)
@@ -575,19 +620,16 @@ static int view_zoom_poll(bContext *C)
}
/* apply transform to view (i.e. adjust 'cur' rect) */
-static void view_zoomstep_apply(bContext *C, wmOperator *op)
+static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool use_mousepos,
+ const float facx, const float facy)
{
- v2dViewZoomData *vzd = op->customdata;
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
- float dx, dy, facx, facy;
-
+ float dx, dy;
+
/* calculate amount to move view by, ensuring symmetry so the
* old zoom level is restored after zooming back the same amount
*/
- facx = RNA_float_get(op->ptr, "zoomfacx");
- facy = RNA_float_get(op->ptr, "zoomfacy");
-
if (facx >= 0.0f) {
dx = BLI_rctf_size_x(&v2d->cur) * facx;
dy = BLI_rctf_size_y(&v2d->cur) * facy;
@@ -609,7 +651,7 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
v2d->cur.xmax -= 2 * dx;
}
else {
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dx) - (mval_faci * dx);
@@ -634,7 +676,7 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
v2d->cur.ymax -= 2 * dy;
}
else {
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dy) - (mval_faci * dy);
@@ -657,6 +699,14 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
+static void view_zoomstep_apply(bContext *C, wmOperator *op)
+{
+ v2dViewZoomData *vzd = op->customdata;
+ view_zoomstep_apply_ex(C, vzd, true,
+ RNA_float_get(op->ptr, "zoomfacx"),
+ RNA_float_get(op->ptr, "zoomfacy"));
+}
+
/* --------------- Individual Operators ------------------- */
/* cleanup temp customdata */
@@ -673,25 +723,18 @@ static void view_zoomstep_exit(wmOperator *op)
/* this operator only needs this single callback, where it calls the view_zoom_*() methods */
static int view_zoomin_exec(bContext *C, wmOperator *op)
{
- ScrArea *sa = CTX_wm_area(C);
- bool do_zoom_x = true;
- bool do_zoom_y = true;
+ bool do_zoom_xy[2];
/* check that there's an active region, as View2D data resides there */
if (!view_zoom_poll(C))
return OPERATOR_PASS_THROUGH;
- /* default not to zoom the sequencer vertically */
- if (sa && sa->spacetype == SPACE_SEQ) {
- ARegion *ar = CTX_wm_region(C);
- if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
- do_zoom_y = false;
- }
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
/* set RNA-Props - zooming in by uniform factor */
- RNA_float_set(op->ptr, "zoomfacx", do_zoom_x ? 0.0375f : 0.0f);
- RNA_float_set(op->ptr, "zoomfacy", do_zoom_y ? 0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? 0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? 0.0375f : 0.0f);
/* apply movement, then we're done */
view_zoomstep_apply(C, op);
@@ -714,7 +757,7 @@ static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ARegion *ar = CTX_wm_region(C);
/* store initial mouse position (in view space) */
- UI_view2d_region_to_view(&ar->v2d,
+ UI_view2d_region_to_view(&ar->v2d,
event->mval[0], event->mval[1],
&vzd->mx_2d, &vzd->my_2d);
}
@@ -742,25 +785,17 @@ static void VIEW2D_OT_zoom_in(wmOperatorType *ot)
/* this operator only needs this single callback, where it calls the view_zoom_*() methods */
static int view_zoomout_exec(bContext *C, wmOperator *op)
{
- ScrArea *sa = CTX_wm_area(C);
- bool do_zoom_x = true;
- bool do_zoom_y = true;
+ bool do_zoom_xy[2];
/* check that there's an active region, as View2D data resides there */
if (!view_zoom_poll(C))
return OPERATOR_PASS_THROUGH;
- /* default not to zoom the sequencer vertically */
- if (sa && sa->spacetype == SPACE_SEQ) {
- ARegion *ar = CTX_wm_region(C);
-
- if (ar && ar->regiontype != RGN_TYPE_PREVIEW)
- do_zoom_y = false;
- }
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
/* set RNA-Props - zooming in by uniform factor */
- RNA_float_set(op->ptr, "zoomfacx", do_zoom_x ? -0.0375f : 0.0f);
- RNA_float_set(op->ptr, "zoomfacy", do_zoom_y ? -0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? -0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? -0.0375f : 0.0f);
/* apply movement, then we're done */
view_zoomstep_apply(C, op);
@@ -998,7 +1033,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (U.viewzoom == USER_ZOOM_CONT) {
/* needs a timer to continue redrawing */
- vzd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+ vzd->timer = WM_event_add_timer(CTX_wm_manager(C), window, TIMER, 0.01f);
vzd->timer_lastdraw = PIL_check_seconds_timer();
}
@@ -1147,8 +1182,8 @@ static int view_borderzoom_exec(bContext *C, wmOperator *op)
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
/* convert coordinates of rect to 'tot' rect coordinates */
- UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmin"), RNA_int_get(op->ptr, "ymin"), &rect.xmin, &rect.ymin);
- UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmax"), RNA_int_get(op->ptr, "ymax"), &rect.xmax, &rect.ymax);
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
/* check if zooming in/out view */
gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
@@ -1220,6 +1255,80 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
WM_operator_properties_gesture_border(ot, false);
}
+
+static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ if (event->type != NDOF_MOTION) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ const wmNDOFMotionData *ndof = event->customdata;
+
+ /* tune these until it feels right */
+ const float zoom_sensitivity = 0.5f;
+ const float speed = 10.0f; /* match view3d ortho */
+ const bool has_translate = (ndof->tvec[0] && ndof->tvec[1]) && view_pan_poll(C);
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && view_zoom_poll(C);
+
+ if (has_translate) {
+ if (view_pan_init(C, op)) {
+ v2dViewPanData *vpd;
+ float pan_vec[3];
+
+ WM_event_ndof_pan_get(ndof, pan_vec, false);
+
+ pan_vec[0] *= speed;
+ pan_vec[1] *= speed;
+
+ vpd = op->customdata;
+
+ view_pan_apply_ex(C, vpd, pan_vec[0], pan_vec[1]);
+
+ view_pan_exit(op);
+ }
+ }
+
+ if (has_zoom) {
+ if (view_zoomdrag_init(C, op)) {
+ v2dViewZoomData *vzd;
+ float zoom_factor = zoom_sensitivity * ndof->dt * -ndof->tvec[2];
+
+ bool do_zoom_xy[2];
+
+ if (U.ndof_flag & NDOF_ZOOM_INVERT)
+ zoom_factor = -zoom_factor;
+
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
+
+ vzd = op->customdata;
+
+ view_zoomstep_apply_ex(C, vzd, false,
+ do_zoom_xy[0] ? zoom_factor : 0.0f,
+ do_zoom_xy[1] ? zoom_factor : 0.0f);
+
+ view_zoomstep_exit(op);
+ }
+ }
+
+ return OPERATOR_FINISHED;
+ }
+}
+
+static void VIEW2D_OT_ndof(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "NDOF Pan/Zoom";
+ ot->idname = "VIEW2D_OT_ndof";
+ ot->description = "Use a 3D mouse device to pan/zoom the view";
+
+ /* api callbacks */
+ ot->invoke = view2d_ndof_invoke;
+ ot->poll = view2d_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_LOCK_BYPASS;
+}
+
/* ********************************************************* */
/* SMOOTH VIEW */
@@ -1239,14 +1348,14 @@ struct SmoothView2DStore {
*/
static float smooth_view_rect_to_fac(const rctf *rect_a, const rctf *rect_b)
{
- float size_a[2] = {BLI_rctf_size_x(rect_a),
- BLI_rctf_size_y(rect_a)};
- float size_b[2] = {BLI_rctf_size_x(rect_b),
- BLI_rctf_size_y(rect_b)};
- float cent_a[2] = {BLI_rctf_cent_x(rect_a),
- BLI_rctf_cent_y(rect_a)};
- float cent_b[2] = {BLI_rctf_cent_x(rect_b),
- BLI_rctf_cent_y(rect_b)};
+ const float size_a[2] = {BLI_rctf_size_x(rect_a),
+ BLI_rctf_size_y(rect_a)};
+ const float size_b[2] = {BLI_rctf_size_x(rect_b),
+ BLI_rctf_size_y(rect_b)};
+ const float cent_a[2] = {BLI_rctf_cent_x(rect_a),
+ BLI_rctf_cent_y(rect_a)};
+ const float cent_b[2] = {BLI_rctf_cent_x(rect_b),
+ BLI_rctf_cent_y(rect_b)};
float fac_max = 0.0f;
float tfac;
@@ -1883,7 +1992,7 @@ static void VIEW2D_OT_reset(wmOperatorType *ot)
/* ********************************************************* */
/* Registration */
-void UI_view2d_operatortypes(void)
+void ED_operatortypes_view2d(void)
{
WM_operatortype_append(VIEW2D_OT_pan);
@@ -1898,6 +2007,8 @@ void UI_view2d_operatortypes(void)
WM_operatortype_append(VIEW2D_OT_zoom);
WM_operatortype_append(VIEW2D_OT_zoom_border);
+ WM_operatortype_append(VIEW2D_OT_ndof);
+
WM_operatortype_append(VIEW2D_OT_smoothview);
WM_operatortype_append(VIEW2D_OT_scroller_activate);
@@ -1905,7 +2016,7 @@ void UI_view2d_operatortypes(void)
WM_operatortype_append(VIEW2D_OT_reset);
}
-void UI_view2d_keymap(wmKeyConfig *keyconf)
+void ED_keymap_view2d(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "View2D", 0, 0);
wmKeyMapItem *kmi;
@@ -1926,6 +2037,8 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_ndof", NDOF_MOTION, 0, 0, 0);
+
/* zoom - single step */
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index f50e4400b91..4d2ea0e64f4 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -184,76 +184,76 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
/* Export Options: */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
/* Texture options */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
/* Armature options */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemL(row, IFACE_("Armature Options:"), ICON_ARMATURE_DATA);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE);
/* Collada options: */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
}
@@ -385,10 +385,10 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
/* Import Options: */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemL(row, IFACE_("Import Data Options:"), ICON_MESH_DATA);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 7fa41c361bb..b816103de13 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -40,7 +40,6 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "WM_api.h"
#include "WM_types.h"
@@ -54,10 +53,16 @@
#include "mask_intern.h" /* own include */
-static int find_nearest_diff_point(const bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather,
- MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r,
- float *u_r, float tangent[2],
- const short use_deform)
+bool ED_mask_find_nearest_diff_point(const bContext *C,
+ struct Mask *mask,
+ const float normal_co[2],
+ int threshold, bool feather,
+ MaskLayer **masklay_r,
+ MaskSpline **spline_r,
+ MaskSplinePoint **point_r,
+ float *u_r, float tangent[2],
+ const bool use_deform,
+ const bool use_project)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -135,7 +140,6 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no
point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point;
dist = cur_dist;
u = (float)j / tot_point;
-
}
}
@@ -159,12 +163,15 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no
*point_r = point;
if (u_r) {
- u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
+ /* TODO(sergey): Projection fails in some weirdo cases.. */
+ if (use_project) {
+ u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
+ }
*u_r = u;
}
- return TRUE;
+ return true;
}
if (masklay_r)
@@ -176,21 +183,19 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no
if (point_r)
*point_r = NULL;
- return FALSE;
+ return false;
}
/******************** add vertex *********************/
static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point,
- const float point_co[2], const float tangent[2], const float u,
- MaskSplinePoint *reference_point, const short reference_adjacent,
- const float view_zoom)
+ const float point_co[2], const float u,
+ MaskSplinePoint *reference_point, const bool reference_adjacent)
{
MaskSplinePoint *prev_point = NULL;
MaskSplinePoint *next_point = NULL;
BezTriple *bezt;
float co[3];
- const float len = 10.0; /* default length of handle in pixel space */
copy_v2_v2(co, point_co);
co[2] = 0.0f;
@@ -201,7 +206,41 @@ static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *
bezt->h1 = bezt->h2 = HD_ALIGN;
if (reference_point) {
- bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1);
+ if (reference_point->bezt.h1 == HD_VECT && reference_point->bezt.h2 == HD_VECT) {
+ /* If the reference point is sharp try using some smooth point as reference
+ * for handles.
+ */
+ int point_index = reference_point - spline->points;
+ int delta = new_point == spline->points ? 1 : -1;
+ int i = 0;
+ for (i = 0; i < spline->tot_point - 1; ++i) {
+ MaskSplinePoint *current_point;
+
+ point_index += delta;
+ if (point_index == -1 || point_index >= spline->tot_point) {
+ if (spline->flag & MASK_SPLINE_CYCLIC) {
+ if (point_index == -1) {
+ point_index = spline->tot_point - 1;
+ }
+ else if (point_index >= spline->tot_point) {
+ point_index = 0;
+ }
+ }
+ else {
+ break;
+ }
+ }
+
+ current_point = &spline->points[point_index];
+ if (current_point->bezt.h1 != HD_VECT || current_point->bezt.h2 != HD_VECT) {
+ bezt->h1 = bezt->h2 = MAX2(current_point->bezt.h2, current_point->bezt.h1);
+ break;
+ }
+ }
+ }
+ else {
+ bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1);
+ }
}
else if (reference_adjacent) {
if (spline->tot_point != 1) {
@@ -219,83 +258,11 @@ static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *
copy_v3_v3(bezt->vec[1], co);
copy_v3_v3(bezt->vec[2], co);
- /* initial offset for handles */
- if (spline->tot_point == 1) {
- /* first point of splien is aligned horizontally */
- bezt->vec[0][0] -= len * view_zoom;
- bezt->vec[2][0] += len * view_zoom;
- }
- else if (tangent) {
- float vec[2];
-
- copy_v2_v2(vec, tangent);
-
- mul_v2_fl(vec, len);
-
- sub_v2_v2(bezt->vec[0], vec);
- add_v2_v2(bezt->vec[2], vec);
-
- if (reference_adjacent) {
- BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
- }
- }
- else {
-
- /* calculating auto handles works much nicer */
-#if 0
- /* next points are aligning in the direction of previous/next point */
- MaskSplinePoint *point;
- float v1[2], v2[2], vec[2];
- float dir = 1.0f;
-
- if (new_point == spline->points) {
- point = new_point + 1;
- dir = -1.0f;
- }
- else
- point = new_point - 1;
-
- if (spline->tot_point < 3) {
- v1[0] = point->bezt.vec[1][0] * width;
- v1[1] = point->bezt.vec[1][1] * height;
-
- v2[0] = new_point->bezt.vec[1][0] * width;
- v2[1] = new_point->bezt.vec[1][1] * height;
- }
- else {
- if (new_point == spline->points) {
- v1[0] = spline->points[1].bezt.vec[1][0] * width;
- v1[1] = spline->points[1].bezt.vec[1][1] * height;
-
- v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width;
- v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height;
- }
- else {
- v1[0] = spline->points[0].bezt.vec[1][0] * width;
- v1[1] = spline->points[0].bezt.vec[1][1] * height;
-
- v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width;
- v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height;
- }
- }
-
- sub_v2_v2v2(vec, v1, v2);
- mul_v2_fl(vec, len * dir / len_v2(vec));
-
- vec[0] /= width;
- vec[1] /= height;
-
- add_v2_v2(bezt->vec[0], vec);
- sub_v2_v2(bezt->vec[2], vec);
-#else
- BKE_mask_calc_handle_point_auto(spline, new_point, TRUE);
+ BKE_mask_parent_init(&new_point->parent);
+ if (spline->tot_point != 1) {
BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
-
-#endif
}
- BKE_mask_parent_init(&new_point->parent);
-
/* select new point */
MASKPOINT_SEL_ALL(new_point);
ED_mask_select_flush_all(mask);
@@ -304,7 +271,7 @@ static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *
/* **** add extrude vertex **** */
-static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active)
+static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, bool check_active)
{
MaskSpline *cur_spline = masklay->splines.first;
@@ -363,7 +330,7 @@ static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
spline->tot_point++;
}
-static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
+static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
{
MaskLayer *masklay;
MaskSpline *spline;
@@ -372,7 +339,7 @@ static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2]
float tangent[2];
float u;
- if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent, TRUE)) {
+ if (ED_mask_find_nearest_diff_point(C, mask, co, threshold, false, &masklay, &spline, &point, &u, tangent, true, true)) {
MaskSplinePoint *new_point;
int point_index = point - spline->points;
@@ -382,7 +349,7 @@ static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2]
new_point = &spline->points[point_index + 1];
- setup_vertex_point(mask, spline, new_point, co, tangent, u, NULL, TRUE, 1.0f);
+ setup_vertex_point(mask, spline, new_point, co, u, NULL, true);
/* TODO - we could pass the spline! */
BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, true, true);
@@ -392,13 +359,13 @@ static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2]
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2])
+static bool add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2])
{
MaskSpline *spline;
MaskSplinePoint *point;
@@ -409,14 +376,13 @@ static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay,
float tangent_point[2];
float tangent_co[2];
bool do_cyclic_correct = false;
- bool do_recalc_src = false; /* when extruding from endpoints only */
bool do_prev; /* use prev point rather then next?? */
if (!masklay) {
- return FALSE;
+ return false;
}
else {
- finSelectedSplinePoint(masklay, &spline, &point, TRUE);
+ finSelectedSplinePoint(masklay, &spline, &point, true);
}
ED_mask_select_toggle_all(mask, SEL_DESELECT);
@@ -432,22 +398,20 @@ static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay,
sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]);
if (dot_v2v2(tangent_point, tangent_co) < 0.0f) {
- do_prev = TRUE;
+ do_prev = true;
}
else {
- do_prev = FALSE;
+ do_prev = false;
}
}
else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) {
- do_prev = TRUE;
- do_recalc_src = TRUE;
+ do_prev = true;
}
else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) {
- do_prev = FALSE;
- do_recalc_src = TRUE;
+ do_prev = false;
}
else {
- do_prev = FALSE; /* quiet warning */
+ do_prev = false; /* quiet warning */
/* should never get here */
BLI_assert(0);
}
@@ -458,7 +422,7 @@ static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay,
if (point_index < 0) {
point_index += spline->tot_point; /* wrap index */
if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) {
- do_cyclic_correct = TRUE;
+ do_cyclic_correct = true;
point_index = 0;
}
}
@@ -482,29 +446,23 @@ static int add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay,
masklay->act_point = new_point;
- setup_vertex_point(mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE, 1.0f);
+ setup_vertex_point(mask, spline, new_point, co, 0.5f, ref_point, false);
if (masklay->splines_shapes.first) {
point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point);
BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, true, true);
}
- if (do_recalc_src) {
- /* TODO, update keyframes in time */
- BKE_mask_calc_handle_point_auto(spline, ref_point, FALSE);
- }
-
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- return TRUE;
+ return true;
}
-static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2])
+static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2])
{
MaskSpline *spline;
MaskSplinePoint *point;
MaskSplinePoint *new_point = NULL, *ref_point = NULL;
- float view_zoom;
if (!masklay) {
/* if there's no masklay currently operationg on, create new one */
@@ -514,7 +472,7 @@ static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, con
point = NULL;
}
else {
- finSelectedSplinePoint(masklay, &spline, &point, TRUE);
+ finSelectedSplinePoint(masklay, &spline, &point, true);
}
ED_mask_select_toggle_all(mask, SEL_DESELECT);
@@ -529,22 +487,7 @@ static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, con
masklay->act_point = new_point;
- {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
-
- float zoom_x, zoom_y;
- /* calc view zoom in a simplistic way */
- ED_mask_zoom(sa, ar, &zoom_x, &zoom_y);
-
- view_zoom = zoom_x + zoom_y / 2.0f;
- view_zoom = 1.0f / view_zoom;
-
- /* arbitrary but gives good results */
- view_zoom /= 500.0f;
- }
-
- setup_vertex_point(mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE, view_zoom);
+ setup_vertex_point(mask, spline, new_point, co, 0.5f, ref_point, false);
{
int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point);
@@ -553,7 +496,7 @@ static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, con
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- return TRUE;
+ return true;
}
static int add_vertex_exec(bContext *C, wmOperator *op)
@@ -599,8 +542,8 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
spline->flag |= MASK_SPLINE_CYCLIC;
/* TODO, update keyframes in time */
- BKE_mask_calc_handle_point_auto(spline, point, FALSE);
- BKE_mask_calc_handle_point_auto(spline, point_other, FALSE);
+ BKE_mask_calc_handle_point_auto(spline, point, false);
+ BKE_mask_calc_handle_point_auto(spline, point_other, false);
/* TODO: only update this spline */
BKE_mask_update_display(mask, CFRA);
@@ -681,7 +624,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op)
if (point)
return OPERATOR_FINISHED;
- if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL, TRUE)) {
+ if (ED_mask_find_nearest_diff_point(C, mask, co, threshold, true, &masklay, &spline, &point, &u, NULL, true, true)) {
Scene *scene = CTX_data_scene(C);
float w = BKE_mask_point_weight(spline, point, u);
float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u);
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index d91dc03c107..b1cde208fa8 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -139,29 +139,122 @@ static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float c
BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co);
}
+static void draw_circle(const float x, const float y,
+ const float size, const float xscale, const float yscale)
+{
+ static GLuint displist = 0;
+
+ /* Initialize round circle shape. */
+ if (displist == 0) {
+ GLUquadricObj *qobj;
+
+ displist = glGenLists(1);
+ glNewList(displist, GL_COMPILE);
+
+ qobj = gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ gluDisk(qobj, 0, 0.7, 8, 1);
+ gluDeleteQuadric(qobj);
+
+ glEndList();
+ }
+
+ gpuPushMatrix();
+ gpuTranslate(x, y, 0.0f);
+ gpuScale(1.0f / xscale * size, 1.0f / yscale * size, 1.0f);
+ glCallList(displist);
+ gpuPopMatrix();
+}
+
+static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoint *point,
+ const eMaskWhichHandle which_handle, const int draw_type,
+ const float handle_size, const float xscale, const float yscale,
+ const float point_pos[2], const float handle_pos[2])
+{
+ const BezTriple *bezt = &point->bezt;
+ char handle_type;
+
+ if (which_handle == MASK_WHICH_HANDLE_STICK || which_handle == MASK_WHICH_HANDLE_LEFT) {
+ handle_type = bezt->h1;
+ }
+ else {
+ handle_type = bezt->h2;
+ }
+
+ if (handle_type == HD_VECT) {
+ return;
+ }
+
+ /* this could be split into its own loop */
+ if (draw_type == MASK_DT_OUTLINE) {
+ const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff};
+ gpuLineWidth(3);
+ gpuColor4ubv(rgb_gray);
+ gpuBegin(GL_LINES);
+ gpuVertex2fv(point_pos);
+ gpuVertex2fv(handle_pos);
+ gpuEnd();
+ gpuLineWidth(1);
+ }
+
+ switch (handle_type) {
+ case HD_FREE:
+ UI_ThemeColor(TH_HANDLE_FREE);
+ break;
+ case HD_AUTO:
+ UI_ThemeColor(TH_HANDLE_AUTO);
+ break;
+ case HD_ALIGN:
+ case HD_ALIGN_DOUBLESIDE:
+ UI_ThemeColor(TH_HANDLE_ALIGN);
+ break;
+ }
+
+ gpuBegin(GL_LINES);
+ gpuVertex2fv(point_pos);
+ gpuVertex2fv(handle_pos);
+ gpuEnd();
+
+ /* draw handle points */
+ if (MASKPOINT_ISSEL_HANDLE(point, which_handle)) {
+ if (point == mask_layer->act_point)
+ gpuColor3P(CPACK_WHITE);
+ else
+ gpuColor3P(CPACK_YELLOW);
+ }
+ else {
+ gpuColor3f(0.5f, 0.5f, 0.0f);
+ }
+
+ draw_circle(handle_pos[0], handle_pos[1], handle_size, xscale, yscale);
+}
+
/* return non-zero if spline is selected */
static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
- const char UNUSED(draw_flag), const char draw_type)
+ const char draw_flag, const char draw_type,
+ const float xscale, const float yscale)
{
const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0;
+ const bool is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH) != 0;
+
unsigned char rgb_spline[4];
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
SpaceClip *sc = CTX_wm_space_clip(C);
- int undistort = FALSE;
+ bool undistort = false;
- int i, hsize, tot_feather_point;
+ int i, handle_size, tot_feather_point;
float (*feather_points)[2], (*fp)[2];
if (!spline->tot_point)
return;
if (sc)
- undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
+ undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
/* TODO, add this to sequence editor */
- hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */
+ handle_size = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
- GPU_point_size(hsize);
+ GPU_point_size(handle_size);
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline);
@@ -181,7 +274,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
for (j = 0; j <= point->tot_uw; j++) {
float feather_point[2];
- int sel = FALSE;
+ bool sel = false;
copy_v2_v2(feather_point, *fp);
@@ -192,7 +285,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
sel = MASKPOINT_ISSEL_ANY(point);
}
else {
- sel = point->uw[j - 1].flag & SELECT;
+ sel = (point->uw[j - 1].flag & SELECT) != 0;
}
if (sel) {
@@ -215,6 +308,11 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
MEM_freeN(feather_points);
+ if (is_smooth) {
+ GPU_aspect_enable(GPU_ASPECT_RASTER, GPU_ASPECT_SMOOTH);
+ glEnable(GL_BLEND);
+ }
+
/* control points */
for (i = 0; i < spline->tot_point; i++) {
@@ -223,37 +321,36 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
MaskSplinePoint *point_deform = &points_array[i];
BezTriple *bezt = &point_deform->bezt;
- float handle[2];
float vert[2];
- const bool has_handle = BKE_mask_point_has_handle(point);
copy_v2_v2(vert, bezt->vec[1]);
- BKE_mask_point_handle(point_deform, handle);
if (undistort) {
mask_point_undistort_pos(sc, vert, vert);
- mask_point_undistort_pos(sc, handle, handle);
}
/* draw handle segment */
- if (has_handle) {
-
- /* this could be split into its own loop */
- if (draw_type == MASK_DT_OUTLINE) {
- gpuLineWidth(3);
- gpuGray3f(0.376f);
- gpuBegin(GL_LINES);
- gpuVertex2fv(vert);
- gpuVertex2fv(handle);
- gpuEnd();
- gpuLineWidth(1);
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ float handle[2];
+ BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_STICK, handle);
+ if (undistort) {
+ mask_point_undistort_pos(sc, handle, handle);
}
-
- gpuColor3ubv(rgb_spline);
- gpuBegin(GL_LINES);
- gpuVertex2fv(vert);
- gpuVertex2fv(handle);
- gpuEnd();
+ draw_single_handle(masklay, point, MASK_WHICH_HANDLE_STICK,
+ draw_type, handle_size, xscale, yscale, vert, handle);
+ }
+ else {
+ float handle_left[2], handle_right[2];
+ BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_LEFT, handle_left);
+ BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_RIGHT, handle_right);
+ if (undistort) {
+ mask_point_undistort_pos(sc, handle_left, handle_left);
+ mask_point_undistort_pos(sc, handle_left, handle_left);
+ }
+ draw_single_handle(masklay, point, MASK_WHICH_HANDLE_LEFT,
+ draw_type, handle_size, xscale, yscale, vert, handle_left);
+ draw_single_handle(masklay, point, MASK_WHICH_HANDLE_RIGHT,
+ draw_type, handle_size, xscale, yscale, vert, handle_right);
}
gpuBegin(GL_POINTS);
@@ -271,32 +368,20 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
gpuVertex2fv(vert);
- /* draw handle points */
- if (has_handle) {
- if (MASKPOINT_ISSEL_HANDLE(point)) {
- if (point == masklay->act_point)
- gpuColor3P(CPACK_WHITE);
- else
- gpuColor3P(CPACK_YELLOW);
- }
- else {
- gpuColor3f(0.5f, 0.5f, 0.0f);
- }
-
- gpuVertex2fv(handle);
- }
-
gpuEnd();
}
GPU_point_size(1);
- gpuImmediateUnformat();
+ if (is_smooth) {
+ GPU_aspect_disable(GPU_ASPECT_RASTER, GPU_RASTER_SMOOTH);
+ glDisable(GL_BLEND);
+ }
}
/* #define USE_XOR */
-static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char rgb[4], const short is_active)
+static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char rgb[4], const bool is_active)
{
if (!is_active) {
r_rgb[0] = (unsigned char)((((int)(rgb[0])) + 128) / 2);
@@ -394,7 +479,7 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
rgb_tmp[2] = (unsigned char)(((short)rgb_tmp[2] + (short)rgb_spline[2]) / 2);
}
- if (is_smooth == FALSE && is_feather) {
+ if (is_smooth == false && is_feather) {
glEnable(GL_BLEND);
}
@@ -403,7 +488,7 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
gpuDrawClientArrays(draw_method, &arrays, 0, tot_point);
gpuRepeat(); // XXX: why twice?
- if (is_smooth == FALSE && is_feather) {
+ if (is_smooth == false && is_feather) {
glDisable(GL_BLEND);
}
@@ -419,7 +504,7 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*
static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
const char draw_flag, const char draw_type,
const bool is_active,
- int width, int height)
+ const int width, const int height)
{
const unsigned int resol = max_ii(BKE_mask_spline_feather_resolution(spline, width, height),
BKE_mask_spline_resolution(spline, width, height));
@@ -448,17 +533,17 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
glEnable(GL_BLEND);
}
- feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, &tot_feather_point, resol, (is_fill != FALSE));
+ feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, &tot_feather_point, resol, (is_fill != false));
/* draw feather */
mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp);
mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
- TRUE, is_smooth, is_active,
+ true, is_smooth, is_active,
rgb_tmp, draw_type);
if (!is_fill) {
- float *fp = &diff_points[0][0];
+ const float *fp = &diff_points[0][0];
float *fp_feather = &feather_points[0][0];
float tvec[2];
int i;
@@ -472,7 +557,7 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
/* same as above */
mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
- TRUE, is_smooth, is_active,
+ true, is_smooth, is_active,
rgb_tmp, draw_type);
}
@@ -481,7 +566,7 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
/* draw main curve */
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp);
mask_draw_curve_type(C, spline, diff_points, tot_diff_point,
- FALSE, is_smooth, is_active,
+ false, is_smooth, is_active,
rgb_tmp, draw_type);
MEM_freeN(diff_points);
@@ -496,7 +581,7 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
}
static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, const char draw_type,
- int width, int height)
+ const int width, const int height, const float xscale, const float yscale)
{
MaskLayer *masklay;
int i;
@@ -518,7 +603,7 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c
if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) {
/* ...and then handles over the curve so they're nicely visible */
- draw_spline_points(C, masklay, spline, draw_flag, draw_type);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type, xscale, yscale);
}
/* show undeform for testing */
@@ -528,7 +613,7 @@ static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, c
spline->points_deform = NULL;
draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height);
// draw_spline_parents(masklay, spline);
- draw_spline_points(C, masklay, spline, draw_flag, draw_type);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type, xscale, yscale);
spline->points_deform = back;
}
}
@@ -539,16 +624,21 @@ void ED_mask_draw(const bContext *C,
const char draw_flag, const char draw_type)
{
ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
Mask *mask = CTX_data_edit_mask(C);
int width, height;
+ float aspx, aspy;
+ float xscale, yscale;
if (!mask)
return;
ED_mask_get_size(sa, &width, &height);
+ ED_mask_get_aspect(sa, ar, &aspx, &aspy);
+ UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
- draw_masklays(C, mask, draw_flag, draw_type, width, height);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height, xscale * aspx, yscale * aspy);
}
typedef struct ThreadedMaskRasterizeState {
@@ -567,15 +657,21 @@ static void mask_rasterize_func(TaskPool *pool, void *taskdata, int UNUSED(threa
ThreadedMaskRasterizeState *state = (ThreadedMaskRasterizeState *) BLI_task_pool_userdata(pool);
ThreadedMaskRasterizeData *data = (ThreadedMaskRasterizeData *) taskdata;
int scanline;
+ const float x_inv = 1.0f / (float)state->width;
+ const float y_inv = 1.0f / (float)state->height;
+ const float x_px_ofs = x_inv * 0.5f;
+ const float y_px_ofs = y_inv * 0.5f;
for (scanline = 0; scanline < data->num_scanlines; scanline++) {
+ float xy[2];
int x, y = data->start_scanline + scanline;
+
+ xy[1] = ((float)y * y_inv) + y_px_ofs;
+
for (x = 0; x < state->width; x++) {
int index = y * state->width + x;
- float xy[2];
- xy[0] = (float) x / state->width;
- xy[1] = (float) y / state->height;
+ xy[0] = ((float)x * x_inv) + x_px_ofs;
state->buffer[index] = BKE_maskrasterize_handle_sample(state->handle, xy);
}
@@ -595,7 +691,7 @@ static float *threaded_mask_rasterize(Mask *mask, const int width, const int hei
/* Initialize rasterization handle. */
handle = BKE_maskrasterize_handle_new();
- BKE_maskrasterize_handle_init(handle, mask, width, height, TRUE, TRUE, TRUE);
+ BKE_maskrasterize_handle_init(handle, mask, width, height, true, true, true);
state.handle = handle;
state.buffer = buffer;
@@ -656,7 +752,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
float xofs, yofs;
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
/* w = BLI_rctf_size_x(&v2d->tot); */
@@ -733,7 +829,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
}
/* draw! */
- draw_masklays(C, mask, draw_flag, draw_type, width, height);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height, maxdim * zoomx, maxdim * zoomy);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index ad287a3af9f..1acdff8b824 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -69,7 +69,7 @@ int ED_maskedit_poll(bContext *C)
return ED_space_image_maskedit_poll(C);
}
}
- return FALSE;
+ return false;
}
int ED_maskedit_mask_poll(bContext *C)
@@ -85,7 +85,7 @@ int ED_maskedit_mask_poll(bContext *C)
return ED_space_image_maskedit_mask_poll(C);
}
}
- return FALSE;
+ return false;
}
/********************** registration *********************/
@@ -326,7 +326,7 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
SpaceClip *sc = sa->spacedata.first;
float aspx, aspy;
- UI_view2d_getscale(&ar->v2d, scalex, scaley);
+ UI_view2d_scale_get(&ar->v2d, scalex, scaley);
ED_space_clip_get_aspect(sc, &aspx, &aspy);
*scalex *= aspx;
@@ -343,7 +343,7 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
SpaceImage *sima = sa->spacedata.first;
float aspx, aspy;
- UI_view2d_getscale(&ar->v2d, scalex, scaley);
+ UI_view2d_scale_get(&ar->v2d, scalex, scaley);
ED_space_image_get_aspect(sima, &aspx, &aspy);
*scalex *= aspx;
@@ -438,6 +438,7 @@ void ED_operatortypes_mask(void)
/* shape */
WM_operatortype_append(MASK_OT_slide_point);
+ WM_operatortype_append(MASK_OT_slide_spline_curvature);
WM_operatortype_append(MASK_OT_cyclic_toggle);
WM_operatortype_append(MASK_OT_handle_type_set);
@@ -487,13 +488,13 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
/* selection */
kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
@@ -502,17 +503,17 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "MASK_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MASK_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -520,20 +521,21 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
/* hide/reveal */
WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
/* select clip while in maker view,
* this matches View3D functionality where you can select an
* object while in editmode to allow vertex parenting */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
/* shape */
WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MASK_OT_slide_point", ACTIONMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MASK_OT_slide_spline_curvature", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
// WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0);
@@ -570,20 +572,20 @@ void ED_operatormacros_mask(void)
"Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
ot->description = "Add new vertex and slide it";
WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
- otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
- RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
+ otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
+ RNA_boolean_set(otmacro->ptr, "is_new_point", true);
ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide",
"Add new vertex to feather and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
ot->description = "Add new feather vertex and slide it";
WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
- RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
+ RNA_boolean_set(otmacro->ptr, "slide_feather", true);
ot = WM_operatortype_append_macro("MASK_OT_duplicate_move", "Add Duplicate", "Duplicate mask and move",
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MASK_OT_duplicate");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
- RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
}
diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c
index d4ac0338456..bcf9ee5c88d 100644
--- a/source/blender/editors/mask/mask_editaction.c
+++ b/source/blender/editors/mask/mask_editaction.c
@@ -36,11 +36,9 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_fcurve.h"
@@ -61,30 +59,30 @@
/* Generics - Loopers */
/* Loops over the mask-frames for a mask-layer, and applies the given callback */
-short ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*masklay_shape_cb)(MaskLayerShape *, Scene *))
+bool ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*masklay_shape_cb)(MaskLayerShape *, Scene *))
{
MaskLayerShape *masklay_shape;
/* error checker */
if (masklay == NULL)
- return 0;
+ return false;
/* do loop */
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
/* execute callback */
if (masklay_shape_cb(masklay_shape, scene))
- return 1;
+ return true;
}
/* nothing to return */
- return 0;
+ return false;
}
/* ****************************************** */
/* Data Conversion Tools */
/* make a listing all the mask-frames in a layer as cfraelems */
-void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short onlysel)
+void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, bool onlysel)
{
MaskLayerShape *masklay_shape;
CfraElem *ce;
@@ -95,7 +93,7 @@ void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short only
/* loop through mask-frames, adding */
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
- if ((onlysel == 0) || (masklay_shape->flag & MASK_SHAPE_SELECT)) {
+ if ((onlysel == false) || (masklay_shape->flag & MASK_SHAPE_SELECT)) {
ce = MEM_callocN(sizeof(CfraElem), "CfraElem");
ce->cfra = (float)masklay_shape->frame;
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index 62872e72cb4..6899cf7e6f5 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -40,6 +40,17 @@ struct wmOperatorType;
/* internal exports only */
/* mask_add.c */
+bool ED_mask_find_nearest_diff_point(const struct bContext *C,
+ struct Mask *mask,
+ const float normal_co[2],
+ int threshold, bool feather,
+ struct MaskLayer **masklay_r,
+ struct MaskSpline **spline_r,
+ struct MaskSplinePoint **point_r,
+ float *u_r, float tangent[2],
+ const bool use_deform,
+ const bool use_project);
+
void MASK_OT_add_vertex(struct wmOperatorType *ot);
void MASK_OT_add_feather_vertex(struct wmOperatorType *ot);
void MASK_OT_primitive_circle_add(struct wmOperatorType *ot);
@@ -55,6 +66,7 @@ void MASK_OT_layer_remove(struct wmOperatorType *ot);
void MASK_OT_cyclic_toggle(struct wmOperatorType *ot);
void MASK_OT_slide_point(struct wmOperatorType *ot);
+void MASK_OT_slide_spline_curvature(struct wmOperatorType *ot);
void MASK_OT_delete(struct wmOperatorType *ot);
@@ -73,7 +85,7 @@ bool ED_mask_feather_find_nearest(
struct MaskSplinePoint *ED_mask_point_find_nearest(
const struct bContext *C, struct Mask *mask, const float normal_co[2], const float threshold,
- struct MaskLayer **masklay_r, struct MaskSpline **spline_r, bool *is_handle_r,
+ struct MaskLayer **masklay_r, struct MaskSpline **spline_r, eMaskWhichHandle *which_handle_r,
float *score);
void MASK_OT_layer_move(struct wmOperatorType *ot);
@@ -102,8 +114,8 @@ bool ED_mask_spline_select_check(struct MaskSpline *spline);
bool ED_mask_layer_select_check(struct MaskLayer *masklay);
bool ED_mask_select_check(struct Mask *mask);
-void ED_mask_spline_select_set(struct MaskSpline *spline, const short do_select);
-void ED_mask_layer_select_set(struct MaskLayer *masklay, const short do_select);
+void ED_mask_spline_select_set(struct MaskSpline *spline, const bool do_select);
+void ED_mask_layer_select_set(struct MaskLayer *masklay, const bool do_select);
void ED_mask_select_toggle_all(struct Mask *mask, int action);
void ED_mask_select_flush_all(struct Mask *mask);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 28f4940f236..b7e026ca8e3 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -59,9 +59,17 @@
/******************** utility functions *********************/
+static void mask_point_scaled_handle(/*const*/ MaskSplinePoint *point, /*const*/ eMaskWhichHandle which_handle,
+ const float scalex, const float scaley, float handle[2])
+{
+ BKE_mask_point_handle(point, which_handle, handle);
+ handle[0] *= scalex;
+ handle[1] *= scaley;
+}
+
MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const float normal_co[2], const float threshold,
- MaskLayer **masklay_r, MaskSpline **spline_r, bool *is_handle_r,
- float *score)
+ MaskLayer **masklay_r, MaskSpline **spline_r,
+ eMaskWhichHandle *which_handle_r, float *score)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -73,7 +81,8 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const
float co[2];
const float threshold_sq = threshold * threshold;
float len_sq = FLT_MAX, scalex, scaley;
- int is_handle = FALSE, width, height;
+ eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE;
+ int width, height;
ED_mask_get_size(sa, &width, &height);
ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);
@@ -96,35 +105,69 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const
for (i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *cur_point = &spline->points[i];
MaskSplinePoint *cur_point_deform = &points_array[i];
- float cur_len_sq, vec[2], handle[2];
+ eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE;
+ BezTriple *bezt = &cur_point_deform->bezt;
+ float cur_len_sq, vec[2];
- vec[0] = cur_point_deform->bezt.vec[1][0] * scalex;
- vec[1] = cur_point_deform->bezt.vec[1][1] * scaley;
+ vec[0] = bezt->vec[1][0] * scalex;
+ vec[1] = bezt->vec[1][1] * scaley;
- if (BKE_mask_point_has_handle(cur_point)) {
- BKE_mask_point_handle(cur_point_deform, handle);
- handle[0] *= scalex;
- handle[1] *= scaley;
+ cur_len_sq = len_squared_v2v2(co, vec);
- cur_len_sq = len_squared_v2v2(co, handle);
+ if (cur_len_sq < len_sq) {
+ point_spline = spline;
+ point_masklay = masklay;
+ point = cur_point;
+ len_sq = cur_len_sq;
+ which_handle = MASK_WHICH_HANDLE_NONE;
+ }
- if (cur_len_sq < len_sq) {
- point_masklay = masklay;
- point_spline = spline;
- point = cur_point;
- len_sq = cur_len_sq;
- is_handle = TRUE;
+ if (BKE_mask_point_handles_mode_get(cur_point_deform) == MASK_HANDLE_MODE_STICK) {
+ float handle[2];
+ mask_point_scaled_handle(cur_point_deform, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle);
+ cur_len_sq = len_squared_v2v2(co, handle);
+ cur_which_handle = MASK_WHICH_HANDLE_STICK;
+ }
+ else {
+ float handle_left[2], handle_right[2];
+ float len_left_sq, len_right_sq;
+ mask_point_scaled_handle(cur_point_deform, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left);
+ mask_point_scaled_handle(cur_point_deform, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right);
+
+ len_left_sq = len_squared_v2v2(co, handle_left);
+ len_right_sq = len_squared_v2v2(co, handle_right);
+ if (i == 0) {
+ if (len_left_sq <= len_right_sq) {
+ if (bezt->h1 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_LEFT;
+ cur_len_sq = len_left_sq;
+ }
+ }
+ else if (bezt->h2 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
+ cur_len_sq = len_right_sq;
+ }
+ }
+ else {
+ if (len_right_sq <= len_left_sq) {
+ if (bezt->h2 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
+ cur_len_sq = len_right_sq;
+ }
+ }
+ else if (bezt->h1 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_LEFT;
+ cur_len_sq = len_left_sq;
+ }
}
}
- cur_len_sq = len_squared_v2v2(co, vec);
-
- if (cur_len_sq < len_sq) {
- point_spline = spline;
+ if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) {
point_masklay = masklay;
+ point_spline = spline;
point = cur_point;
len_sq = cur_len_sq;
- is_handle = FALSE;
+ which_handle = cur_which_handle;
}
}
}
@@ -137,8 +180,8 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const
if (spline_r)
*spline_r = point_spline;
- if (is_handle_r)
- *is_handle_r = is_handle;
+ if (which_handle_r)
+ *which_handle_r = which_handle;
if (score)
*score = sqrtf(len_sq);
@@ -152,8 +195,8 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const
if (spline_r)
*spline_r = NULL;
- if (is_handle_r)
- *is_handle_r = FALSE;
+ if (which_handle_r)
+ *which_handle_r = MASK_WHICH_HANDLE_NONE;
return NULL;
}
@@ -243,7 +286,7 @@ bool ED_mask_feather_find_nearest(const bContext *C, Mask *mask, const float nor
if (score)
*score = sqrtf(len);
- return TRUE;
+ return true;
}
if (masklay_r)
@@ -255,7 +298,7 @@ bool ED_mask_feather_find_nearest(const bContext *C, Mask *mask, const float nor
if (point_r)
*point_r = NULL;
- return FALSE;
+ return false;
}
@@ -419,22 +462,39 @@ enum {
};
typedef struct SlidePointData {
+ /* Generic fields. */
+ short event_invoke_type;
int action;
-
- float co[2];
- float vec[3][3];
-
Mask *mask;
MaskLayer *masklay;
MaskSpline *spline, *orig_spline;
MaskSplinePoint *point;
MaskSplinePointUW *uw;
- float handle[2], no[2], feather[2];
+ eMaskWhichHandle which_handle;
int width, height;
- float weight, weight_scalar;
- short curvature_only, accurate;
- short initial_feather, overall_feather;
+ float prev_mouse_coord[2];
+ float no[2];
+
+ bool is_curvature_only,
+ is_accurate,
+ is_initial_feather,
+ is_overall_feather;
+
+ bool is_sliding_new_point;
+
+ /* Data needed to restre the state. */
+ float vec[3][3];
+ char old_h1, old_h2;
+
+ /* Point sliding. */
+
+ /* Handle sliding. */
+ float orig_handle_coord[2], prev_handle_coord[2];
+
+ /* Feather sliding. */
+ float prev_feather_coord[2];
+ float weight, weight_scalar;
} SlidePointData;
static bool slide_point_check_initial_feather(MaskSpline *spline)
@@ -444,20 +504,64 @@ static bool slide_point_check_initial_feather(MaskSpline *spline)
for (i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point = &spline->points[i];
- if (point->bezt.weight != 0.0f)
- return FALSE;
-
- /* comment for now. if all bezt weights are zero - this is as good-as initial */
-#if 0
- int j;
- for (j = 0; j < point->tot_uw; j++) {
- if (point->uw[j].w != 0.0f)
- return FALSE;
+ if (point->bezt.weight != 0.0f) {
+ return false;
}
-#endif
}
- return TRUE;
+ return true;
+}
+
+static void select_sliding_point(Mask *mask, MaskLayer *mask_layer, MaskSpline *spline,
+ MaskSplinePoint *point, eMaskWhichHandle which_handle)
+{
+ ED_mask_select_toggle_all(mask, SEL_DESELECT);
+
+ switch (which_handle) {
+ case MASK_WHICH_HANDLE_NONE:
+ BKE_mask_point_select_set(point, true);
+ break;
+ case MASK_WHICH_HANDLE_LEFT:
+ point->bezt.f1 |= SELECT;
+ break;
+ case MASK_WHICH_HANDLE_RIGHT:
+ point->bezt.f3 |= SELECT;
+ break;
+ case MASK_WHICH_HANDLE_STICK:
+ point->bezt.f1 |= SELECT;
+ point->bezt.f3 |= SELECT;
+ break;
+ default:
+ BLI_assert(!"Unexpected situation in select_sliding_point()");
+ }
+
+ mask_layer->act_spline = spline;
+ mask_layer->act_point = point;
+ ED_mask_select_flush_all(mask);
+}
+
+static void check_sliding_handle_type(MaskSplinePoint *point, eMaskWhichHandle which_handle)
+{
+ BezTriple *bezt = &point->bezt;
+
+ if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ if (bezt->h1 == HD_VECT) {
+ bezt->h1 = HD_FREE;
+ }
+ else if (bezt->h1 == HD_AUTO) {
+ bezt->h1 = HD_ALIGN_DOUBLESIDE;
+ bezt->h2 = HD_ALIGN_DOUBLESIDE;
+ }
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ if (bezt->h2 == HD_VECT) {
+ bezt->h2 = HD_FREE;
+ }
+ else if (bezt->h2 == HD_AUTO) {
+ bezt->h1 = HD_ALIGN_DOUBLESIDE;
+ bezt->h2 = HD_ALIGN_DOUBLESIDE;
+ }
+ }
}
static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
@@ -472,15 +576,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
MaskSplinePoint *point, *cv_point, *feather_point;
MaskSplinePointUW *uw = NULL;
int width, height, action = SLIDE_ACTION_NONE;
- bool is_handle = false;
const bool slide_feather = RNA_boolean_get(op->ptr, "slide_feather");
float co[2], cv_score, feather_score;
const float threshold = 19;
+ eMaskWhichHandle which_handle;
ED_mask_mouse_pos(sa, ar, event->mval, co);
ED_mask_get_size(sa, &width, &height);
- cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score);
+ cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &which_handle, &cv_score);
if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) {
if (slide_feather || !cv_point || feather_score < cv_score) {
@@ -493,7 +597,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
}
if (cv_point && action == SLIDE_ACTION_NONE) {
- if (is_handle)
+ if (which_handle != MASK_WHICH_HANDLE_NONE)
action = SLIDE_ACTION_HANDLE;
else
action = SLIDE_ACTION_POINT;
@@ -504,8 +608,10 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
}
if (action != SLIDE_ACTION_NONE) {
- customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data");
+ select_sliding_point(mask, masklay, spline, point, which_handle);
+ customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data");
+ customdata->event_invoke_type = event->type;
customdata->mask = mask;
customdata->masklay = masklay;
customdata->spline = spline;
@@ -515,6 +621,13 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
customdata->action = action;
customdata->uw = uw;
+ customdata->old_h1 = point->bezt.h1;
+ customdata->old_h2 = point->bezt.h2;
+
+ customdata->is_sliding_new_point = RNA_boolean_get(op->ptr, "is_new_point");
+
+ check_sliding_handle_type(point, which_handle);
+
if (uw) {
float co_uw[2];
float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u);
@@ -524,7 +637,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
BKE_mask_point_segment_co(spline, point, uw->u, co_uw);
BKE_mask_point_normal(spline, point, uw->u, customdata->no);
- madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar);
+ madd_v2_v2v2fl(customdata->prev_feather_coord, co_uw, customdata->no, uw->w * weight_scalar);
}
else {
BezTriple *bezt = &point->bezt;
@@ -533,16 +646,21 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
customdata->weight_scalar = 1.0f;
BKE_mask_point_normal(spline, point, 0.0f, customdata->no);
- madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight);
+ madd_v2_v2v2fl(customdata->prev_feather_coord, bezt->vec[1], customdata->no, bezt->weight);
}
- if (customdata->action == SLIDE_ACTION_FEATHER)
- customdata->initial_feather = slide_point_check_initial_feather(spline);
+ if (customdata->action == SLIDE_ACTION_FEATHER) {
+ customdata->is_initial_feather = slide_point_check_initial_feather(spline);
+ }
copy_m3_m3(customdata->vec, point->bezt.vec);
- if (BKE_mask_point_has_handle(point))
- BKE_mask_point_handle(point, customdata->handle);
- ED_mask_mouse_pos(sa, ar, event->mval, customdata->co);
+ if (which_handle != MASK_WHICH_HANDLE_NONE) {
+ BKE_mask_point_handle(point, which_handle, customdata->orig_handle_coord);
+ copy_v2_v2(customdata->prev_handle_coord, customdata->orig_handle_coord);
+ }
+ customdata->which_handle = which_handle;
+
+ ED_mask_mouse_pos(sa, ar, event->mval, customdata->prev_mouse_coord);
}
return customdata;
@@ -550,34 +668,20 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- SlidePointData *slidedata = slide_point_customdata(C, op, event);
+ Mask *mask = CTX_data_edit_mask(C);
+ SlidePointData *slidedata;
- if (slidedata) {
- Mask *mask = CTX_data_edit_mask(C);
+ if (mask == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ slidedata = slide_point_customdata(C, op, event);
+ if (slidedata) {
op->customdata = slidedata;
WM_event_add_modal_handler(C, op);
-#if 0
- if (slidedata->uw) {
- if ((slidedata->uw->flag & SELECT) == 0) {
- ED_mask_select_toggle_all(mask, SEL_DESELECT);
-
- slidedata->uw->flag |= SELECT;
-
- ED_mask_select_flush_all(mask);
- }
- }
- else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) {
- ED_mask_select_toggle_all(mask, SEL_DESELECT);
-
- BKE_mask_point_select_set(slidedata->point, TRUE);
-
- ED_mask_select_flush_all(mask);
- }
-#endif
-
slidedata->masklay->act_spline = slidedata->spline;
slidedata->masklay->act_point = slidedata->point;
@@ -598,18 +702,9 @@ static void slide_point_delta_all_feather(SlidePointData *data, float delta)
MaskSplinePoint *orig_point = &data->orig_spline->points[i];
point->bezt.weight = orig_point->bezt.weight + delta;
- if (point->bezt.weight < 0.0f)
+ if (point->bezt.weight < 0.0f) {
point->bezt.weight = 0.0f;
-
- /* not needed anymore */
-#if 0
- int j;
- for (j = 0; j < point->tot_uw; j++) {
- point->uw[j].w = orig_point->uw[j].w + delta;
- if (point->uw[j].w < 0.0f)
- point->uw[j].w = 0.0f;
}
-#endif
}
}
@@ -645,6 +740,8 @@ static void cancel_slide_point(SlidePointData *data)
}
else {
copy_m3_m3(data->point->bezt.vec, data->vec);
+ data->point->bezt.h1 = data->old_h1;
+ data->point->bezt.h2 = data->old_h2;
}
}
}
@@ -661,7 +758,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SlidePointData *data = (SlidePointData *)op->customdata;
BezTriple *bezt = &data->point->bezt;
- float co[2], dco[2];
+ float co[2];
switch (event->type) {
case LEFTALTKEY:
@@ -669,55 +766,79 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
if (ELEM(event->type, LEFTALTKEY, RIGHTALTKEY)) {
- if (data->action == SLIDE_ACTION_FEATHER)
- data->overall_feather = (event->val == KM_PRESS);
- else
- data->curvature_only = (event->val == KM_PRESS);
+ if (data->action == SLIDE_ACTION_FEATHER) {
+ data->is_overall_feather = (event->val == KM_PRESS);
+ }
+ else {
+ data->is_curvature_only = (event->val == KM_PRESS);
+ }
}
if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY))
- data->accurate = (event->val == KM_PRESS);
+ data->is_accurate = (event->val == KM_PRESS);
/* fall-through */ /* update CV position */
case MOUSEMOVE:
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
+ float delta[2];
ED_mask_mouse_pos(sa, ar, event->mval, co);
- sub_v2_v2v2(dco, co, data->co);
+ sub_v2_v2v2(delta, co, data->prev_mouse_coord);
+ if (data->is_accurate) {
+ mul_v2_fl(delta, 0.2f);
+ }
+ copy_v2_v2(data->prev_mouse_coord, co);
if (data->action == SLIDE_ACTION_HANDLE) {
- float delta[2], offco[2];
+ float new_handle[2];
+
+ if (data->is_sliding_new_point && data->which_handle == MASK_WHICH_HANDLE_STICK) {
+ if (ELEM(data->point, &data->spline->points[0],
+ &data->spline->points[data->spline->tot_point - 1]))
+ {
+ SWAP(float, delta[0], delta[1]);
+ delta[1] *= -1;
+
+ /* flip last point */
+ if (data->point != &data->spline->points[0]) {
+ negate_v2(delta);
+ }
+ }
+ }
+
+ add_v2_v2v2(new_handle, data->prev_handle_coord, delta);
- sub_v2_v2v2(delta, data->handle, data->co);
+ BKE_mask_point_set_handle(data->point, data->which_handle,
+ new_handle, data->is_curvature_only,
+ data->orig_handle_coord, data->vec);
+ BKE_mask_point_handle(data->point, data->which_handle, data->prev_handle_coord);
- sub_v2_v2v2(offco, co, data->co);
- if (data->accurate)
- mul_v2_fl(offco, 0.2f);
- add_v2_v2(offco, data->co);
- add_v2_v2(offco, delta);
+ if (data->is_sliding_new_point) {
+ if (ELEM(data->which_handle, MASK_WHICH_HANDLE_LEFT, MASK_WHICH_HANDLE_RIGHT)) {
+ BezTriple *bezt = &data->point->bezt;
+ float vec[2];
+ short self_handle = (data->which_handle == MASK_WHICH_HANDLE_LEFT) ? 0 : 2;
+ short other_handle = (data->which_handle == MASK_WHICH_HANDLE_LEFT) ? 2 : 0;
- BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec);
+ sub_v2_v2v2(vec, bezt->vec[1], bezt->vec[self_handle]);
+ add_v2_v2v2(bezt->vec[other_handle], bezt->vec[1], vec);
+ }
+ }
}
else if (data->action == SLIDE_ACTION_POINT) {
- float delta[2];
-
- copy_v2_v2(delta, dco);
- if (data->accurate)
- mul_v2_fl(delta, 0.2f);
-
- add_v2_v2v2(bezt->vec[0], data->vec[0], delta);
- add_v2_v2v2(bezt->vec[1], data->vec[1], delta);
- add_v2_v2v2(bezt->vec[2], data->vec[2], delta);
+ add_v2_v2(bezt->vec[0], delta);
+ add_v2_v2(bezt->vec[1], delta);
+ add_v2_v2(bezt->vec[2], delta);
}
else if (data->action == SLIDE_ACTION_FEATHER) {
float vec[2], no[2], p[2], c[2], w, offco[2];
float *weight = NULL;
float weight_scalar = 1.0f;
- int overall_feather = data->overall_feather || data->initial_feather;
+ bool is_overall_feather = data->is_overall_feather || data->is_initial_feather;
- add_v2_v2v2(offco, data->feather, dco);
+ add_v2_v2v2(offco, data->prev_feather_coord, delta);
if (data->uw) {
/* project on both sides and find the closest one,
@@ -771,7 +892,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
w = len_v2(vec);
- if (overall_feather) {
+ if (is_overall_feather) {
float delta;
if (dot_v2v2(no, vec) <= 0.0f)
@@ -788,6 +909,10 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
data->orig_spline = BKE_mask_spline_copy(data->spline);
}
+ if (data->is_initial_feather) {
+ *weight = w * weight_scalar;
+ }
+
slide_point_delta_all_feather(data, delta);
}
else {
@@ -806,6 +931,8 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
*weight = w * weight_scalar;
}
}
+
+ copy_v2_v2(data->prev_feather_coord, offco);
}
}
@@ -816,16 +943,27 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
case LEFTMOUSE:
- if (event->val == KM_RELEASE) {
+ case RIGHTMOUSE:
+ if (event->type == data->event_invoke_type && event->val == KM_RELEASE) {
Scene *scene = CTX_data_scene(C);
/* dont key sliding feather uw's */
- if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == FALSE) {
+ if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == false) {
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(data->masklay, CFRA);
}
}
+ if (data->is_sliding_new_point) {
+ BezTriple *bezt = &data->point->bezt;
+ if (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) < FLT_EPSILON) {
+ bezt->h1 = HD_VECT;
+ }
+ if (len_squared_v2v2(bezt->vec[2], bezt->vec[1]) < FLT_EPSILON) {
+ bezt->h2 = HD_VECT;
+ }
+ }
+
WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
DAG_id_tag_update(&data->mask->id, 0);
@@ -850,6 +988,8 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
void MASK_OT_slide_point(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Slide Point";
ot->description = "Slide control points";
@@ -858,12 +998,397 @@ void MASK_OT_slide_point(wmOperatorType *ot)
/* api callbacks */
ot->invoke = slide_point_invoke;
ot->modal = slide_point_modal;
- ot->poll = ED_maskedit_mask_poll;
+ ot->poll = ED_operator_mask;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide feather instead of vertex");
+
+ prop = RNA_def_boolean(ot->srna, "is_new_point", 0, "Slide New Point", "Newly created vertex is being slid");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
+/******************** slide spline curvature *********************/
+
+typedef struct SlideSplineCurvatureData {
+ short event_invoke_type;
+
+ Mask *mask;
+ MaskLayer *mask_layer;
+ MaskSpline *spline;
+ MaskSplinePoint *point;
+ float u;
+ bool accurate;
+
+ BezTriple *adjust_bezt, *other_bezt;
+ BezTriple bezt_backup, other_bezt_backup;
+
+ float prev_mouse_coord[2];
+ float prev_spline_coord[2];
+
+ float P0[2], P1[2], P2[2], P3[3];
+} SlideSplineCurvatureData;
+
+static void cancel_slide_spline_curvature(SlideSplineCurvatureData *slide_data)
+{
+ *slide_data->adjust_bezt = slide_data->bezt_backup;
+ *slide_data->other_bezt = slide_data->other_bezt_backup;
+}
+
+
+static void free_slide_spline_curvature_data(SlideSplineCurvatureData *slide_data)
+{
+ MEM_freeN(slide_data);
+}
+
+static bool slide_spline_curvature_check(bContext *C, const wmEvent *event)
+{
+ Mask *mask = CTX_data_edit_mask(C);
+ float co[2];
+ const float threshold = 19;
+
+ ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, co);
+
+ if (ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL)) {
+ return false;
+ }
+
+ if (ED_mask_feather_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL, NULL)) {
+ return false;
+ }
+
+ return true;
+}
+
+static SlideSplineCurvatureData *slide_spline_curvature_customdata(
+ bContext *C, const wmEvent *event)
+{
+ const float threshold = 19;
+
+ Mask *mask = CTX_data_edit_mask(C);
+ SlideSplineCurvatureData *slide_data;
+ MaskLayer *mask_layer;
+ MaskSpline *spline;
+ MaskSplinePoint *point;
+ float u, co[2];
+ BezTriple *next_bezt;
+
+ ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, co);
+
+ if (!ED_mask_find_nearest_diff_point(C, mask, co, threshold, false,
+ &mask_layer, &spline, &point, &u,
+ NULL, true, false))
+ {
+ return NULL;
+ }
+
+ next_bezt = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
+ if (next_bezt == NULL) {
+ return NULL;
+ }
+
+ slide_data = MEM_callocN(sizeof(SlideSplineCurvatureData), "slide curvature slide");
+ slide_data->event_invoke_type = event->type;
+ slide_data->mask = mask;
+ slide_data->mask_layer = mask_layer;
+ slide_data->spline = spline;
+ slide_data->point = point;
+ slide_data->u = u;
+
+ copy_v2_v2(slide_data->prev_mouse_coord, co);
+ BKE_mask_point_segment_co(spline, point, u, slide_data->prev_spline_coord);
+
+ copy_v2_v2(slide_data->P0, point->bezt.vec[1]);
+ copy_v2_v2(slide_data->P1, point->bezt.vec[2]);
+ copy_v2_v2(slide_data->P2, next_bezt->vec[0]);
+ copy_v2_v2(slide_data->P3, next_bezt->vec[1]);
+
+ /* Depending to which end we're closer to adjust either left or right side of the spline. */
+ if (u <= 0.5f) {
+ slide_data->adjust_bezt = &point->bezt;
+ slide_data->other_bezt = next_bezt;
+ }
+ else {
+ slide_data->adjust_bezt = next_bezt;
+ slide_data->other_bezt = &point->bezt;
+ }
+
+ /* Data needed for restoring state. */
+ slide_data->bezt_backup = *slide_data->adjust_bezt;
+ slide_data->other_bezt_backup = *slide_data->other_bezt;
+
+ /* Let's dont touch other side of the point for now, so set handle to FREE. */
+ if (u < 0.5f) {
+ if (slide_data->adjust_bezt->h2 <= HD_VECT) {
+ slide_data->adjust_bezt->h2 = HD_FREE;
+ }
+ }
+ else {
+ if (slide_data->adjust_bezt->h1 <= HD_VECT) {
+ slide_data->adjust_bezt->h1 = HD_FREE;
+ }
+ }
+
+ /* Change selection */
+ ED_mask_select_toggle_all(mask, SEL_DESELECT);
+ slide_data->adjust_bezt->f2 |= SELECT;
+ slide_data->other_bezt->f2 |= SELECT;
+ if (u < 0.5f) {
+ slide_data->adjust_bezt->f3 |= SELECT;
+ slide_data->other_bezt->f1 |= SELECT;
+ }
+ else {
+ slide_data->adjust_bezt->f1 |= SELECT;
+ slide_data->other_bezt->f3 |= SELECT;
+ }
+ mask_layer->act_spline = spline;
+ mask_layer->act_point = point;
+ ED_mask_select_flush_all(mask);
+
+ return slide_data;
+}
+
+static int slide_spline_curvature_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Mask *mask = CTX_data_edit_mask(C);
+ SlideSplineCurvatureData *slide_data;
+
+ if (mask == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Be sure we don't conflict with point slide here. */
+ if (!slide_spline_curvature_check(C, event)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ slide_data = slide_spline_curvature_customdata(C, event);
+ if (slide_data != NULL) {
+ op->customdata = slide_data;
+ WM_event_add_modal_handler(C, op);
+ WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+static void slide_spline_solve_P1(const float u,
+ const float B[2],
+ const float P0[2],
+ const float P2[2],
+ const float P3[2],
+ float solution[2])
+{
+ const float u2 = u * u, u3 = u * u * u;
+ const float v = 1.0f - u;
+ const float v2 = v * v, v3 = v * v * v;
+ const float inv_divider = 1.0f / (3.0f * v2 * u);
+ const float t = 3.0f * v * u2;
+ solution[0] = -(v3 * P0[0] + t * P2[0] + u3 * P3[0] - B[0]) * inv_divider;
+ solution[1] = -(v3 * P0[1] + t * P2[1] + u3 * P3[1] - B[1]) * inv_divider;
+}
+
+static void slide_spline_solve_P2(const float u,
+ const float B[2],
+ const float P0[2],
+ const float P1[2],
+ const float P3[2],
+ float solution[2])
+{
+ const float u2 = u * u, u3 = u * u * u;
+ const float v = 1.0f - u;
+ const float v2 = v * v, v3 = v * v * v;
+ const float inv_divider = 1.0f / (3.0f * v * u2);
+ const float t = 3.0f * v2 * u;
+ solution[0] = -(v3 * P0[0] + t * P1[0] + u3 * P3[0] - B[0]) * inv_divider;
+ solution[1] = -(v3 * P0[1] + t * P1[1] + u3 * P3[1] - B[1]) * inv_divider;
+}
+
+static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Scene *scene = CTX_data_scene(C);
+ const float margin = 0.2f;
+ SlideSplineCurvatureData *slide_data = (SlideSplineCurvatureData *) op->customdata;
+ float u = slide_data->u;
+
+ switch (event->type) {
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) {
+ slide_data->accurate = (event->val == KM_PRESS);
+ }
+
+ if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) {
+ if (event->val == KM_PRESS) {
+ slide_data->adjust_bezt->h1 = slide_data->adjust_bezt->h2 = HD_FREE;
+ if ((u > margin && u < 0.5f) || (u >= 0.5f && u < 1.0f - margin)) {
+ slide_data->other_bezt->h1 = slide_data->other_bezt->h2 = HD_FREE;
+ }
+ }
+ else if (event->val == KM_RELEASE) {
+ slide_data->adjust_bezt->h1 = slide_data->bezt_backup.h1;
+ slide_data->adjust_bezt->h2 = slide_data->bezt_backup.h2;
+ slide_data->other_bezt->h1 = slide_data->other_bezt_backup.h1;
+ slide_data->other_bezt->h2 = slide_data->other_bezt_backup.h2;
+ }
+
+ if (u < 0.5f) {
+ copy_v2_v2(slide_data->adjust_bezt->vec[0], slide_data->bezt_backup.vec[0]);
+ copy_v2_v2(slide_data->other_bezt->vec[2], slide_data->other_bezt_backup.vec[2]);
+ }
+ else {
+ copy_v2_v2(slide_data->adjust_bezt->vec[2], slide_data->bezt_backup.vec[2]);
+ copy_v2_v2(slide_data->other_bezt->vec[0], slide_data->other_bezt_backup.vec[0]);
+ }
+
+ }
+
+ /* fall-through */ /* update CV position */
+ case MOUSEMOVE:
+ {
+ float B[2], mouse_coord[2], delta[2];
+
+ /* Get coordinate spline is expected to go through. */
+ ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, mouse_coord);
+ sub_v2_v2v2(delta, mouse_coord, slide_data->prev_mouse_coord);
+ if (slide_data->accurate) {
+ mul_v2_fl(delta, 0.2f);
+ }
+ add_v2_v2v2(B, slide_data->prev_spline_coord, delta);
+ copy_v2_v2(slide_data->prev_spline_coord, B);
+ copy_v2_v2(slide_data->prev_mouse_coord, mouse_coord);
+
+ if (u < 0.5f) {
+ float oldP2[2];
+ bool need_restore_P2 = false;
+
+ if (u > margin) {
+ float solution[2];
+ float x = (u - margin) * 0.5f / (0.5f - margin);
+ float weight = (3 * x * x - 2 * x * x * x);
+
+ slide_spline_solve_P2(u, B,
+ slide_data->P0,
+ slide_data->P1,
+ slide_data->P3,
+ solution);
+
+ copy_v2_v2(oldP2, slide_data->P2);
+ interp_v2_v2v2(slide_data->P2, slide_data->P2, solution, weight);
+ copy_v2_v2(slide_data->other_bezt->vec[0], slide_data->P2);
+ need_restore_P2 = true;
+
+ /* Tweak handle type in order to be able to apply the delta. */
+ if (weight > 0.0f) {
+ if (slide_data->other_bezt->h1 <= HD_VECT) {
+ slide_data->other_bezt->h1 = HD_FREE;
+ }
+ }
+ }
+
+ slide_spline_solve_P1(u, B,
+ slide_data->P0,
+ slide_data->P2,
+ slide_data->P3,
+ slide_data->adjust_bezt->vec[2]);
+
+ if (need_restore_P2) {
+ copy_v2_v2(slide_data->P2, oldP2);
+ }
+ }
+ else {
+ float oldP1[2];
+ bool need_restore_P1 = false;
+
+ if (u < 1.0f - margin) {
+ float solution[2];
+ float x = ((1.0f - u) - margin) * 0.5f / (0.5f - margin);
+ float weight = 3 * x * x - 2 * x * x * x;
+
+ slide_spline_solve_P1(u, B,
+ slide_data->P0,
+ slide_data->P2,
+ slide_data->P3,
+ solution);
+
+ copy_v2_v2(oldP1, slide_data->P1);
+ interp_v2_v2v2(slide_data->P1, slide_data->P1, solution, weight);
+ copy_v2_v2(slide_data->other_bezt->vec[2], slide_data->P1);
+ need_restore_P1 = true;
+
+ /* Tweak handle type in order to be able to apply the delta. */
+ if (weight > 0.0f) {
+ if (slide_data->other_bezt->h2 <= HD_VECT) {
+ slide_data->other_bezt->h2 = HD_FREE;
+ }
+ }
+ }
+
+ slide_spline_solve_P2(u, B,
+ slide_data->P0,
+ slide_data->P1,
+ slide_data->P3,
+ slide_data->adjust_bezt->vec[0]);
+
+ if (need_restore_P1) {
+ copy_v2_v2(slide_data->P1, oldP1);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
+ DAG_id_tag_update(&slide_data->mask->id, 0);
+
+ break;
+ }
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ if (event->type == slide_data->event_invoke_type && event->val == KM_RELEASE) {
+ /* dont key sliding feather uw's */
+ if (IS_AUTOKEY_ON(scene)) {
+ ED_mask_layer_shape_auto_key(slide_data->mask_layer, CFRA);
+ }
+
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
+ DAG_id_tag_update(&slide_data->mask->id, 0);
+
+ free_slide_spline_curvature_data(slide_data); /* keep this last! */
+ return OPERATOR_FINISHED;
+ }
+
+ break;
+
+ case ESCKEY:
+ cancel_slide_spline_curvature(slide_data);
+
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
+ DAG_id_tag_update(&slide_data->mask->id, 0);
+
+ free_slide_spline_curvature_data(op->customdata); /* keep this last! */
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void MASK_OT_slide_spline_curvature(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Slide Spline Curvature";
+ ot->description = "Slide a point on the spline to define it's curvature";
+ ot->idname = "MASK_OT_slide_spline_curvature";
+
+ /* api callbacks */
+ ot->invoke = slide_spline_curvature_invoke;
+ ot->modal = slide_spline_curvature_modal;
+ ot->poll = ED_operator_mask;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************** toggle cyclic *********************/
@@ -887,6 +1412,7 @@ static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ DAG_id_tag_update(&mask->id, 0);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
return OPERATOR_FINISHED;
@@ -1149,7 +1675,7 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op)
MaskSplinePoint *point = &spline->points[i];
if (MASKPOINT_ISSEL_ANY(point)) {
- BKE_mask_calc_handle_point_auto(spline, point, FALSE);
+ BKE_mask_calc_handle_point_auto(spline, point, false);
changed = true;
changed_layer = true;
}
@@ -1218,7 +1744,25 @@ static int set_handle_type_exec(bContext *C, wmOperator *op)
if (MASKPOINT_ISSEL_ANY(point)) {
BezTriple *bezt = &point->bezt;
- bezt->h1 = bezt->h2 = handle_type;
+ if (bezt->f2 & SELECT) {
+ bezt->h1 = handle_type;
+ bezt->h2 = handle_type;
+ }
+ else {
+ if (bezt->f1 & SELECT) {
+ bezt->h1 = handle_type;
+ }
+ if (bezt->f3 & SELECT) {
+ bezt->h2 = handle_type;
+ }
+ }
+
+ if (handle_type == HD_ALIGN) {
+ float vec[3];
+ sub_v3_v3v3(vec, bezt->vec[0], bezt->vec[1]);
+ add_v3_v3v3(bezt->vec[2], bezt->vec[1], vec);
+ }
+
changed = true;
}
}
@@ -1239,7 +1783,9 @@ void MASK_OT_handle_type_set(wmOperatorType *ot)
static EnumPropertyItem editcurve_handle_type_items[] = {
{HD_AUTO, "AUTO", 0, "Auto", ""},
{HD_VECT, "VECTOR", 0, "Vector", ""},
- {HD_ALIGN, "ALIGNED", 0, "Aligned", ""},
+ {HD_ALIGN, "ALIGNED", 0, "Aligned Single", ""},
+ {HD_ALIGN_DOUBLESIDE, "ALIGNED_DOUBLESIDE", 0, "Aligned", ""},
+ {HD_FREE, "FREE", 0, "Free", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1271,7 +1817,7 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op))
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
if (masklay->restrictflag & OB_RESTRICT_VIEW) {
- ED_mask_layer_select_set(masklay, TRUE);
+ ED_mask_layer_select_set(masklay, true);
masklay->restrictflag &= ~OB_RESTRICT_VIEW;
changed = true;
}
@@ -1308,7 +1854,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
{
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *masklay;
- const int unselected = RNA_boolean_get(op->ptr, "unselected");
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
bool changed = false;
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
@@ -1319,7 +1865,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
if (!unselected) {
if (ED_mask_layer_select_check(masklay)) {
- ED_mask_layer_select_set(masklay, FALSE);
+ ED_mask_layer_select_set(masklay, false);
masklay->restrictflag |= OB_RESTRICT_VIEW;
changed = true;
@@ -1435,7 +1981,7 @@ static int mask_layer_move_poll(bContext *C)
return mask->masklay_tot > 0;
}
- return FALSE;
+ return false;
}
static int mask_layer_move_exec(bContext *C, wmOperator *op)
@@ -1502,81 +2048,83 @@ static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
- MaskLayer *mask_layer = BKE_mask_layer_active(mask);
- MaskSpline *spline;
-
- if (mask_layer == NULL) {
- return OPERATOR_CANCELLED;
- }
+ MaskLayer *mask_layer;
- for (spline = mask_layer->splines.last;
- spline;
- spline = spline->prev)
+ for (mask_layer = mask->masklayers.first;
+ mask_layer;
+ mask_layer = mask_layer->next)
{
- MaskSplinePoint *point = spline->points;
- int i = 0;
- while (i < spline->tot_point) {
- int start = i, end = -1;
- /* Find next selected segment. */
- while (MASKPOINT_ISSEL_ANY(point)) {
- BKE_mask_point_select_set(point, false);
- end = i;
- if (i >= spline->tot_point - 1) {
- break;
- }
- i++;
- point++;
- }
- if (end >= start) {
- MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
- MaskSplinePoint *new_point;
- int b;
-
- /* BKE_mask_spline_add might allocate the points, need to free them in this case. */
- if (new_spline->points) {
- MEM_freeN(new_spline->points);
- }
+ MaskSpline *spline;
- /* Copy options from old spline. */
- new_spline->flag = spline->flag;
- new_spline->offset_mode = spline->offset_mode;
- new_spline->weight_interp = spline->weight_interp;
- new_spline->parent = spline->parent;
-
- /* Allocate new points and copy them from old spline. */
- new_spline->tot_point = end - start + 1;
- new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point,
- "duplicated mask points");
-
- memcpy(new_spline->points, spline->points + start,
- new_spline->tot_point * sizeof(MaskSplinePoint));
-
- /* Select points and duplicate their UWs (if needed). */
- for (b = 0, new_point = new_spline->points;
- b < new_spline->tot_point;
- b++, new_point++)
- {
- if (new_point->uw) {
- new_point->uw = MEM_dupallocN(new_point->uw);
+ for (spline = mask_layer->splines.last;
+ spline;
+ spline = spline->prev)
+ {
+ MaskSplinePoint *point = spline->points;
+ int i = 0;
+ while (i < spline->tot_point) {
+ int start = i, end = -1;
+ /* Find next selected segment. */
+ while (MASKPOINT_ISSEL_ANY(point)) {
+ BKE_mask_point_select_set(point, false);
+ end = i;
+ if (i >= spline->tot_point - 1) {
+ break;
}
- BKE_mask_point_select_set(new_point, true);
+ i++;
+ point++;
}
+ if (end >= start) {
+ MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
+ MaskSplinePoint *new_point;
+ int b;
+
+ /* BKE_mask_spline_add might allocate the points, need to free them in this case. */
+ if (new_spline->points) {
+ MEM_freeN(new_spline->points);
+ }
- /* Clear cyclic flag if we didn't copy the whole spline. */
- if (new_spline->flag & MASK_SPLINE_CYCLIC) {
- if (start != 0 || end != spline->tot_point - 1) {
- new_spline->flag &= ~MASK_SPLINE_CYCLIC;
+ /* Copy options from old spline. */
+ new_spline->flag = spline->flag;
+ new_spline->offset_mode = spline->offset_mode;
+ new_spline->weight_interp = spline->weight_interp;
+ new_spline->parent = spline->parent;
+
+ /* Allocate new points and copy them from old spline. */
+ new_spline->tot_point = end - start + 1;
+ new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point,
+ "duplicated mask points");
+
+ memcpy(new_spline->points, spline->points + start,
+ new_spline->tot_point * sizeof(MaskSplinePoint));
+
+ /* Select points and duplicate their UWs (if needed). */
+ for (b = 0, new_point = new_spline->points;
+ b < new_spline->tot_point;
+ b++, new_point++)
+ {
+ if (new_point->uw) {
+ new_point->uw = MEM_dupallocN(new_point->uw);
+ }
+ BKE_mask_point_select_set(new_point, true);
}
- }
- /* Flush selection to splines. */
- new_spline->flag |= SELECT;
- spline->flag &= ~SELECT;
+ /* Clear cyclic flag if we didn't copy the whole spline. */
+ if (new_spline->flag & MASK_SPLINE_CYCLIC) {
+ if (start != 0 || end != spline->tot_point - 1) {
+ new_spline->flag &= ~MASK_SPLINE_CYCLIC;
+ }
+ }
- mask_layer->act_spline = new_spline;
+ /* Flush selection to splines. */
+ new_spline->flag |= SELECT;
+ spline->flag &= ~SELECT;
+
+ mask_layer->act_spline = new_spline;
+ }
+ i++;
+ point++;
}
- i++;
- point++;
}
}
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index 9cc1702addb..e02561d839c 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -46,7 +46,6 @@
#include "ED_screen.h"
#include "ED_clip.h" /* frame remapping functions */
-#include "ED_mask.h" /* own include */
#include "mask_intern.h" /* own include */
@@ -112,7 +111,7 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
int framenr, parent_type;
float parmask_pos[2], orig_corners[4][2];
- char *sub_parent_name;
+ const char *sub_parent_name;
if (ELEM(NULL, sc, clip)) {
return OPERATOR_CANCELLED;
@@ -195,7 +194,7 @@ void MASK_OT_parent_set(wmOperatorType *ot)
//ot->invoke = mask_parent_set_invoke;
ot->exec = mask_parent_set_exec;
- ot->poll = ED_maskedit_mask_poll;
+ ot->poll = ED_space_clip_maskedit_mask_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index 16fd8414f22..af6f127327c 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -40,13 +40,11 @@
#include "BKE_mask.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_clip.h"
#include "ED_mask.h" /* own include */
#include "RNA_access.h"
@@ -63,10 +61,10 @@ bool ED_mask_spline_select_check(MaskSpline *spline)
MaskSplinePoint *point = &spline->points[i];
if (MASKPOINT_ISSEL_ANY(point))
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
bool ED_mask_layer_select_check(MaskLayer *masklay)
@@ -74,16 +72,16 @@ bool ED_mask_layer_select_check(MaskLayer *masklay)
MaskSpline *spline;
if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
- return FALSE;
+ return false;
}
for (spline = masklay->splines.first; spline; spline = spline->next) {
if (ED_mask_spline_select_check(spline)) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
bool ED_mask_select_check(Mask *mask)
@@ -92,15 +90,15 @@ bool ED_mask_select_check(Mask *mask)
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
if (ED_mask_layer_select_check(masklay)) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/* 'sel' select */
-void ED_mask_spline_select_set(MaskSpline *spline, const short do_select)
+void ED_mask_spline_select_set(MaskSpline *spline, const bool do_select)
{
int i;
@@ -116,12 +114,12 @@ void ED_mask_spline_select_set(MaskSpline *spline, const short do_select)
}
}
-void ED_mask_layer_select_set(MaskLayer *masklay, const short do_select)
+void ED_mask_layer_select_set(MaskLayer *masklay, const bool do_select)
{
MaskSpline *spline;
if (masklay->restrictflag & MASK_RESTRICT_SELECT) {
- if (do_select == TRUE) {
+ if (do_select == true) {
return;
}
}
@@ -166,7 +164,7 @@ void ED_mask_select_toggle_all(Mask *mask, int action)
}
else {
- ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE);
+ ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? true : false);
}
}
}
@@ -255,38 +253,36 @@ static int select_exec(bContext *C, wmOperator *op)
bool extend = RNA_boolean_get(op->ptr, "extend");
bool deselect = RNA_boolean_get(op->ptr, "deselect");
bool toggle = RNA_boolean_get(op->ptr, "toggle");
-
- bool is_handle = 0;
+ eMaskWhichHandle which_handle;
const float threshold = 19;
RNA_float_get_array(op->ptr, "location", co);
- point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL);
+ point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &which_handle, NULL);
if (extend == false && deselect == false && toggle == false)
ED_mask_select_toggle_all(mask, SEL_DESELECT);
if (point) {
-
- if (is_handle) {
+ if (which_handle != MASK_WHICH_HANDLE_NONE) {
if (extend) {
masklay->act_spline = spline;
masklay->act_point = point;
- BKE_mask_point_select_set_handle(point, TRUE);
+ BKE_mask_point_select_set_handle(point, which_handle, true);
}
else if (deselect) {
- BKE_mask_point_select_set_handle(point, FALSE);
+ BKE_mask_point_select_set_handle(point, which_handle, false);
}
else {
masklay->act_spline = spline;
masklay->act_point = point;
- if (!MASKPOINT_ISSEL_HANDLE(point)) {
- BKE_mask_point_select_set_handle(point, TRUE);
+ if (!MASKPOINT_ISSEL_HANDLE(point, which_handle)) {
+ BKE_mask_point_select_set_handle(point, which_handle, true);
}
else if (toggle) {
- BKE_mask_point_select_set_handle(point, FALSE);
+ BKE_mask_point_select_set_handle(point, which_handle, false);
}
}
}
@@ -295,20 +291,20 @@ static int select_exec(bContext *C, wmOperator *op)
masklay->act_spline = spline;
masklay->act_point = point;
- BKE_mask_point_select_set(point, TRUE);
+ BKE_mask_point_select_set(point, true);
}
else if (deselect) {
- BKE_mask_point_select_set(point, FALSE);
+ BKE_mask_point_select_set(point, false);
}
else {
masklay->act_spline = spline;
masklay->act_point = point;
if (!MASKPOINT_ISSEL_ANY(point)) {
- BKE_mask_point_select_set(point, TRUE);
+ BKE_mask_point_select_set(point, true);
}
else if (toggle) {
- BKE_mask_point_select_set(point, FALSE);
+ BKE_mask_point_select_set(point, false);
}
}
}
@@ -444,11 +440,11 @@ static int border_select_exec(bContext *C, wmOperator *op)
if (BLI_rctf_isect_pt_v(&rectf, point_deform->bezt.vec[1])) {
BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT);
- BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT);
+ BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, mode == GESTURE_MODAL_SELECT);
}
else if (!extend) {
- BKE_mask_point_select_set(point, FALSE);
- BKE_mask_point_select_set_handle(point, FALSE);
+ BKE_mask_point_select_set(point, false);
+ BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, false);
}
changed = true;
@@ -484,7 +480,7 @@ void MASK_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
static bool do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select)
@@ -531,7 +527,7 @@ static bool do_lasso_select_mask(bContext *C, const int mcords[][2], short moves
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX))
{
BKE_mask_point_select_set(point, select);
- BKE_mask_point_select_set_handle(point, select);
+ BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select);
}
changed = true;
@@ -649,7 +645,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) {
BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT);
- BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT);
+ BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, mode == GESTURE_MODAL_SELECT);
changed = true;
}
@@ -701,15 +697,13 @@ static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
MaskSpline *spline;
MaskSplinePoint *point = NULL;
float co[2];
- int do_select = !RNA_boolean_get(op->ptr, "deselect");
-
- bool is_handle = false;
+ bool do_select = !RNA_boolean_get(op->ptr, "deselect");
const float threshold = 19;
bool changed = false;
ED_mask_mouse_pos(sa, ar, event->mval, co);
- point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL);
+ point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, NULL, NULL);
if (point) {
ED_mask_spline_select_set(spline, do_select);
@@ -764,7 +758,7 @@ static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
for (spline = masklay->splines.first; spline; spline = spline->next) {
if (ED_mask_spline_select_check(spline)) {
- ED_mask_spline_select_set(spline, TRUE);
+ ED_mask_spline_select_set(spline, true);
changed = true;
}
}
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index cea350219c0..99ffc9cd7d2 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -38,7 +38,6 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_mask.h"
-#include "BKE_report.h"
#include "DNA_object_types.h"
#include "DNA_mask_types.h"
@@ -257,8 +256,8 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
MaskLayer *masklay;
bool changed = false;
- const short do_feather = RNA_boolean_get(op->ptr, "feather");
- const short do_location = RNA_boolean_get(op->ptr, "location");
+ const bool do_feather = RNA_boolean_get(op->ptr, "feather");
+ const bool do_location = RNA_boolean_get(op->ptr, "location");
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
@@ -272,16 +271,18 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
}
if (masklay->splines_shapes.first) {
- MaskLayerShape *masklay_shape;
+ MaskLayerShape *masklay_shape, *masklay_shape_next;
MaskLayerShape *masklay_shape_lastsel = NULL;
for (masklay_shape = masklay->splines_shapes.first;
masklay_shape;
- masklay_shape = masklay_shape->next)
+ masklay_shape = masklay_shape_next)
{
MaskLayerShape *masklay_shape_a = NULL;
MaskLayerShape *masklay_shape_b = NULL;
+ masklay_shape_next = masklay_shape->next;
+
/* find contiguous selections */
if (masklay_shape->flag & MASK_SHAPE_SELECT) {
if (masklay_shape_lastsel == NULL) {
@@ -293,6 +294,9 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
masklay_shape_a = masklay_shape_lastsel;
masklay_shape_b = masklay_shape;
masklay_shape_lastsel = NULL;
+
+ /* this will be freed below, step over selection */
+ masklay_shape_next = masklay_shape->next;
}
}
@@ -406,8 +410,8 @@ void MASK_OT_shape_key_rekey(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "location", TRUE, "Location", "");
- RNA_def_boolean(ot->srna, "feather", TRUE, "Feather", "");
+ RNA_def_boolean(ot->srna, "location", true, "Location", "");
+ RNA_def_boolean(ot->srna, "feather", true, "Feather", "");
}
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 09d8c988d5d..c7388d689bf 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -29,7 +29,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BLI_bitmap.h"
#include "BLF_translation.h"
@@ -66,7 +65,7 @@ void paintface_flush_flags(Object *ob)
DerivedMesh *dm = ob->derivedFinal;
MPoly *polys, *mp_orig;
MFace *faces;
- int *index_array = NULL;
+ const int *index_array = NULL;
int totface, totpoly;
int i;
@@ -499,7 +498,7 @@ void paintvert_flush_flags(Object *ob)
Mesh *me = BKE_mesh_from_object(ob);
DerivedMesh *dm = ob->derivedFinal;
MVert *dm_mvert, *dm_mv;
- int *index_array = NULL;
+ const int *index_array = NULL;
int totvert;
int i;
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index a442d549a14..b288a02a3d1 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -32,7 +32,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
#include "BLF_translation.h"
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index fe49d9ad000..6a54f1979cf 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -32,7 +32,6 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLF_translation.h"
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 5f23a5deb97..aa3a2c83243 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -196,6 +196,7 @@ static bool edbm_inset_calc(wmOperator *op)
const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
const bool use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset");
const bool use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
+ const bool use_edge_rail = RNA_boolean_get(op->ptr, "use_edge_rail");
const float thickness = RNA_float_get(op->ptr, "thickness");
const float depth = RNA_float_get(op->ptr, "depth");
const bool use_outset = RNA_boolean_get(op->ptr, "use_outset");
@@ -220,9 +221,9 @@ static bool edbm_inset_calc(wmOperator *op)
else {
EDBM_op_init(em, &bmop, op,
"inset_region faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b"
- " use_interpolate=%b thickness=%f depth=%f use_outset=%b",
+ " use_interpolate=%b thickness=%f depth=%f use_outset=%b use_edge_rail=%b",
BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset, use_interpolate,
- thickness, depth, use_outset);
+ thickness, depth, use_outset, use_edge_rail);
}
BMO_op_exec(em->bm, &bmop);
@@ -502,6 +503,7 @@ void MESH_OT_inset(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_boundary", true, "Boundary", "Inset face boundaries");
RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness");
RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry");
+ RNA_def_boolean(ot->srna, "use_edge_rail", false, "Edge Rail", "Inset the region along existing edges");
prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f);
/* use 1 rather then 10 for max else dragging the button moves too far */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 7b85748eae2..fab27d6d040 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -82,7 +82,7 @@
#define KNIFE_FLT_EPS 0.00001f
#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
-#define KNIFE_FLT_EPSBIG 0.001f
+#define KNIFE_FLT_EPSBIG 0.0005f
typedef struct KnifeColors {
unsigned char line[3];
@@ -658,7 +658,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
}
/* Check if edge actually lies within face (might not, if this face is concave) */
- if (lh1->v && lh2->v) {
+ if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) {
if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) {
return;
}
@@ -1158,7 +1158,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
for (i = 0; i < 3; i++)
- max_xyz = max_ff(max_xyz, fabs(v->co[i]));
+ max_xyz = max_ff(max_xyz, fabsf(v->co[i]));
}
kcd->ortho_extent = max_xyz;
}
@@ -1167,25 +1167,30 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
* s in screen projection of p. */
static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats)
{
- float p1[3], no[3], view[3];
BMFace *f_hit;
/* If not cutting through, make sure no face is in front of p */
if (!kcd->cut_through) {
+ float dist;
+ float view[3], p_ofs[3];
+
/* TODO: I think there's a simpler way to get the required raycast ray */
ED_view3d_unproject(mats, view, s[0], s[1], 0.0f);
+
mul_m4_v3(kcd->ob->imat, view);
- /* make p1 a little towards view, so ray doesn't hit p's face. */
- copy_v3_v3(p1, p);
- sub_v3_v3(view, p1);
- normalize_v3(view);
- copy_v3_v3(no, view);
- mul_v3_fl(no, 3.0f * KNIFE_FLT_EPSBIG);
- add_v3_v3(p1, no);
+ /* make p_ofs a little towards view, so ray doesn't hit p's face. */
+ sub_v3_v3(view, p);
+ dist = normalize_v3(view);
+ madd_v3_v3v3fl(p_ofs, p, view, KNIFE_FLT_EPSBIG * 3.0f);
+
+ /* avoid projecting behind the viewpoint */
+ if (kcd->is_ortho) {
+ dist = FLT_MAX;
+ }
/* see if there's a face hit between p1 and the view */
- f_hit = BKE_bmbvh_ray_cast(kcd->bmbvh, p1, no, KNIFE_FLT_EPS, NULL, NULL, NULL);
+ f_hit = BKE_bmbvh_ray_cast(kcd->bmbvh, p_ofs, view, KNIFE_FLT_EPS, &dist, NULL, NULL);
if (f_hit)
return false;
}
@@ -1400,12 +1405,18 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
if (!(d1 <= vert_tol || d2 <= vert_tol || fabsf(d1 - d2) <= vert_tol)) {
lambda = d1 / d2;
/* Can't just interpolate between ends of kfe because
- * that doesn't work with perspective transformation.
- * Need to find 3d intersection of ray through sint */
+ * that doesn't work with perspective transformation.
+ * Need to find 3d intersection of ray through sint */
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p, p2);
if (isect_kind >= 1 && point_is_visible(kcd, p, sint, &mats)) {
memset(&hit, 0, sizeof(hit));
+ if (kcd->snap_midpoints) {
+ /* choose intermediate point snap too */
+ mid_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco);
+ mid_v2_v2v2(sint, se1, se2);
+ lambda = 0.5f;
+ }
hit.kfe = kfe;
copy_v3_v3(hit.hit, p);
copy_v3_v3(hit.cagehit, p);
@@ -1808,6 +1819,10 @@ static int knife_update_active(KnifeTool_OpData *kcd)
{
knife_pos_data_clear(&kcd->curr);
copy_v2_v2(kcd->curr.mval, kcd->mval);
+
+ /* view matrix may have changed, reproject */
+ knife_project_v2(kcd, kcd->prev.co, kcd->prev.mval);
+
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
@@ -2625,9 +2640,9 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
ED_region_tag_redraw(kcd->ar);
- kcd->refs = BLI_mempool_create(sizeof(Ref), 1, 2048, 0);
- kcd->kverts = BLI_mempool_create(sizeof(KnifeVert), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
- kcd->kedges = BLI_mempool_create(sizeof(KnifeEdge), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
+ kcd->refs = BLI_mempool_create(sizeof(Ref), 0, 2048, 0);
+ kcd->kverts = BLI_mempool_create(sizeof(KnifeVert), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ kcd->kedges = BLI_mempool_create(sizeof(KnifeEdge), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
kcd->origedgemap = BLI_ghash_ptr_new("knife origedgemap");
kcd->origvertmap = BLI_ghash_ptr_new("knife origvertmap");
@@ -2868,7 +2883,6 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(kcd->ar);
return OPERATOR_PASS_THROUGH;
- break;
}
}
else { /* non-modal-mapped events */
@@ -2936,7 +2950,7 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
int j;
- float const *best_co[3] = {NULL};
+ const float *best_co[3] = {NULL};
float best_area = -1.0f;
bool ok = false;
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 57a85f1162d..cc26d6079a9 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -143,7 +143,7 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
* note: call after de-select to avoid selection flushing */
EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
- BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
+ BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
BM_mesh_select_mode_flush(em->bm);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 16175fc6bad..184477763f8 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -420,7 +420,7 @@ static int ringsel_init(bContext *C, wmOperator *op, bool do_cut)
lcd->num.unit_type[1] = B_UNIT_NONE;
/* XXX, temp, workaround for [# ] */
- EDBM_mesh_ensure_valid_dm_hack(CTX_data_scene(C), lcd->em);
+ EDBM_mesh_ensure_valid_dm_hack(scene, lcd->em);
em_setup_viewcontext(C, &lcd->vc);
@@ -445,7 +445,7 @@ static void loopcut_update_edge(RingSelOpData *lcd, BMEdge *e, const int preview
static void loopcut_mouse_move(RingSelOpData *lcd, const int previewlines)
{
- float dist = 75.0f;
+ float dist = ED_view3d_select_dist_px();
BMEdge *e = EDBM_edge_find_nearest(&lcd->vc, &dist);
loopcut_update_edge(lcd, e, previewlines);
}
@@ -498,7 +498,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- int mesh_select_mode[3] = {
+ const int mesh_select_mode[3] = {
(settings->selectmode & SCE_SELECT_VERTEX) != 0,
(settings->selectmode & SCE_SELECT_EDGE) != 0,
(settings->selectmode & SCE_SELECT_FACE) != 0,
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 18db21a8726..44d03da93a2 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -88,7 +88,7 @@ static bool mouse_mesh_shortest_path_vert(ViewContext *vc)
BMEditMesh *em = vc->em;
BMesh *bm = em->bm;
BMVert *v_dst;
- float dist = 75.0f;
+ float dist = ED_view3d_select_dist_px();
const bool use_length = true;
v_dst = EDBM_vert_find_nearest(vc, &dist, false, false);
@@ -176,11 +176,10 @@ static bool edgetag_test_cb(BMEdge *e, void *user_data_v)
return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? true : false;
#ifdef WITH_FREESTYLE
case EDGE_MODE_TAG_FREESTYLE:
- {
- FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
- return (!fed) ? FALSE : (fed->flag & FREESTYLE_EDGE_MARK) ? true : false;
- }
- break;
+ {
+ FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
+ return (!fed) ? false : (fed->flag & FREESTYLE_EDGE_MARK) ? true : false;
+ }
#endif
}
return 0;
@@ -253,7 +252,7 @@ static bool mouse_mesh_shortest_path_edge(ViewContext *vc)
BMEditMesh *em = vc->em;
BMesh *bm = em->bm;
BMEdge *e_dst;
- float dist = 75.0f;
+ float dist = ED_view3d_select_dist_px();
const bool use_length = true;
e_dst = EDBM_edge_find_nearest(vc, &dist);
@@ -377,7 +376,7 @@ static bool mouse_mesh_shortest_path_face(ViewContext *vc)
BMEditMesh *em = vc->em;
BMesh *bm = em->bm;
BMFace *f_dst;
- float dist = 75.0f;
+ float dist = ED_view3d_select_dist_px();
const bool use_length = true;
f_dst = EDBM_face_find_nearest(vc, &dist);
@@ -449,14 +448,21 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *UNUSED(op), c
{
ViewContext vc;
BMEditMesh *em;
+ BMElem *ele;
- view3d_operator_needs_opengl(C);
em_setup_viewcontext(C, &vc);
copy_v2_v2_int(vc.mval, event->mval);
em = vc.em;
- if (em->selectmode & SCE_SELECT_VERTEX) {
+ ele = BM_mesh_active_elem_get(em->bm);
+ if (ele == NULL) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ view3d_operator_needs_opengl(C);
+
+ if ((em->selectmode & SCE_SELECT_VERTEX) && (ele->head.htype == BM_VERT)) {
if (mouse_mesh_shortest_path_vert(&vc)) {
return OPERATOR_FINISHED;
}
@@ -464,7 +470,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *UNUSED(op), c
return OPERATOR_PASS_THROUGH;
}
}
- else if (em->selectmode & SCE_SELECT_EDGE) {
+ else if ((em->selectmode & SCE_SELECT_EDGE) && (ele->head.htype == BM_EDGE)) {
if (mouse_mesh_shortest_path_edge(&vc)) {
return OPERATOR_FINISHED;
}
@@ -472,7 +478,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *UNUSED(op), c
return OPERATOR_PASS_THROUGH;
}
}
- else if (em->selectmode & SCE_SELECT_FACE) {
+ else if ((em->selectmode & SCE_SELECT_FACE) && (ele->head.htype == BM_FACE)) {
if (mouse_mesh_shortest_path_face(&vc)) {
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 22560310a92..986c1624467 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -41,7 +41,6 @@
#include "BLI_smallhash.h"
#include "BKE_context.h"
-#include "BKE_displist.h"
#include "BKE_report.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
@@ -61,7 +60,6 @@
#include "GPU_colors.h"
#include "GPU_immediate.h"
-
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -169,7 +167,7 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend,
void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
{
- int ok;
+ bool ok;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
@@ -272,7 +270,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
/* method in use for face selecting too */
if (vc->obedit == NULL) {
- if (!(paint_facesel_test(vc->obact) || paint_vertsel_test(vc->obact))) {
+ if (!BKE_paint_select_elem_test(vc->obact)) {
return false;
}
}
@@ -321,7 +319,7 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
/* method in use for face selecting too */
if (vc->obedit == NULL) {
- if (!(paint_facesel_test(vc->obact) || paint_vertsel_test(vc->obact))) {
+ if (!BKE_paint_select_elem_test(vc->obact)) {
return false;
}
}
@@ -650,7 +648,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
{
BMEditMesh *em = vc->em;
- float dist = 75.0f;
+ float dist = ED_view3d_select_dist_px();
*r_eve = NULL;
*r_eed = NULL;
@@ -1008,6 +1006,34 @@ void MESH_OT_select_mode(wmOperatorType *ot)
/* **************** LOOP SELECTS *************** */
+static void walker_select_count(BMEditMesh *em, int walkercode, void *start, const bool select, const bool select_mix,
+ int *r_totsel, int *r_totunsel)
+{
+ BMesh *bm = em->bm;
+ BMElem *ele;
+ BMWalker walker;
+ int tot[2] = {0, 0};
+
+ BMW_init(&walker, bm, walkercode,
+ BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
+ BMW_FLAG_TEST_HIDDEN,
+ BMW_NIL_LAY);
+
+ for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) {
+ tot[(BM_elem_flag_test_bool(ele, BM_ELEM_SELECT) != select)] += 1;
+
+ if (!select_mix && tot[0] && tot[1]) {
+ tot[0] = tot[1] = -1;
+ break;
+ }
+ }
+
+ *r_totsel = tot[0];
+ *r_totunsel = tot[1];
+
+ BMW_end(&walker);
+}
+
static void walker_select(BMEditMesh *em, int walkercode, void *start, const bool select)
{
BMesh *bm = em->bm;
@@ -1102,13 +1128,69 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
/* ***************** loop select (non modal) ************** */
-static void mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
+static void mouse_mesh_loop_face(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
+{
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ walker_select(em, BMW_FACELOOP, eed, select);
+}
+
+static void mouse_mesh_loop_edge_ring(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
+{
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ walker_select(em, BMW_EDGERING, eed, select);
+}
+
+static void mouse_mesh_loop_edge(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear, bool select_cycle)
+{
+ bool edge_boundary = false;
+
+ /* cycle between BMW_LOOP / BMW_EDGEBOUNDARY */
+ if (select_cycle && BM_edge_is_boundary(eed)) {
+ int tot[2];
+
+ /* if the loops selected toggle the boundaries */
+ walker_select_count(em, BMW_LOOP, eed, select, false,
+ &tot[0], &tot[1]);
+ if (tot[select] == 0) {
+ edge_boundary = true;
+
+ /* if the boundaries selected, toggle back to the loop */
+ walker_select_count(em, BMW_EDGEBOUNDARY, eed, select, false,
+ &tot[0], &tot[1]);
+ if (tot[select] == 0) {
+ edge_boundary = false;
+ }
+ }
+ }
+
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ if (edge_boundary) {
+ walker_select(em, BMW_EDGEBOUNDARY, eed, select);
+ }
+ else {
+ walker_select(em, BMW_LOOP, eed, select);
+ }
+}
+
+
+static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
{
ViewContext vc;
BMEditMesh *em;
BMEdge *eed;
bool select = true;
- float dist = 50.0f;
+ bool select_clear = false;
+ bool select_cycle = true;
+ float dist = ED_view3d_select_dist_px() * 0.6666f;
float mvalf[2];
em_setup_viewcontext(C, &vc);
@@ -1120,105 +1202,105 @@ static void mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
view3d_validate_backbuf(&vc);
eed = EDBM_edge_find_nearest(&vc, &dist);
- if (eed) {
- if (extend == false && deselect == false && toggle == false) {
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- }
-
- if (extend) {
- select = true;
- }
- else if (deselect) {
- select = false;
- }
- else if (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0) {
- select = true;
- }
- else if (toggle) {
- select = false;
- }
+ if (eed == NULL) {
+ return false;
+ }
+
+ if (extend == false && deselect == false && toggle == false) {
+ select_clear = true;
+ }
+
+ if (extend) {
+ select = true;
+ }
+ else if (deselect) {
+ select = false;
+ }
+ else if (select_clear || (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0)) {
+ select = true;
+ }
+ else if (toggle) {
+ select = false;
+ select_cycle = false;
+ }
- if (em->selectmode & SCE_SELECT_FACE) {
- walker_select(em, BMW_FACELOOP, eed, select);
+ if (em->selectmode & SCE_SELECT_FACE) {
+ mouse_mesh_loop_face(em, eed, select, select_clear);
+ }
+ else {
+ if (ring) {
+ mouse_mesh_loop_edge_ring(em, eed, select, select_clear);
}
- else if (em->selectmode & SCE_SELECT_EDGE) {
- if (ring)
- walker_select(em, BMW_EDGERING, eed, select);
- else
- walker_select(em, BMW_LOOP, eed, select);
+ else {
+ mouse_mesh_loop_edge(em, eed, select, select_clear, select_cycle);
}
- else if (em->selectmode & SCE_SELECT_VERTEX) {
- if (ring)
- walker_select(em, BMW_EDGERING, eed, select);
+ }
- else
- walker_select(em, BMW_LOOP, eed, select);
- }
+ EDBM_selectmode_flush(em);
- EDBM_selectmode_flush(em);
+ /* sets as active, useful for other tools */
+ if (select) {
+ if (em->selectmode & SCE_SELECT_VERTEX) {
+ /* Find nearest vert from mouse
+ * (initialize to large values incase only one vertex can be projected) */
+ float v1_co[2], v2_co[2];
+ float length_1 = FLT_MAX;
+ float length_2 = FLT_MAX;
- /* sets as active, useful for other tools */
- if (select) {
- if (em->selectmode & SCE_SELECT_VERTEX) {
- /* Find nearest vert from mouse
- * (initialize to large values incase only one vertex can be projected) */
- float v1_co[2], v2_co[2];
- float length_1 = FLT_MAX;
- float length_2 = FLT_MAX;
-
- /* We can't be sure this has already been set... */
- ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
-
- if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
- length_1 = len_squared_v2v2(mvalf, v1_co);
- }
+ /* We can't be sure this has already been set... */
+ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
- if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
- length_2 = len_squared_v2v2(mvalf, v2_co);
- }
+ if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ length_1 = len_squared_v2v2(mvalf, v1_co);
+ }
+
+ if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ length_2 = len_squared_v2v2(mvalf, v2_co);
+ }
#if 0
- printf("mouse to v1: %f\nmouse to v2: %f\n", len_squared_v2v2(mvalf, v1_co),
- len_squared_v2v2(mvalf, v2_co));
+ printf("mouse to v1: %f\nmouse to v2: %f\n", len_squared_v2v2(mvalf, v1_co),
+ len_squared_v2v2(mvalf, v2_co));
#endif
- BM_select_history_store(em->bm, (length_1 < length_2) ? eed->v1 : eed->v2);
- }
- else if (em->selectmode & SCE_SELECT_EDGE) {
- BM_select_history_store(em->bm, eed);
- }
- else if (em->selectmode & SCE_SELECT_FACE) {
- /* Select the face of eed which is the nearest of mouse. */
- BMFace *f, *efa = NULL;
- BMIter iterf;
- float best_dist = FLT_MAX;
-
- /* We can't be sure this has already been set... */
- ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
-
- BM_ITER_ELEM (f, &iterf, eed, BM_FACES_OF_EDGE) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- float cent[3];
- float co[2], tdist;
-
- BM_face_calc_center_mean(f, cent);
- if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
- tdist = len_squared_v2v2(mvalf, co);
- if (tdist < best_dist) {
-/* printf("Best face: %p (%f)\n", f, tdist);*/
- best_dist = tdist;
- efa = f;
- }
+ BM_select_history_store(em->bm, (length_1 < length_2) ? eed->v1 : eed->v2);
+ }
+ else if (em->selectmode & SCE_SELECT_EDGE) {
+ BM_select_history_store(em->bm, eed);
+ }
+ else if (em->selectmode & SCE_SELECT_FACE) {
+ /* Select the face of eed which is the nearest of mouse. */
+ BMFace *f, *efa = NULL;
+ BMIter iterf;
+ float best_dist = FLT_MAX;
+
+ /* We can't be sure this has already been set... */
+ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+
+ BM_ITER_ELEM (f, &iterf, eed, BM_FACES_OF_EDGE) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ float cent[3];
+ float co[2], tdist;
+
+ BM_face_calc_center_mean(f, cent);
+ if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ tdist = len_squared_v2v2(mvalf, co);
+ if (tdist < best_dist) {
+/* printf("Best face: %p (%f)\n", f, tdist);*/
+ best_dist = tdist;
+ efa = f;
}
}
}
- if (efa) {
- BM_mesh_active_face_set(em->bm, efa);
- BM_select_history_store(em->bm, efa);
- }
+ }
+ if (efa) {
+ BM_mesh_active_face_set(em->bm, efa);
+ BM_select_history_store(em->bm, efa);
}
}
-
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit);
}
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit);
+
+ return true;
}
static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1226,14 +1308,17 @@ static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *e
view3d_operator_needs_opengl(C);
- mouse_mesh_loop(C, event->mval,
- RNA_boolean_get(op->ptr, "extend"),
- RNA_boolean_get(op->ptr, "deselect"),
- RNA_boolean_get(op->ptr, "toggle"),
- RNA_boolean_get(op->ptr, "ring"));
-
- /* cannot do tweaks for as long this keymap is after transform map */
- return OPERATOR_FINISHED;
+ if (mouse_mesh_loop(C, event->mval,
+ RNA_boolean_get(op->ptr, "extend"),
+ RNA_boolean_get(op->ptr, "deselect"),
+ RNA_boolean_get(op->ptr, "toggle"),
+ RNA_boolean_get(op->ptr, "ring")))
+ {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void MESH_OT_loop_select(wmOperatorType *ot)
@@ -1561,12 +1646,24 @@ void EDBM_selectmode_set(BMEditMesh *em)
}
/**
+ * Expand & Contract the Selection
+ * (used when chaning modes and Ctrl key held)
+ *
* Flush the selection up:
* - vert -> edge
+ * - vert -> face
* - edge -> face
+ *
+ * Flush the selection down:
+ * - face -> edge
+ * - face -> vert
+ * - edge -> vert
*/
void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const short selectmode_new)
{
+ BMesh *bm = em->bm;
+
+ BMVert *eve;
BMEdge *eed;
BMFace *efa;
BMIter iter;
@@ -1575,54 +1672,96 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
/* have to find out what the selectionmode was previously */
if (selectmode_old == SCE_SELECT_VERTEX) {
- if (em->bm->totvertsel == 0) {
+ if (bm->totvertsel == 0) {
/* pass */
}
else if (selectmode_new == SCE_SELECT_EDGE) {
+ /* flush up (vert -> edge) */
+
/* select all edges associated with every selected vert */
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
}
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
- BM_edge_select_set(em->bm, eed, true);
+ BM_edge_select_set(bm, eed, true);
}
}
}
else if (selectmode_new == SCE_SELECT_FACE) {
+ /* flush up (vert -> face) */
+
/* select all faces associated with every selected vert */
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
}
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- BM_face_select_set(em->bm, efa, true);
+ BM_face_select_set(bm, efa, true);
}
}
}
}
else if (selectmode_old == SCE_SELECT_EDGE) {
- if (em->bm->totedgesel == 0) {
+ if (bm->totedgesel == 0) {
/* pass */
}
else if (selectmode_new == SCE_SELECT_FACE) {
+ /* flush up (edge -> face) */
+
/* select all faces associated with every selected edge */
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
}
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- BM_face_select_set(em->bm, efa, true);
+ BM_face_select_set(bm, efa, true);
}
}
}
+ else if (selectmode_new == SCE_SELECT_VERTEX) {
+ /* flush down (edge -> vert) */
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_vert_is_all_edge_flag_test(eve, BM_ELEM_SELECT, true)) {
+ BM_vert_select_set(bm, eve, false);
+ }
+ }
+ /* deselect edges without both verts selected */
+ BM_mesh_deselect_flush(bm);
+ }
+ }
+ else if (selectmode_old == SCE_SELECT_FACE) {
+ if (bm->totfacesel == 0) {
+ /* pass */
+ }
+ else if (selectmode_new == SCE_SELECT_EDGE) {
+ /* flush down (face -> edge) */
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_edge_is_all_face_flag_test(eed, BM_ELEM_SELECT, true)) {
+ BM_edge_select_set(bm, eed, false);
+ }
+ }
+ }
+ else if (selectmode_new == SCE_SELECT_VERTEX) {
+ /* flush down (face -> vert) */
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_vert_is_all_face_flag_test(eve, BM_ELEM_SELECT, true)) {
+ BM_vert_select_set(bm, eve, false);
+ }
+ }
+ /* deselect faces without verts selected */
+ BM_mesh_deselect_flush(bm);
+ }
}
}
-/* user facing function, does notification and undo push */
+/* user facing function, does notification */
bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
const int action, const bool use_extend, const bool use_expand)
{
@@ -1669,22 +1808,24 @@ bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
break;
}
+ if (use_extend == 0 || em->selectmode == 0) {
+ if (use_expand) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ EDBM_selectmode_convert(em, selmode_max, selectmode_new);
+ }
+ }
+
switch (selectmode_new) {
case SCE_SELECT_VERTEX:
- if (use_extend == 0 || em->selectmode == 0)
+ if (use_extend == 0 || em->selectmode == 0) {
em->selectmode = SCE_SELECT_VERTEX;
+ }
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
ret = true;
break;
case SCE_SELECT_EDGE:
if (use_extend == 0 || em->selectmode == 0) {
- if (use_expand) {
- const short selmode_max = highest_order_bit_s(ts->selectmode);
- if (selmode_max == SCE_SELECT_VERTEX) {
- EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
- }
- }
em->selectmode = SCE_SELECT_EDGE;
}
ts->selectmode = em->selectmode;
@@ -1693,13 +1834,6 @@ bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
break;
case SCE_SELECT_FACE:
if (use_extend == 0 || em->selectmode == 0) {
- if (use_expand) {
- const short selmode_max = highest_order_bit_s(ts->selectmode);
- if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
- EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
- }
- }
-
em->selectmode = SCE_SELECT_FACE;
}
ts->selectmode = em->selectmode;
@@ -1750,7 +1884,7 @@ bool EDBM_selectmode_disable(Scene *scene, BMEditMesh *em,
}
}
-void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
+void EDBM_deselect_by_material(BMEditMesh *em, const short index, const bool select)
{
BMIter iter;
BMFace *efa;
@@ -1957,7 +2091,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
BMVert *eve;
BMEdge *e, *eed;
BMFace *efa;
- int sel = !RNA_boolean_get(op->ptr, "deselect");
+ const bool sel = !RNA_boolean_get(op->ptr, "deselect");
int limit;
@@ -2076,7 +2210,7 @@ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- int select;
+ bool select;
switch (type) {
case 0:
@@ -2734,7 +2868,8 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
}
if (select) {
- EDBM_select_flush(em);
+ /* was EDBM_select_flush, but it over select in edge/face mode */
+ EDBM_selectmode_flush(em);
}
else {
EDBM_deselect_flush(em);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index dbb15525dfe..159eac4a275 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -313,6 +313,12 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
}
}
+static void edbm_report_delete_info(ReportList *reports, BMesh *bm, const int totelem[3])
+{
+ BKE_reportf(reports, RPT_INFO,
+ "Removed: %d vertices, %d edges, %d faces",
+ totelem[0] - bm->totvert, totelem[1] - bm->totedge, totelem[2] - bm->totface);
+}
/* Note, these values must match delete_mesh() event values */
static EnumPropertyItem prop_mesh_delete_types[] = {
@@ -453,9 +459,7 @@ static int edbm_delete_loose_exec(bContext *C, wmOperator *op)
EDBM_update_generic(em, true, true);
- BKE_reportf(op->reports, RPT_INFO,
- "Removed: %d vertices, %d edges, %d faces",
- totelem[0] - bm->totvert, totelem[1] - bm->totedge, totelem[2] - bm->totface);
+ edbm_report_delete_info(op->reports, bm, totelem);
return OPERATOR_FINISHED;
}
@@ -792,6 +796,8 @@ static int edbm_mark_seam_exec(bContext *C, wmOperator *op)
void MESH_OT_mark_seam(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Mark Seam";
ot->idname = "MESH_OT_mark_seam";
@@ -804,7 +810,8 @@ void MESH_OT_mark_seam(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ prop = RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
@@ -816,27 +823,24 @@ static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
BMEdge *eed;
BMIter iter;
const bool clear = RNA_boolean_get(op->ptr, "clear");
+ const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
/* auto-enable sharp edge drawing */
if (clear == 0) {
me->drawflag |= ME_DRAWSHARP;
}
- if (!clear) {
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_SELECT) || BM_elem_flag_test(eed, BM_ELEM_HIDDEN))
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (use_verts) {
+ if (!(BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) {
continue;
-
- BM_elem_flag_disable(eed, BM_ELEM_SMOOTH);
+ }
}
- }
- else {
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_SELECT) || BM_elem_flag_test(eed, BM_ELEM_HIDDEN))
- continue;
-
- BM_elem_flag_enable(eed, BM_ELEM_SMOOTH);
+ else if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ continue;
}
+
+ BM_elem_flag_set(eed, BM_ELEM_SMOOTH, clear);
}
EDBM_update_generic(em, true, false);
@@ -846,6 +850,8 @@ static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
void MESH_OT_mark_sharp(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Mark Sharp";
ot->idname = "MESH_OT_mark_sharp";
@@ -858,10 +864,13 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ prop = RNA_def_boolean(ot->srna, "clear", false, "Clear", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "use_verts", false, "Vertices",
+ "Consider vertices instead of edges to select which edges to (un)tag as sharp");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -877,7 +886,7 @@ static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
}
}
else {
- if (!EDBM_op_init(em, &bmop, op, "connect_verts verts=%hv", BM_ELEM_SELECT)) {
+ if (!EDBM_op_init(em, &bmop, op, "connect_verts verts=%hv check_degenerate=%b", BM_ELEM_SELECT, true)) {
return OPERATOR_CANCELLED;
}
}
@@ -1275,7 +1284,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
Mesh *me = obedit->data;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
ModifierData *md;
- int mirrx = false, mirry = false, mirrz = false;
+ 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;
@@ -1360,7 +1369,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
Mesh *me = obedit->data;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- int usex = true, usey = true, usez = true, preserve_volume = true;
+ bool usex = true, usey = true, usez = true, preserve_volume = true;
int i, repeat;
float lambda_factor;
float lambda_border;
@@ -1889,6 +1898,16 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
const bool use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
const int totvert_orig = em->bm->totvert;
int count;
+ char htype_select;
+
+ /* avoid loosing selection state (select -> tags) */
+ if (em->selectmode & SCE_SELECT_VERTEX) htype_select = BM_VERT;
+ else if (em->selectmode & SCE_SELECT_EDGE) htype_select = BM_EDGE;
+ else htype_select = BM_FACE;
+
+ /* store selection as tags */
+ BM_mesh_elem_hflag_enable_test(em->bm, htype_select, BM_ELEM_TAG, true, true, BM_ELEM_SELECT);
+
if (use_unselected) {
EDBM_op_init(em, &bmop, op,
@@ -1919,6 +1938,10 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
count = totvert_orig - em->bm->totvert;
BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
+ /* restore selection from tags */
+ BM_mesh_elem_hflag_enable_test(em->bm, htype_select, BM_ELEM_SELECT, true, true, BM_ELEM_TAG);
+ EDBM_selectmode_flush(em);
+
EDBM_update_generic(em, true, true);
return OPERATOR_FINISHED;
@@ -2048,7 +2071,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
if (use_add) {
/* in add mode, we add relative shape key offset */
if (kb) {
- float *rco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative);
+ const float *rco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative);
sub_v3_v3v3(co, co, rco);
}
@@ -2134,6 +2157,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "shape", DummyRNA_NULL_items, 0, "Shape", "Shape key to use for blending");
RNA_def_enum_funcs(prop, shape_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
RNA_def_float(ot->srna, "blend", 1.0f, -FLT_MAX, FLT_MAX, "Blend", "Blending factor", -2.0f, 2.0f);
RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather than blend between shapes");
}
@@ -2576,7 +2600,7 @@ static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BM
BM_mesh_elem_hflag_disable_all(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, false);
/* sel -> tag */
- BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, true, BM_ELEM_SELECT);
+ BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, true, false, BM_ELEM_SELECT);
return (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
}
@@ -2629,7 +2653,7 @@ static void mesh_separate_material_assign_mat_nr(Object *ob, const short mat_nr)
ID *obdata = ob->data;
Material ***matarar;
- short *totcolp;
+ const short *totcolp;
totcolp = give_totcolp_id(obdata);
matarar = give_matarar_id(obdata);
@@ -3676,6 +3700,51 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
"Delimit dissolve operation");
}
+static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const float thresh = RNA_float_get(op->ptr, "threshold");
+ BMesh *bm = em->bm;
+ const int totelem[3] = {bm->totvert, bm->totedge, bm->totface};
+
+ if (!EDBM_op_callf(
+ em, op,
+ "dissolve_degenerate edges=%he dist=%f",
+ BM_ELEM_SELECT, thresh))
+ {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* tricky to maintain correct selection here, so just flush up from verts */
+ EDBM_select_flush(em);
+
+ EDBM_update_generic(em, true, true);
+
+ edbm_report_delete_info(op->reports, bm, totelem);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_dissolve_degenerate(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Degenerate Dissolve";
+ ot->idname = "MESH_OT_dissolve_degenerate";
+ ot->description = "Dissolve zero area faces and zero length edges";
+
+ /* api callbacks */
+ ot->exec = edbm_dissolve_degenerate_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_float(ot->srna, "threshold", 0.0001f, 0.000001f, 50.0f, "Merge Distance",
+ "Minimum distance between elements to merge", 0.00001, 10.0);
+}
+
+
/* internally uses dissolve */
static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
{
@@ -3708,7 +3777,7 @@ static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
+ BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
EDBM_update_generic(em, true, true);
@@ -3814,7 +3883,7 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
/* Just to mark protected elements. */
char *pblock[3] = {NULL, NULL, NULL}, *pb;
BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb;
- int *map[3] = {NULL, NULL, NULL}, *mp;
+ unsigned int *map[3] = {NULL, NULL, NULL}, *mp;
int totelem[3] = {0, 0, 0};
int affected[3] = {0, 0, 0};
int i, j;
@@ -3986,7 +4055,7 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
}
else if (action == SRT_SELECTED) {
- int *tbuf[3] = {NULL, NULL, NULL}, *tb;
+ unsigned int *tbuf[3] = {NULL, NULL, NULL}, *tb;
if (totelem[0]) {
tb = tbuf[0] = MEM_callocN(sizeof(int) * totelem[0], "sort_bmelem vert tbuf");
@@ -4195,7 +4264,7 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
pb = pblock[j];
sb = sblock[j];
if (pb && sb && !map[j]) {
- char *p_blk;
+ const char *p_blk;
BMElemSort *s_blk;
int tot = totelem[j];
int aff = affected[j];
@@ -4861,7 +4930,7 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op)
if (v != v_mirr) {
float co[3], co_mirr[3];
- if ((v->co[axis] > v->co[axis]) == axis_sign) {
+ if ((v->co[axis] > v_mirr->co[axis]) == axis_sign) {
SWAP(BMVert *, v, v_mirr);
}
@@ -4989,6 +5058,8 @@ static int edbm_mark_freestyle_edge_exec(bContext *C, wmOperator *op)
void MESH_OT_mark_freestyle_edge(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Mark Freestyle Edge";
ot->description = "(Un)mark selected edges as Freestyle feature edges";
@@ -5001,7 +5072,8 @@ void MESH_OT_mark_freestyle_edge(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ prop = RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
@@ -5050,6 +5122,8 @@ static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Mark Freestyle Face";
ot->description = "(Un)mark selected faces for exclusion from Freestyle feature edge detection";
@@ -5062,7 +5136,8 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ prop = RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
#endif
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 9f70135b787..758cbd59794 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -50,7 +50,6 @@
#include "BKE_editmesh_bvh.h"
#include "BKE_object.h" /* XXX. only for EDBM_mesh_ensure_valid_dm_hack() which will be removed */
-#include "BKE_scene.h" /* XXX, only for eval_ctx used in EDBM_mesh_ensure_valid_dm_hack */
#include "WM_api.h"
#include "WM_types.h"
@@ -132,16 +131,7 @@ void EDBM_mesh_clear(BMEditMesh *em)
BM_mesh_clear(em->bm);
/* free derived meshes */
- if (em->derivedCage) {
- em->derivedCage->needsFree = 1;
- em->derivedCage->release(em->derivedCage);
- }
- if (em->derivedFinal && em->derivedFinal != em->derivedCage) {
- em->derivedFinal->needsFree = 1;
- em->derivedFinal->release(em->derivedFinal);
- }
-
- em->derivedCage = em->derivedFinal = NULL;
+ BKE_editmesh_free_derivedmesh(em);
/* free tessellation data */
em->tottri = 0;
@@ -411,8 +401,8 @@ void EDBM_mesh_free(BMEditMesh *em)
/* These tables aren't used yet, so it's not strictly necessary
* to 'end' them (with 'e' param) but if someone tries to start
* using them, having these in place will save a lot of pain */
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, 'e');
BKE_editmesh_free(em);
}
@@ -1144,7 +1134,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const int axis,
BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
{
- int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);
+ const int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);
BLI_assert(em->mirror_cdlayer != -1); /* invalid use */
@@ -1270,9 +1260,11 @@ void EDBM_mesh_reveal(BMEditMesh *em)
BM_EDGES_OF_MESH,
BM_FACES_OF_MESH};
- int sels[3] = {(em->selectmode & SCE_SELECT_VERTEX),
- (em->selectmode & SCE_SELECT_EDGE),
- (em->selectmode & SCE_SELECT_FACE), };
+ const bool sels[3] = {
+ (em->selectmode & SCE_SELECT_VERTEX) != 0,
+ (em->selectmode & SCE_SELECT_EDGE) != 0,
+ (em->selectmode & SCE_SELECT_FACE) != 0,
+ };
int i;
/* Use tag flag to remember what was hidden before all is revealed.
@@ -1333,6 +1325,9 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d
/* in debug mode double check we didn't need to recalculate */
BLI_assert(BM_mesh_elem_table_check(em->bm) == true);
}
+
+ /* don't keep stale derivedMesh data around, see: [#38872] */
+ BKE_editmesh_free_derivedmesh(em);
}
/* poll call for mesh operators requiring a view3d context */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index e2111a9fd49..8aea932e93a 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -210,6 +210,7 @@ void MESH_OT_dissolve_edges(struct wmOperatorType *ot);
void MESH_OT_dissolve_faces(struct wmOperatorType *ot);
void MESH_OT_dissolve_mode(struct wmOperatorType *ot);
void MESH_OT_dissolve_limited(struct wmOperatorType *ot);
+void MESH_OT_dissolve_degenerate(struct wmOperatorType *ot);
void MESH_OT_delete_edgeloop(struct wmOperatorType *ot);
void MESH_OT_edge_face_add(struct wmOperatorType *ot);
void MESH_OT_duplicate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 26a6f41b615..7c38ef21791 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -31,7 +31,6 @@
#include "DNA_scene_types.h"
#include "DNA_modifier_types.h"
-#include "BLI_math.h"
#include "RNA_access.h"
@@ -112,6 +111,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_dissolve_faces);
WM_operatortype_append(MESH_OT_dissolve_mode);
WM_operatortype_append(MESH_OT_dissolve_limited);
+ WM_operatortype_append(MESH_OT_dissolve_degenerate);
WM_operatortype_append(MESH_OT_delete_edgeloop);
WM_operatortype_append(MESH_OT_faces_shade_smooth);
WM_operatortype_append(MESH_OT_faces_shade_flat);
@@ -365,7 +365,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_BEAUTY);
kmi = WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "quad_method", MOD_TRIANGULATE_QUAD_FIXED);
- RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_SCANFILL);
+ RNA_enum_set(kmi->ptr, "ngon_method", MOD_TRIANGULATE_NGON_EARCLIP);
WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 1d47d4c49df..d252ae20270 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -47,6 +47,7 @@
#include "BLI_blenlib.h"
+#include "BLI_kdtree.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_deform.h"
@@ -595,7 +596,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
DerivedMesh *dm = NULL;
Key *key = me->key;
KeyBlock *kb;
- int ok = 0, nonequal_verts = 0;
+ bool ok = false, nonequal_verts = false;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
@@ -605,7 +606,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
selme = (Mesh *)base->object->data;
if (selme->totvert == me->totvert)
- ok++;
+ ok = true;
else
nonequal_verts = 1;
}
@@ -657,255 +658,111 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/* ********************* MESH VERTEX OCTREE LOOKUP ************* */
-
-/* important note; this is unfinished, needs better API for editmode, and custom threshold */
-
-#define MOC_RES 8
-#define MOC_NODE_RES 8
-#define MOC_THRESH 0.00002f
+/* -------------------------------------------------------------------- */
+/* Mesh Mirror (Spatial) */
-typedef struct MocNode {
- struct MocNode *next;
- intptr_t index[MOC_NODE_RES];
-} MocNode;
-
-static int mesh_octree_get_base_offs(const float co[3], const float offs[3], const float div[3])
-{
- int vx, vy, vz;
-
- vx = floor((co[0] - offs[0]) / div[0]);
- vy = floor((co[1] - offs[1]) / div[1]);
- vz = floor((co[2] - offs[2]) / div[2]);
+/** \name Mesh Spatial Mirror API
+ * \{ */
- CLAMP(vx, 0, MOC_RES - 1);
- CLAMP(vy, 0, MOC_RES - 1);
- CLAMP(vz, 0, MOC_RES - 1);
+#define KD_THRESH 0.00002f
- return (vx * MOC_RES * MOC_RES) + vy * MOC_RES + vz;
-}
-
-static void mesh_octree_add_node(MocNode **bt, intptr_t index)
-{
- if (*bt == NULL) {
- *bt = MEM_callocN(sizeof(MocNode), "MocNode");
- (*bt)->index[0] = index;
- }
- else {
- int a;
- for (a = 0; a < MOC_NODE_RES; a++) {
- if ((*bt)->index[a] == index)
- return;
- else if ((*bt)->index[a] == 0) {
- (*bt)->index[a] = index;
- return;
- }
- }
- mesh_octree_add_node(&(*bt)->next, index);
- }
-}
+static struct { void *tree; } MirrKdStore = {NULL};
-static void mesh_octree_free_node(MocNode **bt)
+/* mode is 's' start, or 'e' end, or 'u' use */
+/* if end, ob can be NULL */
+int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, const float co[3], char mode)
{
- if ( (*bt)->next) {
- mesh_octree_free_node(&(*bt)->next);
- }
- MEM_freeN(*bt);
-}
-
+ if (mode == 'u') { /* use table */
+ if (MirrKdStore.tree == NULL)
+ ED_mesh_mirror_spatial_table(ob, em, NULL, 's');
-/* temporal define, just to make nicer code below */
-#define MOC_INDEX(vx, vy, vz) (((vx) * MOC_RES * MOC_RES) + (vy) * MOC_RES + (vz))
+ if (MirrKdStore.tree) {
+ KDTreeNearest nearest;
-static void mesh_octree_add_nodes(MocNode **basetable, const float co[3], const float offs[3],
- const float div[3], intptr_t index)
-{
- float fx, fy, fz;
- int vx, vy, vz;
-
- if ((finite(co[0]) == false) ||
- (finite(co[1]) == false) ||
- (finite(co[2]) == false))
- {
- return;
- }
-
- fx = (co[0] - offs[0]) / div[0];
- fy = (co[1] - offs[1]) / div[1];
- fz = (co[2] - offs[2]) / div[2];
- CLAMP(fx, 0.0f, MOC_RES - MOC_THRESH);
- CLAMP(fy, 0.0f, MOC_RES - MOC_THRESH);
- CLAMP(fz, 0.0f, MOC_RES - MOC_THRESH);
-
- vx = (int)floorf(fx);
- vy = (int)floorf(fy);
- vz = (int)floorf(fz);
-
- mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz), index);
-
- if (vx > 0)
- if (fx - ((float)vx) - MOC_THRESH < 0.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx - 1, vy, vz), index);
- if (vx < MOC_RES - 2)
- if (fx - ((float)vx) + MOC_THRESH > 1.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx + 1, vy, vz), index);
-
- if (vy > 0)
- if (fy - ((float)vy) - MOC_THRESH < 0.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx, vy - 1, vz), index);
- if (vy < MOC_RES - 2)
- if (fy - ((float)vy) + MOC_THRESH > 1.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx, vy + 1, vz), index);
-
- if (vz > 0)
- if (fz - ((float)vz) - MOC_THRESH < 0.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz - 1), index);
- if (vz < MOC_RES - 2)
- if (fz - ((float)vz) + MOC_THRESH > 1.0f)
- mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz + 1), index);
+ int i;
-}
+ i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
-static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, const float co[3])
-{
- float *vec;
- int a;
-
- if (*bt == NULL)
- return -1;
-
- for (a = 0; a < MOC_NODE_RES; a++) {
- if ((*bt)->index[a]) {
- /* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
- if (mvert) {
- vec = (mvert + (*bt)->index[a] - 1)->co;
- if (compare_v3v3(vec, co, MOC_THRESH))
- return (*bt)->index[a] - 1;
- }
- else {
- BMVert *eve = (BMVert *)((*bt)->index[a]);
- if (compare_v3v3(eve->co, co, MOC_THRESH))
- return (*bt)->index[a];
+ if (i != -1) {
+ if (nearest.dist < KD_THRESH) {
+ return i;
+ }
}
}
- else {
- return -1;
- }
- }
- if ( (*bt)->next)
- return mesh_octree_find_index(&(*bt)->next, mvert, co);
-
- return -1;
-}
-
-static struct {
- MocNode **table;
- float offs[3], div[3];
-} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}};
-
-/* mode is 's' start, or 'e' end, or 'u' use */
-/* if end, ob can be NULL */
-intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, const float co[3], char mode)
-{
- MocNode **bt;
-
- if (mode == 'u') { /* use table */
- if (MeshOctree.table == NULL)
- mesh_octree_table(ob, em, NULL, 's');
-
- if (MeshOctree.table) {
- Mesh *me = ob->data;
- bt = MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
- if (em)
- return mesh_octree_find_index(bt, NULL, co);
- else
- return mesh_octree_find_index(bt, me->mvert, co);
- }
return -1;
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
- float min[3], max[3];
+ int totvert;
- /* we compute own bounding box and don't reuse ob->bb because
- * we are using the undeformed coordinates*/
- INIT_MINMAX(min, max);
+ if (MirrKdStore.tree) /* happens when entering this call without ending it */
+ ED_mesh_mirror_spatial_table(ob, em, co, 'e');
if (em && me->edit_btmesh == em) {
- BMIter iter;
- BMVert *eve;
-
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- minmax_v3v3_v3(min, max, eve->co);
- }
+ totvert = em->bm->totvert;
}
else {
- MVert *mvert;
- int a;
-
- for (a = 0, mvert = me->mvert; a < me->totvert; a++, mvert++)
- minmax_v3v3_v3(min, max, mvert->co);
+ totvert = me->totvert;
}
-
- /* for quick unit coordinate calculus */
- copy_v3_v3(MeshOctree.offs, min);
- /* we offset it 1 threshold unit extra */
- add_v3_fl(MeshOctree.offs, -MOC_THRESH);
-
- sub_v3_v3v3(MeshOctree.div, max, min);
- /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
- add_v3_fl(MeshOctree.div, 2.0f * MOC_THRESH);
-
- mul_v3_fl(MeshOctree.div, 1.0f / MOC_RES);
- if (MeshOctree.div[0] == 0.0f) MeshOctree.div[0] = 1.0f;
- if (MeshOctree.div[1] == 0.0f) MeshOctree.div[1] = 1.0f;
- if (MeshOctree.div[2] == 0.0f) MeshOctree.div[2] = 1.0f;
-
- if (MeshOctree.table) /* happens when entering this call without ending it */
- mesh_octree_table(ob, em, co, 'e');
-
- MeshOctree.table = MEM_callocN(MOC_RES * MOC_RES * MOC_RES * sizeof(void *), "sym table");
-
+
+ MirrKdStore.tree = BLI_kdtree_new(totvert);
+
if (em && me->edit_btmesh == em) {
+
BMVert *eve;
BMIter iter;
+ int i;
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (intptr_t)(eve));
+ /* this needs to be valid for index lookups later (callers need) */
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ BLI_kdtree_insert(MirrKdStore.tree, i, eve->co);
}
}
else {
MVert *mvert;
- int a;
+ int i;
- for (a = 0, mvert = me->mvert; a < me->totvert; a++, mvert++)
- mesh_octree_add_nodes(MeshOctree.table, mvert->co, MeshOctree.offs, MeshOctree.div, a + 1);
+ for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
+ BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
+ }
}
+
+ BLI_kdtree_balance(MirrKdStore.tree);
}
else if (mode == 'e') { /* end table */
- if (MeshOctree.table) {
- int a;
-
- for (a = 0, bt = MeshOctree.table; a < MOC_RES * MOC_RES * MOC_RES; a++, bt++) {
- if (*bt) mesh_octree_free_node(bt);
- }
- MEM_freeN(MeshOctree.table);
- MeshOctree.table = NULL;
+ if (MirrKdStore.tree) {
+ BLI_kdtree_free(MirrKdStore.tree);
+ MirrKdStore.tree = NULL;
}
}
+ else {
+ BLI_assert(0);
+ }
+
return 0;
}
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/* Mesh Mirror (Topology) */
+
+/** \name Mesh Topology Mirror API
+ * \{ */
+
static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
-int mesh_mirrtopo_table(Object *ob, char mode)
+int ED_mesh_mirror_topo_table(Object *ob, char mode)
{
if (mode == 'u') { /* use table */
if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) {
- mesh_mirrtopo_table(ob, 's');
+ ED_mesh_mirror_topo_table(ob, 's');
}
}
else if (mode == 's') { /* start table */
@@ -914,9 +771,16 @@ int mesh_mirrtopo_table(Object *ob, char mode)
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
+ else {
+ BLI_assert(0);
+ }
+
return 0;
}
+/** \} */
+
+
static int mesh_get_x_mirror_vert_spatial(Object *ob, int index)
{
Mesh *me = ob->data;
@@ -928,12 +792,12 @@ static int mesh_get_x_mirror_vert_spatial(Object *ob, int index)
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
- return mesh_octree_table(ob, NULL, vec, 'u');
+ return ED_mesh_mirror_spatial_table(ob, NULL, vec, 'u');
}
static int mesh_get_x_mirror_vert_topo(Object *ob, int index)
{
- if (mesh_mirrtopo_table(ob, 'u') == -1)
+ if (ED_mesh_mirror_topo_table(ob, 'u') == -1)
return -1;
return mesh_topo_store.index_lookup[index];
@@ -952,7 +816,7 @@ int mesh_get_x_mirror_vert(Object *ob, int index, const bool use_topology)
static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3])
{
float vec[3];
- intptr_t poinval;
+ int i;
/* ignore nan verts */
if ((finite(co[0]) == false) ||
@@ -966,16 +830,17 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
vec[1] = co[1];
vec[2] = co[2];
- poinval = mesh_octree_table(ob, em, vec, 'u');
- if (poinval != -1)
- return (BMVert *)(poinval);
+ i = ED_mesh_mirror_spatial_table(ob, em, vec, 'u');
+ if (i != -1) {
+ return BM_vert_at_index(em->bm, i);
+ }
return NULL;
}
static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, struct BMEditMesh *em, BMVert *eve, int index)
{
intptr_t poinval;
- if (mesh_mirrtopo_table(ob, 'u') == -1)
+ if (ED_mesh_mirror_topo_table(ob, 'u') == -1)
return NULL;
if (index == -1) {
@@ -1153,12 +1018,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em)
mirrorverts = MEM_callocN(sizeof(int) * me->totvert, "MirrorVerts");
mirrorfaces = MEM_callocN(sizeof(int) * 2 * me->totface, "MirrorFaces");
- mesh_octree_table(ob, em, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, em, NULL, 's');
for (a = 0, mv = mvert; a < me->totvert; a++, mv++)
mirrorverts[a] = mesh_get_x_mirror_vert(ob, a, use_topology);
- mesh_octree_table(ob, em, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, em, NULL, 'e');
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
for (a = 0, mf = mface; a < me->totface; a++, mf++)
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index a833c530711..1441a1ef4c0 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -56,7 +56,6 @@
#include "ED_mball.h"
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "ED_transform.h"
#include "ED_util.h"
#include "WM_api.h"
@@ -502,7 +501,7 @@ static int hide_metaelems_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
MetaBall *mb = (MetaBall *)obedit->data;
MetaElem *ml;
- const int invert = RNA_boolean_get(op->ptr, "unselected") ? SELECT : 0;
+ const bool invert = RNA_boolean_get(op->ptr, "unselected") ? SELECT : 0;
ml = mb->editelems->first;
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index 249e7361cc0..b7822200d98 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -81,9 +81,9 @@ void ED_keymap_metaball(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MBALL_OT_reveal_metaelems", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0);
@@ -97,6 +97,6 @@ void ED_keymap_metaball(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MBALL_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
- ED_keymap_proportional_editmode(keyconf, keymap, TRUE);
+ ED_keymap_proportional_editmode(keyconf, keymap, true);
}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index b3a0e0915d4..ef09a9d0ea6 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -42,6 +42,7 @@ set(INC_SYS
set(SRC
object_add.c
object_bake.c
+ object_bake_api.c
object_constraint.c
object_edit.c
object_group.c
@@ -50,6 +51,7 @@ set(SRC
object_lod.c
object_modifier.c
object_ops.c
+ object_random.c
object_relations.c
object_select.c
object_shapekey.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index d52fd657397..99dd8b75609 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -45,7 +45,6 @@
#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_speaker_types.h"
#include "DNA_vfont_types.h"
#include "DNA_actuator_types.h"
@@ -61,7 +60,6 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
-#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -79,7 +77,6 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
-#include "BKE_modifier.h"
#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -477,7 +474,7 @@ void OBJECT_OT_add(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", "");
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/********************* Add Effector Operator ********************/
@@ -499,7 +496,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
if (type == PFIELD_GUIDE) {
Curve *cu;
- ob = ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_CURVE, loc, rot, false, layer);
if (!ob)
return OPERATOR_CANCELLED;
@@ -507,13 +504,13 @@ static int effector_add_exec(bContext *C, wmOperator *op)
cu = ob->data;
cu->flag |= CU_PATH | CU_3D;
ED_object_editmode_enter(C, 0);
- ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE);
+ ED_object_new_primitive_matrix(C, ob, loc, rot, mat, false);
BLI_addtail(&cu->editnurb->nurbs, add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1));
if (!enter_editmode)
ED_object_editmode_exit(C, EM_FREEDATA);
}
else {
- ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer);
if (!ob)
return OPERATOR_CANCELLED;
@@ -545,7 +542,7 @@ void OBJECT_OT_effector_add(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", "");
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/********************* Add Camera Operator ********************/
@@ -560,12 +557,12 @@ static int object_camera_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
/* force view align for cameras */
- RNA_boolean_set(op->ptr, "view_align", TRUE);
+ RNA_boolean_set(op->ptr, "view_align", true);
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL))
return OPERATOR_CANCELLED;
- ob = ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_CAMERA, loc, rot, false, layer);
if (v3d) {
if (v3d->camera == NULL)
@@ -594,7 +591,7 @@ void OBJECT_OT_camera_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
/* hide this for cameras, default */
prop = RNA_struct_type_find_property(ot->srna, "view_align");
@@ -619,7 +616,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if (obedit == NULL || obedit->type != OB_MBALL) {
- obedit = ED_object_add_type(C, OB_MBALL, loc, rot, TRUE, layer);
+ obedit = ED_object_add_type(C, OB_MBALL, loc, rot, true, layer);
newob = true;
}
else {
@@ -659,7 +656,7 @@ void OBJECT_OT_metaball_add(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", metaelem_type_items, 0, "Primitive", "");
ED_object_add_unit_props(ot);
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/********************* Add Text Operator ********************/
@@ -697,7 +694,7 @@ void OBJECT_OT_text_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/********************* Add Armature Operator ********************/
@@ -716,7 +713,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if ((obedit == NULL) || (obedit->type != OB_ARMATURE)) {
- obedit = ED_object_add_type(C, OB_ARMATURE, loc, rot, TRUE, layer);
+ obedit = ED_object_add_type(C, OB_ARMATURE, loc, rot, true, layer);
ED_object_editmode_enter(C, 0);
newob = true;
}
@@ -753,7 +750,7 @@ void OBJECT_OT_armature_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/********************* Add Empty Operator ********************/
@@ -768,7 +765,7 @@ static int object_empty_add_exec(bContext *C, wmOperator *op)
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
- ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer);
BKE_object_empty_draw_type_set(ob, type);
@@ -793,11 +790,13 @@ void OBJECT_OT_empty_add(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", object_empty_drawtype_items, 0, "Type", "");
- ED_object_add_generic_props(ot, FALSE);
+ ED_object_add_generic_props(ot, false);
}
static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Scene *scene = CTX_data_scene(C);
+
Base *base = NULL;
Image *ima = NULL;
Object *ob = NULL;
@@ -826,7 +825,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
/* if empty under cursor, then set object */
if (base && base->object->type == OB_EMPTY) {
ob = base->object;
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
else {
/* add new empty */
@@ -836,15 +835,18 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
if (!ED_object_add_generic_get_opts(C, op, 'Z', NULL, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
- ob = ED_object_add_type(C, OB_EMPTY, NULL, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_EMPTY, NULL, rot, false, layer);
/* add under the mouse */
ED_object_location_from_view(C, ob->loc);
ED_view3d_cursor3d_position(C, ob->loc, event->mval);
}
- ob->empty_drawtype = OB_EMPTY_IMAGE;
+ BKE_object_empty_draw_type_set(ob, OB_EMPTY_IMAGE);
+
+ id_us_min(ob->data);
ob->data = ima;
+ id_us_plus(ob->data);
return OPERATOR_FINISHED;
}
@@ -870,7 +872,7 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Image name to assign");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- ED_object_add_generic_props(ot, FALSE);
+ ED_object_add_generic_props(ot, false);
}
/********************* Add Lamp Operator ********************/
@@ -900,7 +902,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op)
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
- ob = ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_LAMP, loc, rot, false, layer);
la = (Lamp *)ob->data;
la->type = type;
@@ -909,7 +911,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op)
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_node_shader_default(C, &la->id);
- la->use_nodes = TRUE;
+ la->use_nodes = true;
}
return OPERATOR_FINISHED;
@@ -934,7 +936,7 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", "");
RNA_def_property_translation_context(ot->prop, BLF_I18NCONTEXT_ID_LAMP);
- ED_object_add_generic_props(ot, FALSE);
+ ED_object_add_generic_props(ot, false);
}
/********************* Add Group Instance Operator ********************/
@@ -967,7 +969,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
if (group) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Object *ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer);
+ Object *ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer);
rename_id(&ob->id, group->id.name + 2);
ob->dup_group = group;
ob->transflag |= OB_DUPLIGROUP;
@@ -987,6 +989,8 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
/* only used as menu */
void OBJECT_OT_group_instance_add(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Add Group Instance";
ot->description = "Add a dupligroup instance";
@@ -1002,9 +1006,11 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot)
/* properties */
RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add");
- ot->prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
- RNA_def_enum_funcs(ot->prop, RNA_group_itemf);
- ED_object_add_generic_props(ot, FALSE);
+ prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
+ RNA_def_enum_funcs(prop, RNA_group_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
+ ED_object_add_generic_props(ot, false);
}
/********************* Add Speaker Operator ********************/
@@ -1019,7 +1025,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
- ob = ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer);
+ ob = ED_object_add_type(C, OB_SPEAKER, loc, rot, false, layer);
/* to make it easier to start using this immediately in NLA, a default sound clip is created
* ready to be moved around to retime the sound and/or make new sound clips
@@ -1028,7 +1034,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
/* create new data for NLA hierarchy */
AnimData *adt = BKE_id_add_animdata(&ob->id);
NlaTrack *nlt = add_nlatrack(adt, NULL);
- NlaStrip *strip = add_nla_soundstrip(CTX_data_scene(C), ob->data);
+ NlaStrip *strip = add_nla_soundstrip(scene, ob->data);
strip->start = CFRA;
strip->end += strip->start;
@@ -1059,7 +1065,7 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ED_object_add_generic_props(ot, TRUE);
+ ED_object_add_generic_props(ot, true);
}
/**************************** Delete Object *************************/
@@ -1093,7 +1099,7 @@ static int object_delete_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
- const short use_global = RNA_boolean_get(op->ptr, "use_global");
+ const bool use_global = RNA_boolean_get(op->ptr, "use_global");
bool changed = false;
if (CTX_data_edit_object(C))
@@ -1259,8 +1265,8 @@ static void copy_object_set_idnew(bContext *C, int dupflag)
/********************* Make Duplicates Real ************************/
static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
- const short use_base_parent,
- const short use_hierarchy)
+ const bool use_base_parent,
+ const bool use_hierarchy)
{
Main *bmain = CTX_data_main(C);
ListBase *lb;
@@ -1298,6 +1304,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
BKE_free_animdata(&ob->id);
ob->adt = NULL;
+ /* Proxies are not to be copied. */
+ ob->proxy_from = NULL;
+ ob->proxy_group = NULL;
+ ob->proxy = NULL;
+
ob->parent = NULL;
BLI_listbase_clear(&ob->constraints);
ob->curve_cache = NULL;
@@ -1305,12 +1316,14 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
ob->lay = base->lay;
copy_m4_m4(ob->obmat, dob->mat);
- BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
+ BKE_object_apply_mat4(ob, ob->obmat, false, false);
if (dupli_gh)
BLI_ghash_insert(dupli_gh, dob, ob);
if (parent_gh)
BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->persistent_id[0])), ob);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
if (use_hierarchy) {
@@ -1351,7 +1364,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
/* note, this may be the parent of other objects, but it should
* still work out ok */
- BKE_object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE);
+ BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
/* to set ob_dst->orig and in case theres any other discrepicies */
DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
@@ -1370,7 +1383,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
/* similer to the code above, see comments */
invert_m4_m4(ob_dst->parentinv, dob->mat);
- BKE_object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE);
+ BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
}
}
@@ -1403,8 +1416,8 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- const short use_base_parent = RNA_boolean_get(op->ptr, "use_base_parent");
- const short use_hierarchy = RNA_boolean_get(op->ptr, "use_hierarchy");
+ const bool use_base_parent = RNA_boolean_get(op->ptr, "use_base_parent");
+ const bool use_hierarchy = RNA_boolean_get(op->ptr, "use_hierarchy");
BKE_main_id_clear_newpoins(bmain);
@@ -1451,14 +1464,33 @@ static EnumPropertyItem convert_target_items[] = {
{0, NULL, 0, NULL, NULL}
};
-static void curvetomesh(Object *ob)
+static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob)
{
- BLI_assert(ob->curve_cache != NULL);
+ if (ob->curve_cache == NULL) {
+ /* Force creation. This is normally not needed but on operator
+ * redo we might end up with an object which isn't evaluated yet.
+ */
+ if (ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
+ BKE_displist_make_curveTypes(scene, ob, false);
+ }
+ else if (ob->type == OB_MBALL) {
+ BKE_displist_make_mball(bmain->eval_ctx, scene, ob);
+ }
+ }
+}
+static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
+{
+ convert_ensure_curve_cache(bmain, scene, ob);
BKE_mesh_from_nurbs(ob); /* also does users */
- if (ob->type == OB_MESH)
+ if (ob->type == OB_MESH) {
BKE_object_free_modifiers(ob);
+
+ /* Game engine defaults for mesh objects */
+ ob->body_type = OB_BODY_TYPE_STATIC;
+ ob->gameflag = OB_PROP | OB_COLLISION;
+ }
}
static int convert_poll(bContext *C)
@@ -1506,7 +1538,7 @@ static int convert_exec(bContext *C, wmOperator *op)
MetaBall *mb;
Mesh *me;
const short target = RNA_enum_get(op->ptr, "target");
- const short keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
int a, mballConverted = 0;
/* don't forget multiple users! */
@@ -1665,7 +1697,7 @@ static int convert_exec(bContext *C, wmOperator *op)
BKE_curve_curve_dimension_update(cu);
if (target == OB_MESH) {
- curvetomesh(newob);
+ curvetomesh(bmain, scene, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
@@ -1689,7 +1721,7 @@ static int convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
- curvetomesh(newob);
+ curvetomesh(bmain, scene, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
@@ -1727,6 +1759,7 @@ static int convert_exec(bContext *C, wmOperator *op)
for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]);
}
+ convert_ensure_curve_cache(bmain, scene, baseob);
BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data);
if (obact->type == OB_MBALL) {
@@ -2168,8 +2201,11 @@ static int add_named_exec(bContext *C, wmOperator *op)
/* find object, create fake base */
RNA_string_get(op->ptr, "name", name);
ob = (Object *)BKE_libblock_find_name(ID_OB, name);
- if (ob == NULL)
+
+ if (ob == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object not found");
return OPERATOR_CANCELLED;
+ }
base = MEM_callocN(sizeof(Base), "duplibase");
base->object = ob;
@@ -2183,6 +2219,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
if (basen == NULL) {
MEM_freeN(base);
+ BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 0a4bbf10bf0..94574e81b81 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -49,7 +49,6 @@
#include "BLI_math_geom.h"
#include "BKE_blender.h"
-#include "BKE_ccg.h"
#include "BKE_screen.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -60,7 +59,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_subsurf.h"
#include "BKE_depsgraph.h"
#include "BKE_mesh.h"
#include "BKE_scene.h"
@@ -81,6 +79,7 @@
#include "WM_types.h"
#include "ED_object.h"
+#include "ED_screen.h"
#include "object_intern.h"
@@ -548,7 +547,7 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op)
WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL);
- G.is_break = FALSE;
+ G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
WM_cursor_wait(0);
@@ -721,7 +720,7 @@ static void bake_startjob(void *bkv, short *stop, short *do_update, float *progr
bkr->progress = progress;
RE_test_break_cb(bkr->re, NULL, thread_break);
- G.is_break = FALSE; /* blender_test_break uses this global */
+ G.is_break = false; /* blender_test_break uses this global */
RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
@@ -751,7 +750,7 @@ static void bake_freejob(void *bkv)
BKE_report(bkr->reports, RPT_WARNING, "Circular reference in texture stack");
MEM_freeN(bkr);
- G.is_rendering = FALSE;
+ G.is_rendering = false;
}
/* catch esc */
@@ -765,7 +764,6 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
- break;
}
return OPERATOR_PASS_THROUGH;
}
@@ -808,8 +806,8 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent
WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL);
- G.is_break = FALSE;
- G.is_rendering = TRUE;
+ G.is_break = false;
+ G.is_rendering = true;
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -849,7 +847,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
bkr.reports = op->reports;
RE_test_break_cb(bkr.re, NULL, thread_break);
- G.is_break = FALSE; /* blender_test_break uses this global */
+ G.is_break = false; /* blender_test_break uses this global */
RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL);
@@ -896,4 +894,5 @@ void OBJECT_OT_bake_image(wmOperatorType *ot)
ot->exec = bake_image_exec;
ot->invoke = objects_bake_render_invoke;
ot->modal = objects_bake_render_modal;
+ ot->poll = ED_operator_object_active;
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
new file mode 100644
index 00000000000..46555f89da9
--- /dev/null
+++ b/source/blender/editors/object/object_bake_api.c
@@ -0,0 +1,1109 @@
+/*
+ * ***** 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) 2004 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_bake_api.c
+ * \ingroup edobj
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_material_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_fileops.h"
+#include "BLI_math_geom.h"
+#include "BLI_path_util.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_modifier.h"
+#include "BKE_mesh.h"
+
+#include "RE_engine.h"
+#include "RE_pipeline.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_uvedit.h"
+
+#include "GPU_draw.h"
+
+#include "object_intern.h"
+
+/* catch esc */
+static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ /* no running blender, remove handler and pass through */
+ if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE))
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+
+ /* running render */
+ switch (event->type) {
+ case ESCKEY:
+ {
+ G.is_break = true;
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+/* for exec() when there is no render job
+ * note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
+static int bake_break(void *UNUSED(rjv))
+{
+ if (G.is_break)
+ return 1;
+ return 0;
+}
+
+static bool write_internal_bake_pixels(
+ Image *image, BakePixel pixel_array[], float *buffer,
+ const int width, const int height, const int margin,
+ const bool is_clear, const bool is_noncolor)
+{
+ ImBuf *ibuf;
+ void *lock;
+ bool is_float;
+ char *mask_buffer = NULL;
+ const int num_pixels = width * height;
+
+ ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+
+ if (!ibuf)
+ return false;
+
+ if (margin > 0 || !is_clear) {
+ mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ }
+
+ is_float = (ibuf->flags & IB_rectfloat);
+
+ /* colormanagement conversions */
+ if (!is_noncolor) {
+ const char *from_colorspace;
+ const char *to_colorspace;
+
+ from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+
+ if (is_float)
+ to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
+ else
+ to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
+
+ if (from_colorspace != to_colorspace)
+ IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
+ }
+
+ /* populates the ImBuf */
+ if (is_clear) {
+ if (is_float) {
+ IMB_buffer_float_from_float(
+ ibuf->rect_float, buffer, ibuf->channels,
+ IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
+ ibuf->x, ibuf->y, ibuf->x, ibuf->y);
+ }
+ else {
+ IMB_buffer_byte_from_float(
+ (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ }
+ }
+ else {
+ if (is_float) {
+ IMB_buffer_float_from_float_mask(
+ ibuf->rect_float, buffer, ibuf->channels,
+ ibuf->x, ibuf->y, ibuf->x, ibuf->y, mask_buffer);
+ }
+ else {
+ IMB_buffer_byte_from_float_mask(
+ (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
+ false, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
+ }
+ }
+
+ /* margins */
+ if (margin > 0)
+ RE_bake_margin(ibuf, mask_buffer, margin);
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;
+
+ if (ibuf->rect_float)
+ ibuf->userflags |= IB_RECT_INVALID;
+
+ /* force mipmap recalc */
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
+ if (mask_buffer)
+ MEM_freeN(mask_buffer);
+
+ return true;
+}
+
+/* force OpenGL reload */
+static void reset_images_gpu(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);
+ }
+ }
+}
+
+static bool write_external_bake_pixels(
+ const char *filepath, BakePixel pixel_array[], float *buffer,
+ const int width, const int height, const int margin,
+ ImageFormatData *im_format, const bool is_noncolor)
+{
+ ImBuf *ibuf = NULL;
+ bool ok = false;
+ bool is_float;
+
+ is_float = im_format->depth > 8;
+
+ /* create a new ImBuf */
+ ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
+
+ if (!ibuf)
+ return false;
+
+ /* populates the ImBuf */
+ if (is_float) {
+ IMB_buffer_float_from_float(
+ ibuf->rect_float, buffer, ibuf->channels,
+ IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
+ ibuf->x, ibuf->y, ibuf->x, ibuf->y);
+ }
+ else {
+ if (!is_noncolor) {
+ const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+ const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
+ IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
+ }
+
+ IMB_buffer_byte_from_float(
+ (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ }
+
+ /* margins */
+ if (margin > 0) {
+ char *mask_buffer = NULL;
+ const int num_pixels = width * height;
+
+ mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ RE_bake_margin(ibuf, mask_buffer, margin);
+
+ if (mask_buffer)
+ MEM_freeN(mask_buffer);
+ }
+
+ if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
+#ifndef WIN32
+ chmod(filepath, S_IRUSR | S_IWUSR);
+#endif
+ //printf("%s saving bake map: '%s'\n", __func__, filepath);
+ }
+
+ /* garbage collection */
+ IMB_freeImBuf(ibuf);
+
+ return ok;
+}
+
+static bool is_noncolor_pass(ScenePassType pass_type)
+{
+ return ELEM7(pass_type,
+ SCE_PASS_Z,
+ SCE_PASS_NORMAL,
+ SCE_PASS_VECTOR,
+ SCE_PASS_INDEXOB,
+ SCE_PASS_UV,
+ SCE_PASS_RAYHITS,
+ SCE_PASS_INDEXMA);
+}
+
+static bool build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images, ReportList *reports)
+{
+ const int tot_mat = ob->totcol;
+ int i, j;
+ int tot_images = 0;
+
+ /* error handling and tag (in case multiple materials share the same image) */
+ BKE_main_id_tag_idcode(bmain, ID_IM, false);
+
+ for (i = 0; i < tot_mat; i++) {
+ Image *image;
+ ED_object_get_active_image(ob, i + 1, &image, NULL, NULL);
+
+ if (!image) {
+ if (ob->mat[i]) {
+ BKE_reportf(reports, RPT_ERROR,
+ "No active image found in material %d (%s)", i, ob->mat[i]->id.name + 2);
+ }
+ else if (((Mesh *) ob->data)->mat[i]) {
+ BKE_reportf(reports, RPT_ERROR,
+ "No active image found in material %d (%s)", i, ((Mesh *) ob->data)->mat[i]->id.name + 2);
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR,
+ "No active image found in material %d", i);
+ }
+ return false;
+ }
+
+ if ((image->id.flag & LIB_DOIT)) {
+ for (j = 0; j < i; j++) {
+ if (bake_images->data[j].image == image) {
+ bake_images->lookup[i] = j;
+ break;
+ }
+ }
+ }
+ else {
+ bake_images->lookup[i] = tot_images;
+ bake_images->data[tot_images].image = image;
+ image->id.flag |= LIB_DOIT;
+ tot_images++;
+ }
+ }
+
+ bake_images->size = tot_images;
+ return true;
+}
+
+/*
+ * returns the total number of pixels
+ */
+static int initialize_internal_images(BakeImages *bake_images, ReportList *reports)
+{
+ int i;
+ int tot_size = 0;
+
+ for (i = 0; i < bake_images->size; i++) {
+ ImBuf *ibuf;
+ void *lock;
+
+ BakeImage *bk_image = &bake_images->data[i];
+ ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
+
+ if (ibuf) {
+ bk_image->width = ibuf->x;
+ bk_image->height = ibuf->y;
+ bk_image->offset = tot_size;
+
+ tot_size += ibuf->x * ibuf->y;
+ }
+ else {
+ BKE_image_release_ibuf(bk_image->image, ibuf, lock);
+ BKE_reportf(reports, RPT_ERROR, "Not initialized image %s", bk_image->image->id.name + 2);
+ return 0;
+ }
+ BKE_image_release_ibuf(bk_image->image, ibuf, lock);
+ }
+ return tot_size;
+}
+
+typedef struct BakeAPIRender {
+ Object *ob;
+ Main *main;
+ Scene *scene;
+ ReportList *reports;
+ ListBase selected_objects;
+
+ ScenePassType pass_type;
+ int margin;
+
+ int save_mode;
+
+ bool is_clear;
+ bool is_split_materials;
+ bool is_automatic_name;
+ bool use_selected_to_active;
+
+ float cage_extrusion;
+ int normal_space;
+ BakeNormalSwizzle normal_swizzle[3];
+
+ char custom_cage[MAX_NAME];
+ char filepath[FILE_MAX];
+
+ int width;
+ int height;
+ const char *identifier;
+
+ int result;
+ bool ready;
+} BakeAPIRender;
+
+static int bake(
+ Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
+ const ScenePassType pass_type, const int margin,
+ const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
+ const bool is_automatic_name, const bool use_selected_to_active,
+ const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[],
+ const char *custom_cage, const char *filepath, const int width, const int height,
+ const char *identifier)
+{
+ int op_result = OPERATOR_CANCELLED;
+ bool ok = false;
+
+ Object *ob_cage = NULL;
+
+ BakeHighPolyData *highpoly;
+ int tot_highpoly;
+
+ char restrict_flag_low = ob_low->restrictflag;
+ char restrict_flag_cage;
+
+ Mesh *me_low = NULL;
+ Render *re;
+
+ float *result = NULL;
+
+ BakePixel *pixel_array_low = NULL;
+
+ const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL);
+ const bool is_noncolor = is_noncolor_pass(pass_type);
+ const int depth = RE_pass_depth(pass_type);
+
+ bool is_highpoly = false;
+ bool is_tangent;
+
+ BakeImages bake_images = {NULL};
+
+ int num_pixels;
+ int tot_materials;
+ int i;
+
+ re = RE_NewRender(scene->id.name);
+ RE_SetReports(re, NULL);
+
+ is_tangent = pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT;
+ tot_materials = ob_low->totcol;
+
+ if (tot_materials == 0) {
+ if (is_save_internal) {
+ BKE_report(reports, RPT_ERROR,
+ "No active image found. Add a material or bake to an external file");
+
+ goto cleanup;
+ }
+ else if (is_split_materials) {
+ BKE_report(reports, RPT_ERROR,
+ "No active image found. Add a material or bake without the Split Materials option");
+
+ goto cleanup;
+ }
+ else {
+ /* baking externally without splitting materials */
+ tot_materials = 1;
+ }
+ }
+
+ /* we overallocate in case there is more materials than images */
+ bake_images.data = MEM_callocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
+ bake_images.lookup = MEM_callocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");
+
+ if (!build_image_lookup(bmain, ob_low, &bake_images, reports))
+ goto cleanup;
+
+ if (is_save_internal) {
+ num_pixels = initialize_internal_images(&bake_images, reports);
+
+ if (num_pixels == 0) {
+ goto cleanup;
+ }
+
+ if (is_clear) {
+ RE_bake_ibuf_clear(&bake_images, is_tangent);
+ }
+ }
+ else {
+ /* when saving extenally always use the size specified in the UI */
+
+ num_pixels = width * height * bake_images.size;
+
+ for (i = 0; i < bake_images.size; i++) {
+ bake_images.data[i].width = width;
+ bake_images.data[i].height = height;
+ bake_images.data[i].offset = (is_split_materials ? num_pixels : 0);
+ bake_images.data[i].image = NULL;
+ }
+
+ if (!is_split_materials) {
+ /* saving a single image */
+ for (i = 0; i < tot_materials; i++)
+ bake_images.lookup[i] = 0;
+ }
+ }
+
+ if (use_selected_to_active) {
+ CollectionPointerLink *link;
+ tot_highpoly = 0;
+
+ for (link = selected_objects->first; link; link = link->next) {
+ Object *ob_iter = link->ptr.data;
+
+ if (ob_iter == ob_low)
+ continue;
+
+ tot_highpoly ++;
+ }
+
+ if (tot_highpoly == 0) {
+ BKE_report(reports, RPT_ERROR, "No valid selected objects");
+ op_result = OPERATOR_CANCELLED;
+
+ goto cleanup;
+ }
+ else {
+ is_highpoly = true;
+ }
+ }
+
+ if (custom_cage[0] != '\0') {
+ ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2);
+
+ /* TODO check if cage object has the same topology (num of triangles and a valid UV) */
+ if (ob_cage == NULL || ob_cage->type != OB_MESH) {
+ BKE_report(reports, RPT_ERROR, "No valid cage object");
+ op_result = OPERATOR_CANCELLED;
+
+ goto cleanup;
+ }
+ else {
+ restrict_flag_cage = ob_cage->restrictflag;
+ }
+ }
+
+ RE_bake_engine_set_engine_parameters(re, bmain, scene);
+
+ /* blender_test_break uses this global */
+ G.is_break = false;
+
+ RE_test_break_cb(re, NULL, bake_break);
+
+ pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
+ result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
+
+ if (is_highpoly) {
+ CollectionPointerLink *link;
+ ModifierData *md, *nmd;
+ ListBase modifiers_tmp, modifiers_original;
+ float mat_low[4][4];
+ int i = 0;
+ highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
+
+ /* prepare cage mesh */
+ if (ob_cage) {
+ me_low = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 1, 0);
+ copy_m4_m4(mat_low, ob_cage->obmat);
+ }
+ else {
+ modifiers_original = ob_low->modifiers;
+ BLI_listbase_clear(&modifiers_tmp);
+
+ for (md = ob_low->modifiers.first; md; md = md->next) {
+ /* Edge Split cannot be applied in the cage,
+ * the cage is supposed to have interpolated normals
+ * between the faces unless the geometry is physically
+ * split. So we create a copy of the low poly mesh without
+ * the eventual edge split.*/
+
+ if (md->type == eModifierType_EdgeSplit)
+ continue;
+
+ nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
+ modifier_copyData(md, nmd);
+ BLI_addtail(&modifiers_tmp, nmd);
+ }
+
+ /* temporarily replace the modifiers */
+ ob_low->modifiers = modifiers_tmp;
+
+ /* get the cage mesh as it arrives in the renderer */
+ me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
+ copy_m4_m4(mat_low, ob_low->obmat);
+ }
+
+ /* populate highpoly array */
+ for (link = selected_objects->first; link; link = link->next) {
+ TriangulateModifierData *tmd;
+ Object *ob_iter = link->ptr.data;
+
+ if (ob_iter == ob_low)
+ continue;
+
+ /* initialize highpoly_data */
+ highpoly[i].ob = ob_iter;
+ highpoly[i].me = NULL;
+ highpoly[i].tri_mod = NULL;
+ highpoly[i].restrict_flag = ob_iter->restrictflag;
+ highpoly[i].pixel_array = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
+
+
+ /* triangulating so BVH returns the primitive_id that will be used for rendering */
+ highpoly[i].tri_mod = ED_object_modifier_add(
+ reports, bmain, scene, highpoly[i].ob,
+ "TmpTriangulate", eModifierType_Triangulate);
+ tmd = (TriangulateModifierData *)highpoly[i].tri_mod;
+ tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
+ tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
+
+ highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 1, 0);
+ highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
+
+ /* lowpoly to highpoly transformation matrix */
+ invert_m4_m4(highpoly[i].mat_lowtohigh, highpoly[i].ob->obmat);
+ mul_m4_m4m4(highpoly[i].mat_lowtohigh, highpoly[i].mat_lowtohigh, mat_low);
+
+ i++;
+ }
+
+ BLI_assert(i == tot_highpoly);
+
+ /* populate the pixel array with the face data */
+ RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images);
+
+ ob_low->restrictflag |= OB_RESTRICT_RENDER;
+
+ /* populate the pixel arrays with the corresponding face data for each high poly object */
+ RE_bake_pixels_populate_from_objects(
+ me_low, pixel_array_low, highpoly, tot_highpoly,
+ num_pixels, cage_extrusion);
+
+ /* the baking itself */
+ for (i = 0; i < tot_highpoly; i++) {
+ if (RE_bake_has_engine(re)) {
+ ok = RE_bake_engine(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels,
+ depth, pass_type, result);
+ }
+ else {
+ ok = RE_bake_internal(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels,
+ depth, pass_type, result);
+ }
+
+ if (!ok)
+ break;
+ }
+
+ /* reverting data back */
+ if (ob_cage) {
+ ob_cage->restrictflag |= OB_RESTRICT_RENDER;
+ }
+ else {
+ ob_low->modifiers = modifiers_original;
+
+ while ((md = BLI_pophead(&modifiers_tmp))) {
+ modifier_free(md);
+ }
+ }
+ }
+ else {
+ /* get the mesh as it arrives in the renderer */
+ me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
+
+ /* populate the pixel array with the face data */
+ RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images);
+
+ /* make sure low poly renders */
+ ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
+
+ if (RE_bake_has_engine(re))
+ ok = RE_bake_engine(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result);
+ else
+ ok = RE_bake_internal(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result);
+ }
+
+ /* normal space conversion
+ * the normals are expected to be in world space, +X +Y +Z */
+ if (pass_type == SCE_PASS_NORMAL) {
+ switch (normal_space) {
+ case R_BAKE_SPACE_WORLD:
+ {
+ /* Cycles internal format */
+ if ((normal_swizzle[0] == R_BAKE_POSX) &&
+ (normal_swizzle[1] == R_BAKE_POSY) &&
+ (normal_swizzle[2] == R_BAKE_POSZ))
+ {
+ break;
+ }
+ else {
+ RE_bake_normal_world_to_world(pixel_array_low, num_pixels, depth, result, normal_swizzle);
+ }
+ break;
+ }
+ case R_BAKE_SPACE_OBJECT:
+ {
+ RE_bake_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low, normal_swizzle);
+ break;
+ }
+ case R_BAKE_SPACE_TANGENT:
+ {
+ if (is_highpoly) {
+ RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle);
+ }
+ else {
+ /* from multiresolution */
+ Mesh *me_nores = NULL;
+ ModifierData *md = NULL;
+ int mode;
+
+ md = modifiers_findByType(ob_low, eModifierType_Multires);
+
+ if (md) {
+ mode = md->mode;
+ md->mode &= ~eModifierMode_Render;
+ }
+
+ me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
+ RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images);
+
+ RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle);
+ BKE_libblock_free(bmain, me_nores);
+
+ if (md)
+ md->mode = mode;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!ok) {
+ BKE_report(reports, RPT_ERROR, "Problem baking object map");
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ /* save the results */
+ for (i = 0; i < bake_images.size; i++) {
+ BakeImage *bk_image = &bake_images.data[i];
+
+ if (is_save_internal) {
+ ok = write_internal_bake_pixels(
+ bk_image->image,
+ pixel_array_low + bk_image->offset,
+ result + bk_image->offset * depth,
+ bk_image->width, bk_image->height,
+ margin, is_clear, is_noncolor);
+
+ if (!ok) {
+ BKE_report(reports, RPT_ERROR,
+ "Problem saving the bake map internally, "
+ "make sure there is a Texture Image node in the current object material");
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_report(reports, RPT_INFO,
+ "Baking map saved to internal image, save it externally or pack it");
+ op_result = OPERATOR_FINISHED;
+ }
+ }
+ /* save externally */
+ else {
+ BakeData *bake = &scene->r.bake;
+ char name[FILE_MAX];
+
+ BKE_makepicstring_from_type(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false);
+
+ if (is_automatic_name) {
+ BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
+ BLI_path_suffix(name, FILE_MAX, identifier, "_");
+ }
+
+ if (is_split_materials) {
+ if (bk_image->image) {
+ BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
+ }
+ else {
+ if (ob_low->mat[i]) {
+ BLI_path_suffix(name, FILE_MAX, ob_low->mat[i]->id.name + 2, "_");
+ }
+ else if (me_low->mat[i]) {
+ BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_");
+ }
+ else {
+ /* if everything else fails, use the material index */
+ char tmp[4];
+ sprintf(tmp, "%d", i % 1000);
+ BLI_path_suffix(name, FILE_MAX, tmp, "_");
+ }
+ }
+ }
+
+ /* save it externally */
+ ok = write_external_bake_pixels(
+ name,
+ pixel_array_low + bk_image->offset,
+ result + bk_image->offset * depth,
+ bk_image->width, bk_image->height,
+ margin, &bake->im_format, is_noncolor);
+
+ if (!ok) {
+ BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\".", name);
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\".", name);
+ op_result = OPERATOR_FINISHED;
+ }
+
+ if (!is_split_materials) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (is_save_internal)
+ reset_images_gpu(&bake_images);
+
+cleanup:
+
+ if (is_highpoly) {
+ int i;
+ for (i = 0; i < tot_highpoly; i++) {
+ highpoly[i].ob->restrictflag = highpoly[i].restrict_flag;
+
+ if (highpoly[i].pixel_array)
+ MEM_freeN(highpoly[i].pixel_array);
+
+ if (highpoly[i].tri_mod)
+ ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod);
+
+ if (highpoly[i].me)
+ BKE_libblock_free(bmain, highpoly[i].me);
+ }
+ MEM_freeN(highpoly);
+ }
+
+ ob_low->restrictflag = restrict_flag_low;
+
+ if (ob_cage)
+ ob_cage->restrictflag = restrict_flag_cage;
+
+ if (pixel_array_low)
+ MEM_freeN(pixel_array_low);
+
+ if (bake_images.data)
+ MEM_freeN(bake_images.data);
+
+ if (bake_images.lookup)
+ MEM_freeN(bake_images.lookup);
+
+ if (result)
+ MEM_freeN(result);
+
+ if (me_low)
+ BKE_libblock_free(bmain, me_low);
+
+ return op_result;
+}
+
+static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
+{
+ bool is_save_internal;
+
+ bkr->ob = CTX_data_active_object(C);
+ bkr->main = CTX_data_main(C);
+ bkr->scene = CTX_data_scene(C);
+
+ bkr->pass_type = RNA_enum_get(op->ptr, "type");
+ bkr->margin = RNA_int_get(op->ptr, "margin");
+
+ bkr->save_mode = RNA_enum_get(op->ptr, "save_mode");
+ is_save_internal = (bkr->save_mode == R_BAKE_SAVE_INTERNAL);
+
+ bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
+ bkr->is_split_materials = (!is_save_internal) && RNA_boolean_get(op->ptr, "use_split_materials");
+ bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
+ bkr->use_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
+ bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
+
+ bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
+ bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
+ bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
+ bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
+
+ bkr->width = RNA_int_get(op->ptr, "width");
+ bkr->height = RNA_int_get(op->ptr, "height");
+ bkr->identifier = "";
+
+ RNA_string_get(op->ptr, "cage", bkr->custom_cage);
+
+ if ((!is_save_internal) && bkr->is_automatic_name) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
+ RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
+ }
+
+ if (bkr->use_selected_to_active)
+ CTX_data_selected_objects(C, &bkr->selected_objects);
+
+ bkr->reports = op->reports;
+
+ /* XXX hack to force saving to always be internal. Whether (and how) to support
+ * external saving will be addressed later */
+ bkr->save_mode = R_BAKE_SAVE_INTERNAL;
+}
+
+static int bake_exec(bContext *C, wmOperator *op)
+{
+ int result;
+ BakeAPIRender bkr = {NULL};
+
+ bake_init_api_data(op, C, &bkr);
+
+ result = bake(
+ bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports,
+ bkr.pass_type, bkr.margin, bkr.save_mode,
+ bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, bkr.use_selected_to_active,
+ bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
+ bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier);
+
+ BLI_freelistN(&bkr.selected_objects);
+ return result;
+}
+
+static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress))
+{
+ BakeAPIRender *bkr = (BakeAPIRender *)bkv;
+
+ bkr->result = bake(
+ bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports,
+ bkr->pass_type, bkr->margin, bkr->save_mode,
+ bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, bkr->use_selected_to_active,
+ bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
+ bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier
+ );
+}
+
+static void bake_freejob(void *bkv)
+{
+ BakeAPIRender *bkr = (BakeAPIRender *)bkv;
+
+ BLI_freelistN(&bkr->selected_objects);
+ MEM_freeN(bkr);
+
+ G.is_rendering = false;
+}
+
+static void bake_set_props(wmOperator *op, Scene *scene)
+{
+ PropertyRNA *prop;
+ BakeData *bake = &scene->r.bake;
+
+ prop = RNA_struct_find_property(op->ptr, "filepath");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_string_set(op->ptr, prop, bake->filepath);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "width");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->width);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "height");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->width);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "margin");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->margin);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE));
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "cage");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_string_set(op->ptr, prop, bake->cage);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_space");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_space);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_r");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_g");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_b");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "save_mode");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->save_mode);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_clear");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR));
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_split_materials");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT));
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME));
+ }
+}
+
+static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ wmJob *wm_job;
+ BakeAPIRender *bkr;
+ Scene *scene = CTX_data_scene(C);
+
+ bake_set_props(op, scene);
+
+ /* only one render job at a time */
+ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE))
+ return OPERATOR_CANCELLED;
+
+ bkr = MEM_callocN(sizeof(BakeAPIRender), "render bake");
+
+ /* init bake render */
+ bake_init_api_data(op, C, bkr);
+
+ /* setup job */
+ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake",
+ WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE);
+ WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
+ WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL);
+
+ G.is_break = false;
+ G.is_rendering = true;
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+
+ WM_cursor_wait(0);
+
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void OBJECT_OT_bake(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Bake";
+ ot->description = "Bake image textures of selected objects";
+ ot->idname = "OBJECT_OT_bake";
+
+ /* api callbacks */
+ ot->exec = bake_exec;
+ ot->modal = bake_modal;
+ ot->invoke = bake_invoke;
+ ot->poll = ED_operator_object_active_editable_mesh;
+
+ RNA_def_enum(ot->srna, "type", render_pass_type_items, SCE_PASS_COMBINED, "Type",
+ "Type of pass to bake, some of them may not be supported by the current render engine");
+ RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path",
+ "Image filepath to use when saving externally");
+ RNA_def_int(ot->srna, "width", 512, 1, INT_MAX, "Width",
+ "Horizontal dimension of the baking map (external only)", 64, 4096);
+ RNA_def_int(ot->srna, "height", 512, 1, INT_MAX, "Height",
+ "Vertical dimension of the baking map (external only)", 64, 4096);
+ RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin",
+ "Extends the baked result as a post process filter", 0, 64);
+ RNA_def_boolean(ot->srna, "use_selected_to_active", false, "Selected to Active",
+ "Bake shading on the surface of selected objects to the active object");
+ RNA_def_float(ot->srna, "cage_extrusion", 0.0, 0.0, 1.0, "Cage Extrusion",
+ "Distance to use for the inward ray cast when using selected to active", 0.0, 1.0);
+ RNA_def_string(ot->srna, "cage", NULL, MAX_NAME, "Cage",
+ "Object to use as cage");
+ RNA_def_enum(ot->srna, "normal_space", normal_space_items, R_BAKE_SPACE_TANGENT, "Normal Space",
+ "Choose normal space for baking");
+ RNA_def_enum(ot->srna, "normal_r", normal_swizzle_items, R_BAKE_POSX, "R", "Axis to bake in red channel");
+ RNA_def_enum(ot->srna, "normal_g", normal_swizzle_items, R_BAKE_POSY, "G", "Axis to bake in green channel");
+ RNA_def_enum(ot->srna, "normal_b", normal_swizzle_items, R_BAKE_POSZ, "B", "Axis to bake in blue channel");
+ RNA_def_enum(ot->srna, "save_mode", bake_save_mode_items, R_BAKE_SAVE_INTERNAL, "Save Mode",
+ "Choose how to save the baking map");
+ RNA_def_boolean(ot->srna, "use_clear", false, "Clear",
+ "Clear Images before baking (only for internal saving)");
+ RNA_def_boolean(ot->srna, "use_split_materials", false, "Split Materials",
+ "Split baked maps per material, using material name in output file (external only)");
+ RNA_def_boolean(ot->srna, "use_automatic_name", false, "Automatic Name",
+ "Automatically name the output file with the pass type");
+}
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 3d055e7485f..85e4bbce8dc 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -74,7 +74,6 @@
#include "RNA_enum_types.h"
#include "ED_object.h"
-#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
@@ -105,10 +104,10 @@ ListBase *get_active_constraints(Object *ob)
}
/* Find the list that a given constraint belongs to, and/or also get the posechannel this is from (if applicable) */
-ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **pchan_r)
+ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **r_pchan)
{
- if (pchan_r)
- *pchan_r = NULL;
+ if (r_pchan)
+ *r_pchan = NULL;
if (ELEM(NULL, ob, con))
return NULL;
@@ -128,8 +127,8 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **pchan_r
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if ((BLI_findindex(&pchan->constraints, con) != -1)) {
- if (pchan_r)
- *pchan_r = pchan;
+ if (r_pchan)
+ *r_pchan = pchan;
return &pchan->constraints;
}
@@ -143,7 +142,7 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **pchan_r
/* single constraint */
bConstraint *get_active_constraint(Object *ob)
{
- return BKE_constraints_get_active(get_active_constraints(ob));
+ return BKE_constraints_active_get(get_active_constraints(ob));
}
/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
@@ -227,7 +226,7 @@ static void update_pyconstraint_cb(void *arg1, void *arg2)
/* helper function for add_constriant - sets the last target for the active constraint */
static void set_constraint_nth_target(bConstraint *con, Object *target, const char subtarget[], int index)
{
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
int num_targets, i;
@@ -299,7 +298,7 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
/* Check all constraints - is constraint valid? */
if (conlist) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -542,8 +541,20 @@ static int edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
- if (!ob || ob->id.lib) return 0;
- if (ptr.id.data && ((ID *)ptr.id.data)->lib) return 0;
+ if (!ptr.data) {
+ CTX_wm_operator_poll_msg_set(C, "Context missing 'constraint'");
+ return 0;
+ }
+
+ if (!ob) {
+ CTX_wm_operator_poll_msg_set(C, "Context missing active object");
+ return 0;
+ }
+
+ if (ob->id.lib || (ptr.id.data && ((ID *)ptr.id.data)->lib)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
+ return 0;
+ }
return 1;
}
@@ -614,7 +625,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
list = get_active_constraints(ob);
}
- con = BKE_constraints_findByName(list, constraint_name);
+ con = BKE_constraints_find_name(list, constraint_name);
//if (G.debug & G_DEBUG)
//printf("constraint found = %p, %s\n", (void *)con, (con) ? con->name : "<Not found>");
@@ -1135,7 +1146,7 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con)
if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE))
return;
- BKE_constraints_set_active(lb, con);
+ BKE_constraints_active_set(lb, con);
}
void ED_object_constraint_update(Object *ob)
@@ -1174,9 +1185,9 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
const bool is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
/* free the constraint */
- if (BKE_remove_constraint(lb, con)) {
+ if (BKE_constraint_remove(lb, con)) {
/* there's no active constraint now, so make sure this is the case */
- BKE_constraints_set_active(lb, NULL);
+ BKE_constraints_active_set(lb, NULL);
ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
@@ -1319,7 +1330,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* free constraints for all selected bones */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
- BKE_free_constraints(&pchan->constraints);
+ BKE_constraints_free(&pchan->constraints);
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK | PCHAN_HAS_CONST);
}
CTX_DATA_END;
@@ -1356,7 +1367,7 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* do freeing */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- BKE_free_constraints(&ob->constraints);
+ BKE_constraints_free(&ob->constraints);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
@@ -1400,7 +1411,7 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (pchan != chan) {
- BKE_copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
+ BKE_constraints_copy(&chan->constraints, &pchan->constraints, true);
/* update flags (need to add here, not just copy) */
chan->constflag |= pchan->constflag;
}
@@ -1440,7 +1451,7 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (obact != ob) {
- BKE_copy_constraints(&ob->constraints, &obact->constraints, TRUE);
+ BKE_constraints_copy(&ob->constraints, &obact->constraints, true);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
@@ -1650,9 +1661,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
/* create a new constraint of the type requried, and add it to the active/given constraints list */
if (pchan)
- con = BKE_add_pose_constraint(ob, pchan, NULL, type);
+ con = BKE_constraint_add_for_pose(ob, pchan, NULL, type);
else
- con = BKE_add_ob_constraint(ob, NULL, type);
+ con = BKE_constraint_add_for_object(ob, NULL, type);
/* get the first selected object/bone, and make that the target
* - apart from the buttons-window add buttons, we shouldn't add in this way
@@ -1948,7 +1959,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
for (con = pchan->constraints.first; con; con = next) {
next = con->next;
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- BKE_remove_constraint(&pchan->constraints, con);
+ BKE_constraint_remove(&pchan->constraints, con);
}
}
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index b8caf02fcd8..002bec4ef0b 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -45,7 +45,6 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
-#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
#include "DNA_property_types.h"
@@ -64,7 +63,6 @@
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_depsgraph.h"
-#include "BKE_font.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -72,7 +70,6 @@
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
-#include "BKE_paint.h"
#include "BKE_pointcache.h"
#include "BKE_property.h"
#include "BKE_sca.h"
@@ -178,7 +175,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
bool changed = false;
- const int unselected = RNA_boolean_get(op->ptr, "unselected");
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
@@ -209,7 +206,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
DAG_id_type_tag(bmain, ID_OB);
DAG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -273,7 +270,7 @@ void OBJECT_OT_hide_render_clear(wmOperatorType *ot)
static int object_hide_render_set_exec(bContext *C, wmOperator *op)
{
- const int unselected = RNA_boolean_get(op->ptr, "unselected");
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
@@ -338,8 +335,8 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata)
me->edit_btmesh = NULL;
}
if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, 'e');
}
}
else if (obedit->type == OB_ARMATURE) {
@@ -432,7 +429,7 @@ void ED_object_editmode_enter(bContext *C, int flag)
Object *ob;
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = NULL;
- int ok = 0;
+ bool ok = false;
if (scene->id.lib) return;
@@ -990,7 +987,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
}
else if (event == 22) {
/* Copy the constraint channels over */
- BKE_copy_constraints(&base->object->constraints, &ob->constraints, TRUE);
+ BKE_constraints_copy(&base->object->constraints, &ob->constraints, true);
do_depgraph_update = true;
}
@@ -998,7 +995,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
base->object->softflag = ob->softflag;
if (base->object->soft) sbFree(base->object->soft);
- base->object->soft = copy_softbody(ob->soft, FALSE);
+ base->object->soft = copy_softbody(ob->soft, false);
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
@@ -1130,8 +1127,7 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->pd == NULL)
ob->pd = object_add_collision_fields(PFIELD_FORCE);
-
- if (ob->pd->forcefield == 0)
+ else if (ob->pd->forcefield == 0)
ob->pd->forcefield = PFIELD_FORCE;
else
ob->pd->forcefield = 0;
@@ -1439,7 +1435,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
for (base = FIRSTBASE; base; base = base->next) {
if (TESTBASELIB(v3d, base)) {
ob = base->object;
- done = FALSE;
+ done = false;
for (a = 1; a <= ob->totcol; a++) {
ma = give_current_material(ob, a);
@@ -1469,7 +1465,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
if (x > y) ob->size[0] = ob->size[1] * x / y;
else ob->size[1] = ob->size[0] * y / x;
- done = TRUE;
+ done = true;
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
BKE_image_release_ibuf(tex->ima, ibuf, NULL);
@@ -1867,7 +1863,7 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot)
RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", "");
prop = RNA_def_enum(ot->srna, "property", DummyRNA_NULL_items, 0, "Property", "Properties to copy");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_ENUM_NO_TRANSLATE);
RNA_def_enum_funcs(prop, gameprops_itemf);
ot->prop = prop;
}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 72d7ffaf2ea..69bd64542f4 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -238,6 +238,7 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to add other selected objects to");
RNA_def_enum_funcs(prop, group_object_active_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -249,7 +250,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
- int ok = 0;
+ bool ok = false;
if (ob == NULL)
return OPERATOR_CANCELLED;
@@ -301,6 +302,7 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove other selected objects from");
RNA_def_enum_funcs(prop, group_object_active_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -393,6 +395,7 @@ void GROUP_OT_objects_remove(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove this object from");
RNA_def_enum_funcs(prop, group_object_active_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -476,7 +479,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
- Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
+ Group *group = BLI_findlink(&bmain->group, RNA_enum_get(op->ptr, "group"));
if (ELEM(NULL, ob, group))
return OPERATOR_CANCELLED;
@@ -527,6 +530,7 @@ void OBJECT_OT_group_link(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
RNA_def_enum_funcs(prop, RNA_group_local_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index fe27060e5ae..6407d2eb8b8 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -50,7 +50,6 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_report.h"
@@ -65,7 +64,6 @@
#include "ED_curve.h"
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_object.h"
#include "WM_types.h"
#include "WM_api.h"
@@ -74,7 +72,9 @@
#include "object_intern.h"
-static int return_editmesh_indexar(BMEditMesh *em, int *tot, int **indexar, float *cent)
+static int return_editmesh_indexar(
+ BMEditMesh *em,
+ int *r_tot, int **r_indexar, float r_cent[3])
{
BMVert *eve;
BMIter iter;
@@ -85,29 +85,29 @@ static int return_editmesh_indexar(BMEditMesh *em, int *tot, int **indexar, floa
}
if (totvert == 0) return 0;
- *indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
- *tot = totvert;
+ *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
+ *r_tot = totvert;
nr = 0;
- zero_v3(cent);
+ zero_v3(r_cent);
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
*index = nr; index++;
- add_v3_v3(cent, eve->co);
+ add_v3_v3(r_cent, eve->co);
}
nr++;
}
- mul_v3_fl(cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)totvert);
return totvert;
}
-static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *name, float *cent)
+static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, float r_cent[3])
{
const int cd_dvert_offset = obedit->actdef ? CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT) : -1;
- zero_v3(cent);
+ zero_v3(r_cent);
if (cd_dvert_offset != -1) {
const int defgrp_index = obedit->actdef - 1;
@@ -122,14 +122,14 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *name, f
dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
if (defvert_find_weight(dvert, defgrp_index) > 0.0f) {
- add_v3_v3(cent, eve->co);
+ add_v3_v3(r_cent, eve->co);
totvert++;
}
}
if (totvert) {
bDeformGroup *dg = BLI_findlink(&obedit->defbase, defgrp_index);
- BLI_strncpy(name, dg->name, sizeof(dg->name));
- mul_v3_fl(cent, 1.0f / (float)totvert);
+ BLI_strncpy(r_name, dg->name, sizeof(dg->name));
+ mul_v3_fl(r_cent, 1.0f / (float)totvert);
return true;
}
}
@@ -150,7 +150,7 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (nr == hmd->indexar[index]) {
- BM_vert_select_set(em->bm, eve, TRUE);
+ BM_vert_select_set(em->bm, eve, true);
if (index < hmd->totindex - 1) index++;
}
@@ -160,7 +160,9 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
EDBM_select_flush(em);
}
-static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent)
+static int return_editlattice_indexar(
+ Lattice *editlatt,
+ int *r_tot, int **r_indexar, float r_cent[3])
{
BPoint *bp;
int *index, nr, totvert = 0, a;
@@ -177,10 +179,10 @@ static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar
if (totvert == 0) return 0;
- *indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
- *tot = totvert;
+ *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
+ *r_tot = totvert;
nr = 0;
- zero_v3(cent);
+ zero_v3(r_cent);
a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw;
bp = editlatt->def;
@@ -188,14 +190,14 @@ static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar
if (bp->f1 & SELECT) {
if (bp->hide == 0) {
*index = nr; index++;
- add_v3_v3(cent, bp->vec);
+ add_v3_v3(r_cent, bp->vec);
}
}
bp++;
nr++;
}
- mul_v3_fl(cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)totvert);
return totvert;
}
@@ -220,7 +222,9 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
}
}
-static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, float *cent)
+static int return_editcurve_indexar(
+ Object *obedit,
+ int *r_tot, int **r_indexar, float r_cent[3])
{
ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
@@ -250,10 +254,10 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo
}
if (totvert == 0) return 0;
- *indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
- *tot = totvert;
+ *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
+ *r_tot = totvert;
nr = 0;
- zero_v3(cent);
+ zero_v3(r_cent);
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
@@ -262,17 +266,17 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo
while (a--) {
if (bezt->f1 & SELECT) {
*index = nr; index++;
- add_v3_v3(cent, bezt->vec[0]);
+ add_v3_v3(r_cent, bezt->vec[0]);
}
nr++;
if (bezt->f2 & SELECT) {
*index = nr; index++;
- add_v3_v3(cent, bezt->vec[1]);
+ add_v3_v3(r_cent, bezt->vec[1]);
}
nr++;
if (bezt->f3 & SELECT) {
*index = nr; index++;
- add_v3_v3(cent, bezt->vec[2]);
+ add_v3_v3(r_cent, bezt->vec[2]);
}
nr++;
bezt++;
@@ -284,7 +288,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo
while (a--) {
if (bp->f1 & SELECT) {
*index = nr; index++;
- add_v3_v3(cent, bp->vec);
+ add_v3_v3(r_cent, bp->vec);
}
nr++;
bp++;
@@ -292,16 +296,17 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo
}
}
- mul_v3_fl(cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)totvert);
return totvert;
}
-static bool object_hook_index_array(Scene *scene, Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
+static bool object_hook_index_array(Scene *scene, Object *obedit,
+ int *r_tot, int **r_indexar, char *r_name, float r_cent[3])
{
- *indexar = NULL;
- *tot = 0;
- name[0] = 0;
+ *r_indexar = NULL;
+ *r_tot = 0;
+ r_name[0] = 0;
switch (obedit->type) {
case OB_MESH:
@@ -319,18 +324,18 @@ static bool object_hook_index_array(Scene *scene, Object *obedit, int *tot, int
BKE_editmesh_tessface_calc(em);
/* check selected vertices first */
- if (return_editmesh_indexar(em, tot, indexar, cent_r) == 0) {
- return return_editmesh_vgroup(obedit, em, name, cent_r);
+ if (return_editmesh_indexar(em, r_tot, r_indexar, r_cent) == 0) {
+ return return_editmesh_vgroup(obedit, em, r_name, r_cent);
}
return true;
}
case OB_CURVE:
case OB_SURF:
- return return_editcurve_indexar(obedit, tot, indexar, cent_r);
+ return return_editcurve_indexar(obedit, r_tot, r_indexar, r_cent);
case OB_LATTICE:
{
Lattice *lt = obedit->data;
- return return_editlattice_indexar(lt->editlatt->latt, tot, indexar, cent_r);
+ return return_editlattice_indexar(lt->editlatt->latt, r_tot, r_indexar, r_cent);
}
default:
return false;
@@ -467,7 +472,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
if (!ok) {
BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group");
- return FALSE;
+ return false;
}
if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
@@ -526,7 +531,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
DAG_relations_tag_update(bmain);
- return TRUE;
+ return true;
}
static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
@@ -535,7 +540,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Object *obsel = NULL;
- const int use_bone = RNA_boolean_get(op->ptr, "use_bone");
+ const bool use_bone = RNA_boolean_get(op->ptr, "use_bone");
const int mode = use_bone ? OBJECT_ADDHOOK_SELOB_BONE : OBJECT_ADDHOOK_SELOB;
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
@@ -580,7 +585,7 @@ void OBJECT_OT_hook_add_selob(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "use_bone", FALSE, "Active Bone",
+ RNA_def_boolean(ot->srna, "use_bone", false, "Active Bone",
"Assign the hook to the hook objects active bone");
}
@@ -687,6 +692,7 @@ void OBJECT_OT_hook_remove(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove");
RNA_def_enum_funcs(prop, hook_mod_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -730,6 +736,7 @@ void OBJECT_OT_hook_reset(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
static int object_hook_recenter_exec(bContext *C, wmOperator *op)
@@ -779,6 +786,7 @@ void OBJECT_OT_hook_recenter(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
static int object_hook_assign_exec(bContext *C, wmOperator *op)
@@ -838,6 +846,7 @@ void OBJECT_OT_hook_assign(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
static int object_hook_select_exec(bContext *C, wmOperator *op)
@@ -880,5 +889,6 @@ void OBJECT_OT_hook_select(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove");
RNA_def_enum_funcs(prop, hook_mod_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 8b0ddbbeb9b..fd6b9a1bad0 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -254,10 +254,14 @@ void OBJECT_OT_group_remove(struct wmOperatorType *ot);
/* object_bake.c */
void OBJECT_OT_bake_image(wmOperatorType *ot);
+void OBJECT_OT_bake(wmOperatorType *ot);
/* object_lod.c */
void OBJECT_OT_lod_add(struct wmOperatorType *ot);
void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
+/* object_random.c */
+void OBJECT_OT_vertex_random(struct wmOperatorType *ot);
+
#endif /* __OBJECT_INTERN_H__ */
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index 8d12809b0c2..2af2ca3b0e9 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -867,7 +867,7 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel)
/* return 0 1 2: handlepunt */
struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL};
- data.dist = 100;
+ data.dist = ED_view3d_select_dist_px();
data.select = sel;
data.mval_fl[0] = mval[0];
data.mval_fl[1] = mval[1];
@@ -886,7 +886,7 @@ bool mouse_lattice(bContext *C, const int mval[2], bool extend, bool deselect, b
view3d_set_viewcontext(C, &vc);
lt = ((Lattice *)vc.obedit->data)->editlatt->latt;
- bp = findnearestLattvert(&vc, mval, TRUE);
+ bp = findnearestLattvert(&vc, mval, true);
if (bp) {
if (extend) {
diff --git a/source/blender/editors/object/object_lod.c b/source/blender/editors/object/object_lod.c
index fdce59b10ff..a7cc4131a96 100644
--- a/source/blender/editors/object/object_lod.c
+++ b/source/blender/editors/object/object_lod.c
@@ -33,7 +33,6 @@
#include "DNA_object_types.h"
#include "BKE_context.h"
-#include "BKE_main.h"
#include "BKE_object.h"
#include "ED_screen.h"
@@ -51,7 +50,13 @@
static int object_lod_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
+
+#ifdef WITH_GAMEENGINE
BKE_object_lod_add(ob);
+#else
+ (void)ob;
+#endif
+
return OPERATOR_FINISHED;
}
@@ -75,8 +80,13 @@ static int object_lod_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
int index = RNA_int_get(op->ptr, "index");
+#ifdef WITH_GAMEENGINE
if (!BKE_object_lod_remove(ob, index))
return OPERATOR_CANCELLED;
+#else
+ (void)ob;
+ (void)index;
+#endif
WM_event_add_notifier(C, NC_OBJECT | ND_LOD, CTX_wm_view3d(C));
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 013a6c78a15..3e33268704c 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -69,6 +69,7 @@
#include "BKE_report.h"
#include "BKE_object.h"
#include "BKE_ocean.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_softbody.h"
#include "BKE_editmesh.h"
@@ -80,7 +81,6 @@
#include "ED_armature.h"
#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_mesh.h"
#include "WM_api.h"
@@ -161,12 +161,12 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
if (ob->mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
- ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+ BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
}
}
else if (type == eModifierType_Skin) {
/* ensure skin-node customdata exists */
- modifier_skin_customdata_ensure(ob);
+ BKE_mesh_ensure_skin_customdata(ob->data);
}
}
@@ -175,8 +175,8 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
return new_md;
}
-/* Return TRUE if the object has a modifier of type 'type' other than
- * the modifier pointed to be 'exclude', otherwise returns FALSE. */
+/* Return true if the object has a modifier of type 'type' other than
+ * the modifier pointed to be 'exclude', otherwise returns false. */
static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
ModifierType type)
{
@@ -184,19 +184,19 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude,
for (md = ob->modifiers.first; md; md = md->next) {
if ((md != exclude) && (md->type == type))
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* If the object data of 'orig_ob' has other users, run 'callback' on
* each of them.
*
- * If include_orig is TRUE, the callback will run on 'orig_ob' too.
+ * If include_orig is true, the callback will run on 'orig_ob' too.
*
- * If the callback ever returns TRUE, iteration will stop and the
- * function value will be TRUE. Otherwise the function returns FALSE.
+ * If the callback ever returns true, iteration will stop and the
+ * function value will be true. Otherwise the function returns false.
*/
bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
bool (*callback)(Object *ob, void *callback_data),
@@ -220,7 +220,7 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
(ob->data == orig_ob->data))
{
if (callback(ob, callback_data))
- return TRUE;
+ return true;
totfound++;
}
@@ -230,7 +230,7 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig,
return callback(orig_ob, callback_data);
}
- return FALSE;
+ return false;
}
static bool object_has_modifier_cb(Object *ob, void *data)
@@ -254,16 +254,16 @@ bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
- return FALSE;
+ return false;
}
-/* Return TRUE if no modifier of type 'type' other than 'exclude' */
+/* Return true if no modifier of type 'type' other than 'exclude' */
static bool object_modifier_safe_to_delete(Main *bmain, Object *ob,
ModifierData *exclude,
ModifierType type)
{
return (!object_has_modifier(ob, exclude, type) &&
- !ED_object_iter_other(bmain, ob, FALSE,
+ !ED_object_iter_other(bmain, ob, false,
object_has_modifier_cb, &type));
}
@@ -678,7 +678,7 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
}
else if ((ob->mode & OB_MODE_SCULPT) &&
(find_multires_modifier_before(scene, md)) &&
- (modifier_isSameTopology(md) == FALSE))
+ (modifier_isSameTopology(md) == false))
{
BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
return 0;
@@ -834,18 +834,18 @@ static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
ModifierData *md;
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
- return TRUE;
+ return true;
}
else {
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
if (ptr.data) {
md = ptr.data;
RNA_string_set(op->ptr, "modifier", md->name);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
@@ -1134,7 +1134,7 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
multiresModifier_del_levels(mmd, ob, 1);
- ED_object_iter_other(CTX_data_main(C), ob, TRUE,
+ ED_object_iter_other(CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
@@ -1178,7 +1178,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
- ED_object_iter_other(CTX_data_main(C), ob, TRUE,
+ ED_object_iter_other(CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
@@ -1187,7 +1187,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
if (ob->mode & OB_MODE_SCULPT) {
/* ensure that grid paint mask layer is created */
- ED_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
}
return OPERATOR_FINISHED;
@@ -1431,39 +1431,6 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
/************************** skin modifier ***********************/
-void modifier_skin_customdata_ensure(Object *ob)
-{
- Mesh *me = ob->data;
- BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
- MVertSkin *vs;
-
- if (bm && !CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
- BMVert *v;
- BMIter iter;
-
- BM_data_layer_add(bm, &bm->vdata, CD_MVERT_SKIN);
-
- /* Mark an arbitrary vertex as root */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
- CD_MVERT_SKIN);
- vs->flag |= MVERT_SKIN_ROOT;
- break;
- }
- }
- else if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
- vs = CustomData_add_layer(&me->vdata,
- CD_MVERT_SKIN,
- CD_DEFAULT,
- NULL,
- me->totvert);
-
- /* Mark an arbitrary vertex as root */
- if (vs)
- vs->flag |= MVERT_SKIN_ROOT;
- }
-}
-
static void modifier_skin_customdata_delete(Object *ob)
{
Mesh *me = ob->data;
@@ -1487,7 +1454,7 @@ static int skin_edit_poll(bContext *C)
edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
}
-static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GHash *visited)
+static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GSet *visited)
{
BMEdge *bm_edge;
BMIter bm_iter;
@@ -1495,14 +1462,14 @@ static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GHash *visited)
BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
- if (!BLI_ghash_lookup(visited, v2)) {
+ if (!BLI_gset_haskey(visited, v2)) {
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
v2->head.data,
CD_MVERT_SKIN);
/* clear vertex root flag and add to visited set */
vs->flag &= ~MVERT_SKIN_ROOT;
- BLI_ghash_insert(visited, v2, v2);
+ BLI_gset_insert(visited, v2);
skin_root_clear(bm, v2, visited);
}
@@ -1516,14 +1483,14 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
BMesh *bm = em->bm;
BMVert *bm_vert;
BMIter bm_iter;
- GHash *visited;
+ GSet *visited;
- visited = BLI_ghash_ptr_new("skin_root_mark_exec visited");
+ visited = BLI_gset_ptr_new(__func__);
- modifier_skin_customdata_ensure(ob);
+ BKE_mesh_ensure_skin_customdata(ob->data);
BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
- if (!BLI_ghash_lookup(visited, bm_vert) &&
+ if (!BLI_gset_haskey(visited, bm_vert) &&
BM_elem_flag_test(bm_vert, BM_ELEM_SELECT))
{
MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
@@ -1532,14 +1499,14 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
/* mark vertex as root and add to visited set */
vs->flag |= MVERT_SKIN_ROOT;
- BLI_ghash_insert(visited, bm_vert, bm_vert);
+ BLI_gset_insert(visited, bm_vert);
/* clear root flag from all connected vertices (recursively) */
skin_root_clear(bm, bm_vert, visited);
}
}
- BLI_ghash_free(visited, NULL, NULL);
+ BLI_gset_free(visited, NULL);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -2007,7 +1974,7 @@ static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData
if (!omd || !oc) return;
- do_heightfield = TRUE;
+ do_heightfield = true;
do_chop = (omd->chop_amount > 0);
do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
@@ -2056,7 +2023,7 @@ static void oceanbake_update(void *customdata, float progress, int *cancel)
if (oceanbake_breakjob(oj))
*cancel = 1;
- *(oj->do_update) = TRUE;
+ *(oj->do_update) = true;
*(oj->progress) = progress;
}
@@ -2068,11 +2035,11 @@ static void oceanbake_startjob(void *customdata, short *stop, short *do_update,
oj->do_update = do_update;
oj->progress = progress;
- G.is_break = FALSE; /* XXX shared with render - replace with job 'stop' switch */
+ G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
- *do_update = TRUE;
+ *do_update = true;
*stop = 0;
}
@@ -2086,7 +2053,7 @@ static void oceanbake_endjob(void *customdata)
}
oj->omd->oceancache = oj->och;
- oj->omd->cached = TRUE;
+ oj->omd->cached = true;
}
static int ocean_bake_exec(bContext *C, wmOperator *op)
@@ -2153,7 +2120,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
BKE_bake_ocean(ocean, och);
omd->oceancache = och;
- omd->cached = TRUE;
+ omd->cached = true;
scene->r.cfra = cfra;
@@ -2207,7 +2174,7 @@ void OBJECT_OT_ocean_bake(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
- RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");
+ RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
}
/************************ LaplacianDeform bind operator *********************/
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 2dbadd039f4..a8f07747d3a 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -35,8 +35,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -241,11 +239,14 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_hook_recenter);
WM_operatortype_append(OBJECT_OT_bake_image);
+ WM_operatortype_append(OBJECT_OT_bake);
WM_operatortype_append(OBJECT_OT_drop_named_material);
WM_operatortype_append(OBJECT_OT_laplaciandeform_bind);
WM_operatortype_append(OBJECT_OT_lod_add);
WM_operatortype_append(OBJECT_OT_lod_remove);
+
+ WM_operatortype_append(OBJECT_OT_vertex_random);
}
void ED_operatormacros_object(void)
@@ -266,7 +267,7 @@ void ED_operatormacros_object(void)
"Duplicate selected objects and move them", OPTYPE_UNDO | OPTYPE_REGISTER);
if (ot) {
otmacro = WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
- RNA_boolean_set(otmacro->ptr, "linked", TRUE);
+ RNA_boolean_set(otmacro->ptr, "linked", true);
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
@@ -291,19 +292,19 @@ void ED_keymap_object(wmKeyConfig *keyconf)
/* Note: this keymap works disregarding mode */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "mode", OB_MODE_POSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", VKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "mode", OB_MODE_WEIGHT_PAINT);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
WM_keymap_add_item(keymap, "OBJECT_OT_origin_set", CKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
@@ -329,19 +330,19 @@ void ED_keymap_object(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_no_inverse_set", PKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
@@ -359,10 +360,10 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
/* same as above but for rendering */
WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
@@ -371,21 +372,21 @@ void ED_keymap_object(wmKeyConfig *keyconf)
/* conflicts, removing */
#if 0
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
#endif
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "use_global", FALSE);
+ RNA_boolean_set(kmi->ptr, "use_global", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "use_global", TRUE);
+ RNA_boolean_set(kmi->ptr, "use_global", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "use_global", FALSE);
+ RNA_boolean_set(kmi->ptr, "use_global", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "use_global", TRUE);
+ RNA_boolean_set(kmi->ptr, "use_global", true);
WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
@@ -443,7 +444,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
- ED_keymap_proportional_editmode(keyconf, keymap, FALSE);
+ ED_keymap_proportional_editmode(keyconf, keymap, false);
}
void ED_keymap_proportional_cycle(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
@@ -471,7 +472,7 @@ void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct
}
void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap,
- const short do_connected)
+ const bool do_connected)
{
wmKeyMapItem *kmi;
diff --git a/source/blender/editors/object/object_random.c b/source/blender/editors/object/object_random.c
new file mode 100644
index 00000000000..41b26b98047
--- /dev/null
+++ b/source/blender/editors/object/object_random.c
@@ -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) 2014 by Blender Foundation
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_random.c
+ * \ingroup edobj
+ */
+
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+#include "BLI_rand.h"
+
+
+#include "BKE_context.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_transverts.h"
+
+#include "object_intern.h"
+
+
+/**
+ * Generic randomize vertices function
+ */
+
+static bool object_rand_transverts(
+ TransVertStore *tvs,
+ const float offset, const float uniform, const float normal_factor,
+ const unsigned int seed)
+{
+ bool use_normal = (normal_factor != 0.0f);
+ struct RNG *rng;
+ TransVert *tv;
+ int a;
+
+ if (!tvs || !(tvs->transverts)) {
+ return false;
+ }
+
+ rng = BLI_rng_new(seed);
+
+ tv = tvs->transverts;
+ for (a = 0; a < tvs->transverts_tot; a++, tv++) {
+ const float t = max_ff(0.0f, uniform + ((1.0f - uniform) * BLI_rng_get_float(rng)));
+ float vec[3];
+ BLI_rng_get_float_unit_v3(rng, vec);
+
+ if (use_normal && (tv->flag & TX_VERT_USE_NORMAL)) {
+ float no[3];
+
+ /* avoid >90d rotation to align with normal */
+ if (dot_v3v3(vec, tv->normal) < 0.0f) {
+ negate_v3_v3(no, tv->normal);
+ }
+ else {
+ copy_v3_v3(no, tv->normal);
+ }
+
+ interp_v3_v3v3_slerp_safe(vec, vec, no, normal_factor);
+ }
+
+ madd_v3_v3fl(tv->loc, vec, offset * t);
+ }
+
+ BLI_rng_free(rng);
+
+ return true;
+}
+
+static int object_rand_verts_exec(bContext *C, wmOperator *op)
+{
+ const float offset = RNA_float_get(op->ptr, "offset");
+ const float uniform = RNA_float_get(op->ptr, "uniform");
+ const float normal_factor = RNA_float_get(op->ptr, "normal");
+ const unsigned int seed = RNA_int_get(op->ptr, "seed");
+
+ TransVertStore tvs = {NULL};
+ Object *obedit = CTX_data_edit_object(C);
+
+ if (obedit) {
+ int mode = TM_ALL_JOINTS;
+
+ if (normal_factor != 0.0f) {
+ mode |= TX_VERT_USE_NORMAL;
+ }
+
+ ED_transverts_create_from_obedit(&tvs, obedit, mode);
+ if (tvs.transverts_tot == 0)
+ return OPERATOR_CANCELLED;
+
+ object_rand_transverts(&tvs, offset, uniform, normal_factor, seed);
+
+ ED_transverts_update_obedit(&tvs, obedit);
+ ED_transverts_free(&tvs);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_random(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Randomize";
+ ot->description = "Randomize vertices";
+ ot->idname = "OBJECT_OT_vertex_random";
+
+ /* api callbacks */
+ ot->exec = object_rand_verts_exec;
+ ot->poll = ED_transverts_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_float(ot->srna, "offset", 0.1f, -FLT_MAX, FLT_MAX, "Amount", "Distance to offset", -10.0f, 10.0f);
+ RNA_def_float(ot->srna, "uniform", 0.0f, 0.0f, 1.0f, "Uniform",
+ "Increase for uniform offset distance", 0.0f, 1.0f);
+ RNA_def_float(ot->srna, "normal", 0.0f, 0.0f, 1.0f, "normal",
+ "Align offset direction to normals", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "seed", 0, 0, 10000, "Random Seed", "Seed for the random number generator", 0, 50);
+}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index f1a04f81979..6ff21f75733 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -44,9 +44,7 @@
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
#include "DNA_particle_types.h"
-#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
@@ -76,6 +74,7 @@
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mball.h"
@@ -423,6 +422,7 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for"); /* XXX, relies on hard coded ID at the moment */
RNA_def_enum_funcs(prop, proxy_group_object_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -449,7 +449,7 @@ static void object_remove_parent_deform_modifiers(Object *ob, const Object *par)
/* assume that we only need to remove the first instance of matching deform modifier here */
for (md = ob->modifiers.first; md; md = mdn) {
- short free = FALSE;
+ bool free = false;
mdn = md->next;
@@ -457,19 +457,19 @@ static void object_remove_parent_deform_modifiers(Object *ob, const Object *par)
if ((md->type == eModifierType_Armature) && (par->type == OB_ARMATURE)) {
ArmatureModifierData *amd = (ArmatureModifierData *)md;
if (amd->object == par) {
- free = TRUE;
+ free = true;
}
}
else if ((md->type == eModifierType_Lattice) && (par->type == OB_LATTICE)) {
LatticeModifierData *lmd = (LatticeModifierData *)md;
if (lmd->object == par) {
- free = TRUE;
+ free = true;
}
}
else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) {
CurveModifierData *cmd = (CurveModifierData *)md;
if (cmd->object == par) {
- free = TRUE;
+ free = true;
}
}
@@ -501,7 +501,7 @@ void ED_object_parent_clear(Object *ob, int type)
{
/* remove parent, and apply the parented transform result as object's local transforms */
ob->parent = NULL;
- BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE);
+ BKE_object_apply_mat4(ob, ob->obmat, true, false);
break;
}
case CLEAR_PARENT_INVERSE:
@@ -649,7 +649,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
if (keep_transform) {
/* was removed because of bug [#23577],
* but this can be handy in some cases too [#32616], so make optional */
- BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
+ BKE_object_apply_mat4(ob, ob->obmat, false, false);
}
/* set the parent (except for follow-path constraint option) */
@@ -737,19 +737,19 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
bFollowPathConstraint *data;
float cmat[4][4], vec[3];
- con = BKE_add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
+ con = BKE_constraint_add_for_object(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
data = con->data;
data->tar = par;
- BKE_get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
+ BKE_constraint_target_matrix_get(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
copy_v3_v3(ob->loc, vec);
}
else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) {
if (partype == PAR_ARMATURE_NAME)
- create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, FALSE);
+ create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, false);
else if (partype == PAR_ARMATURE_ENVELOPE)
create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror);
else if (partype == PAR_ARMATURE_AUTO) {
@@ -785,7 +785,7 @@ static void parent_set_vert_find(KDTree *tree, Object *child, int vert_par[3], b
KDTreeNearest nearest[3];
int tot;
- tot = BLI_kdtree_find_nearest_n(tree, co_find, NULL, nearest, 3);
+ tot = BLI_kdtree_find_nearest_n(tree, co_find, nearest, 3);
BLI_assert(tot == 3);
vert_par[0] = nearest[0].index;
@@ -795,7 +795,7 @@ static void parent_set_vert_find(KDTree *tree, Object *child, int vert_par[3], b
BLI_assert(min_iii(UNPACK3(vert_par)) >= 0);
}
else {
- vert_par[0] = BLI_kdtree_find_nearest(tree, co_find, NULL, NULL);
+ vert_par[0] = BLI_kdtree_find_nearest(tree, co_find, NULL);
BLI_assert(vert_par[0] >= 0);
vert_par[1] = 0;
vert_par[2] = 0;
@@ -818,7 +818,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
int tree_tot;
struct KDTree *tree = NULL;
int vert_par[3] = {0, 0, 0};
- int *vert_par_p = is_vert_par ? vert_par : NULL;
+ const int *vert_par_p = is_vert_par ? vert_par : NULL;
if (is_vert_par) {
@@ -870,7 +870,7 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
- wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_parent_set", TRUE);
+ wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_parent_set", true);
PointerRNA opptr;
#if 0
@@ -878,12 +878,12 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
#else
opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "type", PAR_OBJECT);
- RNA_boolean_set(&opptr, "keep_transform", FALSE);
+ RNA_boolean_set(&opptr, "keep_transform", false);
opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object (Keep Transform)"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT,
UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "type", PAR_OBJECT);
- RNA_boolean_set(&opptr, "keep_transform", TRUE);
+ RNA_boolean_set(&opptr, "keep_transform", true);
#endif
/* ob becomes parent, make the associated menus */
if (ob->type == OB_ARMATURE) {
@@ -959,9 +959,9 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
- RNA_def_boolean(ot->srna, "xmirror", FALSE, "X Mirror",
+ RNA_def_boolean(ot->srna, "xmirror", false, "X Mirror",
"Apply weights symmetrically along X axis, for Envelope/Automatic vertex groups creation");
- RNA_def_boolean(ot->srna, "keep_transform", FALSE, "Keep Transform",
+ RNA_def_boolean(ot->srna, "keep_transform", false, "Keep Transform",
"Apply transformation before parenting");
}
@@ -1129,11 +1129,11 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
for (con = ob->constraints.last; con; con = pcon) {
pcon = con->prev;
if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK))
- BKE_remove_constraint(&ob->constraints, con);
+ BKE_constraint_remove(&ob->constraints, con);
}
if (type == 1)
- BKE_object_apply_mat4(ob, ob->obmat, TRUE, TRUE);
+ BKE_object_apply_mat4(ob, ob->obmat, true, true);
}
CTX_DATA_END;
@@ -1185,7 +1185,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
+ con = BKE_constraint_add_for_object(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
data = con->data;
data->tar = obact;
@@ -1206,7 +1206,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ con = BKE_constraint_add_for_object(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
data = con->data;
data->tar = obact;
@@ -1228,7 +1228,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
+ con = BKE_constraint_add_for_object(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
data = con->data;
data->tar = obact;
@@ -1319,7 +1319,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
unsigned int lay, local;
- /* bool is_lamp = FALSE; */ /* UNUSED */
+ /* bool is_lamp = false; */ /* UNUSED */
lay = move_to_layer_init(C, op);
lay &= 0xFFFFFF;
@@ -1336,7 +1336,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
base->object->lay = lay;
base->object->flag &= ~SELECT;
base->flag &= ~SELECT;
- /* if (base->object->type == OB_LAMP) is_lamp = TRUE; */
+ /* if (base->object->type == OB_LAMP) is_lamp = true; */
}
CTX_DATA_END;
}
@@ -1349,7 +1349,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
local = base->lay & 0xFF000000;
base->lay = lay + local;
base->object->lay = lay;
- /* if (base->object->type == OB_LAMP) is_lamp = TRUE; */
+ /* if (base->object->type == OB_LAMP) is_lamp = true; */
}
CTX_DATA_END;
}
@@ -1548,13 +1548,13 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&ob_dst->id, 0);
break;
case MAKE_LINKS_ANIMDATA:
- BKE_copy_animdata_id((ID *)ob_dst, (ID *)ob_src, FALSE);
+ BKE_copy_animdata_id((ID *)ob_dst, (ID *)ob_src, false);
if (ob_dst->data && ob_src->data) {
if (obdata_id->lib) {
is_lib = true;
break;
}
- BKE_copy_animdata_id((ID *)ob_dst->data, (ID *)ob_src->data, FALSE);
+ BKE_copy_animdata_id((ID *)ob_dst->data, (ID *)ob_src->data, false);
}
DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
@@ -1571,7 +1571,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
BKE_group_object_add(group_node->link, ob_dst, scene, base_dst);
}
else {
- is_cycle = TRUE;
+ is_cycle = true;
}
}
break;
@@ -1661,6 +1661,7 @@ void OBJECT_OT_make_links_scene(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
RNA_def_enum_funcs(prop, RNA_scene_local_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -1718,6 +1719,17 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, int flag
/* base gets copy of object */
obn = BKE_object_copy(ob);
base->object = obn;
+
+ if (copy_groups) {
+ if (ob->flag & OB_FROMGROUP) {
+ obn->flag |= OB_FROMGROUP;
+ }
+ }
+ else {
+ /* copy already clears */
+ }
+ base->flag = obn->flag;
+
ob->id.us--;
}
}
@@ -2080,6 +2092,56 @@ enum {
MAKE_LOCAL_ALL
};
+static bool tag_localizable_looper(void *UNUSED(user_data), ID **id_pointer, int UNUSED(cd_flag))
+{
+ if (*id_pointer) {
+ (*id_pointer)->flag &= ~LIB_DOIT;
+ }
+ return true;
+}
+
+static void tag_localizable_objects(bContext *C, int mode)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *object;
+
+ BKE_main_id_tag_all(bmain, false);
+
+ /* Set LIB_DOIT flag for all selected objects, so next we can check whether
+ * object is gonna to become local or not.
+ */
+ CTX_DATA_BEGIN (C, Object *, object, selected_objects)
+ {
+ object->id.flag |= LIB_DOIT;
+
+ /* If data is also gonna to become local, mark data we're interested in
+ * as gonna-to-be-local.
+ */
+ if (mode == MAKE_LOCAL_SELECT_OBDATA && object->data) {
+ ID *data_id = (ID *) object->data;
+ data_id->flag |= LIB_DOIT;
+ }
+ }
+ CTX_DATA_END;
+
+ /* Also forbid making objects local if other library objects are using
+ * them for modifiers or constraints.
+ */
+ for (object = bmain->object.first; object; object = object->id.next) {
+ if ((object->id.flag & LIB_DOIT) == 0) {
+ BKE_library_foreach_ID_link(&object->id, tag_localizable_looper, NULL, IDWALK_READONLY);
+ }
+ if (object->data) {
+ ID *data_id = (ID *) object->data;
+ if ((data_id->flag & LIB_DOIT) == 0) {
+ BKE_library_foreach_ID_link(data_id, tag_localizable_looper, NULL, IDWALK_READONLY);
+ }
+ }
+ }
+
+ /* TODO(sergey): Drivers targets? */
+}
+
static int make_local_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -2096,10 +2158,15 @@ static int make_local_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+ tag_localizable_objects(C, mode);
BKE_main_id_clear_newpoins(bmain);
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
+ if ((ob->id.flag & LIB_DOIT) == 0) {
+ continue;
+ }
+
if (ob->id.lib)
id_make_local(&ob->id, false);
}
@@ -2116,6 +2183,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
+ if ((ob->id.flag & LIB_DOIT) == 0) {
+ continue;
+ }
+
id = ob->data;
if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
@@ -2145,6 +2216,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
+ if ((ob->id.flag & LIB_DOIT) == 0) {
+ continue;
+ }
+
if (ob->type == OB_LAMP) {
la = ob->data;
@@ -2211,24 +2286,32 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */
int flag = RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */
bool copy_groups = false;
+ bool update_deps = false;
BKE_main_id_clear_newpoins(bmain);
- if (RNA_boolean_get(op->ptr, "object"))
+ if (RNA_boolean_get(op->ptr, "object")) {
single_object_users(bmain, scene, v3d, flag, copy_groups);
- if (RNA_boolean_get(op->ptr, "obdata"))
+ /* needed since object relationships may have changed */
+ update_deps = true;
+ }
+
+ if (RNA_boolean_get(op->ptr, "obdata")) {
single_obdata_users(bmain, scene, flag);
+ }
- if (RNA_boolean_get(op->ptr, "material"))
+ if (RNA_boolean_get(op->ptr, "material")) {
single_mat_users(scene, flag, RNA_boolean_get(op->ptr, "texture"));
+ }
#if 0 /* can't do this separate from materials */
if (RNA_boolean_get(op->ptr, "texture"))
- single_mat_users(scene, flag, TRUE);
+ single_mat_users(scene, flag, true);
#endif
- if (RNA_boolean_get(op->ptr, "animation"))
+ if (RNA_boolean_get(op->ptr, "animation")) {
single_object_action_users(scene, flag);
+ }
/* TODO(sergey): This should not be needed, however some tool still could rely
* on the fact, that id->newid is kept NULL by default.
@@ -2238,6 +2321,11 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
BKE_main_id_clear_newpoins(bmain);
WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ if (update_deps) {
+ DAG_relations_tag_update(bmain);
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index a1f447fbf50..b1a78407491 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -33,8 +33,6 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_anim_types.h"
#include "DNA_group_types.h"
#include "DNA_material_types.h"
@@ -47,7 +45,6 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_rand.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -183,7 +180,7 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", object_type_items, 1, "Type", "");
}
@@ -398,7 +395,7 @@ void ED_object_select_linked_by_id(bContext *C, ID *id)
changed = object_select_all_by_obdata(C, id);
}
else if (idtype == ID_MA) {
- changed = object_select_all_by_material_texture(C, FALSE, (Material *)id, NULL);
+ changed = object_select_all_by_material_texture(C, false, (Material *)id, NULL);
}
else if (idtype == ID_LI) {
changed = object_select_all_by_library(C, (Library *) id);
@@ -447,12 +444,12 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
else if (nr == OBJECT_SELECT_LINKED_MATERIAL || nr == OBJECT_SELECT_LINKED_TEXTURE) {
Material *mat = NULL;
Tex *tex = NULL;
- int use_texture = FALSE;
+ bool use_texture = false;
mat = give_current_material(ob, ob->actcol);
if (mat == NULL) return OPERATOR_CANCELLED;
if (nr == OBJECT_SELECT_LINKED_TEXTURE) {
- use_texture = TRUE;
+ use_texture = true;
if (mat->mtex[(int)mat->texact]) tex = mat->mtex[(int)mat->texact]->tex;
if (tex == NULL) return OPERATOR_CANCELLED;
@@ -486,7 +483,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if (changed) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_FINISHED;
}
@@ -509,7 +506,7 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", "");
}
@@ -862,7 +859,7 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
else if (nr == 14) changed |= select_similar_pass_index(C, ob);
if (changed) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_FINISHED;
}
@@ -885,7 +882,7 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
}
@@ -951,7 +948,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "match", match_items, 0, "Match", "");
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20);
}
@@ -1099,7 +1096,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* undo? */
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 3df4f721f7a..5dd20a76e28 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -193,7 +193,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
float *fp1, *fp2;
float tvec[3];
- mesh_octree_table(ob, NULL, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
i2 = mesh_get_x_mirror_vert(ob, i1, use_topology);
@@ -224,7 +224,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
}
}
- mesh_octree_table(ob, NULL, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e');
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index dbb4837b009..6e59f9f4aea 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -368,14 +368,14 @@ static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob)
/* a change was made, adjust the children to compensate */
for (ob_child = bmain->object.first; ob_child; ob_child = ob_child->id.next) {
if (ob_child->parent == ob) {
- BKE_object_apply_mat4(ob_child, ob_child->obmat, TRUE, FALSE);
+ BKE_object_apply_mat4(ob_child, ob_child->obmat, true, false);
BKE_object_workob_calc_parent(scene, ob_child, &workob);
invert_m4_m4(ob_child->parentinv, workob.obmat);
}
}
}
-static int apply_objects_internal(bContext *C, ReportList *reports, int apply_loc, int apply_rot, int apply_scale)
+static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, bool apply_rot, bool apply_scale)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -442,7 +442,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
float tmat[3][3], timat[3][3];
/* simple rotation matrix */
- BKE_object_rot_to_mat3(ob, rsmat, TRUE);
+ BKE_object_rot_to_mat3(ob, rsmat, true);
/* correct for scale, note mul_m3_m3m3 has swapped args! */
BKE_object_scale_to_mat3(ob, tmat);
@@ -566,8 +566,14 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
* and is something that many users would be willing to
* sacrifice for having an easy way to do this.
*/
- float max_scale = MAX3(ob->size[0], ob->size[1], ob->size[2]);
- ob->empty_drawsize *= max_scale;
+
+ if ((apply_loc == false) &&
+ (apply_rot == false) &&
+ (apply_scale == true))
+ {
+ float max_scale = max_fff(fabsf(ob->size[0]), fabsf(ob->size[1]), fabsf(ob->size[2]));
+ ob->empty_drawsize *= max_scale;
+ }
}
else {
continue;
@@ -613,7 +619,7 @@ static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
BKE_object_where_is_calc(scene, ob);
- BKE_object_apply_mat4(ob, ob->obmat, TRUE, TRUE);
+ BKE_object_apply_mat4(ob, ob->obmat, true, true);
BKE_object_where_is_calc(scene, ob);
/* update for any children that may get moved */
@@ -647,15 +653,16 @@ void OBJECT_OT_visual_transform_apply(wmOperatorType *ot)
static int object_transform_apply_exec(bContext *C, wmOperator *op)
{
- const int loc = RNA_boolean_get(op->ptr, "location");
- const int rot = RNA_boolean_get(op->ptr, "rotation");
- const int sca = RNA_boolean_get(op->ptr, "scale");
+ const bool loc = RNA_boolean_get(op->ptr, "location");
+ const bool rot = RNA_boolean_get(op->ptr, "rotation");
+ const bool sca = RNA_boolean_get(op->ptr, "scale");
if (loc || rot || sca) {
return apply_objects_internal(C, op->reports, loc, rot, sca);
}
else {
- return OPERATOR_CANCELLED;
+ /* allow for redo */
+ return OPERATOR_FINISHED;
}
}
@@ -817,7 +824,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
float min[3], max[3];
/* only bounds support */
INIT_MINMAX(min, max);
- BKE_object_minmax_dupli(scene, ob, min, max, TRUE);
+ BKE_object_minmax_dupli(scene, ob, min, max, true);
mid_v3_v3v3(cent, min, max);
invert_m4_m4(ob->imat, ob->obmat);
mul_m4_v3(ob->imat, cent);
@@ -827,7 +834,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
ob->dup_group->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
}
}
}
@@ -848,7 +855,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
me->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
@@ -866,7 +873,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
cu->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
if (obedit) {
if (centermode == GEOMETRY_TO_ORIGIN) {
@@ -880,7 +887,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
Curve *cu = ob->data;
- if (cu->bb == NULL && (centermode != ORIGIN_TO_CURSOR)) {
+ if (ob->bb == NULL && (centermode != ORIGIN_TO_CURSOR)) {
/* do nothing*/
}
else {
@@ -888,8 +895,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* done */
}
else {
- cent[0] = 0.5f * (cu->bb->vec[4][0] + cu->bb->vec[0][0]);
- cent[1] = 0.5f * (cu->bb->vec[0][1] + cu->bb->vec[2][1]) - 0.5f; /* extra 0.5 is the height o above line */
+ /* extra 0.5 is the height o above line */
+ cent[0] = 0.5f * (ob->bb->vec[4][0] + ob->bb->vec[0][0]);
+ cent[1] = 0.5f * (ob->bb->vec[0][1] + ob->bb->vec[2][1]);
}
cent[2] = 0.0f;
@@ -899,7 +907,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
cu->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
}
}
else if (ob->type == OB_ARMATURE) {
@@ -920,7 +928,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
arm->id.flag |= LIB_DOIT;
- /* do_inverse_offset = TRUE; */ /* docenter_armature() handles this */
+ /* do_inverse_offset = true; */ /* docenter_armature() handles this */
BKE_object_where_is_calc(scene, ob);
BKE_pose_where_is(scene, ob); /* needed for bone parents */
@@ -943,7 +951,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
mb->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
if (obedit) {
if (centermode == GEOMETRY_TO_ORIGIN) {
@@ -964,7 +972,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
tot_change++;
lt->id.flag |= LIB_DOIT;
- do_inverse_offset = TRUE;
+ do_inverse_offset = true;
}
/* offset other selected objects */
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 6f2af46fa92..ccc3e2e8278 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -60,8 +60,6 @@
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_editmesh.h"
#include "BKE_report.h"
@@ -506,6 +504,9 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
int defbase_tot = BLI_countlist(&ob->defbase);
bool new_vgroup = false;
+ if (ob == ob_from)
+ return true;
+
ED_vgroup_parray_alloc(ob_from->data, &dvert_array_from, &dvert_tot_from, false);
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
@@ -514,7 +515,8 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
new_vgroup = true;
}
- if (ob == ob_from || dvert_tot == 0 || (dvert_tot != dvert_tot_from) || dvert_array_from == NULL || dvert_array == NULL) {
+ if (dvert_tot == 0 || (dvert_tot != dvert_tot_from) || dvert_array_from == NULL || dvert_array == NULL) {
+
if (dvert_array) MEM_freeN(dvert_array);
if (dvert_array_from) MEM_freeN(dvert_array_from);
@@ -522,7 +524,9 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
/* free the newly added vgroup since it wasn't compatible */
vgroup_delete_all(ob);
}
- return false;
+
+ /* if true: both are 0 and nothing needs changing, consider this a success */
+ return (dvert_tot == dvert_tot_from);
}
/* do the copy */
@@ -858,6 +862,7 @@ static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_act
else {
RNA_def_enum_funcs(prop, rna_vertex_group_select_itemf);
}
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -2167,12 +2172,12 @@ static void vgroup_invert_subset(Object *ob,
if (use_mirror && use_vert_sel) {
ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot,
vgroup_validmap, vgroup_tot);
+ }
- if (auto_remove) {
- ED_vgroup_parray_remove_zero(dvert_array, dvert_tot,
- vgroup_validmap, vgroup_tot,
- 0.0f, false);
- }
+ if (auto_remove) {
+ ED_vgroup_parray_remove_zero(dvert_array, dvert_tot,
+ vgroup_validmap, vgroup_tot,
+ 0.0f, false);
}
MEM_freeN(dvert_array);
@@ -3812,7 +3817,8 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
vgroup_operator_subset_select_props(ot, true);
- RNA_def_float(ot->srna, "limit", 0.0f, 0.0f, 1.0, "Limit", "Remove weights under this limit", 0.0f, 0.99f);
+ RNA_def_float(ot->srna, "limit", 0.0f, 0.0f, 1.0, "Limit",
+ "Remove vertices which weight is below or equal to this limit", 0.0f, 0.99f);
RNA_def_boolean(ot->srna, "keep_single", false, "Keep Single",
"Keep verts assigned to at least one group when cleaning");
}
@@ -4222,6 +4228,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "Vertex group to set as active");
RNA_def_enum_funcs(prop, vgroup_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c
index 614939effcd..8016dabf3a3 100644
--- a/source/blender/editors/object/object_warp.c
+++ b/source/blender/editors/object/object_warp.c
@@ -276,18 +276,6 @@ static int object_warp_verts_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int object_warp_verts_poll(bContext *C)
-{
- Object *obedit = CTX_data_edit_object(C);
- if (obedit) {
- if (ED_transverts_check_obedit(obedit)) {
- return true;
- }
- }
- return false;
-}
-
-
void OBJECT_OT_vertex_warp(struct wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -299,7 +287,7 @@ void OBJECT_OT_vertex_warp(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = object_warp_verts_exec;
- ot->poll = object_warp_verts_poll;
+ ot->poll = ED_transverts_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 568802dd7a0..637af5d6536 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -381,7 +381,7 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
/* Set state to baking and init surface */
canvas->error[0] = '\0';
canvas->flags |= MOD_DPAINT_BAKING;
- G.is_break = FALSE; /* reset blender_test_break*/
+ G.is_break = false; /* reset blender_test_break*/
/* Bake Dynamic Paint */
status = dynamicPaint_bakeImageSequence(C, surface, ob);
diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c
index 8a5f623c533..ef1e661c580 100644
--- a/source/blender/editors/physics/particle_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -33,7 +33,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_particle_types.h"
-#include "DNA_scene_types.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 5a172d696ca..44c95951b7d 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -48,7 +48,6 @@
#include "BLI_lasso.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
-#include "BLI_dynstr.h"
#include "BLI_kdtree.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
@@ -62,7 +61,6 @@
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_pointcache.h"
@@ -754,7 +752,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
- BLI_kdtree_insert(tree, p, co, NULL);
+ BLI_kdtree_insert(tree, p, co);
}
BLI_kdtree_balance(tree);
@@ -770,7 +768,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
mul_m4_v3(mat, co);
co[0] = -co[0];
- index= BLI_kdtree_find_nearest(tree, co, NULL, &nearest);
+ index= BLI_kdtree_find_nearest(tree, co, &nearest);
/* this needs a custom threshold still, duplicated for editmode mirror */
if (index != -1 && index != p && (nearest.dist <= 0.0002f))
@@ -920,6 +918,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
int index;
float *vec, *nor, dvec[3], dot, dist_1st=0.0f;
float hairimat[4][4], hairmat[4][4];
+ const float dist = ED_view3d_select_dist_px() * 0.01f;
if (edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0 || (edit->psys->flag & PSYS_GLOBAL_HAIR))
return;
@@ -940,10 +939,10 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
LOOP_KEYS {
if (k==0) {
dist_1st = len_v3v3((key+1)->co, key->co);
- dist_1st *= 0.75f * pset->emitterdist;
+ dist_1st *= dist * pset->emitterdist;
}
else {
- index= BLI_kdtree_find_nearest(edit->emitter_field, key->co, NULL, NULL);
+ index= BLI_kdtree_find_nearest(edit->emitter_field, key->co, NULL);
vec=edit->emitter_cosnos +index*6;
nor=vec+3;
@@ -1127,7 +1126,7 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys)
normalize_v3(nor);
- BLI_kdtree_insert(edit->emitter_field, i, vec, NULL);
+ BLI_kdtree_insert(edit->emitter_field, i, vec);
}
BLI_kdtree_balance(edit->emitter_field);
@@ -1451,7 +1450,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
PE_set_view3d_data(C, &data);
data.mval= mval;
- data.rad= 75.0f;
+ data.rad = ED_view3d_select_dist_px();
/* 1 = nearest only */
if (extend)
@@ -2463,7 +2462,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat);
copy_v3_v3(co, point->keys->co);
mul_m4_v3(mat, co);
- BLI_kdtree_insert(tree, p, co, NULL);
+ BLI_kdtree_insert(tree, p, co);
}
BLI_kdtree_balance(tree);
@@ -2474,7 +2473,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
copy_v3_v3(co, point->keys->co);
mul_m4_v3(mat, co);
- totn = BLI_kdtree_find_nearest_n(tree, co, NULL, nearest, 10);
+ totn = BLI_kdtree_find_nearest_n(tree, co, nearest, 10);
for (n=0; n<totn; n++) {
/* this needs a custom threshold still */
@@ -2795,6 +2794,11 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
newpa->num= mirrorfaces[pa->num*2];
newpa->num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, newpa->num, newpa->fuv, NULL);
+ if ((newpa->num_dmcache != DMCACHE_NOTFOUND) && psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
+ newpa->num = newpa->num_dmcache;
+ newpa->num_dmcache = DMCACHE_ISCHILD;
+ }
+
/* update edit key pointers */
key= newpoint->keys;
for (k=0, hkey=newpa->hair; k<newpa->totkey; k++, hkey++, key++) {
@@ -3030,7 +3034,7 @@ static void brush_puff(PEData *data, int point_index)
mul_m4_v3(mat, co);
mul_v3_m4v3(kco, data->ob->imat, co); /* use 'kco' as the object space version of worldspace 'co', ob->imat is set before calling */
- point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL);
+ point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL);
if (point_index == -1) return;
copy_v3_v3(co_root, co);
@@ -3114,7 +3118,7 @@ static void brush_puff(PEData *data, int point_index)
mul_m4_v3(mat, oco);
mul_v3_m4v3(kco, data->ob->imat, oco); /* use 'kco' as the object space version of worldspace 'co', ob->imat is set before calling */
- point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL);
+ point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL);
if (point_index != -1) {
copy_v3_v3(onor, &edit->emitter_cosnos[point_index*6+3]);
mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */
@@ -3345,7 +3349,7 @@ static int brush_add(PEData *data, short number)
Object *ob= data->ob;
PTCacheEdit *edit = data->edit;
ParticleSystem *psys= edit->psys;
- ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData), "ParticleData add");
+ ParticleData *add_pars;
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
ParticleSimulationData sim= {0};
ParticleEditSettings *pset= PE_settings(scene);
@@ -3358,11 +3362,17 @@ static int brush_add(PEData *data, short number)
short size2= size*size;
DerivedMesh *dm=0;
RNG *rng;
+ const int *index_mf_to_mpoly;
+ const int *index_mp_to_orig;
+ bool release_dm = false;
+
invert_m4_m4(imat, ob->obmat);
if (psys->flag & PSYS_GLOBAL_HAIR)
return 0;
+ add_pars = MEM_callocN(number * sizeof(ParticleData), "ParticleData add");
+
rng = BLI_rng_new_srandom(psys->seed+data->mval[0]+data->mval[1]);
sim.scene= scene;
@@ -3372,11 +3382,15 @@ static int brush_add(PEData *data, short number)
timestep= psys_get_timestep(&sim);
- /* painting onto the deformed mesh, could be an option? */
- if (psmd->dm->deformedOnly)
- dm= psmd->dm;
- else
- dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ if (psmd->dm->deformedOnly || psys->part->use_modifier_stack)
+ dm = psmd->dm;
+ else {
+ dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ release_dm = true;
+ }
+
+ index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
for (i=0; i<number; i++) {
if (number>1) {
@@ -3403,9 +3417,19 @@ static int brush_add(PEData *data, short number)
min_d=2.0;
/* warning, returns the derived mesh face */
- if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num, add_pars[n].fuv, 0, 0, 0, 0)) {
- add_pars[n].num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num, add_pars[n].fuv, NULL);
- n++;
+ if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
+ if (index_mf_to_mpoly && index_mp_to_orig)
+ add_pars[n].num = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, add_pars[n].num_dmcache);
+ else
+ add_pars[n].num = add_pars[n].num_dmcache;
+
+ if (psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num_dmcache, add_pars[n].fuv, NULL) != DMCACHE_NOTFOUND) {
+ if (psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
+ add_pars[n].num = add_pars[n].num_dmcache;
+ add_pars[n].num_dmcache = DMCACHE_ISCHILD;
+ }
+ n++;
+ }
}
}
if (n) {
@@ -3439,7 +3463,7 @@ static int brush_add(PEData *data, short number)
for (i=0, pa=psys->particles; i<totpart; i++, pa++) {
psys_particle_on_dm(psmd->dm, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0);
- BLI_kdtree_insert(tree, i, cur_co, NULL);
+ BLI_kdtree_insert(tree, i, cur_co);
}
BLI_kdtree_balance(tree);
@@ -3483,7 +3507,7 @@ static int brush_add(PEData *data, short number)
float maxd, totw=0.0, weight[3];
psys_particle_on_dm(psmd->dm, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0);
- maxw = BLI_kdtree_find_nearest_n(tree, co1, NULL, ptn, 3);
+ maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3);
maxd= ptn[maxw-1].dist;
@@ -3556,12 +3580,12 @@ static int brush_add(PEData *data, short number)
if (tree)
BLI_kdtree_free(tree);
}
- if (add_pars)
- MEM_freeN(add_pars);
-
- if (!psmd->dm->deformedOnly)
+
+ MEM_freeN(add_pars);
+
+ if (release_dm)
dm->release(dm);
-
+
BLI_rng_free(rng);
return n;
@@ -3870,7 +3894,7 @@ static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *e
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "pen_flip", event->shift != FALSE); // XXX hardcoded
+ RNA_boolean_set(&itemptr, "pen_flip", event->shift != false); // XXX hardcoded
/* apply */
brush_edit_apply(C, op, &itemptr);
@@ -4248,7 +4272,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
}
if (!ok) {
- BKE_object_minmax(ob, min, max, TRUE);
+ BKE_object_minmax(ob, min, max, true);
ok= 1;
}
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 8090cf4fefd..25bc2aeed07 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -623,7 +623,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
}
-static int connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
ParticleData *pa;
@@ -642,7 +642,7 @@ static int connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
float v[4][3], vec[3];
if (!psys || !psys->part || psys->part->type != PART_HAIR || !psmd->dm)
- return FALSE;
+ return false;
edit= psys->edit;
point= edit ? edit->points : NULL;
@@ -730,7 +730,7 @@ static int connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
PE_update_object(scene, ob, 0);
- return TRUE;
+ return true;
}
static int connect_hair_exec(bContext *C, wmOperator *op)
@@ -740,7 +740,7 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= NULL;
const bool all = RNA_boolean_get(op->ptr, "all");
- int any_connected = FALSE;
+ bool any_connected = false;
if (!ob)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index cab4ed6e8b5..3972ed1c49e 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -37,41 +37,27 @@
#include "MEM_guardedalloc.h"
/* types */
-#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_object_types.h"
#include "DNA_object_fluidsim.h"
#include "BLI_blenlib.h"
-#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BKE_animsys.h"
-#include "BKE_armature.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
-#include "BKE_effect.h"
#include "BKE_fluidsim.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
-#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_softbody.h"
-#include "BKE_unit.h"
-
#include "LBM_fluidsim.h"
#include "ED_screen.h"
-#include "ED_fluidsim.h"
#include "WM_types.h"
#include "WM_api.h"
@@ -84,7 +70,6 @@
#include "WM_api.h"
#include "DNA_scene_types.h"
-#include "DNA_ipo_types.h"
#include "DNA_mesh_types.h"
#include "PIL_time.h"
@@ -753,7 +738,7 @@ static void fluidbake_updatejob(void *customdata, float progress)
{
FluidBakeJob *fb= (FluidBakeJob *)customdata;
- *(fb->do_update) = TRUE;
+ *(fb->do_update) = true;
*(fb->progress) = progress;
}
@@ -765,10 +750,10 @@ static void fluidbake_startjob(void *customdata, short *stop, short *do_update,
fb->do_update = do_update;
fb->progress = progress;
- G.is_break = FALSE; /* XXX shared with render - replace with job 'stop' switch */
+ G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
elbeemSimulate();
- *do_update = TRUE;
+ *do_update = true;
*stop = 0;
}
@@ -1101,22 +1086,6 @@ static void UNUSED_FUNCTION(fluidsimFreeBake)(Object *UNUSED(ob))
#else /* WITH_MOD_FLUID */
-/* compile dummy functions for disabled fluid sim */
-
-FluidsimSettings *fluidsimSettingsNew(Object *UNUSED(srcob))
-{
- return NULL;
-}
-
-void fluidsimSettingsFree(FluidsimSettings *UNUSED(fss))
-{
-}
-
-FluidsimSettings *fluidsimSettingsCopy(FluidsimSettings *UNUSED(fss))
-{
- return NULL;
-}
-
/* only compile dummy functions */
static int fluidsimBake(bContext *UNUSED(C), ReportList *UNUSED(reports), Object *UNUSED(ob), short UNUSED(do_job))
{
@@ -1133,7 +1102,7 @@ static int fluid_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
if (WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_SIM_FLUID))
return OPERATOR_CANCELLED;
- if (!fluidsimBake(C, op->reports, CTX_data_active_object(C), TRUE))
+ if (!fluidsimBake(C, op->reports, CTX_data_active_object(C), true))
return OPERATOR_CANCELLED;
return OPERATOR_FINISHED;
@@ -1141,7 +1110,7 @@ static int fluid_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
static int fluid_bake_exec(bContext *C, wmOperator *op)
{
- if (!fluidsimBake(C, op->reports, CTX_data_active_object(C), FALSE))
+ if (!fluidsimBake(C, op->reports, CTX_data_active_object(C), false))
return OPERATOR_CANCELLED;
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index 444c87ded34..48cc51ffb55 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -121,21 +121,21 @@ static void keymap_particle(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(kmi->ptr, "release_confirm", true);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
@@ -153,7 +153,7 @@ static void keymap_particle(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "PARTICLE_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
- ED_keymap_proportional_editmode(keyconf, keymap, FALSE);
+ ED_keymap_proportional_editmode(keyconf, keymap, false);
}
/******************************* boids *************************************/
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 515ac330cc9..71e5e23b5f1 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -29,11 +29,8 @@
* \ingroup edphys
*/
-
#include <stdlib.h>
-#include "MEM_guardedalloc.h"
-
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -42,12 +39,8 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
-
#include "ED_particle.h"
@@ -61,7 +54,7 @@
static int cache_break_test(void *UNUSED(cbd))
{
- return (G.is_break == TRUE);
+ return (G.is_break == true);
}
static int ptcache_bake_all_poll(bContext *C)
{
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index 00b9940121c..dd0816e509d 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -33,21 +33,16 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
-#include "DNA_group_types.h"
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index e4426fdbbf2..7ba37bbb76b 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -642,6 +642,7 @@ void RIGIDBODY_OT_mass_calculate(wmOperatorType *ot)
"Material Preset",
"Type of material that objects are made of (determines material density)");
RNA_def_enum_funcs(prop, rigidbody_materials_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
RNA_def_float(ot->srna, "density", 1.0, FLT_MIN, FLT_MAX,
"Density",
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index b7430cb8a95..1c893992cf2 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -37,7 +37,6 @@
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#ifdef WITH_BULLET
@@ -45,13 +44,8 @@
#endif
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
-#include "BKE_group.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -60,7 +54,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_physics.h"
#include "ED_screen.h"
#include "physics_intern.h"
@@ -159,7 +152,7 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
/* sanity checks */
- if ELEM(NULL, scene, rbw) {
+ if (ELEM(NULL, scene, rbw)) {
BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to export");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index ca478232212..1857d254eb1 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -35,7 +35,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "PIL_time.h"
@@ -51,15 +50,12 @@
#include "BKE_context.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
-#include "BKE_freestyle.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_multires.h"
#include "BKE_object.h"
-#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_sequencer.h"
#include "BKE_screen.h"
@@ -101,12 +97,13 @@ static int render_break(void *rjv);
typedef struct RenderJob {
Main *main;
Scene *scene;
+ Scene *current_scene;
Render *re;
SceneRenderLayer *srl;
struct Object *camera_override;
int lay_override;
bool v3d_override;
- short anim, write_still;
+ bool anim, write_still;
Image *image;
ImageUser iuser;
bool image_outdated;
@@ -126,14 +123,19 @@ typedef struct RenderJob {
static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect)
{
Scene *scene = rj->scene;
- float *rectf = NULL;
+ const float *rectf = NULL;
int ymin, ymax, xmin, xmax;
int rymin, rxmin;
int linear_stride, linear_offset_x, linear_offset_y;
ColorManagedViewSettings *view_settings;
ColorManagedDisplaySettings *display_settings;
- if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) {
+ /* Exception for exr tiles -- display buffer conversion happens here,
+ * NOT in the color management pipeline.
+ */
+ if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID &&
+ rr->do_exr_tile == false)
+ {
/* The whole image buffer it so be color managed again anyway. */
return;
}
@@ -301,7 +303,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
re = RE_NewRender(scene->id.name);
lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0;
- G.is_break = FALSE;
+ G.is_break = false;
RE_test_break_cb(re, NULL, render_break);
ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
@@ -441,7 +443,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
RE_ReleaseResult(rj->re);
/* make jobs timer to send notifier */
- *(rj->do_update) = TRUE;
+ *(rj->do_update) = true;
}
@@ -453,7 +455,7 @@ static void render_progress_update(void *rjv, float progress)
*rj->progress = progress;
/* make jobs timer to send notifier */
- *(rj->do_update) = TRUE;
+ *(rj->do_update) = true;
}
}
@@ -475,7 +477,8 @@ static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr,
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_IMAGE) {
SpaceImage *sima = sa->spacedata.first;
- if (sima->image == rj->image) {
+ // sa->spacedata might be empty when toggling fullscreen mode.
+ if (sima != NULL && sima->image == rj->image) {
if (first_sa == NULL) {
first_sa = sa;
}
@@ -531,10 +534,13 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
/* update entire render */
rj->image_outdated = false;
BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE);
- *(rj->do_update) = TRUE;
+ *(rj->do_update) = true;
return;
}
-
+
+ if (rr == NULL)
+ return;
+
/* update part of render */
render_image_update_pass_and_layer(rj, rr, &rj->iuser);
ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
@@ -552,13 +558,20 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
{
image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect);
}
-
+
/* make jobs timer to send notifier */
- *(rj->do_update) = TRUE;
+ *(rj->do_update) = true;
}
BKE_image_release_ibuf(ima, ibuf, lock);
}
+static void current_scene_update(void *rjv, Scene *scene)
+{
+ RenderJob *rj = rjv;
+ rj->current_scene = scene;
+ rj->iuser.scene = scene;
+}
+
static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
{
RenderJob *rj = rjv;
@@ -634,7 +647,7 @@ static void render_endjob(void *rjv)
}
/* XXX render stability hack */
- G.is_rendering = FALSE;
+ G.is_rendering = false;
WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);
/* Partial render result will always update display buffer
@@ -738,7 +751,6 @@ static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
- break;
}
return OPERATOR_PASS_THROUGH;
}
@@ -806,6 +818,9 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
return OPERATOR_CANCELLED;
+ if (RE_force_single_renderlayer(scene))
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
if (!RE_is_rendering_allowed(scene, camera_override, op->reports)) {
return OPERATOR_CANCELLED;
}
@@ -861,6 +876,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj = MEM_callocN(sizeof(RenderJob), "render job");
rj->main = mainp;
rj->scene = scene;
+ rj->current_scene = rj->scene;
rj->srl = srl;
rj->camera_override = camera_override;
rj->lay_override = 0;
@@ -933,11 +949,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
RE_test_break_cb(re, rj, render_breakjob);
RE_draw_lock_cb(re, rj, render_drawlock);
RE_display_update_cb(re, rj, image_rect_update);
+ RE_current_scene_update_cb(re, rj, current_scene_update);
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
RE_progress_cb(re, rj, render_progress_update);
rj->re = re;
- G.is_break = FALSE;
+ G.is_break = false;
/* store actual owner of job, so modal operator could check for it,
* the reason of this is that active scene could change when rendering
@@ -953,7 +970,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* we set G.is_rendering here already instead of only in the job, this ensure
* main loop or other scene updates are disabled in time, since they may
* have started before the job thread */
- G.is_rendering = TRUE;
+ G.is_rendering = true;
/* add modal handler for ESC */
WM_event_add_modal_handler(C, op);
@@ -1087,7 +1104,7 @@ static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), vo
{
RenderPreview *rp = rpv;
- *(rp->do_update) = TRUE;
+ *(rp->do_update) = true;
}
static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
@@ -1102,7 +1119,7 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
make_renderinfo_string(rs, rp->scene, false, rp->engine->text);
/* make jobs timer to send notifier */
- *(rp->do_update) = TRUE;
+ *(rp->do_update) = true;
}
}
@@ -1125,7 +1142,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
//printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE);
- G.is_break = FALSE;
+ G.is_break = false;
if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth))
return;
@@ -1476,7 +1493,7 @@ Scene *ED_render_job_get_scene(const bContext *C)
RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
if (rj)
- return rj->scene;
+ return rj->current_scene;
return NULL;
}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 18ee9472992..9d4fe32d209 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -35,13 +35,11 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_dlrbTree.h"
#include "BLI_utildefines.h"
#include "BLI_jitter.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -57,7 +55,6 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "ED_image.h"
#include "RE_pipeline.h"
#include "IMB_imbuf_types.h"
@@ -67,8 +64,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "BIF_glutil.h"
-
#include "GPU_glew.h"
#include "GPU_extensions.h"
@@ -210,7 +205,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int) * 4, "accum1");
int i, j;
- BLI_jitter_init(jit_ofs[0], scene->r.osa);
+ BLI_jitter_init(jit_ofs, scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky);
@@ -245,7 +240,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
- IB_rect, OB_SOLID, FALSE, TRUE,
+ IB_rect, OB_SOLID, false, true,
(draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, err_out);
camera = scene->camera;
@@ -306,8 +301,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
IMB_color_to_bw(ibuf);
}
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
- ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, TRUE); /* no need to stamp here */
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
+ ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, true); /* no need to stamp here */
if (ok) printf("OpenGL Render written to '%s'\n", name);
else printf("OpenGL Render failed to write '%s'\n", name);
}
@@ -346,7 +342,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* ensure we have a 3d view */
if (!ED_view3d_context_activate(C)) {
- RNA_boolean_set(op->ptr, "view_context", FALSE);
+ RNA_boolean_set(op->ptr, "view_context", false);
is_view_context = false;
}
@@ -509,8 +505,8 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
ImBuf *ibuf, *ibuf_save = NULL;
void *lock;
char name[FILE_MAX];
- int ok = 0;
- const short view_context = (oglrender->v3d != NULL);
+ bool ok = false;
+ const bool view_context = (oglrender->v3d != NULL);
Object *camera = NULL;
bool is_movie;
@@ -530,7 +526,8 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
if (!is_movie) {
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
@@ -567,7 +564,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
if (ibuf) {
- int needs_free = FALSE;
+ bool needs_free = false;
ibuf_save = ibuf;
@@ -575,7 +572,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, true, true, &scene->view_settings,
&scene->display_settings, &scene->r.im_format);
- needs_free = TRUE;
+ needs_free = true;
}
/* color -> grayscale */
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 8e9c85d403b..9b81723a2f7 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -46,7 +46,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLO_readfile.h"
@@ -58,7 +57,6 @@
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
#include "DNA_space_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
#include "DNA_screen_types.h"
@@ -66,7 +64,6 @@
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
-#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -76,7 +73,6 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
#include "BKE_world.h"
@@ -99,7 +95,6 @@
#include "ED_datafiles.h"
#include "ED_render.h"
-#include "ED_view3d.h"
#include "UI_interface.h"
@@ -351,7 +346,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (base->object->id.name[2] == 'c') {
Material *shadmat = give_current_material(base->object, base->object->actcol);
if (shadmat) {
- if (mat->mode & MA_SHADBUF) shadmat->septex = 0;
+ if (mat->mode2 & MA_CASTSHADOW) shadmat->septex = 0;
else shadmat->septex |= 1;
}
}
@@ -393,8 +388,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sce->lay = 1 << mat->pr_type;
if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, TRUE);
- BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, TRUE);
+ BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true);
+ BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true);
}
}
}
@@ -457,8 +452,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, TRUE);
- BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, TRUE);
+ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
+ BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true);
}
}
else if (id_type == ID_LA) {
@@ -494,8 +489,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, TRUE);
- BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, TRUE);
+ BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true);
+ BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true);
}
}
else if (id_type == ID_WO) {
@@ -512,8 +507,8 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, TRUE);
- BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, TRUE);
+ BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true);
+ BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true);
}
}
@@ -525,7 +520,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
/* new UI convention: draw is in pixel space already. */
/* uses ROUNDBOX button in block to get the rect */
-static int ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
+static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
RenderResult rres;
@@ -533,7 +528,7 @@ static int ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, r
int offx = 0;
int newx = BLI_rcti_size_x(rect);
int newy = BLI_rcti_size_y(rect);
- int ok = 0;
+ bool ok = false;
if (!split || first) sprintf(name, "Preview %p", (void *)sa);
else sprintf(name, "SecondPreview %p", (void *)sa);
@@ -630,7 +625,7 @@ static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), volatile
{
ShaderPreview *sp = spv;
- *(sp->do_update) = TRUE;
+ *(sp->do_update) = true;
}
/* called by renderer, checks job value */
@@ -791,7 +786,7 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
else
shader_preview_render(sp, sp->id, 0, 0);
- *do_update = TRUE;
+ *do_update = true;
}
static void shader_preview_free(void *customdata)
@@ -808,9 +803,9 @@ static void shader_preview_free(void *customdata)
/* get rid of copied material */
BLI_remlink(&pr_main->mat, sp->matcopy);
- BKE_material_free_ex(sp->matcopy, FALSE);
+ BKE_material_free_ex(sp->matcopy, false);
- properties = IDP_GetProperties((ID *)sp->matcopy, FALSE);
+ properties = IDP_GetProperties((ID *)sp->matcopy, false);
if (properties) {
IDP_FreeProperty(properties);
MEM_freeN(properties);
@@ -826,7 +821,7 @@ static void shader_preview_free(void *customdata)
BLI_remlink(&pr_main->tex, sp->texcopy);
BKE_texture_free(sp->texcopy);
- properties = IDP_GetProperties((ID *)sp->texcopy, FALSE);
+ properties = IDP_GetProperties((ID *)sp->texcopy, false);
if (properties) {
IDP_FreeProperty(properties);
MEM_freeN(properties);
@@ -840,9 +835,9 @@ static void shader_preview_free(void *customdata)
/* get rid of copied world */
BLI_remlink(&pr_main->world, sp->worldcopy);
- BKE_world_free_ex(sp->worldcopy, TRUE); /* [#32865] - we need to unlink the texture copies, unlike for materials */
+ BKE_world_free_ex(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */
- properties = IDP_GetProperties((ID *)sp->worldcopy, FALSE);
+ properties = IDP_GetProperties((ID *)sp->worldcopy, false);
if (properties) {
IDP_FreeProperty(properties);
MEM_freeN(properties);
@@ -858,7 +853,7 @@ static void shader_preview_free(void *customdata)
BLI_remlink(&pr_main->lamp, sp->lampcopy);
BKE_lamp_free(sp->lampcopy);
- properties = IDP_GetProperties((ID *)sp->lampcopy, FALSE);
+ properties = IDP_GetProperties((ID *)sp->lampcopy, false);
if (properties) {
IDP_FreeProperty(properties);
MEM_freeN(properties);
@@ -960,7 +955,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
- *do_update = TRUE;
+ *do_update = true;
BKE_image_release_ibuf(ima, ibuf, NULL);
}
@@ -976,7 +971,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
- *do_update = TRUE;
+ *do_update = true;
}
else {
/* re-use shader job */
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 59fd7c03e9e..97f6b346666 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_curve_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -43,7 +42,6 @@
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -55,13 +53,11 @@
#include "BKE_font.h"
#include "BKE_freestyle.h"
#include "BKE_global.h"
-#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_material.h"
-#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
@@ -229,7 +225,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
-static int material_slot_de_select(bContext *C, int select)
+static int material_slot_de_select(bContext *C, bool select)
{
Object *ob = ED_object_context(C);
@@ -295,7 +291,7 @@ static int material_slot_de_select(bContext *C, int select)
static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
{
- return material_slot_de_select(C, 1);
+ return material_slot_de_select(C, true);
}
void OBJECT_OT_material_slot_select(wmOperatorType *ot)
@@ -314,7 +310,7 @@ void OBJECT_OT_material_slot_select(wmOperatorType *ot)
static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
- return material_slot_de_select(C, 0);
+ return material_slot_de_select(C, false);
}
void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
@@ -392,7 +388,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_node_shader_default(C, &ma->id);
- ma->use_nodes = TRUE;
+ ma->use_nodes = true;
}
}
@@ -496,7 +492,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_node_shader_default(C, &wo->id);
- wo->use_nodes = TRUE;
+ wo->use_nodes = true;
}
}
@@ -541,6 +537,7 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
BKE_scene_add_render_layer(scene, NULL);
scene->r.actlay = BLI_countlist(&scene->r.layers) - 1;
+ DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
@@ -568,6 +565,7 @@ static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
if (!BKE_scene_remove_render_layer(CTX_data_main(C), scene, rl))
return OPERATOR_CANCELLED;
+ DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
@@ -714,7 +712,7 @@ static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
- BKE_freestyle_lineset_add(&srl->freestyleConfig);
+ BKE_freestyle_lineset_add(&srl->freestyleConfig, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
@@ -741,7 +739,7 @@ static int freestyle_active_lineset_poll(bContext *C)
SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
if (!srl) {
- return FALSE;
+ return false;
}
return BKE_freestyle_lineset_get_active(&srl->freestyleConfig) != NULL;
@@ -1577,6 +1575,9 @@ static void copy_mtex_copybuf(ID *id)
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
}
if (mtex && *mtex) {
@@ -1610,6 +1611,9 @@ static void paste_mtex_copybuf(ID *id)
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
default:
BLI_assert("invalid id type");
return;
@@ -1676,7 +1680,8 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
Lamp *la = CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data;
World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
-
+ FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
+
if (ma)
id = &ma->id;
else if (la)
@@ -1685,6 +1690,8 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
id = &wo->id;
else if (psys)
id = &psys->part->id;
+ else if (linestyle)
+ id = &linestyle->id;
if (id == NULL)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 5f74bf6576a..94d8d78de1a 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -29,8 +29,6 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
@@ -47,17 +45,12 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
-#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_paint.h"
-#include "BKE_scene.h"
-#include "BKE_texture.h"
-#include "BKE_world.h"
#include "GPU_material.h"
#include "GPU_buffers.h"
@@ -81,7 +74,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
bContext *C;
wmWindowManager *wm;
wmWindow *win;
- static int recursive_check = FALSE;
+ static bool recursive_check = false;
/* don't do this render engine update if we're updating the scene from
* other threads doing e.g. rendering or baking jobs */
@@ -92,7 +85,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
if (recursive_check)
return;
- recursive_check = TRUE;
+ recursive_check = true;
C = CTX_create();
CTX_data_main_set(C, bmain);
@@ -140,7 +133,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
CTX_free(C);
- recursive_check = FALSE;
+ recursive_check = false;
}
void ED_render_engine_area_exit(ScrArea *sa)
@@ -275,7 +268,7 @@ static void material_changed(Main *bmain, Material *ma)
Material *parent;
Object *ob;
Scene *scene;
- int texture_draw = FALSE;
+ int texture_draw = false;
/* icons */
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -302,7 +295,7 @@ static void material_changed(Main *bmain, Material *ma)
/* find if we have a scene with textured display */
for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->customdata_mask & CD_MASK_MTFACE) {
- texture_draw = TRUE;
+ texture_draw = true;
break;
}
}
@@ -351,11 +344,11 @@ static void lamp_changed(Main *bmain, Lamp *la)
static int material_uses_texture(Material *ma, Tex *tex)
{
if (mtex_use_tex(ma->mtex, MAX_MTEX, tex))
- return TRUE;
+ return true;
else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex))
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static void texture_changed(Main *bmain, Tex *tex)
@@ -366,7 +359,7 @@ static void texture_changed(Main *bmain, Tex *tex)
Scene *scene;
Object *ob;
bNode *node;
- int texture_draw = FALSE;
+ bool texture_draw = false;
/* icons */
BKE_icon_changed(BKE_icon_getid(&tex->id));
@@ -424,7 +417,7 @@ static void texture_changed(Main *bmain, Tex *tex)
}
if (scene->customdata_mask & CD_MASK_MTFACE)
- texture_draw = TRUE;
+ texture_draw = true;
}
/* find textured objects */
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index c1cd17465cf..0beb5737ec7 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -29,21 +29,14 @@
#include <string.h>
#include <stddef.h>
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_node.h"
-#include "BKE_report.h"
#include "BKE_screen.h"
#include "WM_api.h"
@@ -167,11 +160,12 @@ ScrArea *render_view_open(bContext *C, int mx, int my)
sa = CTX_wm_area(C);
}
else if (scene->r.displaymode == R_OUTPUT_SCREEN) {
- if (CTX_wm_area(C) && CTX_wm_area(C)->spacetype == SPACE_IMAGE)
- area_was_image = 1;
+ sa = CTX_wm_area(C);
+ if (sa && sa->spacetype == SPACE_IMAGE)
+ area_was_image = true;
/* this function returns with changed context */
- sa = ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
+ sa = ED_screen_full_newspace(C, sa, SPACE_IMAGE);
}
if (!sa) {
@@ -239,8 +233,8 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
SpaceImage *sima = sa->spacedata.first;
/* test if we have a temp screen in front */
- if (CTX_wm_window(C)->screen->temp) {
- wm_window_lower(CTX_wm_window(C));
+ if (win->screen->temp) {
+ wm_window_lower(win);
return OPERATOR_FINISHED;
}
/* determine if render already shows */
@@ -305,7 +299,7 @@ static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), const wm
/* determine if render already shows */
if (sa) {
/* but don't close it when rendering */
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == false) {
SpaceImage *sima = sa->spacedata.first;
if (sima->flag & SI_PREVSPACE) {
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index d6b3b733e95..3b9393e8856 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -39,7 +39,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
#include "BLI_linklist_stack.h"
#include "BLF_translation.h"
@@ -58,8 +57,6 @@
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
-#include "ED_types.h"
-#include "ED_fileselect.h"
#include "GPU_blender_aspect.h"
#include "GPU_colors.h"
@@ -154,7 +151,7 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa)
if (sa->type && sa->type->refresh) {
sa->type->refresh(C, sa);
}
- sa->do_refresh = FALSE;
+ sa->do_refresh = false;
}
/**
@@ -436,7 +433,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
-
+
/* if no partial draw rect set, full rect */
if (ar->drawrct.xmin == ar->drawrct.xmax) {
ar->drawrct = ar->winrct;
@@ -554,7 +551,7 @@ void ED_area_tag_redraw_regiontype(ScrArea *sa, int regiontype)
void ED_area_tag_refresh(ScrArea *sa)
{
if (sa)
- sa->do_refresh = TRUE;
+ sa->do_refresh = true;
}
/* *************************************************************** */
@@ -587,7 +584,7 @@ void ED_area_headerprint(ScrArea *sa, const char *str)
/* ************************************************************ */
-static void area_azone_initialize(bScreen *screen, ScrArea *sa)
+static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa)
{
AZone *az;
@@ -598,15 +595,23 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
return;
}
- /* set area action zones */
- az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
- BLI_addtail(&(sa->actionzones), az);
- az->type = AZONE_AREA;
- az->x1 = sa->totrct.xmin;
- az->y1 = sa->totrct.ymin;
- az->x2 = sa->totrct.xmin + (AZONESPOT - 1);
- az->y2 = sa->totrct.ymin + (AZONESPOT - 1);
- BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
+ /* can't click on bottom corners on OS X, already used for resizing */
+#ifdef __APPLE__
+ if (!(sa->totrct.xmin == 0 && sa->totrct.ymin == 0) || WM_window_is_fullscreen(win))
+#else
+ (void)win;
+#endif
+ {
+ /* set area action zones */
+ az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+ BLI_addtail(&(sa->actionzones), az);
+ az->type = AZONE_AREA;
+ az->x1 = sa->totrct.xmin;
+ az->y1 = sa->totrct.ymin;
+ az->x2 = sa->totrct.xmin + (AZONESPOT - 1);
+ az->y2 = sa->totrct.ymin + (AZONESPOT - 1);
+ BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
+ }
az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
@@ -1302,7 +1307,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win));
/* clear all azones, add the area triange widgets */
- area_azone_initialize(win->screen, sa);
+ area_azone_initialize(win, win->screen, sa);
/* region rect sizes */
rect = sa->totrct;
@@ -1332,6 +1337,27 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
}
}
+static void region_update_rect(ARegion *ar)
+{
+ ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
+ ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+
+ /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
+ BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+}
+
+/**
+ * Call to move a popup window (keep OpenGL context free!)
+ */
+void ED_region_update_rect(bContext *C, ARegion *ar)
+{
+ wmWindow *win = CTX_wm_window(C);
+
+ wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
+
+ region_update_rect(ar);
+}
+
/* externally called for floating regions like menus */
void ED_region_init(bContext *C, ARegion *ar)
{
@@ -1340,11 +1366,7 @@ void ED_region_init(bContext *C, ARegion *ar)
/* refresh can be called before window opened */
region_subwindow(CTX_wm_window(C), ar);
- ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
- ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
-
- /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
- BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+ region_update_rect(ar);
/* UI convention */
wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
@@ -1352,7 +1374,7 @@ void ED_region_init(bContext *C, ARegion *ar)
}
/* for quick toggle, can skip fades */
-void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade)
+void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
{
ScrArea *sa = CTX_wm_area(C);
@@ -1377,55 +1399,54 @@ void ED_region_toggle_hidden(bContext *C, ARegion *ar)
region_toggle_hidden(C, ar, 1);
}
-/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
-/* area vertices were set */
-void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
+/**
+ * we swap spaces for fullscreen to keep all allocated data area vertices were set
+ */
+void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free)
{
SpaceType *st;
ARegion *ar;
- int spacetype = sa1->spacetype;
+ const char spacetype = sa_dst->spacetype;
- sa1->headertype = sa2->headertype;
- sa1->spacetype = sa2->spacetype;
- sa1->type = sa2->type;
- sa1->butspacetype = sa2->butspacetype;
-
- if (swap_space == 1) {
- SWAP(ListBase, sa1->spacedata, sa2->spacedata);
- /* exception: ensure preview is reset */
-// if (sa1->spacetype == SPACE_VIEW3D)
-// XXX BIF_view3d_previewrender_free(sa1->spacedata.first);
- }
- else if (swap_space == 2) {
- BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
- }
- else {
- BKE_spacedata_freelist(&sa1->spacedata);
- BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
+ sa_dst->headertype = sa_src->headertype;
+ sa_dst->spacetype = sa_src->spacetype;
+ sa_dst->type = sa_src->type;
+ sa_dst->butspacetype = sa_src->butspacetype;
+
+ /* area */
+ if (do_free) {
+ BKE_spacedata_freelist(&sa_dst->spacedata);
}
-
+ BKE_spacedata_copylist(&sa_dst->spacedata, &sa_src->spacedata);
+
/* Note; SPACE_EMPTY is possible on new screens */
-
+
/* regions */
- if (swap_space == 1) {
- SWAP(ListBase, sa1->regionbase, sa2->regionbase);
+ if (do_free) {
+ st = BKE_spacetype_from_id(spacetype);
+ for (ar = sa_dst->regionbase.first; ar; ar = ar->next)
+ BKE_area_region_free(st, ar);
+ BLI_freelistN(&sa_dst->regionbase);
}
- else {
- if (swap_space < 2) {
- st = BKE_spacetype_from_id(spacetype);
- for (ar = sa1->regionbase.first; ar; ar = ar->next)
- BKE_area_region_free(st, ar);
- BLI_freelistN(&sa1->regionbase);
- }
-
- st = BKE_spacetype_from_id(sa2->spacetype);
- for (ar = sa2->regionbase.first; ar; ar = ar->next) {
- ARegion *newar = BKE_area_region_copy(st, ar);
- BLI_addtail(&sa1->regionbase, newar);
- }
+ st = BKE_spacetype_from_id(sa_src->spacetype);
+ for (ar = sa_src->regionbase.first; ar; ar = ar->next) {
+ ARegion *newar = BKE_area_region_copy(st, ar);
+ BLI_addtail(&sa_dst->regionbase, newar);
}
}
+void ED_area_data_swap(ScrArea *sa_dst, ScrArea *sa_src)
+{
+ sa_dst->headertype = sa_src->headertype;
+ sa_dst->spacetype = sa_src->spacetype;
+ sa_dst->type = sa_src->type;
+ sa_dst->butspacetype = sa_src->butspacetype;
+
+
+ SWAP(ListBase, sa_dst->spacedata, sa_src->spacedata);
+ SWAP(ListBase, sa_dst->regionbase, sa_src->regionbase);
+}
+
/* *********** Space switching code *********** */
void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
@@ -1435,9 +1456,9 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
ED_area_exit(C, sa1);
ED_area_exit(C, sa2);
- area_copy_data(tmp, sa1, 2);
- area_copy_data(sa1, sa2, 0);
- area_copy_data(sa2, tmp, 0);
+ ED_area_data_copy(tmp, sa1, false);
+ ED_area_data_copy(sa1, sa2, true);
+ ED_area_data_copy(sa2, tmp, true);
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1);
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2);
@@ -1555,7 +1576,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr);
- uiDefButR(block, MENU, 0, NULL, xco, yco, 1.5 * U.widget_unit, U.widget_unit,
+ uiDefButR(block, MENU, 0, "", xco, yco, 1.5 * U.widget_unit, U.widget_unit,
&areaptr, "type", 0, 0.0f, 0.0f, 0.0f, 0.0f, "");
return xco + 1.7 * U.widget_unit;
@@ -1928,8 +1949,8 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
/* the image is located inside (0, 0), (1, 1) as set by view2d */
UI_ThemeColorShade(TH_BACK, 20);
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
- UI_view2d_to_region_no_clip(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
+ UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
gpuSingleFilledRectf(x1, y1, x2, y2);
/* gridsize adapted to zoom level */
@@ -2012,3 +2033,49 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect)
BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
}
+/* Cache display helpers */
+
+void ED_region_cache_draw_background(const ARegion *ar)
+{
+ glColor4ub(128, 128, 255, 64);
+ glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
+}
+
+void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y)
+{
+ uiStyle *style = UI_GetStyle();
+ int fontid = style->widget.uifont_id;
+ char numstr[32];
+ float font_dims[2] = {0.0f, 0.0f};
+
+ /* frame number */
+ BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
+ BLI_snprintf(numstr, sizeof(numstr), "%d", framenr);
+
+ BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
+
+ glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
+
+ UI_ThemeColor(TH_TEXT);
+ BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
+ BLF_draw(fontid, numstr, sizeof(numstr));
+}
+
+void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra)
+{
+ if (num_segments) {
+ int a;
+
+ glColor4ub(128, 128, 255, 128);
+
+ for (a = 0; a < num_segments; a++) {
+ float x1, x2;
+
+ x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
+ x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
+
+ glRecti(x1, 0, x2, 8 * UI_DPI_FAC);
+ }
+ }
+}
+
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 5c8b7c8d24a..4faf5e64662 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -32,9 +32,6 @@
/* extern */
-#include "BKE_blender.h"
-#include "BKE_global.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BLI_rect.h"
@@ -57,16 +54,6 @@
#include "GPU_primitives.h"
#include "GPU_raster.h"
#include "GPU_state_latch.h"
-const GLubyte stipple_checker_8px[128] = {
- 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
- 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
- 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
- 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
- 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
- 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
- 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
- 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
-
#include "MEM_guardedalloc.h"
@@ -99,6 +86,8 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2)
GPU_raster_end();
}
+/* UNUSED */
+#if 0
/*
* x1,y2
* | \
@@ -131,6 +120,7 @@ void sdrawtrifill(short x1, short y1, short x2, short y2)
sdrawtripoints(x1, y1, x2, y2);
gpuEnd();
}
+#endif
/* ******************************************** */
@@ -155,6 +145,8 @@ void set_inverted_drawing(int enable)
GL_TOGGLE(GL_DITHER, !enable);
}
+/* UNUSED */
+#if 0
void sdrawXORline(int x0, int y0, int x1, int y1)
{
if (x0 == x1 && y0 == y1) return;
@@ -222,6 +214,8 @@ void fdrawXORellipse(float xofs, float yofs, float hw, float hh)
set_inverted_drawing(0);
}
+#endif
+
void fdrawXORcirc(float xofs, float yofs, float rad)
{
set_inverted_drawing(1);
@@ -245,7 +239,7 @@ float glaGetOneFloat(int param)
// XXX jwilkins: it seems like this probably doesn't work like it is supposed to
-static int get_cached_work_texture(int *w_r, int *h_r)
+static int get_cached_work_texture(int *r_w, int *r_h)
{
static GLint texid = -1;
int tex_w = 1024;//GPU_max_texture_size();//256;
@@ -269,8 +263,8 @@ static int get_cached_work_texture(int *w_r, int *h_r)
//gpuBindTexture(GL_TEXTURE_2D, ltexid); /* restore default */
}
- *w_r = tex_w;
- *h_r = tex_h;
+ *r_w = tex_w;
+ *r_h = tex_h;
return texid;
}
@@ -638,10 +632,10 @@ gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect)
/**
* Translate the (\a wo_x, \a wo_y) point from world coordinates into screen space.
*/
-void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *sc_x_r, int *sc_y_r)
+void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x, int *r_sc_y)
{
- *sc_x_r = (wo_x - di->world_rect.xmin) * di->wo_to_sc[0];
- *sc_y_r = (wo_y - di->world_rect.ymin) * di->wo_to_sc[1];
+ *r_sc_x = (wo_x - di->world_rect.xmin) * di->wo_to_sc[0];
+ *r_sc_y = (wo_y - di->world_rect.ymin) * di->wo_to_sc[1];
}
/**
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index a516603cfd4..7c8987ae778 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -49,7 +49,6 @@
#include "RNA_access.h"
-#include "ED_object.h"
#include "ED_armature.h"
#include "WM_api.h"
@@ -357,7 +356,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "sequences")) {
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -368,7 +367,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
else if (CTX_data_equals(member, "selected_sequences")) {
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -381,7 +380,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
else if (CTX_data_equals(member, "selected_editable_sequences")) {
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 0e4c197b97c..8db22813107 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -60,11 +60,9 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_image.h"
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
-#include "ED_fileselect.h"
#include "ED_clip.h"
#include "ED_render.h"
@@ -417,7 +415,7 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
sa->v4 = sv2;
}
- area_copy_data(newa, sa, 0);
+ ED_area_data_copy(newa, sa, true);
}
else {
@@ -449,7 +447,7 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
sa->v2 = sv2;
}
- area_copy_data(newa, sa, 0);
+ ED_area_data_copy(newa, sa, true);
}
/* remove double vertices en edges */
@@ -473,7 +471,7 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
sc = BKE_libblock_alloc(G.main, ID_SCR, name);
sc->scene = scene;
- sc->do_refresh = TRUE;
+ sc->do_refresh = true;
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
sc->winid = win->winid;
@@ -530,7 +528,7 @@ static void screen_copy(bScreen *to, bScreen *from)
BLI_listbase_clear(&sa->actionzones);
BLI_listbase_clear(&sa->handlers);
- area_copy_data(sa, saf, 0);
+ ED_area_data_copy(sa, saf, true);
}
/* put at zero (needed?) */
@@ -1112,18 +1110,18 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note)
switch (note->category) {
case NC_WM:
if (note->data == ND_FILEREAD)
- win->screen->do_draw = TRUE;
+ win->screen->do_draw = true;
break;
case NC_WINDOW:
- win->screen->do_draw = TRUE;
+ win->screen->do_draw = true;
break;
case NC_SCREEN:
if (note->action == NA_EDITED)
- win->screen->do_draw = win->screen->do_refresh = TRUE;
+ win->screen->do_draw = win->screen->do_refresh = true;
break;
case NC_SCENE:
if (note->data == ND_MODE)
- region_cursor_set(win, note->swinid, TRUE);
+ region_cursor_set(win, note->swinid, true);
break;
}
}
@@ -1205,7 +1203,7 @@ void ED_screen_draw(wmWindow *win)
glDisable(GL_BLEND);
}
- win->screen->do_draw = FALSE;
+ win->screen->do_draw = false;
}
/* helper call for below, dpi changes headers */
@@ -1260,7 +1258,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
if (G.debug & G_DEBUG_EVENTS) {
printf("%s: set screen\n", __func__);
}
- win->screen->do_refresh = FALSE;
+ win->screen->do_refresh = false;
win->screen->context = ed_screen_context;
}
@@ -1435,11 +1433,11 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
if (oldswin != scr->subwinactive) {
for (sa = scr->areabase.first; sa; sa = sa->next) {
- int do_draw = FALSE;
+ bool do_draw = false;
for (ar = sa->regionbase.first; ar; ar = ar->next)
if (ar->swinid == oldswin || ar->swinid == scr->subwinactive)
- do_draw = TRUE;
+ do_draw = true;
if (do_draw) {
for (ar = sa->regionbase.first; ar; ar = ar->next)
@@ -1456,7 +1454,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
else {
/* notifier invokes freeing the buttons... causing a bit too much redraws */
if (oldswin != scr->subwinactive) {
- region_cursor_set(win, scr->subwinactive, TRUE);
+ region_cursor_set(win, scr->subwinactive, true);
/* this used to be a notifier, but needs to be done immediate
* because it can undo setting the right button as active due
@@ -1464,7 +1462,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
uiFreeActiveButtons(C, win->screen);
}
else
- region_cursor_set(win, scr->subwinactive, FALSE);
+ region_cursor_set(win, scr->subwinactive, false);
}
}
}
@@ -1534,12 +1532,24 @@ void ED_screen_set(bContext *C, bScreen *sc)
/* we put timer to sleep, so screen_exit has to think there's no timer */
oldscreen->animtimer = NULL;
- if (wt)
+ if (wt) {
WM_event_timer_sleep(wm, win, wt, true);
-
+ }
+
ED_screen_exit(C, win, oldscreen);
- oldscreen->animtimer = wt;
-
+
+ /* Same scene, "transfer" playback to new screen. */
+ if (wt) {
+ if (oldscene == sc->scene) {
+ sc->animtimer = wt;
+ }
+ /* Else, stop playback. */
+ else {
+ oldscreen->animtimer = wt;
+ ED_screen_animation_play(C, 0, 0);
+ }
+ }
+
win->screen = sc;
CTX_wm_window_set(C, win); // stores C->wm.screen... hrmf
@@ -1571,7 +1581,7 @@ void ED_screen_set(bContext *C, bScreen *sc)
* have different layers visible in 3D viewpots. This is possible
* because of view3d.lock_camera_and_layers option.
*/
- DAG_on_visible_update(bmain, FALSE);
+ DAG_on_visible_update(bmain, false);
}
}
@@ -1705,7 +1715,7 @@ void ED_screen_set_scene(bContext *C, bScreen *screen, Scene *scene)
CTX_data_scene_set(C, scene);
BKE_scene_set_background(bmain, scene);
- DAG_on_visible_update(bmain, FALSE);
+ DAG_on_visible_update(bmain, false);
ED_render_engine_changed(bmain);
ED_update_for_newframe(bmain, scene, 1);
@@ -1848,7 +1858,7 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa)
return NULL;
}
- area_copy_data(old, sa, 1); /* 1 = swap spacelist */
+ ED_area_data_swap(old, sa);
if (sa->flag & AREA_TEMP_INFO) sa->flag &= ~AREA_TEMP_INFO;
old->full = NULL;
@@ -1895,7 +1905,7 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa)
/* copy area */
newa = newa->prev;
- area_copy_data(newa, sa, 1); /* 1 = swap spacelist */
+ ED_area_data_swap(newa, sa);
sa->flag |= AREA_TEMP_INFO;
sa->full = oldscreen;
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 8a76c52d985..9e0421b6e99 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -38,8 +38,9 @@ struct Scene;
#define AZONESPOT (0.6f * U.widget_unit)
/* area.c */
-void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space);
-void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade);
+void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free);
+void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2);
+void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade);
/* screen_edit.c */
ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 799db37a51e..8b6a1b22a5c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -45,7 +45,6 @@
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_mask_types.h"
#include "DNA_node_types.h"
#include "DNA_userdef_types.h"
@@ -54,8 +53,6 @@
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -193,10 +190,10 @@ int ED_operator_view3d_active(bContext *C)
int ED_operator_region_view3d_active(bContext *C)
{
if (CTX_wm_region_view3d(C))
- return TRUE;
+ return true;
CTX_wm_operator_poll_msg_set(C, "expected a view3d region");
- return FALSE;
+ return false;
}
/* generic for any view2d which uses anim_ops */
@@ -205,7 +202,7 @@ int ED_operator_animview_active(bContext *C)
if (ED_operator_areaactive(C)) {
SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C);
if (sl && (ELEM5(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_IPO, SPACE_TIME)))
- return TRUE;
+ return true;
}
CTX_wm_operator_poll_msg_set(C, "expected a timeline/animation area to be active");
@@ -281,6 +278,11 @@ int ED_operator_sequencer_active(bContext *C)
return ed_spacetype_test(C, SPACE_SEQ);
}
+int ED_operator_sequencer_active_editable(bContext *C)
+{
+ return ed_spacetype_test(C, SPACE_SEQ) && ED_operator_scene_editable(C);
+}
+
int ED_operator_image_active(bContext *C)
{
return ed_spacetype_test(C, SPACE_IMAGE);
@@ -448,10 +450,10 @@ int ED_operator_uvmap(bContext *C)
}
if (em && (em->bm->totface)) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
int ED_operator_editsurfcurve(bContext *C)
@@ -547,7 +549,7 @@ int ED_operator_mask(bContext *C)
}
}
- return FALSE;
+ return false;
}
/* *************************** action zone operator ************************** */
@@ -657,7 +659,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
event.type = EVT_ACTIONZONE_REGION;
event.val = 0;
event.customdata = op->customdata;
- event.customdatafree = TRUE;
+ event.customdatafree = true;
op->customdata = NULL;
wm_event_add(win, &event);
@@ -733,7 +735,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* gesture is large enough? */
if (is_gesture) {
/* second area, for join when (sa1 != sa2) */
- sad->sa2 = screen_areahascursor(CTX_wm_screen(C), event->x, event->y);
+ sad->sa2 = screen_areahascursor(sc, event->x, event->y);
/* apply sends event */
actionzone_apply(C, op, sad->az->type);
actionzone_exit(op);
@@ -771,7 +773,8 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
ot->poll = actionzone_area_poll;
ot->cancel = actionzone_cancel;
- ot->flag = OPTYPE_BLOCKING;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2);
}
@@ -933,7 +936,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
newwin->screen = newsc;
/* copy area to new screen */
- area_copy_data((ScrArea *)newsc->areabase.first, sa, 0);
+ ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true);
ED_area_tag_redraw((ScrArea *)newsc->areabase.first);
@@ -1246,7 +1249,8 @@ static void SCREEN_OT_area_move(wmOperatorType *ot)
ot->modal = area_move_modal;
ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
- ot->flag = OPTYPE_BLOCKING;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* rna */
RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
@@ -1618,7 +1622,7 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- CTX_wm_window(C)->screen->do_draw = TRUE;
+ CTX_wm_window(C)->screen->do_draw = true;
}
@@ -1698,7 +1702,9 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
ot->cancel = area_split_cancel;
ot->poll = screen_active_editable;
- ot->flag = OPTYPE_BLOCKING;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* rna */
RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", "");
@@ -1968,7 +1974,8 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
ot->poll = ED_operator_areaactive;
- ot->flag = OPTYPE_BLOCKING;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
}
@@ -1989,7 +1996,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
sound_seek_scene(bmain, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
return OPERATOR_FINISHED;
}
@@ -2085,6 +2092,12 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* init binarytree-list for getting keyframes */
BLI_dlrbTree_init(&keys);
+ /* seed up dummy dopesheet context with flags to perform necessary filtering */
+ if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
+ /* only selected channels are included */
+ ads.filterflag |= ADS_FILTER_ONLYSEL;
+ }
+
/* populate tree with keyframe nodes */
scene_to_keylist(&ads, scene, &keys, NULL);
@@ -2113,20 +2126,20 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
if (CFRA != (int)ak->cfra) {
/* this changes the frame, so set the frame and we're done */
CFRA = (int)ak->cfra;
- done = TRUE;
+ done = true;
}
else {
/* make this the new starting point for the search */
cfra = ak->cfra;
}
}
- } while ((ak != NULL) && (done == FALSE));
+ } while ((ak != NULL) && (done == false));
/* free temp stuff */
BLI_dlrbTree_free(&keys);
/* any success? */
- if (done == FALSE) {
+ if (done == false) {
BKE_report(op->reports, RPT_INFO, "No more keyframes to jump to in this direction");
return OPERATOR_CANCELLED;
@@ -2152,7 +2165,7 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "next", TRUE, "Next Keyframe", "");
+ RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", "");
}
/* ************** jump to marker operator ***************************** */
@@ -2212,7 +2225,7 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "next", TRUE, "Next Marker", "");
+ RNA_def_boolean(ot->srna, "next", true, "Next Marker", "");
}
/* ************** switch screen operator ***************************** */
@@ -2282,7 +2295,7 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot)
ot->exec = screen_set_exec;
ot->poll = ED_operator_screenactive;
-
+
/* rna */
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
@@ -2606,6 +2619,7 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
ot->poll = screen_active_editable;
ot->cancel = area_join_cancel;
+ /* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* rna */
@@ -2668,6 +2682,9 @@ static void SCREEN_OT_area_options(wmOperatorType *ot)
ot->invoke = screen_area_options_invoke;
ot->poll = ED_operator_screen_mainwinactive;
+
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
}
@@ -2834,6 +2851,10 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar,
{
RegionView3D *rv3d = ar->regiondata;
+ if (persp == RV3D_CAMOB) {
+ ED_view3d_lastview_store(rv3d);
+ }
+
rv3d->viewlock = viewlock;
rv3d->view = view;
rv3d->persp = persp;
@@ -2851,9 +2872,11 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
/* some rules... */
- if (ar->regiontype != RGN_TYPE_WINDOW)
+ if (ar->regiontype != RGN_TYPE_WINDOW) {
BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted");
+ }
else if (ar->alignment == RGN_ALIGN_QSPLIT) {
+ /* Exit quad-view */
ScrArea *sa = CTX_wm_area(C);
ARegion *arn;
@@ -2861,10 +2884,33 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ar->alignment = 0;
if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar_iter;
RegionView3D *rv3d = ar->regiondata;
- rv3d->viewlock_quad = rv3d->viewlock | RV3D_VIEWLOCK_INIT;
+
+ /* if this is a locked view, use settings from 'User' view */
+ if (rv3d->viewlock) {
+ View3D *v3d_user;
+ ARegion *ar_user;
+
+ if (ED_view3d_context_user_region(C, &v3d_user, &ar_user)) {
+ if (ar != ar_user) {
+ SWAP(void *, ar->regiondata, ar_user->regiondata);
+ rv3d = ar->regiondata;
+ }
+ }
+ }
+
+ rv3d->viewlock_quad = RV3D_VIEWLOCK_INIT;
rv3d->viewlock = 0;
rv3d->rflag &= ~RV3D_CLIPPING;
+
+ /* accumulate locks, incase they're mixed */
+ for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) {
+ if (ar_iter->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d_iter = ar_iter->regiondata;
+ rv3d->viewlock_quad |= rv3d_iter->viewlock;
+ }
+ }
}
for (ar = sa->regionbase.first; ar; ar = arn) {
@@ -2879,9 +2925,11 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
}
- else if (ar->next)
+ else if (ar->next) {
BKE_report(op->reports, RPT_ERROR, "Only last region can be 4-splitted");
+ }
else {
+ /* Enter quad-view */
ScrArea *sa = CTX_wm_area(C);
ARegion *newar;
int count;
@@ -2911,9 +2959,13 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
region_quadview_init_rv3d(sa, ar, viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO);
region_quadview_init_rv3d(sa, (ar = ar->next), viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO);
region_quadview_init_rv3d(sa, (ar = ar->next), viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO);
- if (v3d->camera) region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_CAMERA, RV3D_CAMOB);
- else region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_PERSPORTHO, RV3D_PERSP);
-
+ /* forcing camera is distracting */
+#if 0
+ if (v3d->camera) region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_CAMERA, RV3D_CAMOB);
+ else region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_USER, RV3D_PERSP);
+#else
+ (void)v3d;
+#endif
}
ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
@@ -3038,7 +3090,7 @@ static int header_toggle_menus_exec(bContext *C, wmOperator *UNUSED(op))
sa->flag = sa->flag ^ HEADER_NO_PULLDOWN;
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -3220,7 +3272,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
else sync = (scene->flag & SCE_FRAME_DROP);
if ((scene->audio.flag & AUDIO_SYNC) &&
- (sad->flag & ANIMPLAY_FLAG_REVERSE) == FALSE &&
+ (sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
finite(time = sound_sync_scene(scene)))
{
scene->r.cfra = (double)time * FPS + 0.5;
@@ -3455,7 +3507,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
ot->poll = ED_operator_screenactive;
- RNA_def_boolean(ot->srna, "restore_frame", TRUE, "Restore Frame", "Restore the frame when animation was initialized");
+ RNA_def_boolean(ot->srna, "restore_frame", true, "Restore Frame", "Restore the frame when animation was initialized");
}
/* ************** border select operator (template) ***************************** */
@@ -3645,7 +3697,7 @@ static int scene_new_exec(bContext *C, wmOperator *op)
else { /* different kinds of copying */
newscene = BKE_scene_copy(scene, type);
- /* these can't be handled in blenkernel curently, so do them here */
+ /* these can't be handled in blenkernel currently, so do them here */
if (type == SCE_COPY_LINK_DATA) {
ED_object_single_users(bmain, newscene, false, true);
}
@@ -3855,7 +3907,7 @@ static void SCREEN_OT_region_blend(wmOperatorType *ot)
ot->invoke = region_blend_invoke;
/* flags */
- ot->flag = 0;
+ ot->flag = OPTYPE_INTERNAL;
/* properties */
}
@@ -4034,10 +4086,10 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* render */
kmi = WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "use_viewport", TRUE);
+ RNA_boolean_set(kmi->ptr, "use_viewport", true);
kmi = WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "animation", TRUE);
- RNA_boolean_set(kmi->ptr, "use_viewport", TRUE);
+ RNA_boolean_set(kmi->ptr, "animation", true);
+ RNA_boolean_set(kmi->ptr, "use_viewport", true);
WM_keymap_add_item(keymap, "RENDER_OT_view_cancel", ESCKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_view_show", F11KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_play_rendered_anim", F11KEY, KM_PRESS, KM_CTRL, 0);
@@ -4061,27 +4113,27 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELUPMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", -1);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", FALSE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", false);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", TRUE);
+ RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", FALSE);
+ RNA_boolean_set(kmi->ptr, "next", false);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIALAST, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", TRUE);
+ RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", FALSE);
+ RNA_boolean_set(kmi->ptr, "next", false);
/* play (forward and backwards) */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0)->ptr, "reverse", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0)->ptr, "reverse", true);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", ESCKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", MEDIAPLAY, KM_PRESS, 0, 0);
@@ -4091,11 +4143,11 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
#if 0 /* XXX: disabled for restoring later... bad implementation */
keymap = WM_keymap_find(keyconf, "Frames", 0, 0);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "cycle_speed", TRUE);
+ RNA_boolean_set(kmi->ptr, "cycle_speed", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "reverse", TRUE);
- RNA_boolean_set(kmi->ptr, "cycle_speed", TRUE);
+ RNA_boolean_set(kmi->ptr, "reverse", true);
+ RNA_boolean_set(kmi->ptr, "cycle_speed", true);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY, KM_PRESS, KM_ALT, 0);
#endif
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 84891bda21e..592efd83dbf 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -146,11 +146,11 @@ static int screenshot_data_create(bContext *C, wmOperator *op)
op->customdata = scd;
- return TRUE;
+ return true;
}
else {
op->customdata = NULL;
- return FALSE;
+ return false;
}
}
@@ -265,7 +265,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr);
- uiTemplateImageSettings(layout, &ptr, FALSE);
+ uiTemplateImageSettings(layout, &ptr, false);
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
@@ -309,8 +309,8 @@ typedef struct ScreenshotJob {
wmWindowManager *wm;
unsigned int *dumprect;
int x, y, dumpsx, dumpsy;
- short *stop;
- short *do_update;
+ const short *stop;
+ const short *do_update;
ReportList reports;
} ScreenshotJob;
@@ -364,7 +364,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
sj->stop = stop;
sj->do_update = do_update;
- *do_update = TRUE; /* wait for opengl rect */
+ *do_update = true; /* wait for opengl rect */
while (*stop == 0) {
@@ -386,7 +386,8 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
char name[FILE_MAX];
int ok;
- BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, &rd.im_format, rd.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra,
+ &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true);
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
@@ -408,7 +409,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
MEM_freeN(sj->dumprect);
sj->dumprect = NULL;
- *do_update = TRUE;
+ *do_update = true;
rd.cfra++;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index edc7fe8fb32..d1f7afd7b89 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -46,6 +46,7 @@
#include "BKE_image.h"
#include "BKE_paint.h"
#include "BKE_colortools.h"
+#include "BKE_node.h"
#include "BLI_math.h"
#include "BLI_rect.h"
@@ -71,6 +72,12 @@
#include "WM_api.h"
+#include "IMB_imbuf_types.h"
+
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
/* TODOs:
*
@@ -166,6 +173,8 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (refresh) {
struct ImagePool *pool = NULL;
+ bool convert_to_linear = false;
+ struct ColorSpace *colorspace;
/* stencil is rotated later */
const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
-mtex->rot : 0;
@@ -209,11 +218,32 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
pool = BKE_image_pool_new();
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
+
#pragma omp parallel for schedule(static)
for (j = 0; j < size; j++) {
int i;
float y;
float len;
+ int thread_num;
+
+#ifdef _OPENMP
+ thread_num = omp_get_thread_num();
+#else
+ thread_num = 0;
+#endif
+
+ if (mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
+ ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
+ /* For consistency, sampling always returns color in linear space */
+ if (tex_ibuf && tex_ibuf->rect_float == NULL) {
+ convert_to_linear = true;
+ colorspace = tex_ibuf->rect_colorspace;
+ }
+ BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
+ }
+
for (i = 0; i < size; i++) {
@@ -250,16 +280,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
y = len * sinf(angle);
}
- x *= mtex->size[0];
- y *= mtex->size[1];
-
- x += mtex->ofs[0];
- y += mtex->ofs[1];
-
if (col) {
float rgba[4];
- paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
+ paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_num, convert_to_linear, colorspace);
buffer[index * 4] = rgba[0] * 255;
buffer[index * 4 + 1] = rgba[1] * 255;
@@ -267,7 +291,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
buffer[index * 4 + 3] = rgba[3] * 255;
}
else {
- float avg = paint_get_tex_pixel(mtex, x, y, pool);
+ float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_num);
avg += br->texture_sample_bias;
@@ -290,6 +314,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
}
}
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
+
if (pool)
BKE_image_pool_free(pool);
@@ -608,7 +635,7 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
/* scale based on tablet pressure */
if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) {
gpuTranslate(0.5f, 0.5f, 0);
- gpuScale(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
+ gpuScale(1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value, 1);
gpuTranslate(-0.5f, -0.5f, 0);
}
@@ -746,7 +773,7 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
gpuPushMatrix();
gpuLoadIdentity();
gpuTranslate(center[0], center[1], 0);
- gpuScale(ups->pressure_value, ups->pressure_value, 1);
+ gpuScale(ups->size_pressure_value, ups->size_pressure_value, 1);
gpuTranslate(-center[0], -center[1], 0);
}
@@ -852,7 +879,7 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewCon
/* scale 3D brush radius by pressure */
if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush))
- unprojected_radius *= ups->pressure_value;
+ unprojected_radius *= ups->size_pressure_value;
/* set cached value in either Brush or UnifiedPaintSettings */
BKE_brush_unprojected_radius_set(vc->scene, brush, unprojected_radius);
@@ -950,7 +977,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* draw an inner brush */
if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
/* inner at full alpha */
- gpuSingleCircle(translation[0], translation[1], final_radius * ups->pressure_value, 40);
+ gpuSingleCircle(translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
/* outer at half alpha */
gpuColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f);
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 6542bb2ca9b..3d860145f59 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -35,7 +35,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_bitmap.h"
-#include "BLI_listbase.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
@@ -98,7 +97,7 @@ static void partialvis_update_mesh(Object *ob,
{
Mesh *me = ob->data;
MVert *mvert;
- float *paint_mask;
+ const float *paint_mask;
int *vert_indices;
int totvert, i;
bool any_changed = false, any_visible = false;
@@ -253,6 +252,20 @@ static void partialvis_update_bmesh_verts(BMesh *bm,
}
}
+static void partialvis_update_bmesh_faces(GSet *faces, PartialVisAction action)
+{
+ GSetIterator gs_iter;
+
+ GSET_ITER (gs_iter, faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
+
+ if ((action == PARTIALVIS_HIDE) && paint_is_bmesh_face_hidden(f))
+ BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
+ else
+ BM_elem_flag_disable(f, BM_ELEM_HIDDEN);
+ }
+}
+
static void partialvis_update_bmesh(Object *ob,
PBVH *pbvh,
PBVHNode *node,
@@ -261,12 +274,13 @@ static void partialvis_update_bmesh(Object *ob,
float planes[4][4])
{
BMesh *bm;
- GSet *unique, *other;
+ GSet *unique, *other, *faces;
bool any_changed = false, any_visible = false;
bm = BKE_pbvh_get_bmesh(pbvh);
unique = BKE_pbvh_bmesh_node_unique_verts(node);
other = BKE_pbvh_bmesh_node_other_verts(node);
+ faces = BKE_pbvh_bmesh_node_faces(node);
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@@ -286,6 +300,9 @@ static void partialvis_update_bmesh(Object *ob,
&any_changed,
&any_visible);
+ /* finally loop over node faces and tag the ones that are fully hidden */
+ partialvis_update_bmesh_faces(faces, action);
+
if (any_changed) {
BKE_pbvh_node_mark_rebuild_draw(node);
BKE_pbvh_node_fully_hidden_set(node, !any_visible);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 82215855f94..b0c9f94bee9 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -43,9 +43,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_linklist.h"
-#include "BLI_memarena.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "PIL_time.h"
@@ -58,22 +55,14 @@
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_idprop.h"
#include "BKE_brush.h"
#include "BKE_image.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_colortools.h"
#include "BKE_editmesh.h"
@@ -82,17 +71,13 @@
#include "GPU_matrix.h"
#include "GPU_raster.h"
-#include "BIF_glutil.h"
-
#include "UI_view2d.h"
#include "ED_image.h"
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
-#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "ED_mesh.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -691,7 +676,7 @@ void PAINT_OT_image_paint(wmOperatorType *ot)
ot->cancel = paint_stroke_cancel;
/* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_BLOCKING;
RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
"Paint Stroke Mode",
@@ -723,78 +708,6 @@ int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
/************************ cursor drawing *******************************/
-void brush_drawcursor_texpaint_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
-{
-#define PX_SIZE_FADE_MAX 12.0f
-#define PX_SIZE_FADE_MIN 4.0f
-
- Scene *scene = CTX_data_scene(C);
- //Brush *brush = image_paint_brush(C);
- Paint *paint = BKE_paint_get_active_from_context(C);
- Brush *brush = BKE_paint_brush(paint);
-
- if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
- float zoomx, zoomy;
- const float size = (float)BKE_brush_size_get(scene, brush);
- short use_zoom;
- float pixel_size;
- float alpha = 0.5f;
-
- use_zoom = get_imapaint_zoom(C, &zoomx, &zoomy);
-
- if (use_zoom) {
- pixel_size = size * max_ff(zoomx, zoomy);
- }
- else {
- pixel_size = size;
- }
-
- /* fade out the brush (cheap trick to work around brush interfering with sampling [#])*/
- if (pixel_size < PX_SIZE_FADE_MIN) {
- return;
- }
- else if (pixel_size < PX_SIZE_FADE_MAX) {
- alpha *= (pixel_size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
- }
-
- gpuPushMatrix();
-
- gpuTranslate((float)x, (float)y, 0.0f);
-
- /* No need to scale for uv sculpting, on the contrary it might be useful to keep un-scaled */
- if (use_zoom)
- gpuScale(zoomx, zoomy, 1.0f);
-
- gpuColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
-
- GPU_raster_begin();
-
- GPU_aspect_enable(GPU_ASPECT_RASTER, GPU_RASTER_AA);
-
- glEnable(GL_BLEND);
- {
- UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- /* hrmf, duplicate paint_draw_cursor logic here */
- if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
- /* inner at full alpha */
- gpuSingleCircle(0, 0, size * ups->pressure_value, 40);
- /* outer at half alpha */
- gpuColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha * 0.5f);
- }
- }
- gpuSingleCircle(0, 0, size, 40);
- glDisable(GL_BLEND);
-
- GPU_aspect_disable(GPU_ASPECT_RASTER, GPU_RASTER_AA);
-
- GPU_raster_end();
-
- gpuPopMatrix();
- }
-#undef PX_SIZE_FADE_MAX
-#undef PX_SIZE_FADE_MIN
-}
-
static void toggle_paint_cursor(bContext *C, int enable)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -820,13 +733,13 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
wmWindow *win;
ScrArea *sa;
ImagePaintSettings *imapaint = &settings->imapaint;
- int enabled = FALSE;
+ bool enabled = false;
for (win = wm->windows.first; win; win = win->next)
for (sa = win->screen->areabase.first; sa; sa = sa->next)
if (sa->spacetype == SPACE_IMAGE)
if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT)
- enabled = TRUE;
+ enabled = true;
if (enabled) {
BKE_paint_init(&imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
@@ -972,6 +885,7 @@ static int sample_color_exec(bContext *C, wmOperator *op)
static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Paint *paint = BKE_paint_get_active_from_context(C);
+ Brush *brush = BKE_paint_brush(paint);
SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data");
ARegion *ar = CTX_wm_region(C);
wmWindow *win = CTX_wm_window(C);
@@ -987,8 +901,10 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event
RNA_int_set_array(op->ptr, "location", event->mval);
paint_sample_color(C, ar, event->mval[0], event->mval[1]);
+ WM_cursor_modal_set(win, BC_EYEDROPPER_CURSOR);
WM_event_add_modal_handler(C, op);
+ WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
return OPERATOR_RUNNING_MODAL;
}
@@ -1004,6 +920,7 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
paint->flags |= PAINT_SHOW_BRUSH;
}
+ WM_cursor_modal_restore(CTX_wm_window(C));
MEM_freeN(data);
return OPERATOR_FINISHED;
}
@@ -1140,16 +1057,16 @@ int image_texture_paint_poll(bContext *C)
int facemask_paint_poll(bContext *C)
{
- return paint_facesel_test(CTX_data_active_object(C));
+ return BKE_paint_select_face_test(CTX_data_active_object(C));
}
int vert_paint_poll(bContext *C)
{
- return paint_vertsel_test(CTX_data_active_object(C));
+ return BKE_paint_select_vert_test(CTX_data_active_object(C));
}
int mask_paint_poll(bContext *C)
{
- return paint_facesel_test(CTX_data_active_object(C)) || paint_vertsel_test(CTX_data_active_object(C));
+ return BKE_paint_select_elem_test(CTX_data_active_object(C));
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 19f2673d96a..667b487d4b1 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -39,11 +39,9 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_rect.h"
#include "BKE_context.h"
#include "BKE_brush.h"
-#include "BKE_main.h"
#include "BKE_image.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -126,8 +124,8 @@ typedef struct ImagePaintState {
Image *image;
ImBuf *canvas;
ImBuf *clonecanvas;
- char *warnpackedfile;
- char *warnmultifile;
+ const char *warnpackedfile;
+ const char *warnmultifile;
bool do_masking;
@@ -233,6 +231,9 @@ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
Scene *scene = painter->scene;
Brush *brush = painter->brush;
+ const char *display_device = scene->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
+
rctf tex_mapping = painter->tex_mapping;
rctf mask_mapping = painter->mask_mapping;
struct ImagePool *pool = painter->pool;
@@ -258,8 +259,9 @@ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
copy_v3_v3(brush_rgb, brush->rgb);
- if (use_color_correction)
- srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
+ if (use_color_correction) {
+ IMB_colormanagement_display_to_scene_linear_v3(brush_rgb, display);
+ }
}
else {
brush_rgb[0] = 1.0f;
@@ -278,7 +280,7 @@ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
- linearrgb_to_srgb_v3_v3(rgba, rgba);
+ IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
}
mul_v3_v3(rgba, brush_rgb);
}
@@ -326,6 +328,9 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
Scene *scene = painter->scene;
Brush *brush = painter->brush;
+ const char *display_device = scene->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
+
rctf tex_mapping = painter->tex_mapping;
rctf mask_mapping = painter->mask_mapping;
struct ImagePool *pool = painter->pool;
@@ -348,8 +353,9 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
copy_v3_v3(brush_rgb, brush->rgb);
- if (use_color_correction)
- srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
+ if (use_color_correction) {
+ IMB_colormanagement_display_to_scene_linear_v3(brush_rgb, display);
+ }
}
else {
brush_rgb[0] = 1.0f;
@@ -369,7 +375,7 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
- linearrgb_to_srgb_v3_v3(rgba, rgba);
+ IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
}
mul_v3_v3(rgba, brush_rgb);
}
@@ -391,7 +397,7 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
/* read from old texture buffer */
if (use_texture_old) {
- float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
+ const float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
copy_v4_v4(rgba, otf);
}
@@ -485,8 +491,8 @@ static void brush_painter_imbuf_partial_update(BrushPainter *painter, const floa
w = h = 0;
}
- x1 = destx;
- y1 = desty;
+ x1 = min_ii(destx, ibuf->x);
+ y1 = min_ii(desty, ibuf->y);
x2 = min_ii(destx + w, ibuf->x);
y2 = min_ii(desty + h, ibuf->y);
@@ -521,8 +527,8 @@ static void brush_painter_2d_tex_mapping(ImagePaintState *s, int size, const flo
if (mapmode == MTEX_MAP_MODE_STENCIL) {
/* map from view coordinates of brush to region coordinates */
- UI_view2d_to_region_no_clip(s->v2d, ipos[0] * invw, ipos[1] * invh, &xmin, &ymin);
- UI_view2d_to_region_no_clip(s->v2d, (ipos[0] + size) * invw, (ipos[1] + size) * invh, &xmax, &ymax);
+ UI_view2d_view_to_region(s->v2d, ipos[0] * invw, ipos[1] * invh, &xmin, &ymin);
+ UI_view2d_view_to_region(s->v2d, (ipos[0] + size) * invw, (ipos[1] + size) * invh, &xmax, &ymax);
/* output mapping from brush ibuf x/y to region coordinates */
mapping->xmin = xmin;
@@ -663,7 +669,7 @@ static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const bool is_torus
}
if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
+ const float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
copy_v4_v4(r_rgb, rrgbf);
}
else {
@@ -859,7 +865,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *maskb, const f
ImagePaintRegion region[4];
short torus = s->brush->flag & BRUSH_TORUS;
short blend = s->blend;
- float *offset = s->brush->clone.offset;
+ const float *offset = s->brush->clone.offset;
float liftpos[2];
float brush_alpha = BKE_brush_alpha_get(s->scene, s->brush);
unsigned short mask_max = (unsigned short)(brush_alpha * 65535.0f);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index f00153fee66..7941d6088a7 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -60,33 +60,23 @@
#include "BKE_camera.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_idprop.h"
#include "BKE_brush.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_colortools.h"
-
-#include "BKE_editmesh.h"
-
-#include "BIF_glutil.h"
#include "UI_view2d.h"
-#include "ED_image.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "ED_mesh.h"
#include "GPU_extensions.h"
@@ -367,27 +357,6 @@ static int project_bucket_offset_safe(const ProjPaintState *ps, const float proj
}
}
-/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
-static void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
-{
- float wtot_inv, wtot;
-
- w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
- w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
- w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
- wtot = w[0] + w[1] + w[2];
-
- if (wtot != 0.0f) {
- wtot_inv = 1.0f / wtot;
-
- w[0] = w[0] * wtot_inv;
- w[1] = w[1] * wtot_inv;
- w[2] = w[2] * wtot_inv;
- }
- else /* dummy values for zero area face */
- w[0] = w[1] = w[2] = 1.0f / 3.0f;
-}
-
static float VecZDepthOrtho(const float pt[2],
const float v1[3], const float v2[3], const float v3[3],
float w[3])
@@ -436,7 +405,7 @@ static int project_paint_PickFace(const ProjPaintState *ps, const float pt[2], f
{
LinkNode *node;
float w_tmp[3];
- float *v1, *v2, *v3, *v4;
+ const float *v1, *v2, *v3, *v4;
int bucket_index;
int face_index;
int best_side = -1;
@@ -573,7 +542,7 @@ static bool project_paint_PickColor(const ProjPaintState *ps, const float pt[2],
if (rgba) {
if (ibuf->rect_float) {
- float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
+ const float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
premul_float_to_straight_uchar(rgba, rgba_tmp_fp);
}
else {
@@ -653,7 +622,7 @@ static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
- if (!ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (!ED_view3d_clipping_test(ps->rv3d, wco, true)) {
return 1;
}
@@ -890,21 +859,16 @@ static bool check_seam(const ProjPaintState *ps,
/* We need to know the order of the verts in the adjacent face
* set the i1_fidx and i2_fidx to (0,1,2,3) */
- if (mf->v1 == i1) i1_fidx = 0;
- else if (mf->v2 == i1) i1_fidx = 1;
- else if (mf->v3 == i1) i1_fidx = 2;
- else if (mf->v4 && mf->v4 == i1) i1_fidx = 3;
-
- if (mf->v1 == i2) i2_fidx = 0;
- else if (mf->v2 == i2) i2_fidx = 1;
- else if (mf->v3 == i2) i2_fidx = 2;
- else if (mf->v4 && mf->v4 == i2) i2_fidx = 3;
+ i1_fidx = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, i1);
+ i2_fidx = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, i2);
/* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
if (i2_fidx != -1) {
Image *tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
Image *orig_tpage = project_paint_face_image(ps, ps->dm_mtface, orig_face);
+ BLI_assert(i1_fidx != -1);
+
/* This IS an adjacent face!, now lets check if the UVs are ok */
tf = ps->dm_mtface + face_index;
@@ -980,19 +944,16 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
normalize_v2(dir3);
}
- /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
- * This is incorrect. Its already given radians but without it wont work.
- * need to look into a fix - campbell */
if (is_quad) {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
- a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI / 180.0f));
+ a1 = shell_v2v2_mid_normalized_to_dist(dir4, dir1);
+ a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2);
+ a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3);
+ a4 = shell_v2v2_mid_normalized_to_dist(dir3, dir4);
}
else {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
+ a1 = shell_v2v2_mid_normalized_to_dist(dir3, dir1);
+ a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2);
+ a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3);
}
if (is_quad) {
@@ -1074,9 +1035,9 @@ static void project_face_seams_init(const ProjPaintState *ps, const int face_ind
*
* This is used for finding a pixels location in screenspace for painting */
static void screen_px_from_ortho(
- float uv[2],
- float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
+ const float uv[2],
+ const float v1co[3], const float v2co[3], const float v3co[3], /* Screenspace coords */
+ const float uv1co[2], const float uv2co[2], const float uv3co[2],
float pixelScreenCo[4],
float w[3])
{
@@ -1084,47 +1045,12 @@ static void screen_px_from_ortho(
interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
}
-/* same as screen_px_from_ortho except we need to take into account
- * the perspective W coord for each vert */
+/* same as screen_px_from_ortho except we
+ * do perspective correction on the pixel coordinate */
static void screen_px_from_persp(
- float uv[2],
- float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
- float pixelScreenCo[4],
- float w[3])
-{
-
- float wtot_inv, wtot;
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
-
- /* re-weight from the 4th coord of each screen vert */
- w[0] *= v1co[3];
- w[1] *= v2co[3];
- w[2] *= v3co[3];
-
- wtot = w[0] + w[1] + w[2];
-
- if (wtot > 0.0f) {
- wtot_inv = 1.0f / wtot;
- w[0] *= wtot_inv;
- w[1] *= wtot_inv;
- w[2] *= wtot_inv;
- }
- else {
- w[0] = w[1] = w[2] = 1.0f / 3.0f; /* dummy values for zero area face */
- }
- /* done re-weighting */
-
- interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
-}
-
-
-/* same as screen_px_from_persp except we return ortho weights back to the caller.
- * These weights will be used to determine correct interpolation of uvs in cloned uv layer */
-static void screen_px_from_persp_ortho_weights(
- float uv[2],
- float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
+ const float uv[2],
+ const float v1co[4], const float v2co[4], const float v3co[4], /* screenspace coords */
+ const float uv1co[2], const float uv2co[2], const float uv3co[2],
float pixelScreenCo[4],
float w[3])
{
@@ -1159,7 +1085,7 @@ static void screen_px_from_persp_ortho_weights(
static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
int side, unsigned char rgba_ub[4], float rgba_f[4])
{
- float *uvCo1, *uvCo2, *uvCo3;
+ const float *uvCo1, *uvCo2, *uvCo3;
float uv_other[2], x, y;
uvCo1 = (float *)tf_other->uv[0];
@@ -1239,7 +1165,7 @@ static float project_paint_uvpixel_mask(
MFace *mf = &ps->dm_mface[face_index];
float no[3], angle;
if (mf->flag & ME_SMOOTH) {
- short *no1, *no2, *no3;
+ const short *no1, *no2, *no3;
no1 = ps->dm_mvert[mf->v1].no;
if (side == 1) {
no2 = ps->dm_mvert[mf->v3].no;
@@ -1283,7 +1209,7 @@ static float project_paint_uvpixel_mask(
else {
/* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
float viewDirPersp[3];
- float *co1, *co2, *co3;
+ const float *co1, *co2, *co3;
co1 = ps->dm_mvert[mf->v1].co;
if (side == 1) {
co2 = ps->dm_mvert[mf->v3].co;
@@ -1664,7 +1590,7 @@ static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset
}
#endif //PROJ_DEBUG_NOSEAMBLEED
-static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2)
+static float len_squared_v2v2_alt(const float v1[2], const float v2_1, const float v2_2)
{
float x, y;
@@ -1732,8 +1658,8 @@ static bool project_bucket_isect_circle(const float cent[2], const float radius_
static void rect_to_uvspace_ortho(
rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
+ const float *v1coSS, const float *v2coSS, const float *v3coSS,
+ const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[4][2],
const int flip)
{
@@ -1765,8 +1691,8 @@ static void rect_to_uvspace_ortho(
/* same as above but use barycentric_weights_v2_persp */
static void rect_to_uvspace_persp(
rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
+ const float *v1coSS, const float *v2coSS, const float *v3coSS,
+ const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[4][2],
const int flip
)
@@ -1842,7 +1768,7 @@ static void project_bucket_clip_face(
const bool is_ortho,
rctf *bucket_bounds,
float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
+ const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[8][2],
int *tot)
{
@@ -2014,9 +1940,9 @@ static void project_bucket_clip_face(
return;
}
- doubles = TRUE;
- while (doubles == TRUE) {
- doubles = FALSE;
+ doubles = true;
+ while (doubles == true) {
+ doubles = false;
for (i = 1; i < (*tot); i++) {
if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE &&
fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE)
@@ -2026,7 +1952,7 @@ static void project_bucket_clip_face(
isectVCosSS[j - 1][0] = isectVCosSS[j][0];
isectVCosSS[j - 1][1] = isectVCosSS[j][1];
}
- doubles = TRUE; /* keep looking for more doubles */
+ doubles = true; /* keep looking for more doubles */
(*tot)--;
}
}
@@ -2204,7 +2130,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float uv_clip[8][2];
int uv_clip_tot;
const bool is_ortho = ps->is_ortho;
- const bool is_clone_other = ((ps->brush->imagepaint_tool == PAINT_TOOL_CLONE) && ps->dm_mtface_clone);
const bool do_backfacecull = ps->do_backfacecull;
const bool do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
@@ -2305,20 +2230,19 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
* could check the poly direction but better to do this */
- if ((do_backfacecull == TRUE && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
- (do_backfacecull == FALSE && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
+ if ((do_backfacecull == true && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
+ (do_backfacecull == false && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
{
has_x_isect = has_isect = 1;
if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
- else if (is_clone_other) screen_px_from_persp_ortho_weights(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
/* a pity we need to get the worldspace pixel location here */
if (do_clip || do_3d_mapping) {
interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2326,7 +2250,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* Is this UV visible from the view? - raytrace */
/* project_paint_PickFace is less complex, use for testing */
//if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
- if ((ps->do_occlude == FALSE) ||
+ if ((ps->do_occlude == false) ||
!project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
{
mask = project_paint_uvpixel_mask(ps, face_index, side, w);
@@ -2504,7 +2428,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
}
- if ((ps->do_occlude == FALSE) ||
+ if ((ps->do_occlude == false) ||
!project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
{
/* Only bother calculating the weights if we intersect */
@@ -2544,7 +2468,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2673,7 +2597,7 @@ static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int buck
/* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
rctf bucket_bounds;
float p1[2], p2[2], p3[2], p4[2];
- float *v, *v1, *v2, *v3, *v4 = NULL;
+ const float *v, *v1, *v2, *v3, *v4 = NULL;
int fidx;
project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
@@ -2839,20 +2763,20 @@ static void project_paint_begin(ProjPaintState *ps)
if (ps->source == PROJ_SRC_IMAGE_CAM) {
/* using render mesh, assume only camera was rendered from */
ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = TRUE;
+ ps->dm_release = true;
}
else if (ps->ob->derivedFinal &&
CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
(ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
{
ps->dm = ps->ob->derivedFinal;
- ps->dm_release = FALSE;
+ ps->dm_release = false;
}
else {
ps->dm = mesh_get_derived_final(
ps->scene, ps->ob,
ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
- ps->dm_release = TRUE;
+ ps->dm_release = true;
}
if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE) ) {
@@ -2897,7 +2821,7 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
if (ps->dm_mtface_clone == NULL || ps->dm_mtface_clone == ps->dm_mtface) {
- ps->do_layer_clone = FALSE;
+ ps->do_layer_clone = false;
ps->dm_mtface_clone = NULL;
}
}
@@ -2909,7 +2833,7 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
if (ps->dm_mtface_stencil == NULL || ps->dm_mtface_stencil == ps->dm_mtface) {
- ps->do_layer_stencil = FALSE;
+ ps->do_layer_stencil = false;
ps->dm_mtface_stencil = NULL;
}
}
@@ -2961,7 +2885,7 @@ static void project_paint_begin(ProjPaintState *ps)
IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
- float *array = (float *)IDP_Array(view_data);
+ const float *array = (float *)IDP_Array(view_data);
/* use image array, written when creating image */
memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
@@ -3187,7 +3111,7 @@ static void project_paint_begin(ProjPaintState *ps)
}
if (is_face_sel && (tpage = project_paint_face_image(ps, ps->dm_mtface, face_index))) {
- float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
+ const float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
v1coSS = ps->screenCoords[mf->v1];
v2coSS = ps->screenCoords[mf->v2];
@@ -3695,7 +3619,7 @@ static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, f
float co_ofs[2];
float rgba_tmp[4];
sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, true)) {
add_v4_v4(rgba, rgba_tmp);
accum_tot++;
}
@@ -3726,7 +3650,7 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo
float co_ofs[2];
float rgba_tmp[4];
sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, true)) {
add_v4_v4(rgba, rgba_tmp);
accum_tot++;
}
@@ -3757,7 +3681,7 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const
}
rgb_float_to_uchar(rgba_ub, rgb);
- rgba_ub[3] = FTOCHAR(mask);
+ rgba_ub[3] = f_to_char(mask);
if (ps->do_masking) {
IMB_blend_color_byte(projPixel->pixel.ch_pt, projPixel->origColor.ch, rgba_ub, ps->blend);
@@ -4260,7 +4184,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
if (ps->normal_angle_range <= 0.0f)
- ps->do_mask_normal = FALSE; /* no need to do blending */
+ ps->do_mask_normal = false; /* no need to do blending */
return;
}
@@ -4460,6 +4384,7 @@ void PAINT_OT_project_image(wmOperatorType *ot)
prop = RNA_def_enum(ot->srna, "image", DummyRNA_NULL_items, 0, "Image", "");
RNA_def_enum_funcs(prop, RNA_image_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -4483,7 +4408,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(scene, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index adc98afc319..1bc7dc7a24e 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -39,6 +39,7 @@ struct bContext;
struct bglMats;
struct Brush;
struct ImagePool;
+struct ColorSpace;
struct ListBase;
struct Mesh;
struct MTex;
@@ -187,12 +188,12 @@ void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot);
/* Convert the object-space axis-aligned bounding box (expressed as
* its minimum and maximum corners) into a screen-space rectangle,
* returns zero if the result is empty */
-int paint_convert_bb_to_rect(struct rcti *rect,
- const float bb_min[3],
- const float bb_max[3],
- const struct ARegion *ar,
- struct RegionView3D *rv3d,
- struct Object *ob);
+bool paint_convert_bb_to_rect(struct rcti *rect,
+ const float bb_min[3],
+ const float bb_max[3],
+ const struct ARegion *ar,
+ struct RegionView3D *rv3d,
+ struct Object *ob);
/* Get four planes in object-space that describe the projection of
* screen_rect from screen into object-space (essentially converting a
@@ -204,11 +205,8 @@ void paint_calc_redraw_planes(float planes[4][4],
const struct rcti *screen_rect);
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
-float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool);
-void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool);
-int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
-void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
-void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata);
+float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
+void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert, struct ColorSpace *colorspace);
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index dc0c097c558..49b62140fe6 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -32,7 +32,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -87,26 +86,27 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
struct Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
- struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
+ struct MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
PaintMaskFloodMode mode;
float value;
DerivedMesh *dm;
PBVH *pbvh;
PBVHNode **nodes;
int totnode, i;
-#ifdef _OPENMP
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-#endif
mode = RNA_enum_get(op->ptr, "mode");
value = RNA_float_get(op->ptr, "value");
- ED_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
+ ob->sculpt->show_diffuse_color = sd->flags & SCULPT_SHOW_DIFFUSE;
+ pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
sculpt_undo_push_begin("Mask flood fill");
@@ -195,7 +195,7 @@ int do_sculpt_mask_box_select(ViewContext *vc, rcti *rect, bool select, bool UNU
ARegion *ar = vc->ar;
struct Scene *scene = vc->scene;
Object *ob = vc->obact;
- struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
+ struct MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
PaintMaskFloodMode mode;
float value;
DerivedMesh *dm;
@@ -212,12 +212,15 @@ int do_sculpt_mask_box_select(ViewContext *vc, rcti *rect, bool select, bool UNU
ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
mul_m4_fl(clip_planes, -1.0f);
- ED_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
+ ob->sculpt->show_diffuse_color = sd->flags & SCULPT_SHOW_DIFFUSE;
+ pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+
sculpt_undo_push_begin("Mask box fill");
for (symmpass = 0; symmpass <= symm; ++symmpass) {
@@ -356,12 +359,15 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect);
mul_m4_fl(clip_planes, -1.0f);
- mmd = sculpt_multires_active(vc.scene, ob);
- ED_sculpt_mask_layers_ensure(ob, mmd);
+ mmd = BKE_sculpt_multires_active(vc.scene, ob);
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH);
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
+ ob->sculpt->show_diffuse_color = sd->flags & SCULPT_SHOW_DIFFUSE;
+ pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+
sculpt_undo_push_begin("Mask lasso fill");
for (symmpass = 0; symmpass <= symm; ++symmpass) {
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index ce57b12d0ba..543463cd5f3 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -39,7 +39,6 @@
#include "BKE_context.h"
#include "BKE_paint.h"
#include "BKE_main.h"
-#include "BKE_image.h"
#include "ED_sculpt.h"
#include "ED_screen.h"
@@ -1165,11 +1164,11 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
/* multires switch */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0);
RNA_int_set(kmi->ptr, "level", 1);
- RNA_boolean_set(kmi->ptr, "relative", TRUE);
+ RNA_boolean_set(kmi->ptr, "relative", true);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEDOWNKEY, KM_PRESS, 0, 0);
RNA_int_set(kmi->ptr, "level", -1);
- RNA_boolean_set(kmi->ptr, "relative", TRUE);
+ RNA_boolean_set(kmi->ptr, "relative", true);
ed_keymap_paint_brush_switch(keymap, "sculpt");
ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size");
@@ -1177,7 +1176,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
ed_keymap_stencil(keymap);
- keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_DRAW, DKEY, 0);
+ keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_DRAW, XKEY, 0);
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_SMOOTH, SKEY, 0);
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_PINCH, PKEY, 0);
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_INFLATE, IKEY, 0);
@@ -1193,7 +1192,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
/* */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0);
- RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.sculpt_stroke_method");
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.stroke_method");
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.use_smooth_stroke");
@@ -1273,9 +1272,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
/* Image/Texture Paint mode */
@@ -1314,9 +1313,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "PAINT_OT_face_select_reveal", HKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "PAINT_OT_face_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 017ba92236c..3172d2fff41 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -47,6 +47,7 @@
#include "BKE_paint.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
+#include "BKE_image.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -56,6 +57,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "IMB_imbuf_types.h"
+
#include "paint_intern.h"
#include "GPU_blender_aspect.h"
@@ -102,7 +105,7 @@ typedef struct PaintStroke {
bool brush_init;
float initial_mouse[2];
/* cached_pressure stores initial pressure for size pressure influence mainly */
- float cached_pressure;
+ float cached_size_pressure;
/* last pressure will store last pressure value for use in interpolation for space strokes */
float last_pressure;
@@ -182,22 +185,42 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
* brush coord/pressure/etc.
* It's more an events design issue, which doesn't split coordinate/pressure/angle
* changing events. We should avoid this after events system re-design */
- if (paint_supports_dynamic_size(brush, mode) || !stroke->brush_init) {
+ if (!stroke->brush_init) {
copy_v2_v2(stroke->initial_mouse, mouse);
+ copy_v2_v2(ups->last_rake, mouse);
+ copy_v2_v2(ups->tex_mouse, mouse);
+ copy_v2_v2(ups->mask_tex_mouse, mouse);
+ stroke->cached_size_pressure = pressure;
+
+ /* check here if color sampling the main brush should do color conversion. This is done here
+ * to avoid locking up to get the image buffer during sampling */
+ if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) {
+ ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(brush->mtex.tex->ima, &brush->mtex.tex->iuser, NULL);
+ if (tex_ibuf && tex_ibuf->rect_float == NULL) {
+ ups->do_linear_conversion = true;
+ ups->colorspace = tex_ibuf->rect_colorspace;
+ }
+ BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, NULL);
+ }
+
+ stroke->brush_init = true;
+ }
+
+ if (paint_supports_dynamic_size(brush, mode)) {
copy_v2_v2(ups->tex_mouse, mouse);
copy_v2_v2(ups->mask_tex_mouse, mouse);
- stroke->cached_pressure = pressure;
+ stroke->cached_size_pressure = pressure;
}
/* Truly temporary data that isn't stored in properties */
ups->stroke_active = true;
- ups->pressure_value = stroke->cached_pressure;
+ ups->size_pressure_value = stroke->cached_size_pressure;
ups->pixel_radius = BKE_brush_size_get(scene, brush);
if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, mode)) {
- ups->pixel_radius *= stroke->cached_pressure;
+ ups->pixel_radius *= stroke->cached_size_pressure;
}
if (paint_supports_dynamic_tex_coords(brush, mode)) {
@@ -267,13 +290,8 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
ups->draw_anchored = true;
}
else if (brush->flag & BRUSH_RAKE) {
- if (!stroke->brush_init)
- copy_v2_v2(ups->last_rake, mouse);
- else
- paint_calculate_rake_rotation(ups, mouse);
+ paint_calculate_rake_rotation(ups, mouse);
}
-
- stroke->brush_init = TRUE;
}
diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c
index fd8cc4df41e..f3946e30b83 100644
--- a/source/blender/editors/sculpt_paint/paint_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_undo.c
@@ -271,6 +271,77 @@ int ED_undo_paint_step(bContext *C, int type, int step, const char *name)
return 0;
}
+static void undo_step_num(bContext *C, UndoStack *stack, int step)
+{
+ UndoElem *uel;
+ int a = 0;
+ int curnum = BLI_findindex(&stack->elems, stack->current);
+
+ for (uel = stack->elems.first; uel; uel = uel->next, a++) {
+ if (a == step) break;
+ }
+
+ if (curnum > a) {
+ while (a++ != curnum)
+ undo_stack_step(C, stack, 1, NULL);
+ }
+ else if (curnum < a) {
+ while (a-- != curnum)
+ undo_stack_step(C, stack, -1, NULL);
+ }
+}
+
+void ED_undo_paint_step_num(bContext *C, int type, int step)
+{
+ if (type == UNDO_PAINT_IMAGE)
+ undo_step_num(C, &ImageUndoStack, step);
+ else if (type == UNDO_PAINT_MESH)
+ undo_step_num(C, &MeshUndoStack, step);
+}
+
+static char *undo_stack_get_name(UndoStack *stack, int nr, int *active)
+{
+ UndoElem *uel;
+
+ if (active) *active = 0;
+
+ uel = BLI_findlink(&stack->elems, nr);
+ if (uel) {
+ if (active && uel == stack->current)
+ *active = 1;
+ return uel->name;
+ }
+
+ return NULL;
+}
+
+const char *ED_undo_paint_get_name(int type, int nr, int *active)
+{
+ if (type == UNDO_PAINT_IMAGE)
+ return undo_stack_get_name(&ImageUndoStack, nr, active);
+ else if (type == UNDO_PAINT_MESH)
+ return undo_stack_get_name(&MeshUndoStack, nr, active);
+ return NULL;
+}
+
+bool ED_undo_paint_empty(int type)
+{
+ UndoStack *stack;
+
+ if (type == UNDO_PAINT_IMAGE)
+ stack = &ImageUndoStack;
+ else if (type == UNDO_PAINT_MESH)
+ stack = &MeshUndoStack;
+ else
+ return true;
+
+ if (stack->current == NULL) {
+ return true;
+ }
+
+ return false;
+}
+
int ED_undo_paint_valid(int type, const char *name)
{
UndoStack *stack;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f77606465a5..b03d3febb5a 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -49,6 +49,7 @@
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_image.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -59,6 +60,9 @@
#include "GPU_matrix.h"
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf_types.h"
+
#include "RE_shader_ext.h"
#include "RE_render_ext.h"
@@ -79,12 +83,12 @@
/* Convert the object-space axis-aligned bounding box (expressed as
* its minimum and maximum corners) into a screen-space rectangle,
* returns zero if the result is empty */
-int paint_convert_bb_to_rect(rcti *rect,
- const float bb_min[3],
- const float bb_max[3],
- const ARegion *ar,
- RegionView3D *rv3d,
- Object *ob)
+bool paint_convert_bb_to_rect(rcti *rect,
+ const float bb_min[3],
+ const float bb_max[3],
+ const ARegion *ar,
+ RegionView3D *rv3d,
+ Object *ob)
{
float projection_mat[4][4];
int i, j, k;
@@ -168,185 +172,43 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
return len_v3(delta) / scale;
}
-float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool)
+float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
{
float intensity, rgba[4];
float co[3] = {u, v, 0.0f};
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
return intensity;
}
-void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool)
+void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert_to_linear, struct ColorSpace *colorspace)
{
float co[3] = {u, v, 0.0f};
int hasrgb;
float intensity;
hasrgb = externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
-
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
if (!hasrgb) {
rgba[0] = intensity;
rgba[1] = intensity;
rgba[2] = intensity;
rgba[3] = 1.0f;
}
+
+ if (convert_to_linear)
+ IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace);
+
+ linearrgb_to_srgb_v3_v3(rgba, rgba);
+
CLAMP(rgba[0], 0.0f, 1.0f);
CLAMP(rgba[1], 0.0f, 1.0f);
CLAMP(rgba[2], 0.0f, 1.0f);
CLAMP(rgba[3], 0.0f, 1.0f);
}
-/* 3D Paint */
-
-static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4])
-{
- copy_v3_v3(pco, co);
- pco[3] = 1.0f;
-
- mul_m4_v3(ob->obmat, pco);
- mul_m4_v3(model, pco);
- mul_m4_v4(proj, pco);
-}
-
-static void imapaint_tri_weights(Object *ob,
- const float v1[3], const float v2[3], const float v3[3],
- const float co[2], float w[3])
-{
- float pv1[4], pv2[4], pv3[4], h[3], divw;
- float model[4][4], proj[4][4], wmat[3][3], invwmat[3][3];
- GLint view[4];
-
- /* compute barycentric coordinates */
-
- /* get the needed opengl matrices */
- gpuGetViewport(view);
- gpuGetMatrix(GL_MODELVIEW_MATRIX, (float *)model);
- gpuGetMatrix(GL_PROJECTION_MATRIX, (float *)proj);
- view[0] = view[1] = 0;
-
- /* project the verts */
- imapaint_project(ob, model, proj, v1, pv1);
- imapaint_project(ob, model, proj, v2, pv2);
- imapaint_project(ob, model, proj, v3, pv3);
-
- /* do inverse view mapping, see gluProject man page */
- h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1;
- h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1;
- h[2] = 1.0f;
-
- /* solve for (w1,w2,w3)/perspdiv in:
- * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */
-
- wmat[0][0] = pv1[0]; wmat[1][0] = pv2[0]; wmat[2][0] = pv3[0];
- wmat[0][1] = pv1[1]; wmat[1][1] = pv2[1]; wmat[2][1] = pv3[1];
- wmat[0][2] = pv1[3]; wmat[1][2] = pv2[3]; wmat[2][2] = pv3[3];
-
- invert_m3_m3(invwmat, wmat);
- mul_m3_v3(invwmat, h);
-
- copy_v3_v3(w, h);
-
- /* w is still divided by perspdiv, make it sum to one */
- divw = w[0] + w[1] + w[2];
- if (divw != 0.0f) {
- mul_v3_fl(w, 1.0f / divw);
- }
-}
-
-/* compute uv coordinates of mouse in face */
-void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2])
-{
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
- MTFace *tface = dm->getTessFaceDataArray(dm, CD_MTFACE), *tf;
- int numfaces = dm->getNumTessFaces(dm), a, findex;
- float p[2], w[3], absw, minabsw;
- MFace mf;
- MVert mv[4];
-
- /* double lookup */
- const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
- index_mp_to_orig = NULL;
- }
-
- minabsw = 1e10;
- uv[0] = uv[1] = 0.0;
-
- /* test all faces in the derivedmesh with the original index of the picked face */
- for (a = 0; a < numfaces; a++) {
- findex = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
-
- if (findex == faceindex) {
- dm->getTessFace(dm, a, &mf);
-
- dm->getVert(dm, mf.v1, &mv[0]);
- dm->getVert(dm, mf.v2, &mv[1]);
- dm->getVert(dm, mf.v3, &mv[2]);
- if (mf.v4)
- dm->getVert(dm, mf.v4, &mv[3]);
-
- tf = &tface[a];
-
- p[0] = xy[0];
- p[1] = xy[1];
-
- if (mf.v4) {
- /* the triangle with the largest absolute values is the one
- * with the most negative weights */
- imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
- absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
- if (absw < minabsw) {
- uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[3][0] * w[2];
- uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[3][1] * w[2];
- minabsw = absw;
- }
-
- imapaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
- absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
- if (absw < minabsw) {
- uv[0] = tf->uv[1][0] * w[0] + tf->uv[2][0] * w[1] + tf->uv[3][0] * w[2];
- uv[1] = tf->uv[1][1] * w[0] + tf->uv[2][1] * w[1] + tf->uv[3][1] * w[2];
- minabsw = absw;
- }
- }
- else {
- imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
- absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
- if (absw < minabsw) {
- uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[2][0] * w[2];
- uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[2][1] * w[2];
- minabsw = absw;
- }
- }
- }
- }
-
- dm->release(dm);
-}
-
-/* returns 0 if not found, otherwise 1 */
-int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface)
-{
- if (totface == 0)
- return 0;
-
- /* sample only on the exact position */
- *index = view3d_sample_backbuf(vc, mval[0], mval[1]);
-
- if ((*index) == 0 || (*index) > (unsigned int)totface) {
- return 0;
- }
-
- (*index)--;
-
- return 1;
-}
-
/* Uses symm to selectively flip any axis of a coordinate. */
void flip_v3_v3(float out[3], const float in[3], const char symm)
{
@@ -369,7 +231,7 @@ void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* fron
{
Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C));
unsigned int col;
- char *cp;
+ const char *cp;
CLAMP(x, 0, ar->winx);
CLAMP(y, 0, ar->winy);
@@ -482,7 +344,7 @@ void PAINT_OT_face_select_linked_pick(wmOperatorType *ot)
static int face_select_all_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
- paintface_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
+ paintface_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), true);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -506,7 +368,7 @@ void PAINT_OT_face_select_all(wmOperatorType *ot)
static int vert_select_all_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
- paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
+ paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), true);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -537,7 +399,7 @@ static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), TRUE);
+ paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), true);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -561,7 +423,7 @@ void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
static int face_select_hide_exec(bContext *C, wmOperator *op)
{
- const int unselected = RNA_boolean_get(op->ptr, "unselected");
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
Object *ob = CTX_data_active_object(C);
paintface_hide(ob, unselected);
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 55296aeda18..969c5a09a82 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -33,7 +33,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_memarena.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -58,7 +57,6 @@
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -91,12 +89,12 @@ static bool vertex_paint_use_fast_update_check(Object *ob)
}
}
- return FALSE;
+ return false;
}
/* if the polygons from the mesh and the 'derivedFinal' match
* we can assume that no modifiers are applied and that its worth adding tessellated faces
- * so 'vertex_paint_use_fast_update_check()' returns TRUE */
+ * so 'vertex_paint_use_fast_update_check()' returns true */
static bool vertex_paint_use_tessface_check(Object *ob, Mesh *me)
{
DerivedMesh *dm = ob->derivedFinal;
@@ -105,7 +103,7 @@ static bool vertex_paint_use_tessface_check(Object *ob, Mesh *me)
return (me->mpoly == CustomData_get_layer(&dm->polyData, CD_MPOLY));
}
- return FALSE;
+ return false;
}
static void update_tessface_data(Object *ob, Mesh *me)
@@ -189,6 +187,7 @@ static VPaint *new_vpaint(int wpaint)
VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
vp->flag = (wpaint) ? 0 : VP_SPRAY;
+ vp->paint.flags |= PAINT_SHOW_BRUSH;
return vp;
}
@@ -216,7 +215,7 @@ static void do_shared_vertex_tesscol(Mesh *me, bool *mfacetag)
int a;
short *scolmain, *scol;
char *mcol;
- bool *mftag;
+ const bool *mftag;
if (me->mcol == NULL || me->totvert == 0 || me->totface == 0) return;
@@ -225,7 +224,7 @@ static void do_shared_vertex_tesscol(Mesh *me, bool *mfacetag)
mface = me->mface;
mcol = (char *)me->mcol;
for (a = me->totface; a > 0; a--, mface++, mcol += 16) {
- if ((use_face_sel == FALSE) || (mface->flag & ME_FACE_SEL)) {
+ if ((use_face_sel == false) || (mface->flag & ME_FACE_SEL)) {
scol = scolmain + 4 * mface->v1;
scol[0]++; scol[1] += mcol[1]; scol[2] += mcol[2]; scol[3] += mcol[3];
scol = scolmain + 4 * mface->v2;
@@ -254,7 +253,7 @@ static void do_shared_vertex_tesscol(Mesh *me, bool *mfacetag)
mcol = (char *)me->mcol;
mftag = mfacetag;
for (a = me->totface; a > 0; a--, mface++, mcol += 16, mftag += 4) {
- if ((use_face_sel == FALSE) || (mface->flag & ME_FACE_SEL)) {
+ if ((use_face_sel == false) || (mface->flag & ME_FACE_SEL)) {
if (mftag[0]) {
scol = scolmain + 4 * mface->v1;
mcol[1] = scol[1]; mcol[2] = scol[2]; mcol[3] = scol[3];
@@ -296,7 +295,7 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag, bool *mfacetag, const
scol = MEM_callocN(sizeof(int) * me->totvert * 5, "scol");
for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
- if ((use_face_sel == FALSE) || (mp->flag & ME_FACE_SEL)) {
+ if ((use_face_sel == false) || (mp->flag & ME_FACE_SEL)) {
MLoop *ml = me->mloop + mp->loopstart;
MLoopCol *lcol = me->mloopcol + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++, lcol++) {
@@ -319,7 +318,7 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag, bool *mfacetag, const
}
for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
- if ((use_face_sel == FALSE) || (mp->flag & ME_FACE_SEL)) {
+ if ((use_face_sel == false) || (mp->flag & ME_FACE_SEL)) {
MLoop *ml = me->mloop + mp->loopstart;
MLoopCol *lcol = me->mloopcol + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++, lcol++) {
@@ -1054,13 +1053,13 @@ static float wpaint_blend(VPaint *wp, float weight, float weight_prev,
weight = wpaint_blend_tool(tool, weight, paintval, alpha);
/* delay clamping until the end so multi-paint can function when the active group is at the limits */
- if (do_multipaint_totsel == FALSE) {
+ if (do_multipaint_totsel == false) {
CLAMP(weight, 0.0f, 1.0f);
}
/* if no spray, clip result with orig weight & orig alpha */
if ((wp->flag & VP_SPRAY) == 0) {
- if (do_multipaint_totsel == FALSE) {
+ if (do_multipaint_totsel == false) {
float testw = wpaint_blend_tool(tool, weight_prev, paintval, brush_alpha_value);
CLAMP(testw, 0.0f, 1.0f);
@@ -1101,7 +1100,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, true)) {
v_idx_best = index;
}
}
@@ -1152,16 +1151,16 @@ void PAINT_OT_weight_sample(wmOperatorType *ot)
}
/* samples cursor location, and gives menu with vertex groups to activate */
-static int weight_paint_sample_enum_itemf__helper(const MDeformVert *dvert, const int defbase_tot, int *groups)
+static bool weight_paint_sample_enum_itemf__helper(const MDeformVert *dvert, const int defbase_tot, int *groups)
{
/* this func fills in used vgroup's */
- int found = FALSE;
+ bool found = false;
int i = dvert->totweight;
MDeformWeight *dw;
for (dw = dvert->dw; i > 0; dw++, i--) {
if (dw->def_nr < defbase_tot) {
- groups[dw->def_nr] = TRUE;
- found = TRUE;
+ groups[dw->def_nr] = true;
+ found = true;
}
}
return found;
@@ -1181,17 +1180,19 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
const int defbase_tot = BLI_countlist(&vc.obact->defbase);
const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
- int found = FALSE;
+ bool found = false;
unsigned int index;
- int mval[2] = {win->eventstate->x - vc.ar->winrct.xmin,
- win->eventstate->y - vc.ar->winrct.ymin};
+ const int mval[2] = {
+ win->eventstate->x - vc.ar->winrct.xmin,
+ win->eventstate->y - vc.ar->winrct.ymin,
+ };
view3d_operator_needs_opengl(C);
ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, true)) {
MDeformVert *dvert = &me->dvert[index];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
}
@@ -1208,7 +1209,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
}
}
- if (found == FALSE) {
+ if (found == false) {
MEM_freeN(groups);
}
else {
@@ -1272,6 +1273,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot)
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "group", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
RNA_def_enum_funcs(prop, weight_paint_sample_enum_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -1386,11 +1388,11 @@ static bool has_locked_group(MDeformVert *dvert, const int defbase_tot,
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if (dw->def_nr < defbase_tot) {
if (bone_groups[dw->def_nr] && lock_flags[dw->def_nr] && dw->weight > 0.0f) {
- return TRUE;
+ return true;
}
}
}
- return FALSE;
+ return false;
}
static bool has_locked_group_selected(int defbase_tot, const bool *defbase_sel, const bool *lock_flags)
@@ -1411,14 +1413,14 @@ static bool has_unselected_unlocked_bone_group(int defbase_tot, bool *defbase_se
{
int i;
if (defbase_tot == selected) {
- return FALSE;
+ return false;
}
for (i = 0; i < defbase_tot; i++) {
if (vgroup_validmap[i] && !defbase_sel[i] && !lock_flags[i]) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif
@@ -1487,7 +1489,7 @@ static float redistribute_change(MDeformVert *ndv, const int defbase_tot,
if (change_status[ndw->def_nr] == change_me) {
oldval = ndw->weight;
/* if auto normalize is active, don't worry about upper bounds */
- if (do_auto_normalize == FALSE && ndw->weight + change > 1) {
+ if (do_auto_normalize == false && ndw->weight + change > 1) {
totchange -= 1.0f - ndw->weight;
ndw->weight = 1.0f;
/* stop the changes to this group */
@@ -1706,7 +1708,7 @@ typedef struct WeightPaintInfo {
} WeightPaintInfo;
/* fresh start to make multi-paint and locking modular */
-/* returns TRUE if it thinks you need to reset the weights due to
+/* returns true if it thinks you need to reset the weights due to
* normalizing while multi-painting
*
* note: this assumes dw->def_nr range has been checked by the caller
@@ -1752,19 +1754,19 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
if (neww > oldw) {
if (tdw->weight <= oldw) {
MEM_freeN(dv_test.dw);
- return TRUE;
+ return true;
}
}
else {
if (tdw->weight >= oldw) {
MEM_freeN(dv_test.dw);
- return TRUE;
+ return true;
}
}
}
}
MEM_freeN(dv_test.dw);
- return FALSE;
+ return false;
}
/* within the current dvert index, get the dw that is selected and has a weight
@@ -1874,11 +1876,11 @@ static void do_weight_paint_vertex(
/* If there are no locks or multipaint,
* then there is no need to run the more complicated checks */
- if ((do_multipaint_totsel == FALSE) &&
- (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == FALSE))
+ if ((do_multipaint_totsel == false) &&
+ (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == false))
{
dw->weight = wpaint_blend(wp, dw->weight, dw_prev->weight, alpha, paintweight,
- wpi->brush_alpha_value, wpi->do_flip, FALSE);
+ wpi->brush_alpha_value, wpi->do_flip, false);
/* WATCH IT: take care of the ordering of applying mirror -> normalize,
* can give wrong results [#26193], least confusing if normalize is done last */
@@ -2059,8 +2061,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
}
/* weight paint specific */
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, 'e');
paint_cursor_delete_textures();
}
@@ -2075,7 +2077,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
/* weight paint specific */
- mesh_octree_table(ob, NULL, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
ED_vgroup_sync_from_pose(ob);
}
@@ -2148,11 +2150,11 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op)
Mesh *me = BKE_mesh_from_object(ob);
if (scene->obedit) {
- return FALSE;
+ return false;
}
if (me == NULL || me->totpoly == 0) {
- return FALSE;
+ return false;
}
/* if nothing was added yet, we make dverts and a vertex deform group */
@@ -2190,10 +2192,10 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op)
/* ensure we don't try paint onto an invalid group */
if (ob->actdef <= 0) {
BKE_report(op->reports, RPT_WARNING, "No active vertex group for painting, aborting");
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
@@ -2208,8 +2210,8 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN
float mat[4][4], imat[4][4];
- if (wpaint_ensure_data(C, op) == FALSE) {
- return FALSE;
+ if (wpaint_ensure_data(C, op) == false) {
+ return false;
}
{
@@ -2218,7 +2220,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN
bDeformGroup *dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
- return FALSE;
+ return false;
}
}
@@ -2255,7 +2257,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN
wpd->vgroup_mirror = wpaint_mirror_vgroup_ensure(ob, wpd->vgroup_active);
}
- return TRUE;
+ return true;
}
static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
@@ -2495,11 +2497,6 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
swap_m4m4(vc->rv3d->persmat, mat);
- {
- UnifiedPaintSettings *ups = &ts->unified_paint_settings;
- ups->pressure_value = pressure;
- }
-
DAG_id_tag_update(ob->data, 0);
ED_region_tag_redraw(vc->ar);
}
@@ -2610,7 +2607,7 @@ static int weight_paint_set_exec(bContext *C, wmOperator *op)
Brush *brush = BKE_paint_brush(&ts->wpaint->paint);
float vgroup_weight = BKE_brush_weight_get(scene, brush);
- if (wpaint_ensure_data(C, op) == FALSE) {
+ if (wpaint_ensure_data(C, op) == false) {
return OPERATOR_CANCELLED;
}
@@ -2822,11 +2819,11 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
* if not we can skip face map trickyness */
if (vertex_paint_use_fast_update_check(ob)) {
vpaint_build_poly_facemap(vpd, me);
- vpd->use_fast_update = TRUE;
+ vpd->use_fast_update = true;
/* printf("Fast update!\n");*/
}
else {
- vpd->use_fast_update = FALSE;
+ vpd->use_fast_update = false;
/* printf("No fast update!\n");*/
}
@@ -3016,14 +3013,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
do_shared_vertexcol(me, vpd->mlooptag, vpd->mfacetag, do_tessface);
}
- {
- UnifiedPaintSettings *ups = &ts->unified_paint_settings;
- ups->pressure_value = pressure;
- }
-
ED_region_tag_redraw(vc->ar);
- if (vpd->use_fast_update == FALSE) {
+ if (vpd->use_fast_update == false) {
/* recalculate modifier stack to get new colors, slow,
* avoid this if we can! */
DAG_id_tag_update(ob->data, 0);
@@ -3205,7 +3197,7 @@ static void gradientVert__mapFunc(void *userData, int index, const float co[3],
DMGradient_userData *grad_data = userData;
Mesh *me = grad_data->me;
- if (grad_data->use_select == FALSE || (me->mvert[index].flag & SELECT)) {
+ if (grad_data->use_select == false || (me->mvert[index].flag & SELECT)) {
DMGradient_vertStore *vs = &grad_data->vert_cache[index];
/* run first pass only, could be split into its own mapFunc
@@ -3355,7 +3347,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
vert_cache = gesture->userdata;
}
else {
- if (wpaint_ensure_data(C, op) == FALSE) {
+ if (wpaint_ensure_data(C, op) == false) {
return OPERATOR_CANCELLED;
}
@@ -3403,7 +3395,7 @@ static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEve
{
int ret;
- if (wpaint_ensure_data(C, op) == FALSE) {
+ if (wpaint_ensure_data(C, op) == false) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index a04e15d3729..ae729248f7e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -153,6 +153,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index,
vp_handle->dists_sq[index] = dist_sq;
}
+ else if (vp_handle->dists_sq[index] != FLT_MAX) {
+ /* already initialized & couldn't project this 'co' */
+ return;
+ }
}
/* continue with regular functionality */
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5ef0e500681..c9101fff6e5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -38,7 +38,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -55,8 +54,8 @@
#include "BKE_pbvh.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_context.h"
+#include "BKE_crazyspace.h"
#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BKE_key.h"
@@ -66,15 +65,11 @@
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
-#include "BKE_report.h"
-#include "BKE_lattice.h" /* for armature_deform_verts */
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BKE_colortools.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -82,7 +77,6 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "ED_util.h" /* for crazyspace correction */
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -104,6 +98,19 @@
#include <omp.h>
#endif
+#if defined(__APPLE__) && defined _OPENMP
+#include <sys/sysctl.h>
+
+/* Query how many cores not counting HT aka physical cores we've got. */
+static int system_physical_thread_count(void)
+{
+ int pcount;
+ size_t pcount_len = sizeof(pcount);
+ sysctlbyname("hw.physicalcpu", &pcount, &pcount_len, NULL, 0);
+ return pcount;
+}
+#endif /* __APPLE__ */
+
void ED_sculpt_get_average_stroke(Object *ob, float stroke[3])
{
if (ob->sculpt->last_stroke_valid && ob->sculpt->average_stroke_counter > 0) {
@@ -115,7 +122,7 @@ void ED_sculpt_get_average_stroke(Object *ob, float stroke[3])
}
}
-int ED_sculpt_minmax(bContext *C, float min[3], float max[3])
+bool ED_sculpt_minmax(bContext *C, float min[3], float max[3])
{
Object *ob = CTX_data_active_object(C);
@@ -130,41 +137,9 @@ int ED_sculpt_minmax(bContext *C, float min[3], float max[3])
}
}
-/* Sculpt mode handles multires differently from regular meshes, but only if
- * it's the last modifier on the stack and it is not on the first level */
-MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
-{
- Mesh *me = (Mesh *)ob->data;
- ModifierData *md;
- VirtualModifierData virtualModifierData;
-
- if (ob->sculpt && ob->sculpt->bm) {
- /* can't combine multires and dynamic topology */
- return NULL;
- }
-
- if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
- /* multires can't work without displacement layer */
- return NULL;
- }
-
- for (md = modifiers_getVirtualModifierList(ob, &virtualModifierData); md; md = md->next) {
- if (md->type == eModifierType_Multires) {
- MultiresModifierData *mmd = (MultiresModifierData *)md;
-
- if (!modifier_isEnabled(scene, md, eModifierMode_Realtime))
- continue;
-
- if (mmd->sculptlvl > 0) return mmd;
- else return NULL;
- }
- }
-
- return NULL;
-}
/* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */
-static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
+static bool sculpt_has_active_modifiers(Scene *scene, Object *ob)
{
ModifierData *md;
VirtualModifierData virtualModifierData;
@@ -180,35 +155,7 @@ static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
return 0;
}
-/* Checks if there are any supported deformation modifiers active */
-static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
-{
- ModifierData *md;
- Mesh *me = (Mesh *)ob->data;
- MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
- VirtualModifierData virtualModifierData;
-
- if (mmd || ob->sculpt->bm)
- return 0;
- /* non-locked shape keys could be handled in the same way as deformed mesh */
- if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
- return 1;
-
- md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-
- /* exception for shape keys because we can edit those */
- for (; md; md = md->next) {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
- if (md->type == eModifierType_ShapeKey) continue;
-
- if (mti->type == eModifierTypeType_OnlyDeform) return 1;
- else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return 1;
- }
-
- return 0;
-}
typedef enum StrokeFlags {
CLIP_X = 1,
@@ -230,7 +177,7 @@ typedef struct StrokeCache {
float initial_mouse[2];
/* Pre-allocated temporary storage used during smoothing */
- int num_threads;
+ int num_threads, max_threads;
float (**tmpgrid_co)[3], (**tmprow_co)[3];
float **tmpgrid_mask, **tmprow_mask;
@@ -248,7 +195,7 @@ typedef struct StrokeCache {
/* The rest is temporary storage that isn't saved as a property */
- int first_time; /* Beginning of stroke may do some things special */
+ bool first_time; /* Beginning of stroke may do some things special */
/* from ED_view3d_ob_project_mat_get() */
float projection_mat[4][4];
@@ -283,7 +230,7 @@ typedef struct StrokeCache {
int radial_symmetry_pass;
float symm_rot_mat[4][4];
float symm_rot_mat_inv[4][4];
- int original;
+ bool original;
float anchored_location[3];
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
@@ -296,7 +243,7 @@ typedef struct StrokeCache {
char saved_active_brush_name[MAX_ID_NAME];
char saved_mask_brush_tool;
int saved_smooth_size; /* smooth tool copies the size of the current tool */
- int alt_smooth;
+ bool alt_smooth;
float plane_trim_squared;
@@ -305,6 +252,7 @@ typedef struct StrokeCache {
float gravity_direction[3];
rcti previous_r; /* previous redraw rectangle */
+ rcti current_r; /* current redraw rectangle */
} StrokeCache;
/************** Access to original unmodified vertex data *************/
@@ -315,7 +263,7 @@ typedef struct {
SculptUndoNode *unode;
float (*coords)[3];
short (*normals)[3];
- float *vmasks;
+ const float *vmasks;
/* Original coordinate, normal, and mask */
const float *co;
@@ -483,9 +431,9 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
}
if (ss->face_normals) {
- float *fn = ss->face_normals;
- for (i = 0; i < ss->totpoly; ++i, fn += 3)
- copy_v3_v3(fn, cache->face_norms[i]);
+ for (i = 0; i < ss->totpoly; i++) {
+ copy_v3_v3(ss->face_normals[i], cache->face_norms[i]);
+ }
}
if (nodes)
@@ -511,8 +459,8 @@ static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
}
/* Get a screen-space rectangle of the modified area */
-static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
- Object *ob, rcti *rect)
+static bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
+ Object *ob, rcti *rect)
{
PBVH *pbvh = ob->sculpt->pbvh;
float bb_min[3], bb_max[3];
@@ -541,13 +489,19 @@ void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar,
RegionView3D *rv3d, Object *ob)
{
PBVH *pbvh = ob->sculpt->pbvh;
- rcti rect;
+ /* copy here, original will be used below */
+ rcti rect = ob->sculpt->cache->current_r;
- sculpt_get_redraw_rect(ar, rv3d, ob, &rect);
sculpt_extend_redraw_rect_previous(ob, &rect);
paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect);
+ /* we will draw this rect, so now we can set it as the previous partial rect.
+ * Note that we don't update with the union of previous/current (rect), only with
+ * the current. Thus we avoid the rectangle needlessly growing to include
+ * all the stroke area */
+ ob->sculpt->cache->previous_r = ob->sculpt->cache->current_r;
+
/* clear redraw flag from nodes */
if (pbvh)
BKE_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL);
@@ -638,9 +592,9 @@ static bool sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float loc
mul_v3_m4v3(local_co, local, co);
- local_co[0] = fabs(local_co[0]);
- local_co[1] = fabs(local_co[1]);
- local_co[2] = fabs(local_co[2]);
+ local_co[0] = fabsf(local_co[0]);
+ local_co[1] = fabsf(local_co[1]);
+ local_co[2] = fabsf(local_co[2]);
if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
float p = 4.0f;
@@ -719,7 +673,7 @@ static float overlapped_curve(Brush *br, float x)
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);
@@ -760,7 +714,8 @@ static float calc_overlap(StrokeCache *cache, const char symm, const char axis,
flip_v3_v3(mirror, cache->true_location, symm);
if (axis != 0) {
- float mat[4][4] = MAT4_UNITY;
+ float mat[4][4];
+ unit_m4(mat);
rotate_m4(mat, axis, angle);
mul_m4_v3(mat, mirror);
}
@@ -924,6 +879,7 @@ static float tex_strength(SculptSession *ss, Brush *br,
MTex *mtex = &br->mtex;
float avg = 1;
float rgba[4];
+ int thread_num;
if (!mtex->tex) {
avg = 1;
@@ -966,7 +922,12 @@ static float tex_strength(SculptSession *ss, Brush *br,
x += br->mtex.ofs[0];
y += br->mtex.ofs[1];
- avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool);
+#ifdef _OPENMP
+ thread_num = omp_get_thread_num();
+#else
+ thread_num = 0;
+#endif
+ avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_num);
avg += br->texture_sample_bias;
}
@@ -1018,7 +979,7 @@ static bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
sub_v3_v3v3(t, center, nearest);
- return dot_v3v3(t, t) < data->radius_squared;
+ return len_squared_v3(t) < data->radius_squared;
}
/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
@@ -1528,10 +1489,10 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
grid_hidden = BKE_pbvh_grid_hidden(ss->pbvh);
- thread_num = 0;
#ifdef _OPENMP
- if (sd->flags & SCULPT_USE_OPENMP)
- thread_num = omp_get_thread_num();
+ thread_num = omp_get_thread_num();
+#else
+ thread_num = 0;
#endif
tmpgrid_co = ss->cache->tmpgrid_co[thread_num];
tmprow_co = ss->cache->tmprow_co[thread_num];
@@ -1599,7 +1560,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
for (y = 0; y < gridsize; ++y) {
for (x = 0; x < gridsize; ++x) {
float *co;
- float *fno;
+ const float *fno;
float *mask;
int index;
@@ -1709,7 +1670,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
- smooth(sd, ob, nodes, totnode, ss->cache->bstrength, FALSE);
+ smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
}
static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
@@ -1754,7 +1715,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
do_mask_brush_draw(sd, ob, nodes, totnode);
break;
case BRUSH_MASK_SMOOTH:
- smooth(sd, ob, nodes, totnode, ss->cache->bstrength, TRUE);
+ smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true);
break;
}
}
@@ -2195,7 +2156,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
mul_v3_v3fl(val, offset, *disp);
- if (ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+ if (!ss->multires && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
int index = vd.vert_indices[vd.i];
/* persistent base */
@@ -3229,10 +3190,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
brush->autosmooth_factor > 0)
{
if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- smooth(sd, ob, nodes, totnode, brush->autosmooth_factor * (1 - ss->cache->pressure), FALSE);
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor * (1 - ss->cache->pressure), false);
}
else {
- smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, FALSE);
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
}
}
@@ -3540,106 +3501,7 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
}
}
-/**
- * \param need_mask So the DerivedMesh thats returned has mask data
- */
-void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
- int need_pmap, int need_mask)
-{
- DerivedMesh *dm;
- SculptSession *ss = ob->sculpt;
- Mesh *me = ob->data;
- MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
-
- ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
- ss->show_diffuse_color = (sd->flags & SCULPT_SHOW_DIFFUSE) != 0;
-
- if (need_mask) {
- if (mmd == NULL) {
- if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) {
- ED_sculpt_mask_layers_ensure(ob, NULL);
- }
- }
- else {
- if (!CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
-#if 1
- ED_sculpt_mask_layers_ensure(ob, mmd);
-#else /* if we wanted to support adding mask data while multi-res painting, we would need to do this */
- if ((ED_sculpt_mask_layers_ensure(ob, mmd) & ED_SCULPT_MASK_LAYER_CALC_LOOP)) {
- /* remake the derived mesh */
- ob->recalc |= OB_RECALC_DATA;
- BKE_object_handle_update(scene, ob);
- }
-#endif
- }
- }
- }
-
- /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
- BKE_mesh_tessface_ensure(me);
-
- if (!mmd) ss->kb = BKE_keyblock_from_object(ob);
- else ss->kb = NULL;
-
- /* needs to be called after we ensure tessface */
- dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
-
- if (mmd) {
- ss->multires = mmd;
- ss->totvert = dm->getNumVerts(dm);
- ss->totpoly = dm->getNumPolys(dm);
- ss->mvert = NULL;
- ss->mpoly = NULL;
- ss->mloop = NULL;
- ss->face_normals = NULL;
- }
- else {
- ss->totvert = me->totvert;
- ss->totpoly = me->totpoly;
- ss->mvert = me->mvert;
- ss->mpoly = me->mpoly;
- ss->mloop = me->mloop;
- ss->face_normals = NULL;
- ss->multires = NULL;
- ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
- }
-
- ss->pbvh = dm->getPBVH(ob, dm);
- ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
-
- pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
-
- if (ss->modifiers_active) {
- if (!ss->orig_cos) {
- int a;
-
- free_sculptsession_deformMats(ss);
-
- ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
-
- crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
- BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
-
- for (a = 0; a < me->totvert; ++a) {
- invert_m3(ss->deform_imats[a]);
- }
- }
- }
- else {
- free_sculptsession_deformMats(ss);
- }
-
- /* if pbvh is deformed, key block is already applied to it */
- if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
- float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
- if (vertCos) {
- /* apply shape keys coordinates to PBVH */
- BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
- MEM_freeN(vertCos);
- }
- }
-}
int sculpt_mode_poll(bContext *C)
{
@@ -3766,16 +3628,21 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
* Justification: Empirically I've found that two threads per
* processor gives higher throughput. */
if (sd->flags & SCULPT_USE_OPENMP) {
- cache->num_threads = 2 * omp_get_num_procs();
- omp_set_num_threads(cache->num_threads);
- }
- else
+#if defined(__APPLE__)
+ cache->num_threads = system_physical_thread_count();
+#else
+ cache->num_threads = omp_get_num_procs();
#endif
- {
- (void)sd;
+ }
+ else {
cache->num_threads = 1;
}
-
+ cache->max_threads = omp_get_max_threads();
+ omp_set_num_threads(cache->num_threads);
+#else
+ (void)sd;
+ cache->num_threads = 1;
+#endif
if (ss->multires) {
int i, gridsize, array_mem_size;
BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
@@ -3802,6 +3669,9 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
static void sculpt_omp_done(SculptSession *ss)
{
+#ifdef _OPENMP
+ omp_set_num_threads(ss->cache->max_threads);
+#endif
if (ss->multires) {
int i;
@@ -3915,7 +3785,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
mul_m3_v3(mat, viewDir);
normalize_v3_v3(cache->true_view_normal, viewDir);
- cache->supports_gravity = !ELEM(brush->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH) && sd->gravity_factor > 0.0f;
+ cache->supports_gravity = (!ELEM3(brush->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SIMPLIFY) &&
+ (sd->gravity_factor > 0.0f));
/* get gravity vector in world space */
if (cache->supports_gravity) {
if (sd->gravity_object) {
@@ -3952,15 +3823,21 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
}
}
+
+ if (ss->bm) {
+ /* Free any remaining layer displacements from nodes. If not and topology changes
+ * from using another tool, then next layer toolstroke can access past disp array bounds */
+ BKE_pbvh_free_layer_disp(ss->pbvh);
+ }
}
/* Make copies of the mesh vertex locations and normals for some tools */
if (brush->flag & BRUSH_ANCHORED) {
if (ss->face_normals) {
- float *fn = ss->face_normals;
cache->face_norms = MEM_mallocN(sizeof(float) * 3 * ss->totpoly, "Sculpt face norms");
- for (i = 0; i < ss->totpoly; ++i, fn += 3)
- copy_v3_v3(cache->face_norms[i], fn);
+ for (i = 0; i < ss->totpoly; ++i) {
+ copy_v3_v3(cache->face_norms[i], ss->face_normals[i]);
+ }
}
cache->original = 1;
@@ -3990,7 +3867,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
{
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
- float mouse[2] = {
+ const float mouse[2] = {
cache->mouse[0],
cache->mouse[1]
};
@@ -4171,7 +4048,9 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
/* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
* to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2 */
- if (mouse_angle * cache->previous_vertex_rotation < 0 && fabs(cache->previous_vertex_rotation) > M_PI_2) {
+ if ((mouse_angle * cache->previous_vertex_rotation < 0.0f) &&
+ (fabsf(cache->previous_vertex_rotation) > (float)M_PI_2))
+ {
if (cache->previous_vertex_rotation < 0)
cache->num_vertex_turns--;
else
@@ -4196,9 +4075,9 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
/* Returns true if any of the smoothing modes are active (currently
* one of smooth brush, autosmooth, mask smooth, or shift-key
* smooth) */
-static int sculpt_any_smooth_mode(const Brush *brush,
- StrokeCache *cache,
- int stroke_mode)
+static bool sculpt_any_smooth_mode(const Brush *brush,
+ StrokeCache *cache,
+ int stroke_mode)
{
return ((stroke_mode == BRUSH_STROKE_SMOOTH) ||
(cache && cache->alt_smooth) ||
@@ -4212,39 +4091,46 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob)
{
SculptSession *ss = ob->sculpt;
- if (ss->modifiers_active) {
+ if (ss->kb || ss->modifiers_active) {
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob,
- sculpt_any_smooth_mode(brush, ss->cache, 0), FALSE);
+ BKE_sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob,
+ sculpt_any_smooth_mode(brush, ss->cache, 0), false);
}
}
typedef struct {
SculptSession *ss;
- float *ray_start, *ray_normal;
+ const float *ray_start, *ray_normal;
int hit;
float dist;
int original;
} SculptRaycastData;
+typedef struct {
+ const float *ray_start, *ray_normal;
+ int hit;
+ float dist;
+ float detail;
+} SculptDetailRaycastData;
+
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
SculptRaycastData *srd = data_v;
float (*origco)[3] = NULL;
- int use_origco = FALSE;
+ bool use_origco = false;
if (srd->original && srd->ss->cache) {
if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = TRUE;
+ use_origco = true;
}
else {
/* intersect with coordinates from before we started stroke */
SculptUndoNode *unode = sculpt_undo_get_node(node);
origco = (unode) ? unode->co : NULL;
- use_origco = origco ? TRUE : FALSE;
+ use_origco = origco ? true : false;
}
}
@@ -4257,52 +4143,75 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
}
}
+static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
+{
+ if (BKE_pbvh_node_get_tmin(node) < *tmin) {
+ SculptDetailRaycastData *srd = data_v;
+ if (BKE_pbvh_bmesh_node_raycast_detail(node, srd->ray_start, srd->ray_normal,
+ &srd->detail, &srd->dist))
+ {
+ srd->hit = 1;
+ *tmin = srd->dist;
+ }
+ }
+}
+
+static float sculpt_raycast_init(ViewContext *vc, const float mouse[2], float ray_start[3], float ray_end[3], float ray_normal[3], bool original)
+{
+ float obimat[4][4];
+ float dist;
+ Object *ob = vc->obact;
+ RegionView3D *rv3d = vc->ar->regiondata;
+
+ /* TODO: what if the segment is totally clipped? (return == 0) */
+ ED_view3d_win_to_segment(vc->ar, vc->v3d, mouse, ray_start, ray_end, true);
+
+ invert_m4_m4(obimat, ob->obmat);
+ mul_m4_v3(obimat, ray_start);
+ mul_m4_v3(obimat, ray_end);
+
+ sub_v3_v3v3(ray_normal, ray_end, ray_start);
+ dist = normalize_v3(ray_normal);
+
+ if (!rv3d->is_persp) {
+ BKE_pbvh_raycast_project_ray_root(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
+
+ /* recalculate the normal */
+ sub_v3_v3v3(ray_normal, ray_end, ray_start);
+ dist = normalize_v3(ray_normal);
+ }
+
+ return dist;
+}
+
/* Do a raycast in the tree to find the 3d brush location
* (This allows us to ignore the GL depth buffer)
* Returns 0 if the ray doesn't hit the mesh, non-zero otherwise
*/
bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
{
- ViewContext vc;
Object *ob;
SculptSession *ss;
StrokeCache *cache;
float ray_start[3], ray_end[3], ray_normal[3], dist;
- float obimat[4][4];
SculptRaycastData srd;
bool original;
- RegionView3D *rv3d;
+ ViewContext vc;
view3d_set_viewcontext(C, &vc);
-
- rv3d = vc.ar->regiondata;
+
ob = vc.obact;
+
ss = ob->sculpt;
cache = ss->cache;
original = (cache) ? cache->original : 0;
sculpt_stroke_modifiers_check(C, ob);
- /* TODO: what if the segment is totally clipped? (return == 0) */
- ED_view3d_win_to_segment(vc.ar, vc.v3d, mouse, ray_start, ray_end, true);
-
- invert_m4_m4(obimat, ob->obmat);
- mul_m4_v3(obimat, ray_start);
- mul_m4_v3(obimat, ray_end);
-
- sub_v3_v3v3(ray_normal, ray_end, ray_start);
- dist = normalize_v3(ray_normal);
-
- if (!rv3d->is_persp) {
- BKE_pbvh_raycast_project_ray_root(ss->pbvh, original, ray_start, ray_end, ray_normal);
-
- /* recalculate the normal */
- sub_v3_v3v3(ray_normal, ray_end, ray_start);
- dist = normalize_v3(ray_normal);
- }
+ dist = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
srd.original = original;
- srd.ss = vc.obact->sculpt;
+ srd.ss = ob->sculpt;
srd.hit = 0;
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
@@ -4341,18 +4250,18 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
SculptSession *ss = CTX_data_active_object(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
int mode = RNA_enum_get(op->ptr, "mode");
- int is_smooth = 0;
- int need_mask = FALSE;
+ bool is_smooth;
+ bool need_mask = false;
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- need_mask = TRUE;
+ need_mask = true;
}
view3d_operator_needs_opengl(C);
sculpt_brush_init_tex(scene, sd, ss);
is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
- sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
+ BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
zero_v3(ob->sculpt->average_stroke_accum);
ob->sculpt->average_stroke_counter = 0;
@@ -4398,7 +4307,7 @@ static void sculpt_flush_update(bContext *C)
if (ob->derivedFinal) /* VBO no longer valid */
GPU_drawobject_free(ob->derivedFinal);
- if (ss->modifiers_active) {
+ if (ss->kb || ss->modifiers_active) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
ED_region_tag_redraw(ar);
}
@@ -4412,15 +4321,18 @@ static void sculpt_flush_update(bContext *C)
sculpt_update_object_bounding_box(ob);
if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) {
- if (ss->cache)
- ss->cache->previous_r = r;
+ if (ss->cache) {
+ ss->cache->current_r = r;
+ }
+ /* previous is not set in the current cache else
+ * the partial rect will always grow */
sculpt_extend_redraw_rect_previous(ob, &r);
- r.xmin += ar->winrct.xmin + 1;
- r.xmax += ar->winrct.xmin - 1;
- r.ymin += ar->winrct.ymin + 1;
- r.ymax += ar->winrct.ymin - 1;
+ r.xmin += ar->winrct.xmin - 2;
+ r.xmax += ar->winrct.xmin + 2;
+ r.ymin += ar->winrct.ymin - 2;
+ r.ymax += ar->winrct.ymin + 2;
ss->partial_redraw = 1;
ED_region_tag_redraw_partial(ar, &r);
@@ -4474,27 +4386,46 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
sculpt_update_cache_variants(C, sd, ob, itemptr);
sculpt_restore_mesh(sd, ob);
- BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- (ss->cache->radius /
- (float)ups->pixel_radius) *
- (float)sd->detail_size);
+ if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
+ sd->constant_detail / 100.0f);
+ }
+ else {
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
+ (ss->cache->radius /
+ (float)ups->pixel_radius) *
+ (float)sd->detail_size / 0.4f);
+ }
if (sculpt_stroke_dynamic_topology(ss, brush)) {
do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
}
- if (BKE_paint_brush(&sd->paint)->sculpt_tool != SCULPT_TOOL_SIMPLIFY)
- do_symmetrical_brush_actions(sd, ob, do_brush_action);
+ do_symmetrical_brush_actions(sd, ob, do_brush_action);
sculpt_combine_proxies(sd, ob);
/* hack to fix noise texture tearing mesh */
sculpt_fix_noise_tear(sd, ob);
- if (ss->modifiers_active)
+ /* TODO(sergey): This is not really needed for the solid shading,
+ * which does use pBVH drawing anyway, but texture and wireframe
+ * requires this.
+ *
+ * Could be optimized later, but currently don't think it's so
+ * much common scenario.
+ *
+ * Same applies to the DAG_id_tag_update() invoked from
+ * sculpt_flush_update().
+ */
+ if (ss->modifiers_active) {
sculpt_flush_stroke_deform(sd, ob);
+ }
+ else if (ss->kb) {
+ sculpt_update_keyblock(ob);
+ }
- ss->cache->first_time = FALSE;
+ ss->cache->first_time = false;
/* Cleanup */
sculpt_flush_update(C);
@@ -4543,7 +4474,6 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
/* update last stroke position */
ob->sculpt->last_stroke_valid = 1;
ED_sculpt_get_average_stroke(ob, ob->sculpt->last_stroke);
- mul_m4_v3(ob->obmat, ob->sculpt->last_stroke);
sculpt_cache_free(ss->cache);
ss->cache = NULL;
@@ -4569,6 +4499,11 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
+#ifdef _OPENMP
+ if (!(sd->flags & SCULPT_USE_OPENMP))
+ omp_set_num_threads(BLI_system_thread_count()); /* set back to original logical corecount */
+#endif
+
sculpt_brush_exit_tex(sd);
}
@@ -4711,7 +4646,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
static void sculpt_dynamic_topology_triangulate(BMesh *bm)
{
if (bm->totloop != bm->totface * 3) {
- BM_mesh_triangulate(bm, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_SCANFILL, false, NULL, NULL);
+ BM_mesh_triangulate(bm, MOD_TRIANGULATE_QUAD_FIXED, MOD_TRIANGULATE_NGON_EARCLIP, false, NULL, NULL);
}
}
@@ -4729,6 +4664,36 @@ void sculpt_pbvh_clear(Object *ob)
BKE_object_free_derived_caches(ob);
}
+void sculpt_dyntopo_node_layers_add(SculptSession *ss)
+{
+ int cd_node_layer_index;
+
+ char layer_id[] = "_dyntopo_node_id";
+
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT, layer_id);
+ if (cd_node_layer_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT, layer_id);
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT, layer_id);
+ }
+
+ ss->cd_vert_node_offset = CustomData_get_n_offset(&ss->bm->vdata, CD_PROP_INT,
+ cd_node_layer_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_INT));
+
+ ss->bm->vdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
+
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT, layer_id);
+ if (cd_node_layer_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT, layer_id);
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT, layer_id);
+ }
+
+ ss->cd_face_node_offset = CustomData_get_n_offset(&ss->bm->pdata, CD_PROP_INT,
+ cd_node_layer_index - CustomData_get_layer_index(&ss->bm->pdata, CD_PROP_INT));
+
+ ss->bm->pdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
+}
+
+
void sculpt_update_after_dynamic_topology_toggle(bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -4736,7 +4701,7 @@ void sculpt_update_after_dynamic_topology_toggle(bContext *C)
Sculpt *sd = scene->toolsettings->sculpt;
/* Create the PBVH */
- sculpt_update_mesh_elements(scene, sd, ob, FALSE, FALSE);
+ BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
@@ -4750,8 +4715,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
sculpt_pbvh_clear(ob);
- ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
- SCULPT_DYNTOPO_SMOOTH_SHADING);
+ ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags & SCULPT_DYNTOPO_SMOOTH_SHADING) != 0;
/* Dynamic topology doesn't ensure selection state is valid, so remove [#36280] */
BKE_mesh_mselect_clear(me);
@@ -4762,6 +4726,8 @@ void sculpt_dynamic_topology_enable(bContext *C)
BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr);
sculpt_dynamic_topology_triangulate(ss->bm);
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ sculpt_dyntopo_node_layers_add(ss);
+ /* make sure the data for existing faces are initialized */
BM_mesh_normals_update(ss->bm);
/* Enable dynamic topology */
@@ -4813,7 +4779,7 @@ void sculpt_dynamic_topology_disable(bContext *C,
BKE_mesh_update_customdata_pointers(me, false);
}
else {
- sculptsession_bm_to_me(ob, TRUE);
+ BKE_sculptsession_bm_to_me(ob, true);
}
/* Clear data */
@@ -4981,79 +4947,9 @@ static void sculpt_init_session(Scene *scene, Object *ob)
{
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
- sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, FALSE);
+ BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
}
-int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
-{
- float *paint_mask;
- Mesh *me = ob->data;
- int ret = 0;
-
- paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
-
- /* if multires is active, create a grid paint mask layer if there
- * isn't one already */
- if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
- GridPaintMask *gmask;
- int level = max_ii(1, mmd->sculptlvl);
- int gridsize = BKE_ccg_gridsize(level);
- int gridarea = gridsize * gridsize;
- int i, j;
-
- gmask = CustomData_add_layer(&me->ldata, CD_GRID_PAINT_MASK,
- CD_CALLOC, NULL, me->totloop);
-
- for (i = 0; i < me->totloop; i++) {
- GridPaintMask *gpm = &gmask[i];
-
- gpm->level = level;
- gpm->data = MEM_callocN(sizeof(float) * gridarea,
- "GridPaintMask.data");
- }
-
- /* if vertices already have mask, copy into multires data */
- if (paint_mask) {
- for (i = 0; i < me->totpoly; i++) {
- const MPoly *p = &me->mpoly[i];
- float avg = 0;
-
- /* mask center */
- for (j = 0; j < p->totloop; j++) {
- const MLoop *l = &me->mloop[p->loopstart + j];
- avg += paint_mask[l->v];
- }
- avg /= (float)p->totloop;
-
- /* fill in multires mask corner */
- for (j = 0; j < p->totloop; j++) {
- GridPaintMask *gpm = &gmask[p->loopstart + j];
- const MLoop *l = &me->mloop[p->loopstart + j];
- const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j);
- const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j);
-
- gpm->data[0] = avg;
- gpm->data[1] = (paint_mask[l->v] +
- paint_mask[next->v]) * 0.5f;
- gpm->data[2] = (paint_mask[l->v] +
- paint_mask[prev->v]) * 0.5f;
- gpm->data[3] = paint_mask[l->v];
- }
- }
- }
-
- ret |= ED_SCULPT_MASK_LAYER_CALC_LOOP;
- }
-
- /* create vertex paint mask layer if there isn't one already */
- if (!paint_mask) {
- CustomData_add_layer(&me->vdata, CD_PAINT_MASK,
- CD_CALLOC, NULL, me->totvert);
- ret |= ED_SCULPT_MASK_LAYER_CALC_VERT;
- }
-
- return ret;
-}
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
{
@@ -5063,7 +4959,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
const int mode_flag = OB_MODE_SCULPT;
const bool is_mode_set = (ob->mode & mode_flag) != 0;
Mesh *me;
- MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
+ MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
int flush_recalc = 0;
if (!is_mode_set) {
@@ -5096,7 +4992,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
/* Leave sculptmode */
ob->mode &= ~mode_flag;
- free_sculptsession(ob);
+ BKE_free_sculptsession(ob);
paint_cursor_delete_textures();
}
@@ -5119,17 +5015,22 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
/* Turn on X plane mirror symmetry by default */
ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
+ ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH;
/* Make sure at least dyntopo subdivision is enabled */
ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE;
}
- if (!ts->sculpt->detail_size)
+ if (!ts->sculpt->detail_size) {
ts->sculpt->detail_size = 30;
+ }
+
+ if (ts->sculpt->constant_detail == 0.0f)
+ ts->sculpt->constant_detail = 30.0f;
/* Create sculpt mode session data */
if (ob->sculpt)
- free_sculptsession(ob);
+ BKE_free_sculptsession(ob);
sculpt_init_session(scene, ob);
@@ -5137,7 +5038,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
if (mmd) {
/* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res)
* but this ends up being quite tricky (and slow) */
- ED_sculpt_mask_layers_ensure(ob, mmd);
+ BKE_sculpt_mask_layers_ensure(ob, mmd);
}
BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
@@ -5164,6 +5065,175 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+static int sculpt_and_dynamic_topology_constant_detail_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+ return sculpt_mode_poll(C) && ob->sculpt->bm && (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT);
+}
+
+static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ float size;
+ float bb_min[3], bb_max[3];
+ int i, totnodes;
+ PBVHNode **nodes;
+
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes);
+
+ if (!totnodes)
+ return OPERATOR_CANCELLED;
+
+ for (i = 0; i < totnodes; i++) {
+ BKE_pbvh_node_mark_topology_update(nodes[i]);
+ }
+ /* get the bounding box, store the size to bb_max and center (zero) to bb_min */
+ BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max);
+ sub_v3_v3(bb_max, bb_min);
+ zero_v3(bb_min);
+ size = max_fff(bb_max[0], bb_max[1], bb_max[2]);
+
+ /* update topology size */
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f);
+
+ sculpt_undo_push_begin("Dynamic topology flood fill");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
+
+ while (BKE_pbvh_bmesh_update_topology(ss->pbvh, PBVH_Collapse | PBVH_Subdivide, bb_min, size)) {
+ for (i = 0; i < totnodes; i++)
+ BKE_pbvh_node_mark_topology_update(nodes[i]);
+ }
+
+ MEM_freeN(nodes);
+ sculpt_undo_push_end();
+
+ /* force rebuild of pbvh for better BB placement */
+ sculpt_pbvh_clear(ob);
+ /* Redraw */
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Detail Flood Fill";
+ ot->idname = "SCULPT_OT_detail_flood_fill";
+ ot->description = "Flood fill the mesh with the selected detail setting";
+
+ /* api callbacks */
+ ot->exec = sculpt_detail_flood_fill_exec;
+ ot->poll = sculpt_and_dynamic_topology_constant_detail_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static void sample_detail(bContext *C, int ss_co[2])
+{
+ ViewContext vc;
+ Object *ob;
+ Sculpt *sd;
+ float ray_start[3], ray_end[3], ray_normal[3], dist;
+ SculptDetailRaycastData srd;
+ float mouse[2] = {ss_co[0], ss_co[1]};
+ view3d_set_viewcontext(C, &vc);
+
+ sd = CTX_data_tool_settings(C)->sculpt;
+ ob = vc.obact;
+
+ sculpt_stroke_modifiers_check(C, ob);
+
+ dist = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
+
+ srd.hit = 0;
+ srd.ray_start = ray_start;
+ srd.ray_normal = ray_normal;
+ srd.dist = dist;
+ srd.detail = sd->constant_detail;
+
+ BKE_pbvh_raycast(ob->sculpt->pbvh, sculpt_raycast_detail_cb, &srd,
+ ray_start, ray_normal, false);
+
+ if (srd.hit) {
+ sd->constant_detail = srd.detail * 100.0f;
+ }
+}
+
+static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
+{
+ int ss_co[2];
+ RNA_int_get_array(op->ptr, "location", ss_co);
+ sample_detail(C, ss_co);
+ return OPERATOR_FINISHED;
+}
+
+
+static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ED_area_headerprint(sa, "Click on the mesh to set the detail");
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wmEvent *e)
+{
+ switch (e->type) {
+ case LEFTMOUSE:
+ if (e->val == KM_PRESS) {
+ ScrArea *sa = CTX_wm_area(C);
+ int ss_co[2] = {e->mval[0], e->mval[1]};
+
+ sample_detail(C, ss_co);
+
+ RNA_int_set_array(op->ptr, "location", ss_co);
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ ED_area_headerprint(sa, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ return OPERATOR_FINISHED;
+ }
+ break;
+
+ case RIGHTMOUSE:
+ {
+ ScrArea *sa = CTX_wm_area(C);
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ ED_area_headerprint(sa, NULL);
+
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Sample Detail Size";
+ ot->idname = "SCULPT_OT_sample_detail_size";
+ ot->description = "Sample the mesh detail on clicked point";
+
+ /* api callbacks */
+ ot->invoke = sculpt_sample_detail_size_invoke;
+ ot->exec = sculpt_sample_detail_size_exec;
+ ot->modal = sculpt_sample_detail_size_modal;
+ ot->poll = sculpt_and_dynamic_topology_constant_detail_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int_array(ot->srna, "location", 2, NULL, 0, SHRT_MAX, "Location", "Screen Coordinates of sampling", 0, SHRT_MAX);
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -5172,4 +5242,6 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_dynamic_topology_toggle);
WM_operatortype_append(SCULPT_OT_optimize);
WM_operatortype_append(SCULPT_OT_symmetrize);
+ WM_operatortype_append(SCULPT_OT_detail_flood_fill);
+ WM_operatortype_append(SCULPT_OT_sample_detail_size);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 8a6d1b6ee89..258cae9568e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -52,23 +52,18 @@ struct Sculpt;
struct SculptStroke;
struct SculptUndoNode;
-/* Interface */
-struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct Object *ob);
-
int sculpt_mode_poll(struct bContext *C);
int sculpt_mode_poll_view3d(struct bContext *C);
/* checks for a brush, not just sculpt mode */
int sculpt_poll(struct bContext *C);
int sculpt_poll_view3d(struct bContext *C);
-void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
- int need_pmap, int need_mask);
/* Stroke */
bool sculpt_stroke_get_location(struct bContext *C, float out[3], const float mouse[2]);
/* Dynamic topology */
void sculpt_pbvh_clear(struct Object *ob);
-void sculpt_update_after_dynamic_topology_toggle(struct bContext *C);
+void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
void sculpt_dynamic_topology_enable(struct bContext *C);
void sculpt_dynamic_topology_disable(struct bContext *C,
struct SculptUndoNode *unode);
@@ -112,7 +107,7 @@ typedef struct SculptUndoNode {
/* bmesh */
struct BMLogEntry *bm_entry;
- int applied;
+ bool applied;
CustomData bm_enter_vdata;
CustomData bm_enter_edata;
CustomData bm_enter_ldata;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 03321cd1a85..57e852db796 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -49,10 +49,8 @@
#include "DNA_mesh_types.h"
#include "BKE_ccg.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_key.h"
@@ -74,7 +72,7 @@
static void update_cb(PBVHNode *node, void *rebuild)
{
BKE_pbvh_node_mark_update(node);
- if (*((int *)rebuild))
+ if (*((bool *)rebuild))
BKE_pbvh_node_mark_rebuild_draw(node);
BKE_pbvh_node_fully_hidden_set(node, 0);
}
@@ -114,7 +112,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
if (kb) {
ob->shapenr = BLI_findindex(&key->block, kb) + 1;
- sculpt_update_mesh_elements(scene, sd, ob, 0, FALSE);
+ BKE_sculpt_update_mesh_elements(scene, sd, ob, 0, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
}
else {
@@ -273,14 +271,14 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
{
if (unode->applied) {
BM_log_undo(ss->bm, ss->bm_log);
- unode->applied = FALSE;
+ unode->applied = false;
}
else {
BM_log_redo(ss->bm, ss->bm_log);
- unode->applied = TRUE;
+ unode->applied = true;
}
- if (unode->type == SCULPT_UNDO_MASK) {
+ if (ELEM(unode->type, SCULPT_UNDO_MASK, SCULPT_UNDO_MASK)) {
int i, totnode;
PBVHNode **nodes;
@@ -296,10 +294,11 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
for (i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_redraw(nodes[i]);
}
+
+ if (nodes)
+ MEM_freeN(nodes);
}
else {
- /* A bit lame, but for now just recreate the PBVH. The alternative
- * is to store changes to the PBVH in the undo stack. */
sculpt_pbvh_clear(ob);
}
}
@@ -316,6 +315,7 @@ static void sculpt_undo_bmesh_enable(Object *ob,
/* Create empty BMesh and enable logging */
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ sculpt_dyntopo_node_layers_add(ss);
me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
/* Restore the BMLog using saved entries */
@@ -330,7 +330,7 @@ static void sculpt_undo_bmesh_restore_begin(bContext *C,
{
if (unode->applied) {
sculpt_dynamic_topology_disable(C, unode);
- unode->applied = FALSE;
+ unode->applied = false;
}
else {
sculpt_undo_bmesh_enable(ob, unode);
@@ -338,7 +338,7 @@ static void sculpt_undo_bmesh_restore_begin(bContext *C,
/* Restore the mesh from the first log entry */
BM_log_redo(ss->bm, ss->bm_log);
- unode->applied = TRUE;
+ unode->applied = true;
}
}
@@ -353,19 +353,19 @@ static void sculpt_undo_bmesh_restore_end(bContext *C,
/* Restore the mesh from the last log entry */
BM_log_undo(ss->bm, ss->bm_log);
- unode->applied = FALSE;
+ unode->applied = false;
}
else {
/* Disable dynamic topology sculpting */
sculpt_dynamic_topology_disable(C, NULL);
- unode->applied = TRUE;
+ unode->applied = true;
}
}
/* Handle all dynamic-topology updates
*
- * Returns TRUE if this was a dynamic-topology undo step, otherwise
- * returns FALSE to indicate the non-dyntopo code should run. */
+ * Returns true if this was a dynamic-topology undo step, otherwise
+ * returns false to indicate the non-dyntopo code should run. */
static int sculpt_undo_bmesh_restore(bContext *C,
SculptUndoNode *unode,
Object *ob,
@@ -374,21 +374,21 @@ static int sculpt_undo_bmesh_restore(bContext *C,
switch (unode->type) {
case SCULPT_UNDO_DYNTOPO_BEGIN:
sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
- return TRUE;
+ return true;
case SCULPT_UNDO_DYNTOPO_END:
sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
- return TRUE;
+ return true;
default:
if (ss->bm_log) {
sculpt_undo_bmesh_restore_generic(C, unode, ob, ss);
- return TRUE;
+ return true;
}
break;
}
- return FALSE;
+ return false;
}
static void sculpt_undo_restore(bContext *C, ListBase *lb)
@@ -399,21 +399,21 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
SculptUndoNode *unode;
- int update = FALSE, rebuild = FALSE;
- int need_mask = FALSE;
+ bool update = false, rebuild = false;
+ bool need_mask = false;
for (unode = lb->first; unode; unode = unode->next) {
if (strcmp(unode->idname, ob->id.name) == 0) {
if (unode->type == SCULPT_UNDO_MASK) {
/* is possible that we can't do the mask undo (below)
* because of the vertex count */
- need_mask = TRUE;
+ need_mask = true;
break;
}
}
}
- sculpt_update_mesh_elements(scene, sd, ob, 0, need_mask);
+ BKE_sculpt_update_mesh_elements(scene, sd, ob, 0, need_mask);
/* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
dm = mesh_get_derived_final(scene, ob, 0);
@@ -442,15 +442,15 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
switch (unode->type) {
case SCULPT_UNDO_COORDS:
if (sculpt_undo_restore_coords(C, dm, unode))
- update = TRUE;
+ update = true;
break;
case SCULPT_UNDO_HIDDEN:
if (sculpt_undo_restore_hidden(C, dm, unode))
- rebuild = TRUE;
+ rebuild = true;
break;
case SCULPT_UNDO_MASK:
if (sculpt_undo_restore_mask(C, dm, unode))
- update = TRUE;
+ update = true;
break;
case SCULPT_UNDO_DYNTOPO_BEGIN:
@@ -462,29 +462,29 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
}
if (update || rebuild) {
- int tag_update = 0;
+ bool tag_update = false;
/* we update all nodes still, should be more clever, but also
* needs to work correct when exiting/entering sculpt mode and
* the nodes get recreated, though in that case it could do all */
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
- if (sculpt_multires_active(scene, ob)) {
+ if (BKE_sculpt_multires_active(scene, ob)) {
if (rebuild)
multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
else
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
}
- tag_update = ((Mesh *)ob->data)->id.us > 1;
+ tag_update |= ((Mesh *)ob->data)->id.us > 1;
- if (ss->modifiers_active) {
+ if (ss->kb || ss->modifiers_active) {
Mesh *mesh = ob->data;
BKE_mesh_calc_normals_tessface(mesh->mvert, mesh->totvert,
mesh->mface, mesh->totface, NULL);
- free_sculptsession_deformMats(ss);
- tag_update |= 1;
+ BKE_free_sculptsession_deformMats(ss);
+ tag_update |= true;
}
if (tag_update) {
@@ -709,11 +709,11 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
PBVHVertexIter vd;
if (!lb->first) {
- unode = MEM_callocN(sizeof(*unode), AT);
+ unode = MEM_callocN(sizeof(*unode), __func__);
BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
unode->type = type;
- unode->applied = TRUE;
+ unode->applied = true;
if (type == SCULPT_UNDO_DYNTOPO_END) {
unode->bm_entry = BM_log_entry_add(ss->bm_log);
@@ -753,15 +753,30 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
if (node) {
switch (type) {
case SCULPT_UNDO_COORDS:
- case SCULPT_UNDO_HIDDEN:
case SCULPT_UNDO_MASK:
/* Before any vertex values get modified, ensure their
* original positions are logged */
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
- BM_log_vert_before_modified(ss->bm, ss->bm_log, vd.bm_vert);
+ BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
+ }
+ BKE_pbvh_vertex_iter_end;
+ break;
+
+ case SCULPT_UNDO_HIDDEN:
+ {
+ GSetIterator gs_iter;
+ GSet *faces = BKE_pbvh_bmesh_node_faces(node);
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
+ BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
}
BKE_pbvh_vertex_iter_end;
+
+ GSET_ITER (gs_iter, faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
+ BM_log_face_modified(ss->bm_log, f);
+ }
break;
+ }
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 4dc2c87ca0a..797a881ce79 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -40,16 +40,13 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_brush.h"
#include "BKE_paint.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_main.h"
#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@@ -68,6 +65,9 @@
#include "paint_intern.h"
#include "uvedit_intern.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
#include "UI_view2d.h"
#define MARK_BOUNDARY 1
@@ -185,6 +185,45 @@ static int uv_sculpt_brush_poll(bContext *C)
return 0;
}
+static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
+{
+#define PX_SIZE_FADE_MAX 12.0f
+#define PX_SIZE_FADE_MIN 4.0f
+
+ Scene *scene = CTX_data_scene(C);
+ //Brush *brush = image_paint_brush(C);
+ Paint *paint = BKE_paint_get_active_from_context(C);
+ Brush *brush = BKE_paint_brush(paint);
+
+ if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
+ const float size = (float)BKE_brush_size_get(scene, brush);
+ float alpha = 0.5f;
+
+ /* fade out the brush (cheap trick to work around brush interfering with sampling [#])*/
+ if (size < PX_SIZE_FADE_MIN) {
+ return;
+ }
+ else if (size < PX_SIZE_FADE_MAX) {
+ alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
+ }
+
+ glPushMatrix();
+
+ glTranslatef((float)x, (float)y, 0.0f);
+
+ glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size, 40);
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+
+ glPopMatrix();
+ }
+#undef PX_SIZE_FADE_MAX
+#undef PX_SIZE_FADE_MIN
+}
+
void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
{
@@ -194,12 +233,14 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings
settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
+ /* Uv sculpting does not include explicit brush view control yet, always enable */
+ settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
}
BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
- brush_drawcursor_texpaint_uvsculpt, NULL);
+ brush_drawcursor_uvsculpt, NULL);
}
else {
if (settings->uvsculpt)
@@ -516,8 +557,8 @@ static int uv_element_offset_from_face_get(UvElementMap *map, BMFace *efa, BMLoo
static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
- return (BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)));
+ return (BLI_ghashutil_uinthash(edge->uv2) +
+ BLI_ghashutil_uinthash(edge->uv1));
}
static int uv_edge_compare(const void *a, const void *b)
@@ -628,7 +669,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
MEM_freeN(uniqueUv);
}
if (edgeHash) {
- MEM_freeN(edgeHash);
+ BLI_ghash_free(edgeHash, NULL, NULL);
}
uv_sculpt_stroke_exit(C, op);
return NULL;
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 168693db60b..619fbd7f4c8 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -39,7 +39,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "DNA_anim_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -187,8 +186,8 @@ static void SOUND_OT_open(wmOperatorType *ot)
/* properties */
WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
- RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
- RNA_def_boolean(ot->srna, "mono", FALSE, "Mono", "Mixdown the sound to mono");
+ RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
+ RNA_def_boolean(ot->srna, "mono", false, "Mono", "Mixdown the sound to mono");
}
static void SOUND_OT_open_mono(wmOperatorType *ot)
@@ -209,8 +208,8 @@ static void SOUND_OT_open_mono(wmOperatorType *ot)
/* properties */
WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
- RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
- RNA_def_boolean(ot->srna, "mono", TRUE, "Mono", "Mixdown the sound to mono");
+ RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
+ RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
}
/* ******************************************************* */
@@ -430,10 +429,10 @@ static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
return check;
RNA_property_string_set(op->ptr, prop, filepath);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
#endif // WITH_AUDASPACE
@@ -476,12 +475,6 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem ac3_format_items[] = {
- {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
- {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
- {0, NULL, 0, NULL, NULL}
- };
-
#ifdef WITH_SNDFILE
static EnumPropertyItem flac_format_items[] = {
{AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
@@ -527,10 +520,9 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
switch (container) {
case AUD_CONTAINER_AC3:
- RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
- RNA_def_property_enum_items(prop_format, ac3_format_items);
RNA_def_property_enum_items(prop_codec, all_codec_items);
RNA_enum_set(op->ptr, "codec", AUD_CODEC_AC3);
+ RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
break;
case AUD_CONTAINER_FLAC:
RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
@@ -552,8 +544,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
RNA_enum_set(op->ptr, "format", AUD_FORMAT_S16);
break;
case AUD_CODEC_AC3:
- RNA_def_property_enum_items(prop_format, ac3_format_items);
- RNA_def_property_clear_flag(prop_format, PROP_HIDDEN);
+ RNA_enum_set(op->ptr, "format", AUD_FORMAT_FLOAT32);
break;
case AUD_CODEC_FLAC:
RNA_def_property_flag(prop_bitrate, PROP_HIDDEN);
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index db23bfd188f..39f179c965a 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -38,7 +38,6 @@
#include <float.h>
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
/* Types --------------------------------------------------------------- */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index e2ca45bbdc9..92e727fc2d7 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -42,7 +42,6 @@
#include "DNA_anim_types.h"
#include "DNA_gpencil_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
@@ -65,7 +64,6 @@
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
#include "ED_screen.h"
-#include "ED_transform.h"
#include "ED_markers.h"
#include "ED_mask.h"
@@ -122,7 +120,7 @@ static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
}
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
}
@@ -285,7 +283,7 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
float tmin, tmax;
/* get range and apply necessary scaling before processing */
- if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE)) {
+ if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, true)) {
if (adt) {
tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
@@ -335,7 +333,7 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
scene = ac.scene;
/* set the range directly */
- get_keyframe_extents(&ac, &min, &max, FALSE);
+ get_keyframe_extents(&ac, &min, &max, false);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = iroundf(min);
scene->r.pefra = iroundf(max);
@@ -364,11 +362,64 @@ void ACTION_OT_previewrange_set(wmOperatorType *ot)
/* ****************** View-All Operator ****************** */
-static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xaxis)
+/* Find the extents of the active channel
+ * > min: (float) bottom y-extent of channel
+ * > max: (float) top y-extent of channel
+ * > returns: success of finding a selected channel
+ */
+static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min, float *max)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ float y;
+
+ /* get all items - we need to do it this way */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through all channels, finding the first one that's selected */
+ y = (float)ACHANNEL_FIRST;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* must be selected... */
+ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
+ ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
+ {
+ /* update best estimate */
+ *min = (float)(y - ACHANNEL_HEIGHT_HALF);
+ *max = (float)(y + ACHANNEL_HEIGHT_HALF);
+
+ /* is this high enough priority yet? */
+ found = acf->channel_role;
+
+ /* only stop our search when we've found an actual channel
+ * - datablock expanders get less priority so that we don't abort prematurely
+ */
+ if (found == ACHANNEL_ROLE_CHANNEL) {
+ break;
+ }
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP;
+ }
+
+ /* free all temp data */
+ BLI_freelistN(&anim_data);
+
+ return (found != 0);
+}
+
+static int actkeys_viewall(bContext *C, const bool only_sel)
{
bAnimContext ac;
View2D *v2d;
- float extra;
+ float extra, min, max;
bool found;
/* get editor data */
@@ -377,20 +428,38 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
v2d = &ac.ar->v2d;
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
- found = get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel);
+ found = get_keyframe_extents(&ac, &min, &max, only_sel);
if (only_sel && (found == false))
return OPERATOR_CANCELLED;
-
+
+ v2d->cur.xmin = min;
+ v2d->cur.xmax = max;
+
extra = 0.1f * BLI_rctf_size_x(&v2d->cur);
v2d->cur.xmin -= extra;
v2d->cur.xmax += extra;
/* set vertical range */
- if (only_xaxis == false) {
+ if (only_sel == false) {
+ /* view all -> the summary channel is usually the shows everything, and resides right at the top... */
v2d->cur.ymax = 0.0f;
v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
}
+ else {
+ /* locate first selected channel (or the active one), and frame those */
+ float ymin = v2d->cur.ymin;
+ float ymax = v2d->cur.ymax;
+
+ if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
+ /* recenter the view so that this range is in the middle */
+ float ymid = (ymax - ymin) / 2.0f + ymin;
+ float x_center;
+
+ UI_view2d_center_get(v2d, &x_center, NULL);
+ UI_view2d_center_set(v2d, x_center, ymid);
+ }
+ }
/* do View2D syncing */
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
@@ -406,13 +475,13 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op))
{
/* whole range */
- return actkeys_viewall(C, false, false);
+ return actkeys_viewall(C, false);
}
static int actkeys_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
{
/* only selected */
- return actkeys_viewall(C, true, true);
+ return actkeys_viewall(C, true);
}
void ACTION_OT_view_all(wmOperatorType *ot)
@@ -677,7 +746,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
}
@@ -750,7 +819,7 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
}
@@ -840,7 +909,7 @@ static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 346ffcbc3e2..93cd94ed892 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -35,7 +35,6 @@
#include "DNA_space_types.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "ED_anim_api.h"
@@ -111,61 +110,61 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* action_select.c - selection tools */
/* click-select: keyframe (replace) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
- RNA_boolean_set(kmi->ptr, "channel", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "column", false);
+ RNA_boolean_set(kmi->ptr, "channel", false);
/* click-select: all on same frame (replace) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "column", TRUE);
- RNA_boolean_set(kmi->ptr, "channel", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "column", true);
+ RNA_boolean_set(kmi->ptr, "channel", false);
/* click-select: keyframe (add) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
- RNA_boolean_set(kmi->ptr, "channel", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "column", false);
+ RNA_boolean_set(kmi->ptr, "channel", false);
/* click-select: all on same frame (add) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "column", TRUE);
- RNA_boolean_set(kmi->ptr, "channel", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "column", true);
+ RNA_boolean_set(kmi->ptr, "channel", false);
/* click-select: all on same channel (replace) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
- RNA_boolean_set(kmi->ptr, "channel", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "column", false);
+ RNA_boolean_set(kmi->ptr, "channel", true);
/* click-select: all on same channel (add) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
- RNA_boolean_set(kmi->ptr, "channel", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "column", false);
+ RNA_boolean_set(kmi->ptr, "channel", true);
/* click-select: left/right */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_RIGHT);
/* deselect all */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "invert", FALSE);
+ RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "invert", TRUE);
+ RNA_boolean_set(kmi->ptr, "invert", true);
/* borderselect */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", FALSE);
+ RNA_boolean_set(kmi->ptr, "axis_range", false);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", TRUE);
+ RNA_boolean_set(kmi->ptr, "axis_range", true);
/* column select */
RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS);
@@ -216,6 +215,7 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* auto-set range */
WM_keymap_add_item(keymap, "ACTION_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "ACTION_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ACTION_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACTION_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
/* animation module */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index c256dbb3b59..1e89b304279 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -35,7 +35,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_dlrbTree.h"
#include "BLI_utildefines.h"
@@ -203,7 +202,7 @@ enum {
} /*eActKeys_BorderSelect_Mode*/;
-static void borderselect_action(bAnimContext *ac, rcti rect, short mode, short selectmode)
+static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, short selectmode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -369,7 +368,7 @@ void ACTION_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
}
@@ -890,7 +889,7 @@ static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wm
float x;
/* determine which side of the current frame mouse is on */
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL);
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
if (x < CFRA)
RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_LEFT);
else
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 8d27b914905..49bed19898b 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -374,11 +374,20 @@ static void action_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
ED_area_tag_refresh(sa);
}
- /* for selection changes of animation data, we can just redraw... otherwise autocolor might need to be done again */
- else if (ELEM(wmn->data, ND_KEYFRAME, ND_ANIMCHAN) && (wmn->action == NA_SELECTED))
- ED_area_tag_redraw(sa);
- else
+ /* autocolor only really needs to change when channels are added/removed, or previously hidden stuff appears
+ * (assume for now that if just adding these works, that will be fine)
+ */
+ else if (((wmn->data == ND_KEYFRAME) && ELEM(wmn->action, NA_ADDED, NA_REMOVED)) ||
+ ((wmn->data == ND_ANIMCHAN) && (wmn->action != NA_SELECTED)))
+ {
ED_area_tag_refresh(sa);
+ }
+ /* for simple edits to the curve data though (or just plain selections), a simple redraw should work
+ * (see T39851 for an example of how this can go wrong)
+ */
+ else {
+ ED_area_tag_redraw(sa);
+ }
break;
case NC_SCENE:
switch (wmn->data) {
@@ -448,10 +457,9 @@ static void action_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
}
}
-static void action_header_area_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn)
+static void action_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
{
-
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+ // SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
/* context changes */
switch (wmn->category) {
@@ -469,7 +477,7 @@ static void action_header_area_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegio
case NC_ANIMATION:
switch (wmn->data) {
case ND_KEYFRAME:
- saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
+ //saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index e2262398a52..83040a26480 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -119,7 +119,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_mask();
ED_operatortypes_io();
- UI_view2d_operatortypes();
+ ED_operatortypes_view2d();
UI_buttons_operatortypes();
/* register operators */
@@ -177,9 +177,9 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
ED_keymap_metaball(keyconf);
ED_keymap_paint(keyconf);
ED_keymap_mask(keyconf);
- ED_marker_keymap(keyconf);
+ ED_keymap_marker(keyconf);
- UI_view2d_keymap(keyconf);
+ ED_keymap_view2d(keyconf);
spacetypes = BKE_spacetypes_list();
for (stype = spacetypes->first; stype; stype = stype->next) {
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 4718f5dbbdd..a00aac12fba 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -44,8 +44,8 @@
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
-#include "DNA_speaker_types.h"
#include "DNA_brush_types.h"
+#include "DNA_linestyle_types.h"
#include "BKE_context.h"
#include "BKE_action.h"
@@ -140,6 +140,30 @@ static int buttons_context_path_world(ButsContextPath *path)
return 0;
}
+static int buttons_context_path_linestyle(ButsContextPath *path)
+{
+ Scene *scene;
+ FreestyleLineStyle *linestyle;
+ PointerRNA *ptr = &path->ptr[path->len - 1];
+
+ /* if we already have a (pinned) linestyle, we're done */
+ if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
+ return 1;
+ }
+ /* if we have a scene, use the lineset's linestyle */
+ else if (buttons_context_path_scene(path)) {
+ scene = path->ptr[path->len - 1].data;
+ linestyle = CTX_data_linestyle_from_scene(scene);
+ if (linestyle) {
+ RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]);
+ path->len++;
+ return 1;
+ }
+ }
+
+ /* no path to a linestyle possible */
+ return 0;
+}
static int buttons_context_path_object(ButsContextPath *path)
{
@@ -396,6 +420,8 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
buttons_context_path_particle(path);
else if (GS(id->name) == ID_OB)
buttons_context_path_object(path);
+ else if (GS(id->name) == ID_LS)
+ buttons_context_path_linestyle(path);
}
if (ct->texture) {
@@ -411,6 +437,7 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
Lamp *la;
World *wo;
ParticleSystem *psys;
+ FreestyleLineStyle *ls;
Tex *tex;
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -476,12 +503,50 @@ static int buttons_context_path_texture(ButsContextPath *path, ButsContextTextur
return 1;
}
}
+ /* try linestyle */
+ else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) {
+ ls = path->ptr[path->len - 1].data;
+
+ if (ls) {
+ tex = give_current_linestyle_texture(ls);
+
+ RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+ path->len++;
+ return 1;
+ }
+ }
}
/* no path to a texture possible */
return 0;
}
+#ifdef WITH_FREESTYLE
+static bool buttons_context_linestyle_pinnable(const bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneRenderLayer *actsrl;
+ FreestyleConfig *config;
+ SpaceButs *sbuts;
+
+ /* if Freestyle is disabled in the scene */
+ if ((scene->r.mode & R_EDGE_FRS) == 0) {
+ return false;
+ }
+ /* if Freestyle is not in the Parameter Editor mode */
+ actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ config = &actsrl->freestyleConfig;
+ if (config->mode != FREESTYLE_CONTROL_EDITOR_MODE) {
+ return false;
+ }
+ /* if the scene has already been pinned */
+ sbuts = CTX_wm_space_buts(C);
+ if (sbuts->pinid && sbuts->pinid == &scene->id) {
+ return false;
+ }
+ return true;
+}
+#endif
static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
@@ -513,7 +578,17 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
switch (mainb) {
case BCONTEXT_SCENE:
case BCONTEXT_RENDER:
+ found = buttons_context_path_scene(path);
+ break;
case BCONTEXT_RENDER_LAYER:
+#ifdef WITH_FREESTYLE
+ if (buttons_context_linestyle_pinnable(C)) {
+ found = buttons_context_path_linestyle(path);
+ if (found) {
+ break;
+ }
+ }
+#endif
found = buttons_context_path_scene(path);
break;
case BCONTEXT_WORLD:
@@ -587,13 +662,16 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
PointerRNA *ptr;
int a, pflag = 0, flag = 0;
- buttons_texture_context_compute(C, sbuts);
-
if (!sbuts->path)
sbuts->path = MEM_callocN(sizeof(ButsContextPath), "ButsContextPath");
-
+
path = sbuts->path;
-
+
+ /* We need to set Scene path now! Else, buttons_texture_context_compute() might not get a valid scene. */
+ buttons_context_path(C, path, BCONTEXT_SCENE, pflag);
+
+ buttons_texture_context_compute(C, sbuts);
+
/* for each context, see if we can compute a valid path to it, if
* this is the case, we know we have to display the button */
for (a = 0; a < BCONTEXT_TOT; a++) {
@@ -656,11 +734,12 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
/************************* Context Callback ************************/
const char *buttons_context_dir[] = {
- "texture_slot", "world", "object", "mesh", "armature", "lattice", "curve",
+ "texture_slot", "scene", "world", "object", "mesh", "armature", "lattice", "curve",
"meta_ball", "lamp", "speaker", "camera", "material", "material_slot",
"texture", "texture_user", "texture_user_property", "bone", "edit_bone",
"pose_bone", "particle_system", "particle_system_editable", "particle_settings",
- "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint", NULL
+ "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint",
+ "line_style", NULL
};
int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -681,6 +760,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_dir_set(result, buttons_context_dir);
return 1;
}
+ else if (CTX_data_equals(member, "scene")) {
+ /* Do not return one here if scene not found in path, in this case we want to get default context scene! */
+ return set_pointer_type(path, result, &RNA_Scene);
+ }
else if (CTX_data_equals(member, "world")) {
set_pointer_type(path, result, &RNA_World);
return 1;
@@ -854,6 +937,12 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
if (wo)
CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]);
}
+ else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) {
+ FreestyleLineStyle *ls = ptr->data;
+
+ if (ls)
+ CTX_data_pointer_set(result, &ls->id, &RNA_LineStyleTextureSlot, ls->mtex[(int)ls->texact]);
+ }
return 1;
}
@@ -966,6 +1055,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
}
+ else if (CTX_data_equals(member, "line_style")) {
+ set_pointer_type(path, result, &RNA_FreestyleLineStyle);
+ return 1;
+ }
else {
return 0; /* not found */
}
@@ -1002,13 +1095,13 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
if (!path)
return;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
block = uiLayoutGetBlock(row);
uiBlockSetEmboss(block, UI_EMBOSSN);
but = uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag,
- 0, 0, 0, 0, IFACE_("Follow context or keep fixed datablock displayed"));
+ 0, 0, 0, 0, TIP_("Follow context or keep fixed datablock displayed"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
uiButSetFunc(but, pin_cb, NULL, NULL);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 7c42ea9a13b..c558d811693 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -51,6 +51,8 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
+
#include "BKE_context.h"
#include "BKE_material.h"
@@ -59,6 +61,7 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
+#include "BKE_freestyle.h"
#include "RNA_access.h"
@@ -99,6 +102,32 @@ bool ED_texture_context_check_particles(const bContext *C)
return (ob && ob->particlesystem.first);
}
+bool ED_texture_context_check_linestyle(const bContext *C)
+{
+#ifdef WITH_FREESTYLE
+ Scene *scene = CTX_data_scene(C);
+ SceneRenderLayer *actsrl;
+ FreestyleConfig *config;
+ FreestyleLineSet *lineset;
+ FreestyleLineStyle *linestyle;
+
+ if (scene && (scene->r.mode & R_EDGE_FRS)) {
+ actsrl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ config = &actsrl->freestyleConfig;
+ if (config->mode == FREESTYLE_CONTROL_EDITOR_MODE) {
+ lineset = BKE_freestyle_lineset_get_active(config);
+ if (lineset) {
+ linestyle = lineset->linestyle;
+ return linestyle && (linestyle->flag & LS_TEXTURE);
+ }
+ }
+ }
+#else
+ (void)C;
+#endif
+ return false;
+}
+
static void texture_context_check_modifier_foreach(void *userData, Object *UNUSED(ob), ModifierData *UNUSED(md),
const char *UNUSED(propname))
{
@@ -148,6 +177,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
bool valid_material = ED_texture_context_check_material(C);
bool valid_lamp = ED_texture_context_check_lamp(C);
bool valid_particles = ED_texture_context_check_particles(C);
+ bool valid_linestyle = ED_texture_context_check_linestyle(C);
bool valid_others = ED_texture_context_check_others(C);
/* this is similar to direct user action, no need to keep "better" ctxt in _prev */
@@ -163,6 +193,9 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) {
sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES;
}
+ else if ((sbuts->mainb == BCONTEXT_RENDER_LAYER) && valid_linestyle) {
+ sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LINESTYLE;
+ }
else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) {
sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_OTHER;
}
@@ -172,6 +205,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
((sbuts->texture_context_prev == SB_TEXC_MATERIAL) && valid_material) ||
((sbuts->texture_context_prev == SB_TEXC_LAMP) && valid_lamp) ||
((sbuts->texture_context_prev == SB_TEXC_PARTICLES) && valid_particles) ||
+ ((sbuts->texture_context_prev == SB_TEXC_LINESTYLE) && valid_linestyle) ||
((sbuts->texture_context_prev == SB_TEXC_OTHER) && valid_others)))
{
sbuts->texture_context = sbuts->texture_context_prev;
@@ -181,6 +215,7 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
+ ((sbuts->texture_context == SB_TEXC_LINESTYLE) && !valid_linestyle) ||
((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
{
/* this is default fallback, do keep "better" ctxt in _prev */
@@ -194,6 +229,9 @@ static void set_texture_context(const bContext *C, SpaceButs *sbuts)
else if (valid_particles) {
sbuts->texture_context = SB_TEXC_PARTICLES;
}
+ else if (valid_linestyle) {
+ sbuts->texture_context = SB_TEXC_LINESTYLE;
+ }
else if (valid_world) {
sbuts->texture_context = SB_TEXC_WORLD;
}
@@ -284,6 +322,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
Material *ma = NULL;
Lamp *la = NULL;
World *wrld = NULL;
+ FreestyleLineStyle *linestyle = NULL;
Brush *brush = NULL;
ID *pinid = sbuts->pinid;
bool limited_mode = (sbuts->flag & SB_TEX_USER_LIMITED) != 0;
@@ -302,6 +341,8 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
ma = (Material *)pinid;
else if (GS(pinid->name) == ID_BR)
brush = (Brush *)pinid;
+ else if (GS(pinid->name) == ID_LS)
+ linestyle = (FreestyleLineStyle *)pinid;
}
if (!scene)
@@ -311,6 +352,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
ob = (scene->basact) ? scene->basact->object : NULL;
wrld = scene->world;
brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
+ linestyle = CTX_data_linestyle_from_scene(scene);
}
if (ob && ob->type == OB_LAMP && !la)
@@ -327,6 +369,8 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp");
if (wrld && !limited_mode)
buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World");
+ if (linestyle && !limited_mode)
+ buttons_texture_users_find_nodetree(users, &linestyle->id, linestyle->nodetree, "LineStyle");
if (ob) {
ParticleSystem *psys = psys_get_current(ob);
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 8e03dc50abc..1257dcb5e4c 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -35,7 +35,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -44,15 +43,12 @@
#include "ED_space_api.h"
#include "ED_screen.h"
-#include "GPU_glew.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "ED_render.h"
#include "buttons_intern.h" /* own include */
@@ -311,6 +307,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *
switch (wmn->data) {
case ND_SELECT:
case ND_DATA:
+ case ND_VERTEX_GROUP:
ED_area_tag_redraw(sa);
break;
}
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 50bb8a0e061..cda46d2a9c2 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -42,7 +42,6 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
-#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLF_translation.h"
@@ -53,7 +52,6 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
-#include "ED_clip.h"
#include "ED_gpencil.h"
#include "UI_interface.h"
@@ -130,18 +128,18 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
if (clip) {
uiLayout *col;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
uiDefBut(block, LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
- row = uiLayoutRow(layout, FALSE);
- split = uiLayoutSplit(row, 0.0f, FALSE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(layout, false);
+ split = uiLayoutSplit(row, 0.0f, false);
+ row = uiLayoutRow(split, true);
uiItemR(row, &clipptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "clip.reload");
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiTemplateColorspaceSettings(col, &clipptr, "colorspace_settings");
}
}
@@ -153,7 +151,7 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
PropertyRNA *prop;
PointerRNA scopesptr;
uiBlock *block;
- rctf rect;
+ uiLayout *col;
MovieClipScopes *scopes;
if (!ptr->data)
@@ -175,16 +173,21 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
scopesptr = RNA_property_pointer_get(ptr, prop);
scopes = (MovieClipScopes *)scopesptr.data;
- rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
- rect.ymin = 0; rect.ymax = 6.0f * UI_UNIT_Y;
+ if (scopes->track_preview_height < UI_UNIT_Y) {
+ scopes->track_preview_height = UI_UNIT_Y;
+ }
+ else if (scopes->track_preview_height > UI_UNIT_Y * 20) {
+ scopes->track_preview_height = UI_UNIT_Y * 20;
+ }
- block = uiLayoutAbsoluteBlock(layout);
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
- scopes->track_preview_height =
- (scopes->track_preview_height <= 20) ? 20 : scopes->track_preview_height;
+ uiDefBut(block, TRACKPREVIEW, 0, "", 0, 0, UI_UNIT_X * 10, scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
- uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
- scopes->track_preview_height * UI_DPI_FAC, scopes, 0, 0, 0, 0, "");
+ /* Resize grip. */
+ uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.8f),
+ &scopes->track_preview_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
/********************* Marker Template ************************/
@@ -412,7 +415,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
BKE_movieclip_get_size(clip, user, &width, &height);
if (track->flag & TRACK_LOCKED) {
- uiLayoutSetActive(layout, FALSE);
+ uiLayoutSetActive(layout, false);
block = uiLayoutAbsoluteBlock(layout);
uiDefBut(block, LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
@@ -450,7 +453,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 0.5 * UI_UNIT_X, 9.5 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y,
&cb->marker_flag, 0, 0, 0, 0, tip);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0);
block = uiLayoutAbsoluteBlock(col);
@@ -523,7 +526,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout, PointerRNA *ptr, const cha
clip = (MovieClip *)clipptr.data;
user = userptr->data;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
ibuf = BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, MOVIECLIP_CACHE_SKIP);
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 4a6084db1c4..cbe79fcd48e 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -33,17 +33,12 @@
#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BKE_context.h"
#include "BKE_movieclip.h"
-#include "BKE_tracking.h"
#include "ED_screen.h"
#include "ED_clip.h"
@@ -54,7 +49,6 @@
#include "GPU_primitives.h"
#include "GPU_raster.h"
-#include "BIF_glutil.h"
#include "WM_types.h"
@@ -84,7 +78,7 @@ static void track_channel_color(MovieTrackingTrack *track, float default_color[3
}
}
-static void draw_keyframe_shape(float x, float y, float xscale, float yscale, short sel, float alpha)
+static void draw_keyframe_shape(float x, float y, float xscale, float yscale, bool sel, float alpha)
{
/* coordinates for diamond shape */
static const float _unit_diamond_shape[4][2] = {
@@ -185,7 +179,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
y = (float) CHANNEL_FIRST;
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
/* setup colors for regular and selected strips */
UI_GetThemeColor3fv(TH_STRIP, strip);
@@ -208,7 +202,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
{
MovieTrackingTrack *track = channel->track;
float alpha;
- int i, sel = track->flag & TRACK_DOPE_SEL;
+ int i;
+ bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
/* selection background */
if (sel) {
@@ -321,7 +316,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
{
MovieTrackingTrack *track = channel->track;
float font_height, color[3];
- int sel = track->flag & TRACK_DOPE_SEL;
+ bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
track_channel_color(track, NULL, color);
gpuColor3fv(color);
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
index 0fbed2c3c1e..573b6bc9276 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_ops.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -32,17 +32,12 @@
#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BKE_context.h"
-#include "BKE_movieclip.h"
#include "BKE_tracking.h"
-#include "BKE_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -71,7 +66,7 @@ static int space_clip_dopesheet_poll(bContext *C)
}
}
- return FALSE;
+ return false;
}
/********************** select channel operator *********************/
@@ -83,7 +78,7 @@ static int dopesheet_select_channel_poll(bContext *C)
if (sc && sc->clip)
return sc->view == SC_VIEW_DOPESHEET;
- return FALSE;
+ return false;
}
static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
@@ -113,7 +108,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
if (track->flag & TRACK_DOPE_SEL) {
tracking->act_track = track;
- BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, TRUE);
+ BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, true);
}
}
else if (!extend)
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 014ebee0bd2..299f1a75c9f 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -32,8 +32,6 @@
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_types.h" /* SELECT */
-#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
@@ -44,14 +42,12 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_string.h"
-#include "BLI_rect.h"
#include "BLI_math_base.h"
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
-#include "BKE_mask.h"
#include "ED_screen.h"
#include "ED_clip.h"
@@ -69,7 +65,6 @@
#include "BIF_glutil.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
@@ -84,26 +79,6 @@
/*********************** main area drawing *************************/
-void clip_draw_curfra_label(const int framenr, const float x, const float y)
-{
- uiStyle *style = UI_GetStyle();
- int fontid = style->widget.uifont_id;
- char numstr[32];
- float font_dims[2] = {0.0f, 0.0f};
-
- /* frame number */
- BLF_size(fontid, 11.0f, U.dpi);
- BLI_snprintf(numstr, sizeof(numstr), "%d", framenr);
-
- BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
-
- gpuSingleFilledRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
-
- UI_ThemeColor(TH_TEXT);
- BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
- BLF_draw(fontid, numstr, sizeof(numstr));
-}
-
static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width)
{
int height = (frame == cfra) ? 22 : 10;
@@ -191,23 +166,11 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* cache background */
- gpuColor4ub(128, 128, 255, 64);
- gpuSingleFilledRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
+ ED_region_cache_draw_background(ar);
/* cached segments -- could be usefu lto debug caching strategies */
BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
- if (totseg) {
- gpuColor4ub(128, 128, 255, 128);
-
- for (a = 0; a < totseg; a++) {
- float x1, x2;
-
- x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
- x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
-
- gpuSingleFilledRecti(x1, 0, x2, 8 * UI_DPI_FAC);
- }
- }
+ ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);
/* track */
if (act_track || act_plane_track) {
@@ -279,7 +242,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
UI_ThemeColor(TH_CFRAME);
gpuSingleFilledRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
- clip_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
+ ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
/* solver keyframes */
gpuColor4ub(175, 255, 0, 255);
@@ -321,7 +284,7 @@ static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx
int x, y;
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
gpuColor3f(0.0f, 0.0f, 0.0f);
gpuSingleFilledRectf(x, y, x + zoomx * width, y + zoomy * height);
@@ -335,7 +298,7 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
int x, y;
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
@@ -370,7 +333,7 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int
MovieClip *clip = ED_space_clip_get_clip(sc);
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
/* draw boundary border for frame if stabilization is enabled */
if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
@@ -521,7 +484,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin
}
static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- float marker_pos[2], int width, int height)
+ const float marker_pos[2], int width, int height)
{
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
bool show_search = false;
@@ -633,7 +596,7 @@ static void track_colors(MovieTrackingTrack *track, int act, float col[3], float
}
static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- float marker_pos[2], int width, int height, int act, int sel)
+ const float marker_pos[2], int width, int height, int act, int sel)
{
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
bool show_search = false;
@@ -859,7 +822,7 @@ static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int
}
static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- float marker_pos[2], int outline, int sel, int act, int width, int height)
+ const float marker_pos[2], int outline, int sel, int act, int width, int height)
{
float dx, dy, patdx, patdy, searchdx, searchdy;
int tiny = sc->flag & SC_SHOW_TINY_MARKER;
@@ -975,7 +938,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
}
static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
+ const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
{
char str[128] = {0}, state[64] = {0};
float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
@@ -985,7 +948,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
if (!TRACK_VIEW_SELECTED(sc, track))
return;
- BLF_size(fontid, 11.0f, U.dpi);
+ BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
fontsize = BLF_height_max(fontid);
if (marker->flag & MARKER_DISABLED) {
@@ -1335,12 +1298,12 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
/* ** find window pixel coordinates of origin ** */
- /* UI_view2d_to_region_no_clip return integer values, this could
+ /* UI_view2d_view_to_region_no_clip return integer values, this could
* lead to 1px flickering when view is locked to selection during playbeck.
* to avoid this flickering, calculate base point in the same way as it happens
- * in UI_view2d_to_region_no_clip, but do it in floats here */
+ * in UI_view2d_view_to_region_no_clip, but do it in floats here */
- UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
gpuPushMatrix();
gpuTranslate(x, y, 0);
@@ -1358,7 +1321,9 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie
plane_track;
plane_track = plane_track->next)
{
- draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
+ }
}
if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
@@ -1580,7 +1545,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
return;
- UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
gpuPushMatrix();
gpuTranslate(x, y, 0);
@@ -1682,7 +1647,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
if (track) {
int framenr = ED_space_clip_get_clip_frame_number(sc);
- MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
offsx = marker->pos[0];
offsy = marker->pos[1];
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index b57c8a847ee..5b898688687 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -43,18 +43,15 @@
#include "MEM_guardedalloc.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_rect.h"
#include "BLI_threads.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_context.h"
#include "BKE_tracking.h"
@@ -84,9 +81,9 @@ int ED_space_clip_poll(bContext *C)
SpaceClip *sc = CTX_wm_space_clip(C);
if (sc && sc->clip)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
int ED_space_clip_view_clip_poll(bContext *C)
@@ -97,7 +94,7 @@ int ED_space_clip_view_clip_poll(bContext *C)
return sc->view == SC_VIEW_CLIP;
}
- return FALSE;
+ return false;
}
int ED_space_clip_tracking_poll(bContext *C)
@@ -107,7 +104,7 @@ int ED_space_clip_tracking_poll(bContext *C)
if (sc && sc->clip)
return ED_space_clip_check_show_trackedit(sc);
- return FALSE;
+ return false;
}
int ED_space_clip_maskedit_poll(bContext *C)
@@ -118,7 +115,7 @@ int ED_space_clip_maskedit_poll(bContext *C)
return ED_space_clip_check_show_maskedit(sc);
}
- return FALSE;
+ return false;
}
int ED_space_clip_maskedit_mask_poll(bContext *C)
@@ -133,7 +130,7 @@ int ED_space_clip_maskedit_mask_poll(bContext *C)
}
}
- return FALSE;
+ return false;
}
/* ******** common editing functions ******** */
@@ -261,10 +258,11 @@ ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale
return NULL;
}
-/* returns color in SRGB */
-/* matching ED_space_image_color_sample() */
-bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
+/* Returns color in the display space, matching ED_space_image_color_sample(). */
+bool ED_space_clip_color_sample(Scene *scene, SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
{
+ const char *display_device = scene->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
ImBuf *ibuf;
float fx, fy, co[2];
bool ret = false;
@@ -281,7 +279,7 @@ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r
fy = co[1];
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
@@ -290,16 +288,23 @@ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
- linearrgb_to_srgb_v3_v3(r_col, fp);
+ copy_v3_v3(r_col, fp);
ret = true;
}
else if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
+ IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
ret = true;
}
}
+ if (ret) {
+ IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
+ }
+
+ IMB_freeImBuf(ibuf);
+
return ret;
}
@@ -317,7 +322,7 @@ void ED_clip_update_frame(const Main *mainp, int cfra)
if (sa->spacetype == SPACE_CLIP) {
SpaceClip *sc = sa->spacedata.first;
- sc->scopes.ok = FALSE;
+ sc->scopes.ok = false;
BKE_movieclip_user_set_frame(&sc->user, cfra);
}
@@ -446,7 +451,7 @@ void ED_clip_point_stable_pos(SpaceClip *sc, ARegion *ar, float x, float y, floa
ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
ED_space_clip_get_size(sc, &width, &height);
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
pos[0] = (x - sx) / zoomx;
pos[1] = (y - sy) / zoomy;
@@ -482,7 +487,7 @@ void ED_clip_point_stable_pos__reverse(SpaceClip *sc, ARegion *ar, const float c
int width, height;
int sx, sy;
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
ED_space_clip_get_size(sc, &width, &height);
ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
@@ -644,7 +649,7 @@ static unsigned char *prefetch_read_file_to_memory(MovieClip *clip, int current_
BKE_movieclip_filename_for_frame(clip, &user, name);
file = BLI_open(name, O_BINARY | O_RDONLY, 0);
- if (file < 0) {
+ if (file == -1) {
return NULL;
}
@@ -766,12 +771,18 @@ static void *do_prefetch_thread(void *data_v)
MovieClipUser user = {0};
int flag = IB_rect | IB_alphamode_detect;
int result;
+ char *colorspace_name = NULL;
user.framenr = current_frame;
user.render_size = data->queue->render_size;
user.render_flag = data->queue->render_flag;
- ibuf = IMB_ibImageFromMemory(mem, size, flag, clip->colorspace_settings.name, "prefetch frame");
+ /* Proxies are stored in the display space. */
+ if (data->queue->render_flag & MCLIP_USE_PROXY) {
+ colorspace_name = clip->colorspace_settings.name;
+ }
+
+ ibuf = IMB_ibImageFromMemory(mem, size, flag, colorspace_name, "prefetch frame");
result = BKE_movieclip_put_frame_if_possible(data->clip, &user, ibuf);
@@ -969,6 +980,10 @@ static bool prefetch_check_early_out(const bContext *C)
int first_uncached_frame, end_frame;
int clip_len;
+ if (clip == NULL) {
+ return true;
+ }
+
clip_len = BKE_movieclip_get_duration(clip);
/* check whether all the frames from prefetch range are cached */
@@ -1017,7 +1032,7 @@ void clip_start_prefetch_job(const bContext *C)
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | ND_DISPLAY, 0);
WM_jobs_callbacks(wm_job, prefetch_startjob, NULL, NULL, NULL);
- G.is_break = FALSE;
+ G.is_break = false;
/* and finally start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index 7bb6350c2f7..0c2bb7d3623 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -31,13 +31,9 @@
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_types.h" /* SELECT */
-
-#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_movieclip.h"
@@ -51,7 +47,6 @@
#include "GPU_primitives.h"
#include "GPU_raster.h"
-#include "BIF_glutil.h"
#include "WM_types.h"
@@ -83,8 +78,10 @@ static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack
static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
{
- static float colors[2][3] = {{1.0f, 0.0f, 0.0f},
- {0.0f, 1.0f, 0.0f}};
+ const float colors[2][3] = {
+ {1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f},
+ };
float col[4];
copy_v3_v3(col, colors[coord]);
@@ -155,7 +152,7 @@ static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
userdata.sel = false;
userdata.act_track = act_track;
- UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
+ UI_view2d_scale_get(v2d, &userdata.xscale, &userdata.yscale);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
@@ -171,7 +168,7 @@ static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
glDisable(GL_BLEND);
/* selected knot handles on top of curves */
- userdata.sel = TRUE;
+ userdata.sel = true;
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index 44261b8b500..95f59e79c08 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -29,18 +29,13 @@
* \ingroup spclip
*/
-#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BKE_context.h"
-#include "BKE_movieclip.h"
#include "BKE_tracking.h"
#include "BKE_depsgraph.h"
@@ -69,7 +64,7 @@ static int ED_space_clip_graph_poll(bContext *C)
return sc->view == SC_VIEW_GRAPH;
}
- return FALSE;
+ return false;
}
static int clip_graph_knots_poll(bContext *C)
@@ -79,7 +74,7 @@ static int clip_graph_knots_poll(bContext *C)
return (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) != 0;
}
- return FALSE;
+ return false;
}
typedef struct {
@@ -136,7 +131,7 @@ static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack
}
}
- data->has_prev = TRUE;
+ data->has_prev = true;
copy_v2_v2(data->prev_co, co);
}
@@ -166,7 +161,7 @@ static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *tr
}
-static void mouse_select_init_data(MouseSelectUserData *userdata, float *co)
+static void mouse_select_init_data(MouseSelectUserData *userdata, const float co[2])
{
memset(userdata, 0, sizeof(MouseSelectUserData));
userdata->min_dist = FLT_MAX;
@@ -193,10 +188,10 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend)
if (userdata.marker) {
int x1, y1, x2, y2;
- UI_view2d_view_to_region(v2d, co[0], co[1], &x1, &y1);
- UI_view2d_view_to_region(v2d, userdata.min_co[0], userdata.min_co[1], &x2, &y2);
-
- if (abs(x2 - x1) <= delta && abs(y2 - y1) <= delta) {
+ if (UI_view2d_view_to_region_clip(v2d, co[0], co[1], &x1, &y1) &&
+ UI_view2d_view_to_region_clip(v2d, userdata.min_co[0], userdata.min_co[1], &x2, &y2) &&
+ (abs(x2 - x1) <= delta && abs(y2 - y1) <= delta))
+ {
if (!extend) {
SelectUserData selectdata = {SEL_DESELECT};
@@ -248,7 +243,7 @@ static bool mouse_select_curve(bContext *C, float co[2], bool extend)
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
tracking->act_track = userdata.track;
- BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, TRUE);
+ BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, true);
/* deselect all knots on newly selected curve */
clip_graph_tracking_iterate(sc,
@@ -366,17 +361,15 @@ static int border_select_graph_exec(bContext *C, wmOperator *op)
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
BorderSelectuserData userdata;
- rcti rect;
+ rctf rect;
if (act_track == NULL) {
return OPERATOR_CANCELLED;
}
/* get rectangle from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &userdata.rect.xmin, &userdata.rect.ymin);
- UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &userdata.rect.xmax, &userdata.rect.ymax);
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(&ar->v2d, &rect, &userdata.rect);
userdata.changed = false;
userdata.mode = RNA_int_get(op->ptr, "gesture_mode");
@@ -410,7 +403,7 @@ void CLIP_OT_graph_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/********************** select all operator *********************/
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 811f8e2eaab..2a5d959bb84 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -72,7 +72,6 @@ void CLIP_OT_dopesheet_view_all(struct wmOperatorType *ot);
/* clip_draw.c */
void clip_draw_main(const struct bContext *C, struct SpaceClip *sc, struct ARegion *ar);
void clip_draw_grease_pencil(struct bContext *C, int onlyv2d);
-void clip_draw_curfra_label(const int framenr, const float x, const float y);
void clip_draw_cache_and_notes(const bContext *C, SpaceClip *sc, ARegion *ar);
/* clip_editor.c */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index e02fca80894..7ccee73626c 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -58,7 +58,6 @@
#include "BKE_global.h"
#include "BKE_report.h"
#include "BKE_main.h"
-#include "BKE_library.h"
#include "BKE_movieclip.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
@@ -110,10 +109,21 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2])
}
if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) {
+ float dx, dy;
+
ED_space_clip_get_size(sc, &width, &height);
- sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
- sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+ dx = ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
+ dy = ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+
+ if (sc->flag & SC_LOCK_SELECTION) {
+ sc->xlockof += dx;
+ sc->ylockof += dy;
+ }
+ else {
+ sc->xof += dx;
+ sc->yof += dy;
+ }
}
}
@@ -609,7 +619,7 @@ static int view_zoom_in_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", location);
- sclip_zoom_set_factor(C, 1.25f, location);
+ sclip_zoom_set_factor(C, powf(2.0f, 1.0f / 3.0f), location);
ED_region_tag_redraw(CTX_wm_region(C));
@@ -652,7 +662,7 @@ static int view_zoom_out_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", location);
- sclip_zoom_set_factor(C, 0.8f, location);
+ sclip_zoom_set_factor(C, powf(0.5f, 1.0f / 3.0f), location);
ED_region_tag_redraw(CTX_wm_region(C));
@@ -769,7 +779,7 @@ static int view_all_exec(bContext *C, wmOperator *op)
sc->xof = sc->yof = 0.0f;
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -803,7 +813,7 @@ static int view_selected_exec(bContext *C, wmOperator *UNUSED(op))
sc->ylockof = 0.0f;
ED_clip_view_selection(C, ar, 1);
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -841,7 +851,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- sound_seek_scene(CTX_data_main(C), CTX_data_scene(C));
+ sound_seek_scene(CTX_data_main(C), scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -1002,13 +1012,16 @@ static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build
}
else {
sfra = 1;
- efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+ efra = clip->len;
}
if (build_undistort_count) {
int threads = BLI_system_thread_count();
+ int width, height;
- distortion = BKE_tracking_distortion_new();
+ BKE_movieclip_get_size(clip, NULL, &width, &height);
+
+ distortion = BKE_tracking_distortion_new(&clip->tracking, width, height);
BKE_tracking_distortion_set_threads(distortion, threads);
}
@@ -1019,7 +1032,7 @@ static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build
if (*stop || G.is_break)
break;
- *do_update = TRUE;
+ *do_update = true;
*progress = ((float) cfra - sfra) / (efra - sfra);
}
@@ -1042,7 +1055,7 @@ typedef struct ProxyQueue {
int efra;
SpinLock spin;
- short *stop;
+ const short *stop;
short *do_update;
float *progress;
} ProxyQueue;
@@ -1118,7 +1131,8 @@ static void *do_proxy_thread(void *data_v)
while ((mem = proxy_thread_next_frame(data->queue, data->clip, &size, &cfra))) {
ImBuf *ibuf;
- ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect, NULL, "proxy frame");
+ ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect,
+ data->clip->colorspace_settings.name, "proxy frame");
BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, NULL, cfra,
data->build_sizes, data->build_count, false);
@@ -1173,8 +1187,11 @@ static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count,
handle->build_undistort_count = build_undistort_count;
handle->build_undistort_sizes = build_undistort_sizes;
- if (build_undistort_count)
- handle->distortion = BKE_tracking_distortion_new();
+ if (build_undistort_count) {
+ int width, height;
+ BKE_movieclip_get_size(clip, NULL, &width, &height);
+ handle->distortion = BKE_tracking_distortion_new(&clip->tracking, width, height);
+ }
if (tot_thread > 1)
BLI_insert_thread(&threads, handle);
@@ -1265,10 +1282,10 @@ static int clip_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | ND_DISPLAY, 0);
WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob);
- G.is_break = FALSE;
+ G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(sa);
return OPERATOR_FINISHED;
}
@@ -1333,32 +1350,19 @@ static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
else {
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
+ float pan_vec[3];
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
-
- float dt = ndof->dt;
-
- /* tune these until it feels right */
- const float zoom_sensitivity = 0.5f; /* 50% per second (I think) */
- const float pan_sensitivity = 300.0f; /* screen pixels per second */
+ const wmNDOFMotionData *ndof = event->customdata;
+ const float speed = NDOF_PIXELS_PER_SECOND;
- float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sc->zoom;
- float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sc->zoom;
+ WM_event_ndof_pan_get(ndof, pan_vec, true);
- /* "mouse zoom" factor = 1 + (dx + dy) / 300
- * what about "ndof zoom" factor? should behave like this:
- * at rest -> factor = 1
- * move forward -> factor > 1
- * move backward -> factor < 1
- */
- float zoom_factor = 1.0f + zoom_sensitivity * dt * - ndof->tvec[2];
+ mul_v2_fl(pan_vec, (speed * ndof->dt) / sc->zoom);
+ pan_vec[2] *= -ndof->dt;
- if (U.ndof_flag & NDOF_ZOOM_INVERT)
- zoom_factor = -zoom_factor;
-
- sclip_zoom_set_factor(C, zoom_factor, NULL);
- sc->xof += pan_x;
- sc->yof += pan_y;
+ sclip_zoom_set_factor(C, 1.0f + pan_vec[2], NULL);
+ sc->xof += pan_vec[0];
+ sc->yof += pan_vec[1];
ED_region_tag_redraw(ar);
@@ -1375,6 +1379,7 @@ void CLIP_OT_view_ndof(wmOperatorType *ot)
/* api callbacks */
ot->invoke = clip_view_ndof_invoke;
+ ot->poll = ED_space_clip_view_clip_poll;
}
/********************** Prefetch operator *********************/
@@ -1389,7 +1394,6 @@ static int clip_prefetch_modal(bContext *C, wmOperator *UNUSED(op), const wmEven
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
- break;
}
return OPERATOR_PASS_THROUGH;
@@ -1524,5 +1528,5 @@ void ED_operatormacros_clip(void)
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "CLIP_OT_add_marker");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
- RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(otmacro->ptr, "release_confirm", true);
}
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index 42300f88a4f..55b78219770 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -239,7 +239,7 @@ static void clip_panel_operator_redo(const bContext *C, Panel *pa)
uiBlock *block = uiLayoutGetBlock(pa->layout);
if (!WM_operator_check_ui_enabled(C, op->type->name))
- uiLayoutSetEnabled(pa->layout, FALSE);
+ uiLayoutSetEnabled(pa->layout, false);
/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index 4950440e94d..5aacc9c34b1 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -260,7 +260,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
if (update_stab) {
- tracking->stabilization.ok = FALSE;
+ tracking->stabilization.ok = false;
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip);
}
@@ -314,10 +314,10 @@ void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene)
UI_view2d_view_orthoSpecial(ar, v2d, 1);
/* because the frame number text is subject to the same scaling as the contents of the view */
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
gpuScale(1.0f / xscale, 1.0f, 1.0f);
- clip_draw_curfra_label(sc->user.framenr, (float)sc->user.framenr * xscale, 18);
+ ED_region_cache_draw_curfra_label(sc->user.framenr, (float)sc->user.framenr * xscale, 18);
/* restore view transform */
gpuScale(xscale, 1.0, 1.0);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 464a1526347..cf69f170d13 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -43,7 +43,6 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BKE_main.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_movieclip.h"
@@ -215,7 +214,7 @@ static void clip_scopes_tag_refresh(ScrArea *sa)
return;
}
- sc->scopes.ok = FALSE;
+ sc->scopes.ok = false;
}
static void clip_scopes_check_gpencil_change(ScrArea *sa)
@@ -235,7 +234,7 @@ static void clip_stabilization_tag_refresh(ScrArea *sa)
if (clip) {
MovieTrackingStabilization *stab = &clip->tracking.stabilization;
- stab->ok = FALSE;
+ stab->ok = false;
}
}
@@ -338,7 +337,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
scn->scopes.track_search = NULL;
scn->scopes.track_preview = NULL;
- scn->scopes.ok = FALSE;
+ scn->scopes.ok = false;
return (SpaceLink *)scn;
}
@@ -566,20 +565,23 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* 2d tracking */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "backwards", TRUE);
- RNA_boolean_set(kmi->ptr, "sequence", FALSE);
+ RNA_boolean_set(kmi->ptr, "backwards", true);
+ RNA_boolean_set(kmi->ptr, "sequence", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "backwards", FALSE);
- RNA_boolean_set(kmi->ptr, "sequence", FALSE);
+ RNA_boolean_set(kmi->ptr, "backwards", false);
+ RNA_boolean_set(kmi->ptr, "sequence", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "backwards", FALSE);
- RNA_boolean_set(kmi->ptr, "sequence", TRUE);
+ RNA_boolean_set(kmi->ptr, "backwards", false);
+ RNA_boolean_set(kmi->ptr, "sequence", true);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "backwards", TRUE);
- RNA_boolean_set(kmi->ptr, "sequence", TRUE);
+ RNA_boolean_set(kmi->ptr, "backwards", true);
+ RNA_boolean_set(kmi->ptr, "sequence", true);
/* mode */
- WM_keymap_add_menu(keymap, "CLIP_MT_select_mode", TABKEY, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", TABKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.mode");
+ RNA_string_set(kmi->ptr, "value_1", "TRACKING");
+ RNA_string_set(kmi->ptr, "value_2", "MASK");
WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0);
@@ -626,7 +628,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CLIP_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_view_all", FKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "fit_view", TRUE);
+ RNA_boolean_set(kmi->ptr, "fit_view", true);
WM_keymap_add_item(keymap, "CLIP_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
@@ -651,9 +653,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* selection */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -663,9 +665,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "CLIP_MT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
/* marker */
WM_keymap_add_item(keymap, "CLIP_OT_add_marker_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
@@ -689,15 +691,15 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "action", 1); /* unlock */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
/* plane tracks */
- WM_keymap_add_item(keymap, "CLIP_OT_slide_plane_marker", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_slide_plane_marker", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_keyframe_delete", IKEY, KM_PRESS, KM_ALT, 0);
@@ -726,13 +728,13 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* clean-up */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
- RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
+ RNA_boolean_set(kmi->ptr, "clear_active", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
- RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
+ RNA_boolean_set(kmi->ptr, "clear_active", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
- RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
+ RNA_boolean_set(kmi->ptr, "clear_active", false);
/* Cursor */
WM_keymap_add_item(keymap, "CLIP_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
@@ -763,9 +765,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* selection */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select_all_markers", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
@@ -783,6 +785,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* view */
WM_keymap_add_item(keymap, "CLIP_OT_graph_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_graph_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_graph_center_current_frame", PADPERIOD, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0);
@@ -791,13 +794,13 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* clean-up */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
- RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "clear_active", true);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
- RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "clear_active", true);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
- RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "clear_active", true);
/* tracks */
kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0);
@@ -810,9 +813,10 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
+ RNA_boolean_set(kmi->ptr, "extend", true); /* toggle */
WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
}
const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
@@ -824,20 +828,20 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, clip_context_dir);
- return TRUE;
+ return true;
}
else if (CTX_data_equals(member, "edit_movieclip")) {
if (sc->clip)
CTX_data_id_pointer_set(result, &sc->clip->id);
- return TRUE;
+ return true;
}
else if (CTX_data_equals(member, "edit_mask")) {
if (sc->mask_info.mask)
CTX_data_id_pointer_set(result, &sc->mask_info.mask->id);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* dropboxes */
@@ -845,9 +849,9 @@ static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS
{
if (drag->type == WM_DRAG_PATH)
if (ELEM4(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static void clip_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -1181,14 +1185,14 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
clip_draw_main(C, sc, ar);
/* TODO(sergey): would be nice to find a way to de-duplicate all this space conversions */
- UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
ED_space_clip_get_size(sc, &width, &height);
ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
ED_space_clip_get_aspect(sc, &aspx, &aspy);
if (sc->mode == SC_MODE_MASKEDIT) {
Mask *mask = CTX_data_edit_mask(C);
- if (mask) {
+ if (mask && clip) {
ScrArea *sa = CTX_wm_area(C);
int mask_width, mask_height;
ED_mask_get_size(sa, &mask_width, &mask_height);
@@ -1198,7 +1202,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
sc->mask_info.overlay_mode,
mask_width, mask_height,
aspx, aspy,
- TRUE, TRUE,
+ true, true,
sc->stabmat, C);
}
}
@@ -1314,7 +1318,7 @@ static void dopesheet_area_draw(const bContext *C, ARegion *ar)
/* time grid */
unit = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
- grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP,
+ grid = UI_view2d_grid_calc(scene, v2d, unit, V2D_GRID_CLAMP,
V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
UI_view2d_grid_free(grid);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 8abda84c1e6..5c3ee5ccca2 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -34,7 +34,6 @@
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
#include "DNA_gpencil_types.h"
-#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
@@ -54,10 +53,7 @@
#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_library.h"
-#include "BKE_mask.h"
-#include "BKE_node.h"
#include "BKE_sound.h"
#include "WM_api.h"
@@ -65,7 +61,6 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "ED_keyframing.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -193,7 +188,6 @@ static int add_marker_at_click_modal(bContext *C, wmOperator *UNUSED(op), const
switch (event->type) {
case MOUSEMOVE:
return OPERATOR_RUNNING_MODAL;
- break;
case LEFTMOUSE:
ED_area_headerprint(CTX_wm_area(C), NULL);
@@ -208,7 +202,6 @@ static int add_marker_at_click_modal(bContext *C, wmOperator *UNUSED(op), const
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
return OPERATOR_FINISHED;
- break;
case ESCKEY:
ED_area_headerprint(CTX_wm_area(C), NULL);
@@ -254,7 +247,7 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
{
next_plane_track = plane_track->next;
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
BKE_tracking_plane_track_free(plane_track);
BLI_freelinkN(plane_tracks_base, plane_track);
changed = true;
@@ -335,7 +328,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
{
plane_track_next = plane_track->next;
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, framenr);
if (plane_marker) {
@@ -396,7 +389,7 @@ typedef struct {
float *min, *max, *pos, *offset, (*corners)[2];
float spos[2];
- short lock, accurate;
+ bool lock, accurate;
/* data to restore on cancel */
float old_search_min[2], old_search_max[2], old_pos[2], old_offset[2];
@@ -464,7 +457,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra
data->height = height;
if (action == SLIDE_ACTION_SIZE)
- data->lock = 1;
+ data->lock = true;
/* backup marker's settings */
memcpy(data->old_corners, marker->pattern_corners, sizeof(data->old_corners));
@@ -477,7 +470,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra
}
static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker,
- int area, float co[2], float slide_zone[2],
+ int area, const float co[2], const float slide_zone[2],
float padding, int width, int height)
{
const float size = 12.0f;
@@ -508,7 +501,7 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker,
}
static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker,
- int area, float co[2], int corner, float padding,
+ int area, const float co[2], int corner, float padding,
int width, int height)
{
float min[2], max[2], crn[2];
@@ -577,7 +570,7 @@ static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker,
}
static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- float co[2], int width, int height)
+ const float co[2], int width, int height)
{
float pos[2], dx, dy;
float pat_min[2], pat_max[2];
@@ -1284,7 +1277,7 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
else if (!BKE_tracking_context_step(tmj->context))
break;
- *do_update = TRUE;
+ *do_update = true;
*progress = (float)(framenr - tmj->sfra) / (tmj->efra - tmj->sfra);
if (tmj->backwards)
@@ -1311,10 +1304,13 @@ static void track_markers_updatejob(void *tmv)
static void track_markers_endjob(void *tmv)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
+ wmWindowManager *wm = tmj->main->wm.first;
tmj->clip->tracking_context = NULL;
tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra);
- ED_update_for_newframe(tmj->main, tmj->scene, 0);
+ if (wm != NULL) {
+ ED_update_for_newframe(tmj->main, tmj->scene, 0);
+ }
BKE_tracking_context_sync(tmj->context);
BKE_tracking_context_finish(tmj->context);
@@ -1441,7 +1437,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
clip = ED_space_clip_get_clip(sc);
framenr = ED_space_clip_get_clip_frame_number(sc);
- if (WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY)) {
+ if (WM_jobs_test(CTX_wm_manager(C), sa, WM_JOB_TYPE_ANY)) {
/* only one tracking is allowed at a time */
return OPERATOR_CANCELLED;
}
@@ -1478,7 +1474,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
WM_jobs_callbacks(wm_job, track_markers_startjob, NULL, track_markers_updatejob, track_markers_endjob);
- G.is_break = FALSE;
+ G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
WM_cursor_wait(0);
@@ -1499,7 +1495,6 @@ static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), const wmEven
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
- break;
}
return OPERATOR_PASS_THROUGH;
@@ -1718,7 +1713,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
wmJob *wm_job;
char error_msg[256] = "\0";
- if (WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY)) {
+ if (WM_jobs_test(CTX_wm_manager(C), sa, WM_JOB_TYPE_ANY)) {
/* only one solve is allowed at a time */
return OPERATOR_CANCELLED;
}
@@ -1746,7 +1741,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0);
WM_jobs_callbacks(wm_job, solve_camera_startjob, NULL, solve_camera_updatejob, NULL);
- G.is_break = FALSE;
+ G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
WM_cursor_wait(0);
@@ -1767,7 +1762,6 @@ static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
- break;
}
return OPERATOR_PASS_THROUGH;
@@ -2017,7 +2011,7 @@ static int set_orientation_poll(bContext *C)
MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
- return TRUE;
+ return true;
}
else {
return OBACT != NULL;
@@ -2025,7 +2019,7 @@ static int set_orientation_poll(bContext *C)
}
}
- return FALSE;
+ return false;
}
static int count_selected_bundles(bContext *C)
@@ -2053,7 +2047,7 @@ static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat
bool found = false;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (!cti)
continue;
@@ -2084,7 +2078,7 @@ static Object *object_solver_camera(Scene *scene, Object *ob)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (!cti)
continue;
@@ -2277,7 +2271,7 @@ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingOb
if (!flip) {
float lmat[4][4], ilmat[4][4], rmat[3][3];
- BKE_object_rot_to_mat3(ob, rmat, TRUE);
+ BKE_object_rot_to_mat3(ob, rmat, true);
invert_m3(rmat);
mul_m4_m4m3(mat, mat, rmat);
@@ -2656,7 +2650,7 @@ static int set_solution_scale_poll(bContext *C)
}
}
- return FALSE;
+ return false;
}
static int set_solution_scale_exec(bContext *C, wmOperator *op)
@@ -2712,7 +2706,7 @@ static int apply_solution_scale_poll(bContext *C)
}
}
- return FALSE;
+ return false;
}
static int apply_solution_scale_exec(bContext *C, wmOperator *op)
@@ -2794,9 +2788,12 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
+ MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
int unselected;
unselected = RNA_boolean_get(op->ptr, "unselected");
@@ -2821,6 +2818,22 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
sc->flag &= ~SC_LOCK_SELECTION;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (unselected == 0 && plane_track->flag & SELECT) {
+ plane_track->flag |= PLANE_TRACK_HIDDEN;
+ }
+ else if (unselected == 1 && (plane_track->flag & SELECT) == 0) {
+ plane_track->flag |= PLANE_TRACK_HIDDEN;
+ }
+ }
+
+ if (act_plane_track && act_plane_track->flag & TRACK_HIDDEN) {
+ clip->tracking.act_plane_track = NULL;
+ }
+
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL);
@@ -2854,7 +2867,9 @@ static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op))
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
track = tracksbase->first;
while (track) {
@@ -2863,6 +2878,13 @@ static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op))
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ plane_track->flag &= ~PLANE_TRACK_HIDDEN;
+ }
+
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL);
@@ -3037,7 +3059,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
if (CFRA != sc->user.framenr) {
CFRA = sc->user.framenr;
- sound_seek_scene(CTX_data_main(C), CTX_data_scene(C));
+ sound_seek_scene(CTX_data_main(C), scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -3284,7 +3306,7 @@ static int stabilize_2d_poll(bContext *C)
return tracking_object->flag & TRACKING_OBJECT_CAMERA;
}
- return FALSE;
+ return false;
}
static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3476,9 +3498,10 @@ void CLIP_OT_stabilize_2d_set_rotation(wmOperatorType *ot)
/********************** clean tracks operator *********************/
-static int is_track_clean(MovieTrackingTrack *track, int frames, int del)
+static bool is_track_clean(MovieTrackingTrack *track, int frames, int del)
{
- int ok = 1, a, prev = -1, count = 0;
+ bool ok = true;
+ int a, prev = -1, count = 0;
MovieTrackingMarker *markers = track->markers, *new_markers = NULL;
int start_disabled = 0;
int markersnr = track->markersnr;
@@ -3867,6 +3890,7 @@ void CLIP_OT_create_plane_track(wmOperatorType *ot)
/********************** Slide plane marker corner operator *********************/
typedef struct SlidePlaneMarkerData {
+ int event_type;
MovieTrackingPlaneTrack *plane_track;
MovieTrackingPlaneMarker *plane_marker;
int width, height;
@@ -3913,7 +3937,7 @@ static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(bContext *C, c
plane_track;
plane_track = plane_track->next)
{
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
bool ok = false;
int i;
@@ -3962,6 +3986,8 @@ static void *slide_plane_marker_customdata(bContext *C, const wmEvent *event)
customdata = MEM_callocN(sizeof(SlidePlaneMarkerData), "slide plane marker data");
+ customdata->event_type = event->type;
+
plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
customdata->plane_track = plane_track;
@@ -4031,7 +4057,7 @@ static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *
SlidePlaneMarkerData *data = (SlidePlaneMarkerData *) op->customdata;
float dx, dy, mdelta[2];
int next_corner_index, prev_corner_index, diag_corner_index;
- float *next_corner, *prev_corner, *diag_corner;
+ const float *next_corner, *prev_corner, *diag_corner;
float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2];
switch (event->type) {
@@ -4111,7 +4137,8 @@ static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *
break;
case LEFTMOUSE:
- if (event->val == KM_RELEASE) {
+ case RIGHTMOUSE:
+ if (event->type == data->event_type && event->val == KM_RELEASE) {
/* Marker is now keyframed. */
data->plane_marker->flag &= ~PLANE_MARKER_TRACKED;
@@ -4189,7 +4216,7 @@ static void keyframe_set_flag(bContext *C, bool set)
}
for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
if (set) {
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
if (plane_marker->flag & PLANE_MARKER_TRACKED) {
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 65b7a5dee65..4d9c262e1ff 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -31,11 +31,7 @@
#include "MEM_guardedalloc.h"
-#include "DNA_camera_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
@@ -43,27 +39,15 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_lasso.h"
-#include "BLI_blenlib.h"
-#include "BKE_main.h"
#include "BKE_context.h"
-#include "BKE_constraint.h"
-#include "BKE_movieclip.h"
#include "BKE_tracking.h"
-#include "BKE_global.h"
-#include "BKE_depsgraph.h"
-#include "BKE_object.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_library.h"
-#include "BKE_sound.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
#include "ED_clip.h"
-#include "ED_keyframing.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -174,8 +158,8 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
{
float d1, d2, d3, d4;
float p[2] = {co[0] - pos[0], co[1] - pos[1]};
- float *v1 = crns[0], *v2 = crns[1];
- float *v3 = crns[2], *v4 = crns[3];
+ const float *v1 = crns[0], *v2 = crns[1];
+ const float *v3 = crns[2], *v4 = crns[3];
d1 = dist_squared_to_line_segment_v2(p, v1, v2);
d2 = dist_squared_to_line_segment_v2(p, v2, v3);
@@ -189,8 +173,8 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
static float dist_to_crns_abs(float co[2], float corners[4][2])
{
float d1, d2, d3, d4;
- float *v1 = corners[0], *v2 = corners[1];
- float *v3 = corners[2], *v4 = corners[3];
+ const float *v1 = corners[0], *v2 = corners[1];
+ const float *v3 = corners[2], *v4 = corners[3];
d1 = dist_squared_to_line_segment_v2(co, v1, v2);
d2 = dist_squared_to_line_segment_v2(co, v2, v3);
@@ -349,7 +333,7 @@ static int mouse_select(bContext *C, float co[2], int extend)
delect_all_tracks(tracksbase);
}
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
if (extend) {
plane_track->flag &= ~SELECT;
}
@@ -382,7 +366,7 @@ static int select_poll(bContext *C)
return sc->clip && sc->view == SC_VIEW_CLIP;
}
- return FALSE;
+ return false;
}
static int select_exec(bContext *C, wmOperator *op)
@@ -553,12 +537,12 @@ void CLIP_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/********************** lasso select operator *********************/
-static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, short select)
+static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, bool select)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -650,7 +634,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op)
const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
if (mcords) {
- short select;
+ bool select;
select = !RNA_boolean_get(op->ptr, "deselect");
do_lasso_select_marker(C, mcords, mcords_tot, select);
@@ -846,7 +830,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
plane_track;
plane_track = plane_track->next)
{
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
action = SEL_DESELECT;
break;
}
@@ -898,10 +882,9 @@ static int select_all_exec(bContext *C, wmOperator *op)
plane_track->flag ^= SELECT;
break;
}
- }
-
- if (plane_track->flag & SELECT) {
- has_selection = true;
+ if (plane_track->flag & SELECT) {
+ has_selection = true;
+ }
}
}
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index d0a97372198..9146472bc69 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -24,7 +24,6 @@
* \ingroup spconsole
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -39,16 +38,10 @@
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
-#include "BKE_report.h"
-
#include "MEM_guardedalloc.h"
#include "GPU_primitives.h"
-#include "BIF_glutil.h"
-
-#include "ED_datafiles.h"
-#include "ED_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 36144a074e3..b8743d69762 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -43,7 +43,6 @@
#include "BLI_math.h"
#include "BKE_context.h"
-#include "BKE_text.h" /* only for character utility funcs */
#include "WM_api.h"
#include "WM_types.h"
@@ -554,7 +553,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
int stride;
const short type = RNA_enum_get(op->ptr, "type");
- int done = FALSE;
+ bool done = false;
if (ci->len == 0) {
return OPERATOR_CANCELLED;
@@ -573,7 +572,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - (ci->cursor + stride)) + 1);
ci->len -= stride;
BLI_assert(ci->len >= 0);
- done = TRUE;
+ done = true;
}
}
break;
@@ -590,7 +589,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - (ci->cursor + stride)) + 1);
ci->len -= stride;
BLI_assert(ci->len >= 0);
- done = TRUE;
+ done = true;
}
}
break;
@@ -1063,7 +1062,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven
sel_prev[0] = sc->sel_start;
sel_prev[1] = sc->sel_end;
- console_cursor_set_to_pos(sc, ar, scu, mval, TRUE);
+ console_cursor_set_to_pos(sc, ar, scu, mval, true);
/* only redraw if the selection changed */
if (sel_prev[0] != sc->sel_start || sel_prev[1] != sc->sel_end) {
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index c30fc7afe3c..adc58fd98cc 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -34,12 +34,10 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "BKE_idcode.h"
#include "ED_space_api.h"
#include "ED_screen.h"
@@ -280,25 +278,25 @@ static void console_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", FALSE);
+ RNA_boolean_set(kmi->ptr, "reverse", false);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", TRUE);
+ RNA_boolean_set(kmi->ptr, "reverse", true);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", FALSE);
+ RNA_boolean_set(kmi->ptr, "reverse", false);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", TRUE);
+ RNA_boolean_set(kmi->ptr, "reverse", true);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
- RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", FALSE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", false);
#if 0
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 2c340fb2017..421a771a74e 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -60,7 +60,6 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_fileops_types.h"
-
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 17b8eefe370..c5137d54655 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -69,18 +69,24 @@
#include <ctype.h>
/* ---------- FILE SELECTION ------------ */
-static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const rcti *rect)
+static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const rcti *rect_region)
{
FileSelection sel;
- float fxmin, fymin, fxmax, fymax;
View2D *v2d = &ar->v2d;
rcti rect_view;
+ rctf rect_view_fl;
+ rctf rect_region_fl;
- UI_view2d_region_to_view(v2d, (float)rect->xmin, (float)rect->ymin, &fxmin, &fymin);
- UI_view2d_region_to_view(v2d, (float)rect->xmax, (float)rect->ymax, &fxmax, &fymax);
+ BLI_rctf_rcti_copy(&rect_region_fl, rect_region);
- BLI_rcti_init(&rect_view, (int)(v2d->tot.xmin + fxmin), (int)(v2d->tot.xmin + fxmax), (int)(v2d->tot.ymax - fymin), (int)(v2d->tot.ymax - fymax));
+ UI_view2d_region_to_view_rctf(v2d, &rect_region_fl, &rect_view_fl);
+
+ BLI_rcti_init(&rect_view,
+ (int)(v2d->tot.xmin + rect_view_fl.xmin),
+ (int)(v2d->tot.xmin + rect_view_fl.xmax),
+ (int)(v2d->tot.ymax - rect_view_fl.ymin),
+ (int)(v2d->tot.ymax - rect_view_fl.ymax));
sel = ED_fileselect_layout_offset_rect(sfile->layout, &rect_view);
@@ -127,7 +133,7 @@ static void clamp_to_filelist(int numfiles, FileSelection *sel)
}
}
-static FileSelection file_selection_get(bContext *C, const rcti *rect, short fill)
+static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -155,7 +161,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, short fil
return sel;
}
-static FileSelect file_select_do(bContext *C, int selected_idx, short do_diropen)
+static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
{
FileSelect retval = FILE_SELECT_NOTHING;
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -171,7 +177,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, short do_diropen
params->active_file = selected_idx;
if (S_ISDIR(file->type)) {
- if (do_diropen == FALSE) {
+ if (do_diropen == false) {
params->file[0] = '\0';
retval = FILE_SELECT_DIR;
}
@@ -205,7 +211,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, short do_diropen
}
-static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select, short fill, short do_diropen)
+static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen)
{
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelect retval = FILE_SELECT_NOTHING;
@@ -287,7 +293,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect);
- ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, FALSE, FALSE);
+ ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, false, false);
if (FILE_SELECT_DIR == ret) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -363,11 +369,11 @@ void FILE_OT_select(wmOperatorType *ot)
ot->poll = ED_operator_file_active;
/* properties */
- prop = RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection");
+ prop = RNA_def_boolean(ot->srna, "fill", false, "Fill", "Select everything beginning with the last selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it");
+ prop = RNA_def_boolean(ot->srna, "open", true, "Open", "Open a directory when selecting it");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -494,7 +500,7 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op)
if (RNA_struct_find_property(op->ptr, "index")) {
int index = RNA_int_get(op->ptr, "index");
- if ( (index > -1) && (index < nentries)) {
+ if ((index > -1) && (index < nentries)) {
char name[FILE_MAX];
fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
@@ -773,13 +779,13 @@ bool file_draw_check_exists(SpaceFile *sfile)
char filepath[FILE_MAX];
BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file);
if (BLI_is_file(filepath)) {
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
/* sends events now, so things get handled on windowqueue level */
@@ -851,7 +857,19 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
if (sfile->params) {
if (BLI_parent_dir(sfile->params->dir)) {
BLI_cleanup_dir(G.main->name, sfile->params->dir);
- file_change_dir(C, 0);
+ /* if not browsing in .blend file, we still want to check whether the path is a directory */
+ if (sfile->params->type == FILE_LOADLIB) {
+ char tdir[FILE_MAX], tgroup[FILE_MAX];
+ if (BLO_is_a_library(sfile->params->dir, tdir, tgroup)) {
+ file_change_dir(C, 0);
+ }
+ else {
+ file_change_dir(C, 1);
+ }
+ }
+ else {
+ file_change_dir(C, 1);
+ }
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
}
@@ -1042,7 +1060,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
}
}
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
/* and restore context */
CTX_wm_region_set(C, oldar);
@@ -1129,7 +1147,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE);
/* set timer to smoothly view newly generated file */
- sfile->smoothscroll_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0 / 1000.0); /* max 30 frs/sec */
+ sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0); /* max 30 frs/sec */
sfile->scroll_offset = 0;
/* reload dir to make sure we're seeing what's in the directory */
@@ -1200,10 +1218,30 @@ static void file_expand_directory(bContext *C)
sfile->params->dir[2] = '\\';
sfile->params->dir[3] = '\0';
}
+ else if (BLI_path_is_unc(sfile->params->dir)) {
+ BLI_cleanup_unc(sfile->params->dir, FILE_MAX_LIBEXTRA);
+ }
#endif
}
}
+#if defined(WIN32)
+static bool can_create_dir(const char *dir)
+{
+ /* for UNC paths we need to check whether the parent of the new
+ * directory is a proper directory itself and not a share or the
+ * UNC root (server name) itself. Calling BLI_is_dir does this
+ */
+ if (BLI_path_is_unc(dir)) {
+ char parent[PATH_MAX];
+ BLI_strncpy(parent, dir, PATH_MAX);
+ BLI_parent_dir(parent);
+ return BLI_is_dir(parent);
+ }
+ return true;
+}
+#endif
+
void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UNUSED(arg_but))
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1228,6 +1266,13 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
* placing cursor at the end */
/* UI_textbutton_activate_but(C, but); */
}
+#if defined(WIN32)
+ else if (!can_create_dir(sfile->params->dir)) {
+ const char *lastdir = folderlist_peeklastdir(sfile->folders_prev);
+ if (lastdir)
+ BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir));
+ }
+#endif
else {
const char *lastdir = folderlist_peeklastdir(sfile->folders_prev);
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 77cea89f2f7..69789569912 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -58,7 +58,7 @@
static void file_panel_cb(bContext *C, void *arg_entry, void *UNUSED(arg_v))
{
PointerRNA ptr;
- char *entry = (char *)arg_entry;
+ const char *entry = (char *)arg_entry;
WM_operator_properties_create(&ptr, "FILE_OT_select_bookmark");
RNA_string_set(&ptr, "dir", entry);
@@ -86,12 +86,12 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat
uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT);
block = uiLayoutGetBlock(pa->layout);
box = uiLayoutBox(pa->layout);
- col = uiLayoutColumn(box, TRUE);
+ col = uiLayoutColumn(box, true);
for (i = 0; i < nentries; ++i) {
char dir[FILE_MAX];
char temp[FILE_MAX];
- uiLayout *layout = uiLayoutRow(col, FALSE);
+ uiLayout *layout = uiLayoutRow(col, false);
char *entry;
entry = fsmenu_get_entry(fsmenu, category, i);
@@ -135,6 +135,12 @@ static void file_panel_system(const bContext *C, Panel *pa)
file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0);
}
+static int file_panel_system_bookmarks_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ return (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS));
+}
+
static void file_panel_system_bookmarks(const bContext *C, Panel *pa)
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -151,7 +157,7 @@ static void file_panel_bookmarks(const bContext *C, Panel *pa)
uiLayout *row;
if (sfile) {
- row = uiLayoutRow(pa->layout, FALSE);
+ row = uiLayoutRow(pa->layout, false);
uiItemO(row, IFACE_("Add"), ICON_ZOOMIN, "file.bookmark_add");
uiItemL(row, NULL, ICON_NONE);
@@ -159,6 +165,12 @@ static void file_panel_bookmarks(const bContext *C, Panel *pa)
}
}
+static int file_panel_recent_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ return (sfile && !(U.uiflag & USER_HIDE_RECENT));
+}
+
static void file_panel_recent(const bContext *C, Panel *pa)
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -166,7 +178,7 @@ static void file_panel_recent(const bContext *C, Panel *pa)
if (sfile) {
if (!(U.uiflag & USER_HIDE_RECENT)) {
- row = uiLayoutRow(pa->layout, FALSE);
+ row = uiLayoutRow(pa->layout, false);
uiItemO(row, IFACE_("Reset"), ICON_X, "file.reset_recent");
uiItemL(row, NULL, ICON_NONE);
@@ -228,6 +240,7 @@ void file_panels_register(ARegionType *art)
strcpy(pt->label, N_("System Bookmarks"));
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = file_panel_system_bookmarks;
+ pt->poll = file_panel_system_bookmarks_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype file bookmarks");
@@ -242,6 +255,7 @@ void file_panels_register(ARegionType *art)
strcpy(pt->label, N_("Recent"));
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = file_panel_recent;
+ pt->poll = file_panel_recent_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 6ea5638b8f0..871abbda48a 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -46,7 +46,6 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
@@ -94,8 +93,8 @@ typedef struct FileImage {
typedef struct ThumbnailJob {
ListBase loadimages;
- short *stop;
- short *do_update;
+ const short *stop;
+ const short *do_update;
struct FileList *filelist;
ReportList reports;
} ThumbnailJob;
@@ -393,7 +392,7 @@ void filelist_init_icons(void)
ImBuf *bbuf;
ImBuf *ibuf;
- BLI_assert(G.background == FALSE);
+ BLI_assert(G.background == false);
#ifdef WITH_HEADLESS
bbuf = NULL;
@@ -421,7 +420,7 @@ void filelist_free_icons(void)
{
int i;
- BLI_assert(G.background == FALSE);
+ BLI_assert(G.background == false);
for (i = 0; i < SPECIAL_IMG_MAX; ++i) {
IMB_freeImBuf(gSpecialFileImages[i]);
@@ -624,7 +623,7 @@ ImBuf *filelist_getimage(struct FileList *filelist, int index)
ImBuf *ibuf = NULL;
int fidx = 0;
- BLI_assert(G.background == FALSE);
+ BLI_assert(G.background == false);
if ((index < 0) || (index >= filelist->numfiltered)) {
return NULL;
@@ -641,7 +640,7 @@ ImBuf *filelist_geticon(struct FileList *filelist, int index)
struct direntry *file = NULL;
int fidx = 0;
- BLI_assert(G.background == FALSE);
+ BLI_assert(G.background == false);
if ((index < 0) || (index >= filelist->numfiltered)) {
return NULL;
@@ -1033,7 +1032,7 @@ bool filelist_islibrary(struct FileList *filelist, char *dir, char *group)
static int groupname_to_code(const char *group)
{
- char buf[32];
+ char buf[BLO_GROUP_MAX];
char *lslash;
BLI_strncpy(buf, group, sizeof(buf));
@@ -1041,7 +1040,7 @@ static int groupname_to_code(const char *group)
if (lslash)
lslash[0] = '\0';
- return BKE_idcode_from_name(buf);
+ return buf[0] ? BKE_idcode_from_name(buf) : 0;
}
void filelist_from_library(struct FileList *filelist)
@@ -1097,7 +1096,7 @@ void filelist_from_library(struct FileList *filelist)
filelist->filelist[0].type |= S_IFDIR;
for (i = 0, l = names; i < nnames; i++, l = l->next) {
- char *blockname = l->link;
+ const char *blockname = l->link;
filelist->filelist[i + 1].relname = BLI_strdup(blockname);
if (idcode) {
@@ -1333,7 +1332,7 @@ static void thumbnails_startjob(void *tjv, short *stop, short *do_update, float
limg->flags |= MOVIEFILE_ICON;
}
}
- *do_update = TRUE;
+ *do_update = true;
PIL_sleep_ms(10);
limg = limg->next;
}
@@ -1353,7 +1352,7 @@ static void thumbnails_update(void *tjv)
tj->filelist->filelist[limg->index].flags &= ~MOVIEFILE;
tj->filelist->filelist[limg->index].flags |= MOVIEFILE_ICON;
}
- limg->done = TRUE;
+ limg->done = true;
}
limg = limg->next;
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 4fb7a1fd32c..3799c062517 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -45,7 +45,6 @@
# include <unistd.h>
# include <sys/times.h>
# include <dirent.h>
-# include <unistd.h>
#endif
#include "DNA_space_types.h"
@@ -55,8 +54,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_linklist.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
#include "BLI_fnmatch.h"
@@ -124,7 +121,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
else
params->type = FILE_SPECIAL;
- if (is_filepath && RNA_struct_property_is_set_ex(op->ptr, "filepath", FALSE)) {
+ if (is_filepath && RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
char name[FILE_MAX];
RNA_string_get(op->ptr, "filepath", name);
if (params->type == FILE_LOADLIB) {
@@ -136,12 +133,12 @@ short ED_fileselect_set_params(SpaceFile *sfile)
}
}
else {
- if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", FALSE)) {
+ if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", false)) {
RNA_string_get(op->ptr, "directory", params->dir);
sfile->params->file[0] = '\0';
}
- if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", FALSE)) {
+ if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", false)) {
RNA_string_get(op->ptr, "filename", params->file);
}
}
@@ -151,7 +148,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
BLI_path_abs(params->dir, G.main->name);
}
- if (is_directory == TRUE && is_filename == FALSE && is_filepath == FALSE && is_files == FALSE) {
+ if (is_directory == true && is_filename == false && is_filepath == false && is_files == false) {
params->flag |= FILE_DIRSEL_ONLY;
}
else {
@@ -228,7 +225,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
}
if (is_relative_path) {
- if (!RNA_struct_property_is_set_ex(op->ptr, "relative_path", FALSE)) {
+ if (!RNA_struct_property_is_set_ex(op->ptr, "relative_path", false)) {
RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
}
}
@@ -267,7 +264,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
/* switching thumbnails needs to recalc layout [#28809] */
if (sfile->layout) {
- sfile->layout->dirty = TRUE;
+ sfile->layout->dirty = true;
}
return 1;
@@ -396,7 +393,7 @@ float file_shorten_string(char *string, float w, int front)
sw = file_string_width(string);
if (front == 1) {
- char *s = string;
+ const char *s = string;
BLI_strncpy(temp, "...", 4);
pad = file_string_width(temp);
while ((*s) && (sw + pad > w)) {
@@ -412,7 +409,7 @@ float file_shorten_string(char *string, float w, int front)
}
}
else {
- char *s = string;
+ const char *s = string;
while (sw > w) {
int slen = strlen(string);
string[slen - 1] = '\0';
@@ -498,9 +495,9 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
if (sfile->layout == NULL) {
sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout");
- sfile->layout->dirty = TRUE;
+ sfile->layout->dirty = true;
}
- else if (sfile->layout->dirty == FALSE) {
+ else if (sfile->layout->dirty == false) {
return;
}
@@ -576,7 +573,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
layout->width = sfile->layout->columns * (layout->tile_w + 2 * layout->tile_border_x) + layout->tile_border_x * 2;
layout->flag = FILE_LAYOUT_HOR;
}
- layout->dirty = FALSE;
+ layout->dirty = false;
}
FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar)
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 201abf6934a..6284caf1456 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -37,12 +37,8 @@
#include "MEM_guardedalloc.h"
-#include "DNA_space_types.h" /* FILE_MAX */
-
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
-#include "BLI_linklist.h"
-#include "BLI_dynstr.h"
#ifdef WIN32
# include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
@@ -542,7 +538,7 @@ void fsmenu_refresh_system_category(struct FSMenu *fsmenu)
fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL);
/* Add all entries to system category */
- fsmenu_read_system(fsmenu, TRUE);
+ fsmenu_read_system(fsmenu, true);
}
void fsmenu_free(void)
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 0819433fbe5..e815e2094ae 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -36,7 +36,6 @@
#include "GPU_glew.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
@@ -152,7 +151,7 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
/* refresh system directory list */
fsmenu_refresh_system_category(fsmenu_get());
- if (sfile->layout) sfile->layout->dirty = TRUE;
+ if (sfile->layout) sfile->layout->dirty = true;
}
static void file_exit(wmWindowManager *wm, ScrArea *sa)
@@ -250,7 +249,7 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
BLI_strncpy(sfile->params->renameedit, sfile->params->renamefile, sizeof(sfile->params->renameedit));
params->renamefile[0] = '\0';
}
- if (sfile->layout) sfile->layout->dirty = TRUE;
+ if (sfile->layout) sfile->layout->dirty = true;
}
@@ -417,26 +416,26 @@ static void file_keymap(struct wmKeyConfig *keyconf)
/* keys for main area */
keymap = WM_keymap_find(keyconf, "File Browser Main", SPACE_FILE, 0);
kmi = WM_keymap_add_item(keymap, "FILE_OT_execute", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
- RNA_boolean_set(kmi->ptr, "need_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "need_active", true);
/* left mouse selects and opens */
WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "fill", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "fill", true);
/* right mouse selects without opening */
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", RIGHTMOUSE, KM_CLICK, 0, 0);
- RNA_boolean_set(kmi->ptr, "open", FALSE);
+ RNA_boolean_set(kmi->ptr, "open", false);
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", RIGHTMOUSE, KM_CLICK, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "open", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "open", false);
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", RIGHTMOUSE, KM_CLICK, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "fill", TRUE);
- RNA_boolean_set(kmi->ptr, "open", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "fill", true);
+ RNA_boolean_set(kmi->ptr, "open", false);
/* front and back mouse folder navigation */
WM_keymap_add_item(keymap, "FILE_OT_previous", BUTTON4MOUSE, KM_CLICK, 0, 0);
@@ -639,7 +638,7 @@ void ED_file_init(void)
{
ED_file_read_bookmarks();
- if (G.background == FALSE) {
+ if (G.background == false) {
filelist_init_icons();
}
@@ -650,7 +649,7 @@ void ED_file_exit(void)
{
fsmenu_free();
- if (G.background == FALSE) {
+ if (G.background == false) {
filelist_free_icons();
}
}
@@ -661,7 +660,7 @@ void ED_file_read_bookmarks(void)
fsmenu_free();
- fsmenu_read_system(fsmenu_get(), TRUE);
+ fsmenu_read_system(fsmenu_get(), true);
if (cfgdir) {
char name[FILE_MAX];
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a01f4bcaaf1..8193008098e 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -122,20 +122,20 @@ static void graph_panel_view(const bContext *C, Panel *pa)
RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
/* 2D-Cursor */
- col = uiLayoutColumn(pa->layout, FALSE);
+ col = uiLayoutColumn(pa->layout, false);
uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
- row = uiLayoutSplit(sub, 0.7f, TRUE);
+ row = uiLayoutSplit(sub, 0.7f, true);
uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
- row = uiLayoutSplit(sub, 0.7f, TRUE);
+ row = uiLayoutSplit(sub, 0.7f, true);
uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
}
@@ -165,24 +165,24 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
/* user-friendly 'name' for F-Curve */
/* TODO: only show the path if this is invalid? */
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
icon = getname_anim_fcurve(name, ale->id, fcu);
uiItemL(col, name, icon);
/* RNA-Path Editing - only really should be enabled when things aren't working */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
/* color settings */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
- row = uiLayoutRow(col, TRUE);
+ row = uiLayoutRow(col, true);
uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
@@ -255,6 +255,32 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
}
+/* update callback for editing coordinates of right handle in active keyframe properties
+ * NOTE: we cannot just do graphedit_activekey_handles_cb() due to "order of computation"
+ * weirdness (see calchandleNurb_intern() and T39911)
+ */
+static void graphedit_activekey_right_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
+{
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
+
+ /* original state of handle selection - to be restored after performing the recalculation */
+ const char f1 = bezt->f1;
+ const char f3 = bezt->f3;
+
+ /* temporarily make it so that only the right handle is selected, so that updates go correctly
+ * (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
+ */
+ bezt->f1 = 0;
+ bezt->f3 = 1;
+
+ /* perform normal updates NOW */
+ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
+
+ /* restore selection state so that no-one notices this hack */
+ bezt->f1 = f1;
+ bezt->f3 = f3;
+}
+
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
bAnimListElem *ale;
@@ -289,14 +315,33 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
}
/* interpolation */
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
-
+
+ /* easing type */
+ if (bezt->ipo > BEZT_IPO_BEZ)
+ uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
+
+ /* easing extra */
+ switch (bezt->ipo) {
+ case BEZT_IPO_BACK:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
+ break;
+ case BEZT_IPO_ELASTIC:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
+ break;
+ default:
+ break;
+ }
+
/* numerical coordinate editing
* - we use the button-versions of the calls so that we can attach special update handlers
* and unit conversion magic that cannot be achieved using a purely RNA-approach
*/
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
/* keyframe itself */
{
uiItemL(col, IFACE_("Key:"), ICON_NONE);
@@ -323,20 +368,31 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
&bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
uiButSetUnitType(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
+ uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
}
/* next handle - only if current is Bezier interpolation */
if (bezt->ipo == BEZT_IPO_BEZ) {
+ /* NOTE: special update callbacks are needed on the coords here due to T39911 */
uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
+ uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
+ uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
uiButSetUnitType(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
+ uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
}
}
else {
@@ -447,7 +503,7 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa
RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
/* Target ID */
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
@@ -459,7 +515,7 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa
RNA_id_pointer_create(dtar->id, &root_ptr);
/* rna path */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
}
@@ -480,7 +536,7 @@ static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar *
RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
/* Bone 1 */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Bone 1:"));
@@ -491,7 +547,7 @@ static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar *
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
}
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiTemplateAnyID(col, &dtar2_ptr, "id", "id_type", IFACE_("Bone 2:"));
@@ -518,7 +574,7 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
/* Bone 1 */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Ob/Bone 1:"));
@@ -532,7 +588,7 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
uiLayoutSetRedAlert(col, false); /* we can clear it again now - it's only needed when creating the ID/Bone fields */
uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiTemplateAnyID(col, &dtar2_ptr, "id", "id_type", IFACE_("Ob/Bone 2:"));
@@ -559,7 +615,7 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
/* properties */
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Ob/Bone:"));
@@ -570,7 +626,7 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
}
- sub = uiLayoutColumn(layout, TRUE);
+ sub = uiLayoutColumn(layout, true);
uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
}
@@ -598,49 +654,84 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL);
/* general actions - management */
- col = uiLayoutColumn(pa->layout, FALSE);
+ col = uiLayoutColumn(pa->layout, false);
block = uiLayoutGetBlock(col);
- but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22,
- NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies"));
+ but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
+ 0, 0, 10 * UI_UNIT_X, 22,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Force updates of dependencies"));
uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);
- but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18,
- NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver"));
+ but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"),
+ 0, 0, 10 * UI_UNIT_X, 18,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Remove this driver"));
uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
/* driver-level settings - type, expressions, and errors */
RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
block = uiLayoutGetBlock(col);
uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
if (driver->type == DRIVER_TYPE_PYTHON) {
+ bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
+ bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
+
/* expression */
uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);
/* errors? */
if ((G.f & G_SCRIPT_AUTOEXEC) == 0) {
- uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_ERROR);
+ uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_CANCEL);
}
else if (driver->flag & DRIVER_FLAG_INVALID) {
- uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR);
+ uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
+ }
+
+ /* Explicit bpy-references are evil. Warn about these to prevent errors */
+ /* TODO: put these in a box? */
+ if (bpy_data_expr_error || bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
+
+ if (bpy_data_expr_error) {
+ uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
+ }
+ if (bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
+ }
}
}
else {
/* errors? */
if (driver->flag & DRIVER_FLAG_INVALID)
uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
+
+ /* Warnings about a lack of variables
+ * NOTE: The lack of variables is generally a bad thing, since it indicates
+ * that the driver doesn't work at all. This particular scenario arises
+ * primarily when users mistakenly try to use drivers for procedural
+ * property animation
+ */
+ if (BLI_listbase_is_empty(&driver->variables)) {
+ uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
+
+ if (!BLI_listbase_is_empty(&fcu->modifiers)) {
+ uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
+ uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
+ }
+ }
}
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
/* debug setting */
uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE);
/* value of driver */
if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
- uiLayout *row = uiLayoutRow(col, TRUE);
+ uiLayout *row = uiLayoutRow(col, true);
char valBuf[32];
uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
@@ -650,10 +741,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
}
/* add driver variables */
- col = uiLayoutColumn(pa->layout, FALSE);
+ col = uiLayoutColumn(pa->layout, false);
block = uiLayoutGetBlock(col);
- but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0, TIP_("Add a new target variable for this Driver"));
+ but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
+ 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
uiButSetFunc(but, driver_add_var_cb, driver, NULL);
/* loop over targets, drawing them */
@@ -662,14 +755,14 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiLayout *box, *row;
/* sub-layout column for this variable's settings */
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
/* header panel */
box = uiLayoutBox(col);
/* first row context info for driver */
RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row);
/* variable name */
uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE);
@@ -682,7 +775,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiBlockSetEmboss(block, UI_EMBOSS);
/* variable type */
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE);
/* variable type settings */
@@ -708,7 +801,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
char valBuf[32];
box = uiLayoutBox(col);
- row = uiLayoutRow(box, TRUE);
+ row = uiLayoutRow(box, true);
uiItemL(row, IFACE_("Value:"), ICON_NONE);
if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
@@ -760,7 +853,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
/* 'add modifier' button at top of panel */
{
- row = uiLayoutRow(pa->layout, FALSE);
+ row = uiLayoutRow(pa->layout, false);
block = uiLayoutGetBlock(row);
/* this is an operator button which calls a 'add modifier' operator...
@@ -770,14 +863,14 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
0.5 * UI_UNIT_X, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, TIP_("Adds a new F-Curve Modifier for the active F-Curve"));
/* copy/paste (as sub-row)*/
- row = uiLayoutRow(row, TRUE);
+ row = uiLayoutRow(row, true);
uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
}
/* draw each modifier */
for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index c40517d949a..e63e7414ecd 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -32,26 +32,16 @@
#include <string.h>
#include <float.h>
-#ifndef _WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_userdef_types.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_fcurve.h"
#include "GPU_blender_aspect.h"
@@ -206,7 +196,7 @@ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2
/* get view settings */
hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
/* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */
yscale *= units_scale;
@@ -345,7 +335,7 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
for (sel = 0; sel < 2; sel++) {
BezTriple *bezt = fcu->bezt, *prevbezt = NULL;
int basecol = (sel) ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE;
- float *fp;
+ const float *fp;
unsigned char col[4];
for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) {
@@ -444,7 +434,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* get view settings */
hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
- UI_view2d_getscale(&ar->v2d, &xscale, &yscale);
+ UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
/* set vertex color */
if (fcu->flag & (FCURVE_ACTIVE | FCURVE_SELECTED)) UI_ThemeColor(TH_TEXT_HI);
@@ -567,7 +557,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1];
}
else {
- /* extrapolate linear dosnt use the handle, use the next points center instead */
+ /* extrapolate linear doesn't use the handle, use the next points center instead */
fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
if (fac) fac = 1.0f / fac;
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
@@ -605,7 +595,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
v[1] = prevfpt->vec[1];
}
else {
- /* extrapolate linear dosnt use the handle, use the previous points center instead */
+ /* extrapolate linear doesn't use the handle, use the previous points center instead */
fpt = prevfpt - 1;
fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
if (fac) fac = 1.0f / fac;
@@ -619,6 +609,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
gpuPopMatrix();
}
+#if 0
/* helper func - draw one repeat of an F-Curve */
static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
{
@@ -774,7 +765,8 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
gpuEnd();
gpuPopMatrix();
-}
+}
+#endif
/* Debugging -------------------------------- */
@@ -1016,7 +1008,8 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
/* just draw curve based on defined data (i.e. no modifiers) */
if (fcu->bezt)
- draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
+ //draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); // XXX: better to do an optimised integration here instead, but for now, this works
else if (fcu->fpt)
draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
}
@@ -1055,7 +1048,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
gpuScale(1.0f, unit_scale, 1.0f);
if (fcu->bezt) {
- int do_handles = draw_fcurve_handles_check(sipo, fcu);
+ bool do_handles = draw_fcurve_handles_check(sipo, fcu);
if (do_handles) {
/* only draw handles/vertices on keyframes */
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 93d103e11a6..364dd1d0344 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -46,7 +46,6 @@
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "RNA_access.h"
@@ -85,7 +84,7 @@
/* Get the min/max keyframes*/
/* note: it should return total boundbox, filter for selection only can be argument... */
void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
- const short do_sel_only, const short include_handles)
+ const bool do_sel_only, const bool include_handles)
{
Scene *scene = ac->scene;
@@ -105,7 +104,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
/* check if any channels to set range with */
if (anim_data.first) {
- short foundBounds = FALSE;
+ bool foundBounds = false;
/* go through channels, finding max extents */
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -135,7 +134,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
if ((ymin) && (tymin < *ymin)) *ymin = tymin;
if ((ymax) && (tymax > *ymax)) *ymax = tymax;
- foundBounds = TRUE;
+ foundBounds = true;
}
}
@@ -187,7 +186,7 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
scene = ac.scene;
/* set the range directly */
- get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, FALSE, FALSE);
+ get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = iroundf(min);
scene->r.pefra = iroundf(max);
@@ -216,16 +215,16 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot)
/* ****************** View-All Operator ****************** */
-static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles,
+static int graphkeys_viewall(bContext *C, const bool do_sel_only, const bool include_handles,
const int smooth_viewtx)
{
bAnimContext ac;
rctf cur_new;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
get_graph_keyframe_extents(&ac,
&cur_new.xmin, &cur_new.xmax,
@@ -233,9 +232,9 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i
do_sel_only, include_handles);
BLI_rctf_scale(&cur_new, 1.1f);
-
+
UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
-
+
return OPERATOR_FINISHED;
}
@@ -243,7 +242,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i
static int graphkeys_viewall_exec(bContext *C, wmOperator *op)
{
- const short include_handles = RNA_boolean_get(op->ptr, "include_handles");
+ const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
/* whole range */
@@ -252,7 +251,7 @@ static int graphkeys_viewall_exec(bContext *C, wmOperator *op)
static int graphkeys_view_selected_exec(bContext *C, wmOperator *op)
{
- const short include_handles = RNA_boolean_get(op->ptr, "include_handles");
+ const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
/* only selected */
@@ -269,12 +268,12 @@ void GRAPH_OT_view_all(wmOperatorType *ot)
/* api callbacks */
ot->exec = graphkeys_viewall_exec;
ot->poll = ED_operator_graphedit_active; /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", TRUE, "Include Handles",
+ ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
"Include handles of keyframes when calculating extents");
}
@@ -293,7 +292,7 @@ void GRAPH_OT_view_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", TRUE, "Include Handles",
+ ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
"Include handles of keyframes when calculating extents");
}
@@ -334,7 +333,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
int cfra;
SpaceIpo *sipo = (SpaceIpo *) ac->sl;
short mapping_flag = ANIM_get_normalization_flags(ac);
-
+
/* disable driver so that it don't muck up the sampling process */
fcu->driver = NULL;
@@ -532,7 +531,7 @@ static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
}
@@ -839,7 +838,7 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
}
@@ -924,7 +923,7 @@ static int graphkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
ANIM_editkeyframes_refresh(&ac);
/* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
return OPERATOR_FINISHED;
}
@@ -1502,6 +1501,72 @@ void GRAPH_OT_interpolation_type(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", beztriple_interpolation_mode_items, 0, "Type", "");
}
+/* ******************** Set Easing Operator *********************** */
+
+static void seteasing_graph_keys(bAnimContext *ac, short mode)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting BezTriple easing
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next)
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+}
+
+static int graphkeys_easing_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ short mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
+
+ /* set handle type */
+ seteasing_graph_keys(&ac, mode);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_easing_type(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Keyframe Easing Type";
+ ot->idname = "GRAPH_OT_easing_type";
+ ot->description = "Set easing type for the F-Curve segments starting from the selected keyframes";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_easing_exec;
+ ot->poll = graphop_editable_keyframes_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", beztriple_interpolation_easing_items, 0, "Type", "");
+}
+
/* ******************** Set Handle-Type Operator *********************** */
/* this function is responsible for setting handle-type of selected keyframes */
@@ -1595,7 +1660,7 @@ typedef struct tEulerFilter {
ID *id; /* ID-block which owns the channels */
FCurve *(fcurves[3]); /* 3 Pointers to F-Curves */
- char *rna_path; /* Pointer to one of the RNA Path's used by one of the F-Curves */
+ const char *rna_path; /* Pointer to one of the RNA Path's used by one of the F-Curves */
} tEulerFilter;
static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
@@ -1902,11 +1967,16 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
/* snap keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag);
-
- ked.f1 = cursor_value / unit_scale;
-
+
+ /* normalise cursor value (for normalised F-Curves display) */
+ if (mode == GRAPHKEYS_SNAP_VALUE) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag);
+
+ ked.f1 = cursor_value / unit_scale;
+ }
+
+ /* perform snapping */
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
@@ -2024,12 +2094,16 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
/* mirror keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS);
-
+
/* apply unit corrections */
- ked.f1 = cursor_value * unit_scale;
-
+ if (mode == GRAPHKEYS_MIRROR_VALUE) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS);
+
+ ked.f1 = cursor_value * unit_scale;
+ }
+
+ /* perform actual mirroring */
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
@@ -2254,7 +2328,7 @@ static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
bAnimListElem *ale;
- short ok = 0;
+ bool ok = false;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -2328,7 +2402,7 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
/* TODO: do we want to replace existing modifiers? add user pref for that! */
ok += ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, 0);
}
-
+
/* clean up */
BLI_freelistN(&anim_data);
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 8dc5e9a441d..408c78d194e 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -61,6 +61,7 @@ void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, str
void GRAPH_OT_select_all_toggle(struct wmOperatorType *ot);
void GRAPH_OT_select_border(struct wmOperatorType *ot);
+void GRAPH_OT_select_lasso(struct wmOperatorType *ot);
void GRAPH_OT_select_column(struct wmOperatorType *ot);
void GRAPH_OT_select_linked(struct wmOperatorType *ot);
void GRAPH_OT_select_more(struct wmOperatorType *ot);
@@ -87,7 +88,7 @@ enum eGraphKeys_ColumnSelect_Mode {
/* graph_edit.c */
void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
- const short do_selected, const short include_handles);
+ const bool do_selected, const bool include_handles);
void GRAPH_OT_previewrange_set(struct wmOperatorType *ot);
void GRAPH_OT_view_all(struct wmOperatorType *ot);
@@ -111,6 +112,7 @@ void GRAPH_OT_euler_filter(struct wmOperatorType *ot);
void GRAPH_OT_handle_type(struct wmOperatorType *ot);
void GRAPH_OT_interpolation_type(struct wmOperatorType *ot);
void GRAPH_OT_extrapolation_type(struct wmOperatorType *ot);
+void GRAPH_OT_easing_type(struct wmOperatorType *ot);
void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
void GRAPH_OT_snap(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 4409a5b180e..cfd82b67289 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -33,9 +33,7 @@
#include <math.h>
#include "DNA_scene_types.h"
-#include "DNA_anim_types.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
@@ -112,19 +110,27 @@ static int graphview_cursor_exec(bContext *C, wmOperator *op)
/* set the operator properties from the initial event */
static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
float viewx, viewy;
-
+ int frame;
+
/* abort if not active region (should not really be possible) */
if (ar == NULL)
return;
-
+
/* convert from region coordinates to View2D 'tot' space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
- /* store the values in the operator properties */
/* frame is rounded to the nearest int, since frames are ints */
- RNA_int_set(op->ptr, "frame", iroundf(viewx));
+ frame = iroundf(viewx);
+
+ if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
+ CLAMP(frame, PSFRA, PEFRA);
+ }
+
+ /* store the values in the operator properties */
+ RNA_int_set(op->ptr, "frame", frame);
RNA_float_set(op->ptr, "value", viewy);
}
@@ -213,6 +219,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_clickselect);
WM_operatortype_append(GRAPH_OT_select_all_toggle);
WM_operatortype_append(GRAPH_OT_select_border);
+ WM_operatortype_append(GRAPH_OT_select_lasso);
WM_operatortype_append(GRAPH_OT_select_column);
WM_operatortype_append(GRAPH_OT_select_linked);
WM_operatortype_append(GRAPH_OT_select_more);
@@ -226,6 +233,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_handle_type);
WM_operatortype_append(GRAPH_OT_interpolation_type);
WM_operatortype_append(GRAPH_OT_extrapolation_type);
+ WM_operatortype_append(GRAPH_OT_easing_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
WM_operatortype_append(GRAPH_OT_sound_bake);
@@ -280,71 +288,76 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* graph_select.c - selection tools */
/* click-select: keyframe (replace) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "curves", FALSE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "curves", false);
+ RNA_boolean_set(kmi->ptr, "column", false);
/* click-select: all keyframes on same frame (replace) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "curves", FALSE);
- RNA_boolean_set(kmi->ptr, "column", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "curves", false);
+ RNA_boolean_set(kmi->ptr, "column", true);
/* click-select: keyframe (add) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "curves", FALSE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "curves", false);
+ RNA_boolean_set(kmi->ptr, "column", false);
/* click-select: all keyframes on same frame (add) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "curves", FALSE);
- RNA_boolean_set(kmi->ptr, "column", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "curves", false);
+ RNA_boolean_set(kmi->ptr, "column", true);
/* click-select: all keyframes in same curve (replace) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "curves", TRUE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "curves", true);
+ RNA_boolean_set(kmi->ptr, "column", false);
/* click-select: all keyframes in same curve (add) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "curves", TRUE);
- RNA_boolean_set(kmi->ptr, "column", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "curves", true);
+ RNA_boolean_set(kmi->ptr, "column", false);
/* click-select left/right */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
/* deselect all */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "invert", FALSE);
+ RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "invert", TRUE);
+ RNA_boolean_set(kmi->ptr, "invert", true);
/* borderselect */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", FALSE);
- RNA_boolean_set(kmi->ptr, "include_handles", FALSE);
+ RNA_boolean_set(kmi->ptr, "axis_range", false);
+ RNA_boolean_set(kmi->ptr, "include_handles", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", TRUE);
- RNA_boolean_set(kmi->ptr, "include_handles", FALSE);
+ RNA_boolean_set(kmi->ptr, "axis_range", true);
+ RNA_boolean_set(kmi->ptr, "include_handles", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", FALSE);
- RNA_boolean_set(kmi->ptr, "include_handles", TRUE);
+ RNA_boolean_set(kmi->ptr, "axis_range", false);
+ RNA_boolean_set(kmi->ptr, "include_handles", true);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", TRUE);
- RNA_boolean_set(kmi->ptr, "include_handles", TRUE);
-
+ RNA_boolean_set(kmi->ptr, "axis_range", true);
+ RNA_boolean_set(kmi->ptr, "include_handles", true);
+
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
+
/* column select */
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA);
@@ -370,6 +383,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_handle_type", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0);
/* destructive */
WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0);
@@ -398,11 +412,12 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* auto-set range */
WM_keymap_add_item(keymap, "GRAPH_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
/* F-Modifiers */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "only_active", FALSE);
+ RNA_boolean_set(kmi->ptr, "only_active", false);
/* animation module */
/* channels list
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index a8beaadd711..82eddfbe4a9 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -37,9 +37,9 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_lasso.h"
#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -163,9 +163,9 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
- deselect_graph_keys(&ac, 0, SELECT_INVERT, TRUE);
+ deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
else
- deselect_graph_keys(&ac, 1, SELECT_ADD, TRUE);
+ deselect_graph_keys(&ac, 1, SELECT_ADD, true);
/* restore active F-Curve... */
if (ale_active) {
@@ -217,7 +217,9 @@ void GRAPH_OT_select_all_toggle(wmOperatorType *ot)
* this, and allow handles to be considered independently too.
* Also, for convenience, handles should get same status as keyframe (if it was within bounds).
*/
-static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, short selectmode, short incl_handles)
+static void borderselect_graphkeys(
+ bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, bool incl_handles,
+ struct KeyframeEdit_LassoData *data_lasso)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -230,8 +232,7 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor
rctf rectf, scaled_rectf;
/* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
- UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+ UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
@@ -243,7 +244,13 @@ static void borderselect_graphkeys(bAnimContext *ac, rcti rect, short mode, shor
/* init editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
- ked.data = &scaled_rectf;
+ if (data_lasso) {
+ data_lasso->rectf_scaled = &scaled_rectf;
+ ked.data = data_lasso;
+ }
+ else {
+ ked.data = &scaled_rectf;
+ }
/* treat handles separately? */
if (incl_handles) {
@@ -313,9 +320,10 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
rcti rect;
+ rctf rect_fl;
short mode = 0, selectmode = 0;
- short incl_handles;
- int extend;
+ bool incl_handles;
+ bool extend;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -324,7 +332,7 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
/* clear all selection if not extending selection */
extend = RNA_boolean_get(op->ptr, "extend");
if (!extend)
- deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, TRUE);
+ deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
/* get select mode
* - 'gesture_mode' from the operator specifies how to select
@@ -354,9 +362,11 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
}
else
mode = BEZT_OK_REGION;
-
+
+ BLI_rctf_rcti_copy(&rect_fl, &rect);
+
/* apply borderselect action */
- borderselect_graphkeys(&ac, rect, mode, selectmode, incl_handles);
+ borderselect_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
@@ -383,12 +393,98 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
RNA_def_boolean(ot->srna, "include_handles", 0, "Include Handles", "Are handles tested individually against the selection criteria");
}
+static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ rcti rect;
+ rctf rect_fl;
+ short selectmode;
+ bool incl_handles;
+ bool extend;
+
+ struct KeyframeEdit_LassoData data_lasso;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ data_lasso.rectf_view = &rect_fl;
+ data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
+ if (data_lasso.mcords == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* clear all selection if not extending selection */
+ extend = RNA_boolean_get(op->ptr, "extend");
+ if (!extend)
+ deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
+
+ if (!RNA_boolean_get(op->ptr, "deselect"))
+ selectmode = SELECT_ADD;
+ else
+ selectmode = SELECT_SUBTRACT;
+
+ if (ac.spacetype == SPACE_IPO) {
+ SpaceIpo *sipo = (SpaceIpo *)ac.sl;
+ if (selectmode == SELECT_ADD) {
+ incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) ||
+ (sipo->flag & SIPO_NOHANDLES)) == 0;
+ }
+ else {
+ incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
+ }
+ }
+ else {
+ incl_handles = false;
+ }
+
+
+ /* get settings from operator */
+ BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
+
+ BLI_rctf_rcti_copy(&rect_fl, &rect);
+
+ /* apply borderselect action */
+ borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
+
+ MEM_freeN((void *)data_lasso.mcords);
+
+
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+
+void GRAPH_OT_select_lasso(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Lasso Select";
+ ot->description = "Select keyframe points using lasso selection";
+ ot->idname = "GRAPH_OT_select_lasso";
+
+ /* api callbacks */
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = graphkeys_lassoselect_exec;
+ ot->poll = graphop_visible_keyframes_poll;
+ ot->cancel = WM_gesture_lasso_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
+ RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
+}
+
/* ******************** Column Select Operator **************************** */
/* This operator works in one of four ways:
* - 1) select all keyframes in the same frame as a selected one (KKEY)
@@ -769,7 +865,7 @@ static void graphkeys_select_leftright(bAnimContext *ac, short leftright, short
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE);
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
}
/* set callbacks and editing data */
@@ -854,7 +950,7 @@ static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const
float x;
/* determine which side of the current frame mouse is on */
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL);
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
if (x < CFRA)
RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
else
@@ -938,7 +1034,9 @@ static bool fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt)
/* check if the given vertex is within bounds or not */
// TODO: should we return if we hit something?
-static void nearest_fcurve_vert_store(ListBase *matches, View2D *v2d, FCurve *fcu, BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale)
+static void nearest_fcurve_vert_store(
+ ListBase *matches, View2D *v2d, FCurve *fcu,
+ BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale)
{
/* Keyframes or Samples? */
if (bezt) {
@@ -949,17 +1047,14 @@ static void nearest_fcurve_vert_store(ListBase *matches, View2D *v2d, FCurve *fc
* needed to access the relevant vertex coordinates in the 3x3
* 'vec' matrix
*/
- UI_view2d_view_to_region(v2d, bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale, &screen_co[0], &screen_co[1]);
-
- /* check if distance from mouse cursor to vert in screen space is within tolerance */
- // XXX: inlined distance calculation, since we cannot do this on ints using the math lib...
- //dist = len_v2v2(mval, screen_co);
- dist = sqrt((mval[0] - screen_co[0]) * (mval[0] - screen_co[0]) +
- (mval[1] - screen_co[1]) * (mval[1] - screen_co[1]));
-
- if (dist <= GVERTSEL_TOL) {
+ if (UI_view2d_view_to_region_clip(v2d,
+ bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale,
+ &screen_co[0], &screen_co[1]) &&
+ /* check if distance from mouse cursor to vert in screen space is within tolerance */
+ ((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL))
+ {
tNearestVertInfo *nvi = (tNearestVertInfo *)matches->last;
- short replace = 0;
+ bool replace = false;
/* if there is already a point for the F-Curve, check if this point is closer than that was */
if ((nvi) && (nvi->fcu == fcu)) {
@@ -1136,7 +1231,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
select_mode = SELECT_ADD;
/* deselect all other keyframes (+ F-Curves too) */
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, TRUE);
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
/* deselect other channels too, but only only do this if
* selection of channel when the visibility of keyframes
@@ -1273,7 +1368,7 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE);
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
}
/* initialize keyframe editing data */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index f9585c9fabb..06612a013ec 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -257,7 +257,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
graph_draw_curves(&ac, sipo, ar, grid, 1);
/* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
- get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, FALSE, TRUE);
+ get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
/* extra offset so that these items are visible */
v2d->tot.xmin -= 10.0f;
v2d->tot.xmax += 10.0f;
@@ -547,6 +547,8 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
int filter;
int i;
+ UI_SetTheme(SPACE_IPO, RGN_TYPE_WINDOW);
+
/* build list of F-Curves which will be visible as channels in channel-region
* - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a
* mismatch between channel-colors and the drawn curves
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index aaa3aa46cbb..c2b9d92d00a 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -30,24 +30,18 @@
#include <string.h>
#include <stdio.h>
-#include "DNA_meshdata_types.h"
-#include "DNA_object_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
#include "BKE_image.h"
-#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_screen.h"
@@ -57,7 +51,6 @@
#include "IMB_imbuf_types.h"
#include "ED_gpencil.h"
-#include "ED_image.h"
#include "ED_screen.h"
#include "RNA_access.h"
@@ -179,7 +172,7 @@ void image_preview_event(int event)
ntreeCompositTagGenerators(G.scene->nodetree);
- G.is_break = FALSE;
+ G.is_break = false;
G.scene->nodetree->timecursor = set_timecursor;
G.scene->nodetree->test_break = blender_test_break;
@@ -330,7 +323,7 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void
RenderResult *rr = rnd_data[0];
ImageUser *iuser = rnd_data[1];
RenderLayer *rl;
- RenderLayer rl_fake = {0};
+ RenderLayer rl_fake = {NULL};
const char *fake_name;
int nr;
@@ -382,7 +375,7 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
ImageUser *iuser = ptrpair[1];
/* rl==NULL means composite result */
RenderLayer *rl = ptrpair[2];
- RenderPass rpass_fake = {0};
+ RenderPass rpass_fake = {NULL};
RenderPass *rpass;
const char *fake_name;
int nr;
@@ -509,7 +502,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image
const char *fake_name;
const char *display_name;
- uiLayoutRow(layout, TRUE);
+ uiLayoutRow(layout, true);
/* layer menu is 1/3 larger than pass */
wmenu1 = (2 * w) / 5;
@@ -561,7 +554,7 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr,
uiBut *but;
const float dpi_fac = UI_DPI_FAC;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
if (rr == NULL || iuser == NULL)
return;
@@ -706,13 +699,13 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE);
if (ima->source != IMA_SRC_GENERATED) {
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
if (ima->packedfile)
uiItemO(row, "", ICON_PACKAGE, "image.unpack");
else
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
- row = uiLayoutRow(row, TRUE);
+ row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, ima->packedfile == NULL);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
@@ -742,7 +735,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
}
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
@@ -753,7 +746,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ibuf) {
int imtype = BKE_ftype_to_imtype(ibuf->ftype);
- char valid_channels = BKE_imtype_valid_channels(imtype);
+ char valid_channels = BKE_imtype_valid_channels(imtype, false);
has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
@@ -761,29 +754,29 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
if (has_alpha) {
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
- uiItemR(col, &imaptr, "alpha_mode", 0, "Alpha", ICON_NONE);
+ uiItemR(col, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
}
uiItemS(layout);
- split = uiLayoutSplit(layout, 0.0f, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
/* XXX Why only display fields_per_frame only for video image types?
* And why allow fields for non-video image types at all??? */
if (BKE_image_is_animated(ima)) {
- uiLayout *subsplit = uiLayoutSplit(col, 0.0f, FALSE);
- uiLayout *subcol = uiLayoutColumn(subsplit, FALSE);
+ uiLayout *subsplit = uiLayoutSplit(col, 0.0f, false);
+ uiLayout *subcol = uiLayoutColumn(subsplit, false);
uiItemR(subcol, &imaptr, "use_fields", 0, NULL, ICON_NONE);
- subcol = uiLayoutColumn(subsplit, FALSE);
+ subcol = uiLayoutColumn(subsplit, false);
uiLayoutSetActive(subcol, RNA_boolean_get(&imaptr, "use_fields"));
uiItemR(subcol, userptr, "fields_per_frame", 0, IFACE_("Fields"), ICON_NONE);
}
else
uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
@@ -792,24 +785,24 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (BKE_image_is_animated(ima)) {
uiItemS(layout);
- split = uiLayoutSplit(layout, 0.0f, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
BLI_snprintf(str, sizeof(str), IFACE_("(%d) Frames"), iuser->framenr);
uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE);
uiItemR(col, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemO(col, NULL, ICON_NONE, "IMAGE_OT_match_movie_length");
uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
}
else if (ima->source == IMA_SRC_GENERATED) {
- split = uiLayoutSplit(layout, 0.0f, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
@@ -839,14 +832,14 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
const bool is_render_out = (id && GS(id->name) == ID_SCE);
uiLayout *col, *row, *split, *sub;
- int show_preview = FALSE;
+ bool show_preview = false;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
- split = uiLayoutSplit(col, 0.5f, FALSE);
+ split = uiLayoutSplit(col, 0.5f, false);
uiItemR(split, imfptr, "file_format", 0, "", ICON_NONE);
- sub = uiLayoutRow(split, FALSE);
+ sub = uiLayoutRow(split, false);
uiItemR(sub, imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
/* only display depth setting if multiple depths can be used */
@@ -859,7 +852,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
R_IMF_CHAN_DEPTH_24,
R_IMF_CHAN_DEPTH_32)) == 0)
{
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemL(row, IFACE_("Color Depth:"), ICON_NONE);
uiItemR(row, imfptr, "color_depth", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -877,20 +870,20 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
uiItemR(col, imfptr, "exr_codec", 0, NULL, ICON_NONE);
}
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
if (BKE_imtype_supports_zbuf(imf->imtype)) {
uiItemR(row, imfptr, "use_zbuffer", 0, NULL, ICON_NONE);
}
if (is_render_out && (imf->imtype == R_IMF_IMTYPE_OPENEXR)) {
- show_preview = TRUE;
+ show_preview = true;
uiItemR(row, imfptr, "use_preview", 0, NULL, ICON_NONE);
}
if (imf->imtype == R_IMF_IMTYPE_JP2) {
uiItemR(col, imfptr, "jpeg2k_codec", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE);
@@ -920,7 +913,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
prop = RNA_struct_find_property(imfptr, "display_settings");
display_settings_ptr = RNA_property_pointer_get(imfptr, prop);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Color Management"), ICON_NONE);
uiItemR(col, &display_settings_ptr, "display_device", 0, NULL, ICON_NONE);
@@ -948,6 +941,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
void image_buttons_register(ARegionType *art)
{
PanelType *pt;
+ const char *category = "Grease Pencil";
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
strcpy(pt->idname, "IMAGE_PT_gpencil");
@@ -955,6 +949,7 @@ void image_buttons_register(ARegionType *art)
strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
+ BLI_strncpy(pt->category, category, BLI_strlen_utf8(category));
BLI_addtail(&art->paneltypes, pt);
}
@@ -985,7 +980,7 @@ void IMAGE_OT_properties(wmOperatorType *ot)
static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = image_has_scope_region(sa);
+ ARegion *ar = image_has_tools_region(sa);
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -993,12 +988,12 @@ static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void IMAGE_OT_scopes(wmOperatorType *ot)
+void IMAGE_OT_toolshelf(wmOperatorType *ot)
{
- ot->name = "Scopes";
- ot->idname = "IMAGE_OT_scopes";
- ot->description = "Toggle display scopes panel";
-
+ ot->name = "Tool Shelf";
+ ot->idname = "IMAGE_OT_toolshelf";
+ ot->description = "Toggles tool shelf display";
+
ot->exec = image_scopes_toggle_exec;
ot->poll = ED_operator_image_active;
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 04219119d12..3b6ed52a7cc 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -40,6 +40,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_brush_types.h"
+#include "DNA_mask_types.h"
#include "PIL_time.h"
@@ -52,6 +53,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
+#include "IMB_moviecache.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -71,15 +73,13 @@
#include "ED_gpencil.h"
#include "ED_image.h"
+#include "ED_mask.h"
#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "RE_pipeline.h"
#include "RE_engine.h"
@@ -110,7 +110,7 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx,
rcti *tile;
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
gpuPushMatrix();
gpuTranslate(x, y, 0.0f);
@@ -172,7 +172,7 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx,
}
/* used by node view too */
-void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_default_view, int channels, int x, int y,
+void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf)
{
rcti color_rect;
@@ -523,7 +523,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
glaDefine2DArea(&ar->winrct);
/* find window pixel coordinates of origin */
- UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
/* this part is generic image display */
if (sima->flag & SI_SHOW_ALPHA) {
@@ -613,7 +613,7 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
/* draw repeated */
for (sy = 0; sy + dy <= ibuf->y; sy += dy) {
for (sx = 0; sx + dx <= ibuf->x; sx += dx) {
- UI_view2d_to_region_no_clip(&ar->v2d, fx + (float)sx / (float)ibuf->x, fy + (float)sy / (float)ibuf->y, &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, fx + (float)sx / (float)ibuf->x, fy + (float)sy / (float)ibuf->y, &x, &y);
glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
@@ -655,7 +655,7 @@ static void draw_image_buffer_repeated(const bContext *C, SpaceImage *sima, AReg
/* draw uv edit */
/* draw grease pencil */
-void draw_image_grease_pencil(bContext *C, short onlyv2d)
+void draw_image_grease_pencil(bContext *C, bool onlyv2d)
{
/* draw in View2D space? */
if (onlyv2d) {
@@ -795,7 +795,7 @@ static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scen
clonerect = get_alpha_clone_image(C, scene, &w, &h);
if (clonerect) {
- UI_view2d_to_region_no_clip(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
+ UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
GPU_pixels_zoom(zoomx, zoomy);
@@ -900,5 +900,61 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* render info */
if (ima && show_render)
- draw_render_info(scene, ima, ar, zoomx, zoomy);
+ draw_render_info(sima->iuser.scene, ima, ar, zoomx, zoomy);
+}
+
+static bool show_image_cache(Image *image, Mask *mask)
+{
+ if (image == NULL && mask == NULL) {
+ return false;
+ }
+ if (mask == NULL) {
+ return ELEM(image->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE);
+ }
+ return true;
+}
+
+void draw_image_cache(const bContext *C, ARegion *ar)
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ Image *image = ED_space_image(sima);
+ float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
+ Mask *mask = NULL;
+
+ if (sima->mode == SI_MODE_MASK) {
+ mask = ED_space_image_get_mask(sima);
+ }
+
+ if (!show_image_cache(image, mask)) {
+ return;
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* Draw cache background. */
+ ED_region_cache_draw_background(ar);
+
+ /* Draw cached segments. */
+ if (image != NULL && image->cache != NULL && ELEM(image->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
+ int num_segments = 0;
+ int *points = NULL;
+
+ IMB_moviecache_get_cache_segments(image->cache, IMB_PROXY_NONE, 0, &num_segments, &points);
+ ED_region_cache_draw_cached_segments(ar, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset);
+ }
+
+ glDisable(GL_BLEND);
+
+ /* Draw current frame. */
+ x = (cfra - sfra) / (efra - sfra + 1) * ar->winx;
+
+ UI_ThemeColor(TH_CFRAME);
+ glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
+ ED_region_cache_draw_curfra_label(cfra, x, 8.0f * UI_DPI_FAC);
+
+ if (mask != NULL) {
+ ED_mask_draw_frames(mask, ar, cfra, sfra, efra);
+ }
}
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 9b9c13a1d4f..a2f7d9e7d6c 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -32,13 +32,11 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
#include "BLI_rect.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_main.h"
#include "BKE_editmesh.h"
#include "BKE_library.h"
@@ -257,7 +255,7 @@ void ED_image_mouse_pos(SpaceImage *sima, ARegion *ar, const int mval[2], float
ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
ED_space_image_get_size(sima, &width, &height);
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
co[0] = ((mval[0] - sx) / zoomx) / width;
co[1] = ((mval[1] - sy) / zoomy) / height;
@@ -271,7 +269,7 @@ void ED_image_point_pos(SpaceImage *sima, ARegion *ar, float x, float y, float *
ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
ED_space_image_get_size(sima, &width, &height);
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
*xr = ((x - sx) / zoomx) / width;
*yr = ((y - sy) / zoomy) / height;
@@ -283,7 +281,7 @@ void ED_image_point_pos__reverse(SpaceImage *sima, ARegion *ar, const float co[2
int width, height;
int sx, sy;
- UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
ED_space_image_get_size(sima, &width, &height);
ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
@@ -345,7 +343,7 @@ bool ED_space_image_check_show_maskedit(Scene *scene, SpaceImage *sima)
/* check editmode - this is reserved for UV editing */
Object *ob = OBACT;
if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) {
- return FALSE;
+ return false;
}
return (sima->mode == SI_MODE_MASK);
@@ -360,7 +358,7 @@ int ED_space_image_maskedit_poll(bContext *C)
return ED_space_image_check_show_maskedit(scene, sima);
}
- return FALSE;
+ return false;
}
int ED_space_image_maskedit_mask_poll(bContext *C)
@@ -370,6 +368,6 @@ int ED_space_image_maskedit_mask_poll(bContext *C)
return sima->mask_info.mask != NULL;
}
- return FALSE;
+ return false;
}
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 5184b1e1a73..4d391874f9b 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -47,13 +47,14 @@ struct bNodeTree;
/* space_image.c */
struct ARegion *image_has_buttons_region(struct ScrArea *sa);
-struct ARegion *image_has_scope_region(struct ScrArea *sa);
+struct ARegion *image_has_tools_region(struct ScrArea *sa);
extern const char *image_context_dir[]; /* doc access */
/* image_draw.c */
void draw_image_main(const struct bContext *C, struct ARegion *ar);
-void draw_image_grease_pencil(struct bContext *C, short onlyv2d);
+void draw_image_cache(const struct bContext *C, struct ARegion *ar);
+void draw_image_grease_pencil(struct bContext *C, bool onlyv2d);
void draw_image_sample_line(struct SpaceImage *sima);
/* image_ops.c */
@@ -87,11 +88,13 @@ void IMAGE_OT_sample(struct wmOperatorType *ot);
void IMAGE_OT_sample_line(struct wmOperatorType *ot);
void IMAGE_OT_curves_point_set(struct wmOperatorType *ot);
+void IMAGE_OT_change_frame(struct wmOperatorType *ot);
+
/* image_panels.c */
struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree);
void image_buttons_register(struct ARegionType *art);
void IMAGE_OT_properties(struct wmOperatorType *ot);
-void IMAGE_OT_scopes(struct wmOperatorType *ot);
+void IMAGE_OT_toolshelf(struct wmOperatorType *ot);
#endif /* __IMAGE_INTERN_H__ */
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index bbc24004937..57be15f23fb 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -53,10 +53,10 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_node.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_screen.h"
+#include "BKE_sound.h"
#include "GPU_draw.h"
@@ -156,7 +156,7 @@ static int space_image_file_exists_poll(bContext *C)
SpaceImage *sima = CTX_wm_space_image(C);
ImBuf *ibuf;
void *lock;
- int ret = FALSE;
+ bool ret = false;
char name[FILE_MAX];
ibuf = ED_space_image_acquire_buffer(sima, &lock);
@@ -164,14 +164,14 @@ static int space_image_file_exists_poll(bContext *C)
BLI_strncpy(name, ibuf->name, FILE_MAX);
BLI_path_abs(name, bmain->name);
- if (BLI_exists(name) == FALSE) {
+ if (BLI_exists(name) == false) {
CTX_wm_operator_poll_msg_set(C, "image file not found");
}
else if (!BLI_file_is_writable(name)) {
CTX_wm_operator_poll_msg_set(C, "image path can't be written to");
}
else {
- ret = TRUE;
+ ret = true;
}
}
ED_space_image_release_buffer(sima, ibuf, lock);
@@ -223,16 +223,16 @@ static int image_sample_poll(bContext *C)
if (obedit) {
if (ED_space_image_show_uvedit(sima, obedit) && (toolsettings->use_uv_sculpt))
- return FALSE;
+ return false;
}
else if (sima->mode != SI_MODE_VIEW) {
- return FALSE;
+ return false;
}
return space_image_main_area_poll(C);
}
else {
- return FALSE;
+ return false;
}
}
/********************** view pan operator *********************/
@@ -439,7 +439,7 @@ static int image_view_zoom_exec(bContext *C, wmOperator *op)
sima_zoom_set_factor(sima, ar, RNA_float_get(op->ptr, "factor"), NULL);
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
/* XXX notifier? */
#if 0
@@ -476,7 +476,7 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, sima->zoom * factor, location);
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -599,31 +599,19 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
else {
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
+ float pan_vec[3];
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
-
- float dt = ndof->dt;
- /* tune these until it feels right */
- const float zoom_sensitivity = 0.5f; // 50% per second (I think)
- const float pan_sensitivity = 300.f; // screen pixels per second
+ const wmNDOFMotionData *ndof = event->customdata;
+ const float speed = NDOF_PIXELS_PER_SECOND;
- float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
- float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
+ WM_event_ndof_pan_get(ndof, pan_vec, true);
- /* "mouse zoom" factor = 1 + (dx + dy) / 300
- * what about "ndof zoom" factor? should behave like this:
- * at rest -> factor = 1
- * move forward -> factor > 1
- * move backward -> factor < 1
- */
- float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
+ mul_v2_fl(pan_vec, (speed * ndof->dt) / sima->zoom);
+ pan_vec[2] *= -ndof->dt;
- if (U.ndof_flag & NDOF_ZOOM_INVERT)
- zoom_factor = -zoom_factor;
-
- sima_zoom_set_factor(sima, ar, zoom_factor, NULL);
- sima->xof += pan_x;
- sima->yof += pan_y;
+ sima_zoom_set_factor(sima, ar, 1.0f + pan_vec[2], NULL);
+ sima->xof += pan_vec[0];
+ sima->yof += pan_vec[1];
ED_region_tag_redraw(ar);
@@ -640,6 +628,7 @@ void IMAGE_OT_view_ndof(wmOperatorType *ot)
/* api callbacks */
ot->invoke = image_view_ndof_invoke;
+ ot->poll = space_image_main_area_poll;
/* flags */
ot->flag = OPTYPE_LOCK_BYPASS;
@@ -695,7 +684,7 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
sima->xof = sima->yof = 0.0f;
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -758,7 +747,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
if (size <= 0.01f) size = 0.01f;
sima_zoom_set(sima, ar, 0.7f / size, NULL);
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -787,12 +776,12 @@ static int image_view_zoom_in_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float location[2];
-
+
RNA_float_get_array(op->ptr, "location", location);
- sima_zoom_set_factor(sima, ar, 1.25f, location);
+ sima_zoom_set_factor(sima, ar, powf(2.0f, 1.0f / 3.0f), location);
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -832,12 +821,12 @@ static int image_view_zoom_out_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float location[2];
-
+
RNA_float_get_array(op->ptr, "location", location);
- sima_zoom_set_factor(sima, ar, 0.8f, location);
-
- ED_region_tag_redraw(CTX_wm_region(C));
+ sima_zoom_set_factor(sima, ar, powf(0.5f, 1.0f / 3.0f), location);
+
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -894,7 +883,7 @@ static int image_view_zoom_ratio_exec(bContext *C, wmOperator *op)
}
#endif
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -1037,6 +1026,7 @@ static int image_sequence_get_len(ListBase *frames, int *ofs)
static int image_open_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
@@ -1048,6 +1038,8 @@ static int image_open_exec(bContext *C, wmOperator *op)
int frame_seq_len = 0;
int frame_ofs = 1;
+ const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
+
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_struct_property_is_set(op->ptr, "directory")) {
ListBase frames;
@@ -1074,6 +1066,12 @@ static int image_open_exec(bContext *C, wmOperator *op)
if (!op->customdata)
image_open_init(C, op);
+ /* only image path after save, never ibuf */
+ if (is_relative_path) {
+ const char *relbase = ID_BLEND_PATH(bmain, &ima->id);
+ BLI_path_rel(ima->name, relbase);
+ }
+
/* hook into UI */
iod = op->customdata;
@@ -1126,7 +1124,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
- char *path = U.textudir;
+ const char *path = U.textudir;
Image *ima = NULL;
if (sima) {
@@ -1450,22 +1448,24 @@ static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op)
RNA_string_set(op->ptr, "filepath", simopts->filepath);
}
-/* assumes name is FILE_MAX */
-/* ima->name and ibuf->name should end up the same */
-static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveImageOptions *simopts, int do_newpath)
+/**
+ * \return success.
+ * \note ``ima->name`` and ``ibuf->name`` should end up the same.
+ */
+static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveImageOptions *simopts, bool do_newpath)
{
Image *ima = ED_space_image(sima);
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
+ bool ok = false;
if (ibuf) {
ImBuf *colormanaged_ibuf;
const char *relbase = ID_BLEND_PATH(CTX_data_main(C), &ima->id);
- const short relative = (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"));
- const short save_copy = (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
+ const bool relative = (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"));
+ const bool save_copy = (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
const bool save_as_render = (RNA_struct_find_property(op->ptr, "save_as_render") && RNA_boolean_get(op->ptr, "save_as_render"));
ImageFormatData *imf = &simopts->im_format;
- short ok = FALSE;
/* old global to ensure a 2nd save goes to same dir */
BLI_strncpy(G.ima, simopts->filepath, sizeof(G.ima));
@@ -1495,8 +1495,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
Scene *scene = CTX_data_scene(C);
RenderResult *rr = BKE_image_acquire_renderresult(scene, ima);
if (rr) {
- RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.exr_codec);
- ok = TRUE;
+ ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.exr_codec);
}
else {
BKE_report(op->reports, RPT_ERROR, "Did not write, no Multilayer Image");
@@ -1504,9 +1503,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
BKE_image_release_renderresult(scene, ima);
}
else {
- if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
- ok = TRUE;
- }
+ ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy);
}
if (ok) {
@@ -1569,6 +1566,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
ED_space_image_release_buffer(sima, ibuf, lock);
+
+ return ok;
}
static void image_save_as_free(wmOperator *op)
@@ -1595,7 +1594,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
save_image_options_from_op(&simopts, op);
- save_image_doit(C, sima, op, &simopts, TRUE);
+ save_image_doit(C, sima, op, &simopts, true);
image_save_as_free(op);
return OPERATOR_FINISHED;
@@ -1627,7 +1626,7 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
/* enable save_copy by default for render results */
if (ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE) && !RNA_struct_property_is_set(op->ptr, "copy")) {
- RNA_boolean_set(op->ptr, "copy", TRUE);
+ RNA_boolean_set(op->ptr, "copy", true);
}
RNA_boolean_set(op->ptr, "save_as_render", save_as_render);
@@ -1665,7 +1664,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &ptr);
- uiTemplateImageSettings(layout, &ptr, FALSE);
+ uiTemplateImageSettings(layout, &ptr, false);
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
@@ -1682,12 +1681,12 @@ static int image_save_as_poll(bContext *C)
if (ima->source == IMA_SRC_VIEWER) {
CTX_wm_operator_poll_msg_set(C, "can't save image while rendering");
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
void IMAGE_OT_save_as(wmOperatorType *ot)
@@ -1732,7 +1731,10 @@ static int image_save_exec(bContext *C, wmOperator *op)
save_image_options_from_op(&simopts, op);
if (BLI_exists(simopts.filepath) && BLI_file_is_writable(simopts.filepath)) {
- save_image_doit(C, sima, op, &simopts, FALSE);
+ if (save_image_doit(C, sima, op, &simopts, false)) {
+ /* report since this can be called from key-shortcuts */
+ BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", simopts.filepath);
+ }
}
else {
BKE_reportf(op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", simopts.filepath);
@@ -2020,10 +2022,10 @@ static int image_invert_exec(bContext *C, wmOperator *op)
bool support_undo = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
/* flags indicate if this channel should be inverted */
- const short r = RNA_boolean_get(op->ptr, "invert_r");
- const short g = RNA_boolean_get(op->ptr, "invert_g");
- const short b = RNA_boolean_get(op->ptr, "invert_b");
- const short a = RNA_boolean_get(op->ptr, "invert_a");
+ const bool r = RNA_boolean_get(op->ptr, "invert_r");
+ const bool g = RNA_boolean_get(op->ptr, "invert_g");
+ const bool b = RNA_boolean_get(op->ptr, "invert_b");
+ const bool a = RNA_boolean_get(op->ptr, "invert_a");
int i;
@@ -2301,7 +2303,7 @@ typedef struct ImageSampleInfo {
float zf;
unsigned char *colp;
- float *colfp;
+ const float *colfp;
int *zp;
float *zfp;
@@ -2321,10 +2323,11 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
}
-/* returns color in SRGB */
-/* matching ED_space_node_color_sample() */
-bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
+/* Returns color in the display space, matching ED_space_node_color_sample(). */
+bool ED_space_image_color_sample(Scene *scene, SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
{
+ const char *display_device = scene->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
float fx, fy;
@@ -2332,13 +2335,13 @@ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], flo
if (ibuf == NULL) {
ED_space_image_release_buffer(sima, ibuf, lock);
- return FALSE;
+ return false;
}
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &fx, &fy);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
@@ -2347,16 +2350,21 @@ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], flo
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
- linearrgb_to_srgb_v3_v3(r_col, fp);
- ret = TRUE;
+ copy_v3_v3(r_col, fp);
+ ret = true;
}
else if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
- ret = TRUE;
+ IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
+ ret = true;
}
}
+ if (ret) {
+ IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
+ }
+
ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
@@ -2381,7 +2389,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fx, &fy);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
Image *image = ED_space_image(sima);
@@ -2399,7 +2407,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
info->zp = NULL;
info->zfp = NULL;
- info->use_default_view = (image->flag & IMA_VIEW_AS_RENDER) ? FALSE : TRUE;
+ info->use_default_view = (image->flag & IMA_VIEW_AS_RENDER) ? false : true;
if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
@@ -2419,7 +2427,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
copy_v4_v4(info->linearcol, info->colf);
IMB_colormanagement_colorspace_to_scene_linear_v4(info->linearcol, false, ibuf->rect_colorspace);
- info->color_manage = TRUE;
+ info->color_manage = true;
}
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -2432,7 +2440,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
copy_v4_v4(info->linearcol, info->colf);
- info->color_manage = TRUE;
+ info->color_manage = true;
}
if (ibuf->zbuf) {
@@ -2498,6 +2506,11 @@ static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event
ARegion *ar = CTX_wm_region(C);
ImageSampleInfo *info;
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (event->mval[1] <= 16)
+ return OPERATOR_PASS_THROUGH;
+ }
+
if (!ED_space_image_has_buffer(sima))
return OPERATOR_CANCELLED;
@@ -2829,7 +2842,7 @@ static int image_cycle_render_slot_exec(bContext *C, wmOperator *op)
{
Image *ima = CTX_data_edit_image(C);
int a, slot, cur = ima->render_slot;
- const short use_reverse = RNA_boolean_get(op->ptr, "reverse");
+ const bool use_reverse = RNA_boolean_get(op->ptr, "reverse");
for (a = 1; a < IMA_MAX_RENDER_SLOT; a++) {
slot = (cur + (use_reverse ? -a : a)) % IMA_MAX_RENDER_SLOT;
@@ -2869,3 +2882,117 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "reverse", 0, "Cycle in Reverse", "");
}
+
+/********************** change frame operator *********************/
+
+static int change_frame_poll(bContext *C)
+{
+ /* prevent changes during render */
+ if (G.is_rendering)
+ return 0;
+
+ return space_image_main_area_poll(C);
+}
+
+static void change_frame_apply(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ /* set the new frame number */
+ CFRA = RNA_int_get(op->ptr, "frame");
+ FRAMENUMBER_MIN_CLAMP(CFRA);
+ SUBFRA = 0.0f;
+
+ /* do updates */
+ sound_seek_scene(CTX_data_main(C), scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+}
+
+static int change_frame_exec(bContext *C, wmOperator *op)
+{
+ change_frame_apply(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+static int frame_from_event(bContext *C, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ int framenr = 0;
+
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
+
+ framenr = sfra + event->mval[0] / framelen;
+ }
+ else {
+ float viewx, viewy;
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
+
+ framenr = iroundf(viewx);
+ }
+
+ return framenr;
+}
+
+static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (event->mval[1] > 16)
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
+
+ change_frame_apply(C, op);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_FINISHED;
+
+ case MOUSEMOVE:
+ RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
+ change_frame_apply(C, op);
+ break;
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ if (event->val == KM_RELEASE)
+ return OPERATOR_FINISHED;
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void IMAGE_OT_change_frame(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Change Frame";
+ ot->idname = "IMAGE_OT_change_frame";
+ ot->description = "Interactively change the current frame number";
+
+ /* api callbacks */
+ ot->exec = change_frame_exec;
+ ot->invoke = change_frame_invoke;
+ ot->modal = change_frame_modal;
+ ot->poll = change_frame_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
+
+ /* rna */
+ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 84649d35525..0c81ddfa77a 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -43,12 +43,8 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
-#include "BKE_global.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_editmesh.h"
-#include "BKE_sequencer.h"
-#include "BKE_node.h"
#include "IMB_imbuf_types.h"
@@ -69,6 +65,7 @@
#include "WM_types.h"
#include "UI_resources.h"
+#include "UI_interface.h"
#include "UI_view2d.h"
#include "image_intern.h"
@@ -82,7 +79,7 @@ static void image_scopes_tag_refresh(ScrArea *sa)
/* only while histogram is visible */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_PREVIEW && ar->flag & RGN_FLAG_HIDDEN)
+ if (ar->regiontype == RGN_TYPE_TOOLS && ar->flag & RGN_FLAG_HIDDEN)
return;
}
@@ -116,11 +113,11 @@ ARegion *image_has_buttons_region(ScrArea *sa)
return arnew;
}
-ARegion *image_has_scope_region(ScrArea *sa)
+ARegion *image_has_tools_region(ScrArea *sa)
{
ARegion *ar, *arnew;
- ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
if (ar) return ar;
/* add subdiv level; after buttons */
@@ -132,7 +129,7 @@ ARegion *image_has_scope_region(ScrArea *sa)
arnew = MEM_callocN(sizeof(ARegion), "scopes for image");
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
- arnew->regiontype = RGN_TYPE_PREVIEW;
+ arnew->regiontype = RGN_TYPE_TOOLS;
arnew->alignment = RGN_ALIGN_LEFT;
arnew->flag = RGN_FLAG_HIDDEN;
@@ -152,10 +149,10 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
simage = MEM_callocN(sizeof(SpaceImage), "initimage");
simage->spacetype = SPACE_IMAGE;
simage->zoom = 1.0f;
- simage->lock = TRUE;
+ simage->lock = true;
simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA;
- simage->iuser.ok = TRUE;
+ simage->iuser.ok = true;
simage->iuser.fie_ima = 2;
simage->iuser.frames = 100;
@@ -177,11 +174,11 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
- /* scopes */
+ /* scopes/uv sculpt/paint */
ar = MEM_callocN(sizeof(ARegion), "buttons for image");
BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_PREVIEW;
+ ar->regiontype = RGN_TYPE_TOOLS;
ar->alignment = RGN_ALIGN_LEFT;
ar->flag = RGN_FLAG_HIDDEN;
@@ -255,7 +252,9 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_curves_point_set);
WM_operatortype_append(IMAGE_OT_properties);
- WM_operatortype_append(IMAGE_OT_scopes);
+ WM_operatortype_append(IMAGE_OT_toolshelf);
+
+ WM_operatortype_append(IMAGE_OT_change_frame);
}
static void image_keymap(struct wmKeyConfig *keyconf)
@@ -270,17 +269,17 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "IMAGE_OT_scopes", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", true);
keymap = WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "IMAGE_OT_view_all", FKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "fit_view", TRUE);
+ RNA_boolean_set(kmi->ptr, "fit_view", true);
WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
@@ -311,6 +310,8 @@ static void image_keymap(struct wmKeyConfig *keyconf)
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
+ WM_keymap_add_item(keymap, "IMAGE_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
+
WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
@@ -318,7 +319,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
/* toggle editmode is handy to have while UV unwrapping */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
/* fast switch to render slots */
for (i = 0; i < MAX2(IMA_MAX_RENDER_SLOT, 9); i++) {
@@ -394,8 +395,8 @@ static void image_refresh(const bContext *C, ScrArea *sa)
else if (obedit && obedit->type == OB_MESH) {
Mesh *me = (Mesh *)obedit->data;
struct BMEditMesh *em = me->edit_btmesh;
- int sloppy = TRUE; /* partially selected face is ok */
- int selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); /* only selected active face? */
+ bool sloppy = true; /* partially selected face is ok */
+ bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); /* only selected active face? */
if (BKE_scene_use_new_shading_nodes(scene)) {
/* new shading system does not alter image */
@@ -511,18 +512,21 @@ static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
}
case NC_OBJECT:
{
- Object *ob = OBACT;
switch (wmn->data) {
case ND_TRANSFORM:
case ND_MODIFIER:
- if (ob == (Object *)wmn->reference && (ob->mode & OB_MODE_EDIT)) {
+ {
+ Object *ob = OBACT;
+ if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
}
break;
+ }
}
+
break;
}
}
@@ -546,7 +550,7 @@ static int image_context(const bContext *C, const char *member, bContextDataResu
if (mask) {
CTX_data_id_pointer_set(result, &mask->id);
}
- return TRUE;
+ return true;
}
return 0;
}
@@ -693,7 +697,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
if (sima->flag & SI_SHOW_GPENCIL) {
/* Grease Pencil too (in addition to UV's) */
- draw_image_grease_pencil((bContext *)C, TRUE);
+ draw_image_grease_pencil((bContext *)C, true);
}
/* sample line */
@@ -703,7 +707,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
if (sima->flag & SI_SHOW_GPENCIL) {
/* draw Grease Pencil - screen space only */
- draw_image_grease_pencil((bContext *)C, FALSE);
+ draw_image_grease_pencil((bContext *)C, false);
}
if (mask) {
@@ -732,16 +736,16 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
sima->mask_info.overlay_mode,
width, height,
aspx, aspy,
- TRUE, FALSE,
+ true, false,
NULL, C);
- ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra);
-
UI_view2d_view_ortho(v2d);
draw_image_cursor(ar, sima->cursor);
UI_view2d_view_restore(C);
}
+ draw_image_cache(C, ar);
+
/* scrollers? */
#if 0
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
@@ -788,27 +792,35 @@ static void image_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
{
/* context changes */
switch (wmn->category) {
- case NC_GPENCIL:
- if (wmn->data == ND_DATA)
- ED_region_tag_redraw(ar);
- break;
- case NC_BRUSH:
- if (wmn->action == NA_EDITED)
- ED_region_tag_redraw(ar);
- break;
case NC_TEXTURE:
case NC_MATERIAL:
/* sending by texture render job and needed to properly update displaying
* brush texture icon */
ED_region_tag_redraw(ar);
break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_MODE:
+ case ND_RENDER_RESULT:
+ case ND_COMPO_RESULT:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_IMAGE:
+ if (wmn->action != NA_PAINTING)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_NODE:
+ ED_region_tag_redraw(ar);
+ break;
}
}
/* *********************** scopes region ************************ */
/* add handlers, stuff you only do once or on area/region changes */
-static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
+static void image_tools_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
@@ -819,31 +831,44 @@ static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
-static void image_scope_area_draw(const bContext *C, ARegion *ar)
+static void image_tools_area_draw(const bContext *C, ARegion *ar)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
-
- if (ibuf) {
- if (!sima->scopes.ok) {
- BKE_histogram_update_sample_line(&sima->sample_line_hist, ibuf, &scene->view_settings, &scene->display_settings);
+ /* XXX performance regression if name of scopes category changes! */
+ PanelCategoryStack *category = UI_panel_category_active_find(ar, "Scopes");
+
+ /* only update scopes if scope category is active */
+ if (category) {
+ if (ibuf) {
+ if (!sima->scopes.ok) {
+ BKE_histogram_update_sample_line(&sima->sample_line_hist, ibuf, &scene->view_settings, &scene->display_settings);
+ }
+ if (sima->image->flag & IMA_VIEW_AS_RENDER)
+ scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
+ else
+ scopes_update(&sima->scopes, ibuf, NULL, &scene->display_settings);
}
- if (sima->image->flag & IMA_VIEW_AS_RENDER)
- scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
- else
- scopes_update(&sima->scopes, ibuf, NULL, &scene->display_settings);
}
ED_space_image_release_buffer(sima, ibuf, lock);
ED_region_panels(C, ar, 1, NULL, -1);
}
-static void image_scope_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void image_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch (wmn->category) {
+ case NC_GPENCIL:
+ if (wmn->data == ND_DATA)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_BRUSH:
+ if (wmn->action == NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SCENE:
switch (wmn->data) {
case ND_MODE:
@@ -942,17 +967,17 @@ void ED_spacetype_image(void)
art->draw = image_buttons_area_draw;
BLI_addhead(&st->regiontypes, art);
- image_buttons_register(art);
ED_uvedit_buttons_register(art);
-
+ image_buttons_register(art);
+
/* regions: statistics/scope buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
- art->regionid = RGN_TYPE_PREVIEW;
+ art->regionid = RGN_TYPE_TOOLS;
art->prefsizex = 220; // XXX
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
- art->listener = image_scope_area_listener;
- art->init = image_scope_area_init;
- art->draw = image_scope_area_draw;
+ art->listener = image_tools_area_listener;
+ art->init = image_tools_area_init;
+ art->draw = image_tools_area_draw;
BLI_addhead(&st->regiontypes, art);
/* regions: header */
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 3e3213534eb..22b0432e06b 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -27,8 +27,6 @@
* \ingroup spinfo
*/
-
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -37,7 +35,6 @@
#include "BLF_api.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "DNA_space_types.h"
@@ -48,10 +45,6 @@
#include "GPU_glew.h"
-#include "MEM_guardedalloc.h"
-
-#include "BIF_glutil.h"
-
#include "ED_datafiles.h"
#include "ED_types.h"
@@ -149,10 +142,10 @@ static int report_textview_begin(TextViewContext *tvc)
tvc->iter_char = 0;
report_textview_init__internal(tvc);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
#else
return (tvc->iter != NULL);
@@ -178,10 +171,10 @@ static int report_textview_step(TextViewContext *tvc)
tvc->iter_char = 0; /* reset start */
report_textview_init__internal(tvc);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
else {
@@ -189,7 +182,7 @@ static int report_textview_step(TextViewContext *tvc)
tvc->iter_char = tvc->iter_char_next + 1;
report_textview_init__internal(tvc);
- return TRUE;
+ return true;
}
}
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 827e4427ca0..0cc01646e82 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -41,7 +41,6 @@
#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -236,15 +235,6 @@ static int borderselect_exec(bContext *C, wmOperator *op)
WM_operator_properties_border_to_rcti(op, &rect);
-#if 0
- mval[0] = rect.xmin;
- mval[1] = rect.ymin;
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmin, &rectf.ymin);
- mval[0] = rect.xmax;
- mval[1] = rect.ymax;
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmax, &rectf.ymax);
-#endif
-
if (!extend) {
for (report = reports->list.first; report; report = report->next) {
@@ -319,7 +309,7 @@ void INFO_OT_select_border(wmOperatorType *ot)
/* ot->flag = OPTYPE_REGISTER; */
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 1fd47219463..8664ebf30b7 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -34,7 +34,6 @@
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
@@ -50,14 +49,12 @@
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
-#include "BKE_mesh.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_editmesh.h"
#include "ED_info.h"
#include "ED_armature.h"
-#include "ED_mesh.h"
#define MAX_INFO_LEN 512
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 865694804f4..ff6ef23af65 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -35,7 +35,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 14446d22109..41235707833 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -41,12 +41,9 @@
#include "GPU_colors.h"
#include "GPU_primitives.h"
-#include "BIF_glutil.h"
#include "BKE_text.h"
-#include "ED_datafiles.h"
-
#include "textview.h"
static void console_font_begin(TextViewContext *sc)
@@ -65,7 +62,7 @@ typedef struct ConsoleDrawContext {
int *xy; // [2]
int *sel; // [2]
int *pos_pick; // bottom of view == 0, top of file == combine chars, end of line is lower then start.
- int *mval; // [2]
+ const int *mval; // [2]
int draw;
} ConsoleDrawContext;
@@ -294,7 +291,9 @@ int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mous
cdc.lofs = -BLF_descender(mono);
/* note, scroll bar must be already subtracted () */
cdc.console_width = (tvc->winx - (CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth;
- CLAMP(cdc.console_width, 1, INT_MAX); /* avoid divide by zero on small windows */
+ /* avoid divide by zero on small windows */
+ if (cdc.console_width < 1)
+ cdc.console_width = 1;
cdc.winx = tvc->winx - CONSOLE_DRAW_MARGIN;
cdc.ymin = tvc->ymin;
cdc.ymax = tvc->ymax;
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 0d4246144da..62703ba517e 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -42,7 +42,6 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_sca.h"
-#include "BKE_material.h" //for texface convert
#include "ED_logic.h"
#include "ED_object.h"
@@ -59,11 +58,6 @@
#include "logic_intern.h"
-// temporary new includes for texface functions
-#include "DNA_mesh_types.h"
-#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
-
/* ************* Generic Operator Helpers ************* */
static int edit_sensor_poll(bContext *C)
{
@@ -228,9 +222,9 @@ static int logicbricks_move_property_get(wmOperator *op)
int type = RNA_enum_get(op->ptr, "direction");
if (type == 1)
- return TRUE;
+ return true;
else
- return FALSE;
+ return false;
}
/* ************* Add/Remove Sensor Operator ************* */
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 09b158815ea..9cf648eeef6 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -42,7 +42,6 @@
#include "DNA_screen_types.h"
#include "DNA_sensor_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
@@ -52,19 +51,13 @@
#include "BKE_action.h"
#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_sca.h"
-#include "BKE_screen.h"
#include "ED_util.h"
-#include "WM_types.h"
-
#include "GPU_primitives.h"
-
#include "BLF_translation.h"
#include "UI_interface.h"
@@ -122,7 +115,7 @@ void make_unique_prop_names(bContext *C, char *str)
bActuator *act;
ID **idar;
short a, obcount, propcount=0, nr;
- char **names;
+ const char **names;
/* this function is called by a Button, and gives the current
* stringpointer as an argument, this is the one that can change
@@ -427,109 +420,109 @@ static const char *sensor_name(int type)
{
switch (type) {
case SENS_ALWAYS:
- return "Always";
+ return N_("Always");
case SENS_NEAR:
- return "Near";
+ return N_("Near");
case SENS_KEYBOARD:
- return "Keyboard";
+ return N_("Keyboard");
case SENS_PROPERTY:
- return "Property";
+ return N_("Property");
case SENS_ARMATURE:
- return "Armature";
+ return N_("Armature");
case SENS_ACTUATOR:
- return "Actuator";
+ return N_("Actuator");
case SENS_DELAY:
- return "Delay";
+ return N_("Delay");
case SENS_MOUSE:
- return "Mouse";
+ return N_("Mouse");
case SENS_COLLISION:
- return "Collision";
+ return N_("Collision");
case SENS_RADAR:
- return "Radar";
+ return N_("Radar");
case SENS_RANDOM:
- return "Random";
+ return N_("Random");
case SENS_RAY:
- return "Ray";
+ return N_("Ray");
case SENS_MESSAGE:
- return "Message";
+ return N_("Message");
case SENS_JOYSTICK:
- return "Joystick";
+ return N_("Joystick");
}
- return "unknown";
+ return N_("Unknown");
}
static const char *controller_name(int type)
{
switch (type) {
case CONT_LOGIC_AND:
- return "And";
+ return N_("And");
case CONT_LOGIC_OR:
- return "Or";
+ return N_("Or");
case CONT_LOGIC_NAND:
- return "Nand";
+ return N_("Nand");
case CONT_LOGIC_NOR:
- return "Nor";
+ return N_("Nor");
case CONT_LOGIC_XOR:
- return "Xor";
+ return N_("Xor");
case CONT_LOGIC_XNOR:
- return "Xnor";
+ return N_("Xnor");
case CONT_EXPRESSION:
- return "Expression";
+ return N_("Expression");
case CONT_PYTHON:
- return "Python";
+ return N_("Python");
}
- return "unknown";
+ return N_("Unknown");
}
static const char *actuator_name(int type)
{
switch (type) {
case ACT_SHAPEACTION:
- return "Shape Action";
+ return N_("Shape Action");
case ACT_ACTION:
- return "Action";
+ return N_("Action");
case ACT_OBJECT:
- return "Motion";
+ return N_("Motion");
case ACT_IPO:
- return "F-Curve";
+ return N_("F-Curve");
case ACT_LAMP:
- return "Lamp";
+ return N_("Lamp");
case ACT_CAMERA:
- return "Camera";
+ return N_("Camera");
case ACT_MATERIAL:
- return "Material";
+ return N_("Material");
case ACT_SOUND:
- return "Sound";
+ return N_("Sound");
case ACT_PROPERTY:
- return "Property";
+ return N_("Property");
case ACT_EDIT_OBJECT:
- return "Edit Object";
+ return N_("Edit Object");
case ACT_CONSTRAINT:
- return "Constraint";
+ return N_("Constraint");
case ACT_SCENE:
- return "Scene";
+ return N_("Scene");
case ACT_GROUP:
- return "Group";
+ return N_("Group");
case ACT_RANDOM:
- return "Random";
+ return N_("Random");
case ACT_MESSAGE:
- return "Message";
+ return N_("Message");
case ACT_GAME:
- return "Game";
+ return N_("Game");
case ACT_VISIBILITY:
- return "Visibility";
+ return N_("Visibility");
case ACT_2DFILTER:
- return "Filter 2D";
+ return N_("Filter 2D");
case ACT_PARENT:
- return "Parent";
+ return N_("Parent");
case ACT_STATE:
- return "State";
+ return N_("State");
case ACT_ARMATURE:
- return "Armature";
+ return N_("Armature");
case ACT_STEERING:
- return "Steering";
+ return N_("Steering");
}
- return "unknown";
+ return N_("Unknown");
}
static void set_sca_ob(Object *ob)
@@ -599,9 +592,9 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
/* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
if (scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
- do_it = TRUE;
+ do_it = true;
while (do_it) {
- do_it = FALSE;
+ do_it = false;
ob= bmain->object.first;
while (ob) {
@@ -614,7 +607,7 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
if (sens->links[a]) {
obt= (Object *)sens->links[a]->mynew;
if (obt && (obt->scavisflag & OB_VIS_CONT)) {
- do_it = TRUE;
+ do_it = true;
ob->scavisflag |= OB_VIS_SENS;
break;
}
@@ -633,7 +626,7 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
if (cont->links[a]) {
obt= (Object *)cont->links[a]->mynew;
if (obt && (obt->scavisflag & OB_VIS_ACT)) {
- do_it = TRUE;
+ do_it = true;
ob->scavisflag |= OB_VIS_CONT;
break;
}
@@ -652,7 +645,7 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
if (sens->links[a]) {
obt= (Object *)sens->links[a]->mynew;
if (obt && (obt->scavisflag & OB_VIS_CONT)==0) {
- do_it = TRUE;
+ do_it = true;
obt->scavisflag |= OB_VIS_CONT;
}
}
@@ -669,7 +662,7 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
if (cont->links[a]) {
obt= (Object *)cont->links[a]->mynew;
if (obt && (obt->scavisflag & OB_VIS_ACT)==0) {
- do_it = TRUE;
+ do_it = true;
obt->scavisflag |= OB_VIS_ACT;
}
}
@@ -923,7 +916,7 @@ static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_c
return block;
}
-static int is_sensor_linked(uiBlock *block, bSensor *sens)
+static bool is_sensor_linked(uiBlock *block, bSensor *sens)
{
bController *cont;
int i;
@@ -944,30 +937,39 @@ static void draw_sensor_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *lo
bSensor *sens= (bSensor *)ptr->data;
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
- uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")) {
- uiItemR(row, ptr, "type", 0, "", ICON_NONE);
- uiItemR(row, ptr, "name", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
}
else {
- uiItemL(row, sensor_name(sens->type), ICON_NONE);
- uiItemL(row, sens->name, ICON_NONE);
+ uiItemL(sub, IFACE_(sensor_name(sens->type)), ICON_NONE);
+ uiItemL(sub, sens->name, ICON_NONE);
}
- sub = uiLayoutRow(row, FALSE);
- uiLayoutSetActive(sub, ((RNA_boolean_get(logic_ptr, "show_sensors_active_states") &&
- RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, (((RNA_boolean_get(logic_ptr, "show_sensors_active_states") &&
+ RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")) &&
+ RNA_boolean_get(ptr, "active")));
uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")==0) {
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_UP, "direction", 1); // up
uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_DOWN, "direction", 2); // down
}
- uiItemO(row, "", ICON_X, "LOGIC_OT_sensor_remove");
+ sub = uiLayoutRow(row, false);
+ uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
+
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemO(sub, "", ICON_X, "LOGIC_OT_sensor_remove");
}
static void draw_sensor_internal_header(uiLayout *layout, PointerRNA *ptr)
@@ -975,18 +977,19 @@ static void draw_sensor_internal_header(uiLayout *layout, PointerRNA *ptr)
uiLayout *box, *split, *sub, *row;
box = uiLayoutBox(layout);
- split = uiLayoutSplit(box, 0.45f, FALSE);
+ uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
+ split = uiLayoutSplit(box, 0.45f, false);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_pulse_true_level", 0, "", ICON_DOTSUP);
uiItemR(row, ptr, "use_pulse_false_level", 0, "", ICON_DOTSDOWN);
- sub = uiLayoutRow(row, FALSE);
+ sub = uiLayoutRow(row, false);
uiLayoutSetActive(sub, (RNA_boolean_get(ptr, "use_pulse_true_level") ||
RNA_boolean_get(ptr, "use_pulse_false_level")));
uiItemR(sub, ptr, "frequency", 0, IFACE_("Freq"), ICON_NONE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_level", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_tap", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
@@ -1027,7 +1030,7 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr))
uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
}
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "test_type", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "test_type") != SENS_ARM_STATE_CHANGED)
uiItemR(row, ptr, "value", 0, NULL, ICON_NONE);
@@ -1040,8 +1043,8 @@ static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr, bContext *C
RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
- split = uiLayoutSplit(layout, 0.3f, FALSE);
- row = uiLayoutRow(split, TRUE);
+ split = uiLayoutSplit(layout, 0.3f, false);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_material", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
@@ -1059,7 +1062,7 @@ static void draw_sensor_delay(uiLayout *layout, PointerRNA *ptr)
{
uiLayout *row;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "delay", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "duration", 0, NULL, ICON_NONE);
@@ -1077,30 +1080,30 @@ static void draw_sensor_joystick(uiLayout *layout, PointerRNA *ptr)
case SENS_JOY_BUTTON:
uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == FALSE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
uiItemR(col, ptr, "button_number", 0, NULL, ICON_NONE);
break;
case SENS_JOY_AXIS:
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "axis_number", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == FALSE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
uiItemR(col, ptr, "axis_direction", 0, NULL, ICON_NONE);
break;
case SENS_JOY_HAT:
uiItemR(layout, ptr, "hat_number", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == FALSE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
uiItemR(col, ptr, "hat_direction", 0, NULL, ICON_NONE);
break;
case SENS_JOY_AXIS_SINGLE:
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "single_axis_number", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
break;
@@ -1113,21 +1116,21 @@ static void draw_sensor_keyboard(uiLayout *layout, PointerRNA *ptr)
PointerRNA settings_ptr;
uiLayout *row, *col;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, CTX_IFACE_(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "Key:"), ICON_NONE);
- col = uiLayoutColumn(row, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == FALSE);
+ col = uiLayoutColumn(row, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == false);
uiItemR(col, ptr, "key", UI_ITEM_R_EVENT, "", ICON_NONE);
- col = uiLayoutColumn(row, FALSE);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "use_all_keys", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == FALSE);
- row = uiLayoutRow(col, FALSE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == false);
+ row = uiLayoutRow(col, false);
uiItemL(row, IFACE_("First Modifier:"), ICON_NONE);
uiItemR(row, ptr, "modifier_key_1", UI_ITEM_R_EVENT, "", ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemL(row, IFACE_("Second Modifier:"), ICON_NONE);
uiItemR(row, ptr, "modifier_key_2", UI_ITEM_R_EVENT, "", ICON_NONE);
@@ -1145,7 +1148,7 @@ static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr)
{
uiLayout *split;
- split = uiLayoutSplit(layout, 0.8f, FALSE);
+ split = uiLayoutSplit(layout, 0.8f, false);
uiItemR(split, ptr, "mouse_event", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "mouse_event") == BL_SENS_MOUSE_MOUSEOVER_ANY)
@@ -1158,7 +1161,7 @@ static void draw_sensor_near(uiLayout *layout, PointerRNA *ptr)
uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "reset_distance", 0, NULL, ICON_NONE);
}
@@ -1176,7 +1179,7 @@ static void draw_sensor_property(uiLayout *layout, PointerRNA *ptr)
switch (RNA_enum_get(ptr, "evaluation_type")) {
case SENS_PROP_INTERVAL:
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "value_min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "value_max", 0, NULL, ICON_NONE);
break;
@@ -1198,7 +1201,7 @@ static void draw_sensor_radar(uiLayout *layout, PointerRNA *ptr)
uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "axis", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "angle", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
}
@@ -1214,7 +1217,7 @@ static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C)
PointerRNA main_ptr;
RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
- split = uiLayoutSplit(layout, 0.3f, FALSE);
+ split = uiLayoutSplit(layout, 0.3f, false);
uiItemR(split, ptr, "ray_type", 0, "", ICON_NONE);
switch (RNA_enum_get(ptr, "ray_type")) {
case SENS_RAY_PROPERTY:
@@ -1225,9 +1228,9 @@ static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C)
break;
}
- split = uiLayoutSplit(layout, 0.3, FALSE);
+ split = uiLayoutSplit(layout, 0.3, false);
uiItemR(split, ptr, "axis", 0, "", ICON_NONE);
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "range", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "use_x_ray", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
}
@@ -1242,6 +1245,7 @@ static void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr, bContext *C)
draw_sensor_internal_header(layout, ptr);
box = uiLayoutBox(layout);
+ uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
switch (RNA_enum_get(ptr, "type")) {
@@ -1299,29 +1303,40 @@ static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, i
BLI_snprintf(state, sizeof(state), "%d", RNA_int_get(ptr, "states"));
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
+ row = uiLayoutRow(box, false);
- uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")) {
- uiItemR(row, ptr, "type", 0, "", ICON_NONE);
- uiItemR(row, ptr, "name", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
/* XXX provisory for Blender 2.50Beta */
uiDefBlockBut(uiLayoutGetBlock(layout), controller_state_mask_menu, cont, state, (short)(xco+width-44), yco, 22+22, UI_UNIT_Y, IFACE_("Set controller state index (from 1 to 30)"));
}
else {
- uiItemL(row, controller_name(cont->type), ICON_NONE);
- uiItemL(row, cont->name, ICON_NONE);
- uiItemL(row, state, ICON_NONE);
+ uiItemL(sub, IFACE_(controller_name(cont->type)), ICON_NONE);
+ uiItemL(sub, cont->name, ICON_NONE);
+ uiItemL(sub, state, ICON_NONE);
}
- uiItemR(row, ptr, "use_priority", 0, "", ICON_NONE);
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemR(sub, ptr, "use_priority", 0, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")==0) {
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_UP, "direction", 1); // up
uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_DOWN, "direction", 2); // down
}
- uiItemO(row, "", ICON_X, "LOGIC_OT_controller_remove");
+
+ sub = uiLayoutRow(row, false);
+ uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
+
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemO(sub, "", ICON_X, "LOGIC_OT_controller_remove");
}
static void draw_controller_expression(uiLayout *layout, PointerRNA *ptr)
@@ -1333,13 +1348,13 @@ static void draw_controller_python(uiLayout *layout, PointerRNA *ptr)
{
uiLayout *split, *sub;
- split = uiLayoutSplit(layout, 0.3, TRUE);
+ split = uiLayoutSplit(layout, 0.3, true);
uiItemR(split, ptr, "mode", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "mode") == CONT_PY_SCRIPT) {
uiItemR(split, ptr, "text", 0, "", ICON_NONE);
}
else {
- sub = uiLayoutSplit(split, 0.8f, FALSE);
+ sub = uiLayoutSplit(split, 0.8f, false);
uiItemR(sub, ptr, "module", 0, "", ICON_NONE);
uiItemR(sub, ptr, "use_debug", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
}
@@ -1358,6 +1373,7 @@ static void draw_brick_controller(uiLayout *layout, PointerRNA *ptr)
return;
box = uiLayoutBox(layout);
+ uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
draw_controller_state(box, ptr);
@@ -1390,29 +1406,39 @@ static void draw_actuator_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *
bActuator *act= (bActuator *)ptr->data;
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, FALSE);
-
- uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
+ row = uiLayoutRow(box, false);
+
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")) {
- uiItemR(row, ptr, "type", 0, "", ICON_NONE);
- uiItemR(row, ptr, "name", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
+ uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
}
else {
- uiItemL(row, actuator_name(act->type), ICON_NONE);
- uiItemL(row, act->name, ICON_NONE);
+ uiItemL(sub, IFACE_(actuator_name(act->type)), ICON_NONE);
+ uiItemL(sub, act->name, ICON_NONE);
}
- sub = uiLayoutRow(row, FALSE);
- uiLayoutSetActive(sub, ((RNA_boolean_get(logic_ptr, "show_actuators_active_states") &&
- RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, (((RNA_boolean_get(logic_ptr, "show_actuators_active_states") &&
+ RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")) &&
+ RNA_boolean_get(ptr, "active")));
uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
if (RNA_boolean_get(ptr, "show_expanded")==0) {
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_UP, "direction", 1); // up
uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_DOWN, "direction", 2); // down
}
- uiItemO(row, "", ICON_X, "LOGIC_OT_actuator_remove");
+
+ sub = uiLayoutRow(row, false);
+ uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
+
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
+ uiItemO(sub, "", ICON_X, "LOGIC_OT_actuator_remove");
}
static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
@@ -1423,22 +1449,22 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "play_mode", 0, "", ICON_NONE);
- sub = uiLayoutRow(row, TRUE);
+ sub = uiLayoutRow(row, true);
uiItemR(sub, ptr, "use_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(sub, ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutColumn(sub, FALSE);
+ row = uiLayoutColumn(sub, false);
uiLayoutSetActive(row, (RNA_boolean_get(ptr, "use_additive") || RNA_boolean_get(ptr, "use_force")));
uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "action", 0, "", ICON_NONE);
uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
if ((RNA_enum_get(ptr, "play_mode") == ACT_ACTION_FROM_PROP))
uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
@@ -1449,11 +1475,11 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "layer", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "layer_weight", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "blend_mode", 0, "", ICON_NONE);
@@ -1542,11 +1568,11 @@ static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr)
uiLayout *row;
uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "height", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "axis", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "max", 0, NULL, ICON_NONE);
@@ -1565,7 +1591,7 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext
case ACT_CONST_TYPE_LOC:
uiItemR(layout, ptr, "limit", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "limit_min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "limit_max", 0, NULL, ICON_NONE);
@@ -1573,36 +1599,36 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext
break;
case ACT_CONST_TYPE_DIST:
- split = uiLayoutSplit(layout, 0.8, FALSE);
+ split = uiLayoutSplit(layout, 0.8, false);
uiItemR(split, ptr, "direction", 0, NULL, ICON_NONE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
- col = uiLayoutColumn(row, TRUE);
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, true);
uiItemL(col, IFACE_("Range:"), ICON_NONE);
uiItemR(col, ptr, "range", 0, "", ICON_NONE);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemR(col, ptr, "use_force_distance", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, FALSE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_force_distance") == TRUE);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_force_distance") == true);
uiItemR(sub, ptr, "distance", 0, "", ICON_NONE);
uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.15f, FALSE);
+ split = uiLayoutSplit(layout, 0.15f, false);
uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
if (RNA_boolean_get(ptr, "use_material_detect"))
uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
else
uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.15, FALSE);
+ split = uiLayoutSplit(layout, 0.15, false);
uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
break;
@@ -1610,43 +1636,43 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext
case ACT_CONST_TYPE_ORI:
uiItemR(layout, ptr, "direction_axis_pos", 0, NULL, ICON_NONE);
- row=uiLayoutRow(layout, TRUE);
+ row=uiLayoutRow(layout, true);
uiItemR(row, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
- row=uiLayoutRow(layout, FALSE);
+ row=uiLayoutRow(layout, false);
uiItemR(row, ptr, "rotation_max", 0, NULL, ICON_NONE);
- row=uiLayoutRow(layout, TRUE);
+ row=uiLayoutRow(layout, true);
uiItemR(row, ptr, "angle_min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "angle_max", 0, NULL, ICON_NONE);
break;
case ACT_CONST_TYPE_FH:
- split = uiLayoutSplit(layout, 0.75, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.75, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "fh_damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "fh_height", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_fh_paralel_axis", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "direction_axis", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(row, 0.9f, FALSE);
+ split = uiLayoutSplit(row, 0.9f, false);
uiItemR(split, ptr, "fh_force", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_fh_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.15, FALSE);
+ split = uiLayoutSplit(layout, 0.15, false);
uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
if (RNA_boolean_get(ptr, "use_material_detect"))
uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
else
uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.15, FALSE);
+ split = uiLayoutSplit(layout, 0.15, false);
uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
break;
@@ -1661,17 +1687,17 @@ static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
switch (RNA_enum_get(ptr, "mode")) {
case ACT_EDOB_ADD_OBJECT:
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
break;
@@ -1682,16 +1708,16 @@ static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
uiItemL(layout, IFACE_("Mode only available for mesh objects"), ICON_NONE);
break;
}
- split = uiLayoutSplit(layout, 0.6, FALSE);
+ split = uiLayoutSplit(layout, 0.6, false);
uiItemR(split, ptr, "mesh", 0, NULL, ICON_NONE);
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "use_replace_display_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_replace_physics_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
break;
case ACT_EDOB_TRACK_TO:
- split = uiLayoutSplit(layout, 0.5, FALSE);
+ split = uiLayoutSplit(layout, 0.5, false);
uiItemR(split, ptr, "track_object", 0, NULL, ICON_NONE);
- sub = uiLayoutSplit(split, 0.7f, FALSE);
+ sub = uiLayoutSplit(split, 0.7f, false);
uiItemR(sub, ptr, "time", 0, NULL, ICON_NONE);
uiItemR(sub, ptr, "use_3d_tracking", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
break;
@@ -1718,9 +1744,9 @@ static void draw_actuator_filter_2d(uiLayout *layout, PointerRNA *ptr)
uiItemR(layout, ptr, "glsl_shader", 0, NULL, ICON_NONE);
break;
case ACT_2DFILTER_MOTIONBLUR:
- split=uiLayoutSplit(layout, 0.75f, TRUE);
- row = uiLayoutRow(split, FALSE);
- uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_motion_blur") == TRUE);
+ split=uiLayoutSplit(layout, 0.75f, true);
+ row = uiLayoutRow(split, false);
+ uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_motion_blur") == true);
uiItemR(row, ptr, "motion_blur_factor", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_motion_blur", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
break;
@@ -1751,7 +1777,7 @@ static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr, bContext *C
uiItemPointerR(layout, ptr, "to_property", &main_ptr, "objects", NULL, ICON_OBJECT_DATA);
uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "body_type", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "body_type") == ACT_MESG_MESG)
@@ -1775,37 +1801,37 @@ static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
switch (RNA_enum_get(ptr, "mode")) {
case ACT_OBJECT_NORMAL:
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
if (ELEM3(physics_type, OB_BODY_TYPE_DYNAMIC, OB_BODY_TYPE_RIGID, OB_BODY_TYPE_SOFT)) {
uiItemL(layout, IFACE_("Dynamic Object Settings:"), ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "force", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "torque", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_torque", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_add_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
@@ -1815,30 +1841,30 @@ static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
case ACT_OBJECT_SERVO:
uiItemR(layout, ptr, "reference_object", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
- col = uiLayoutColumn(row, FALSE);
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "use_servo_limit_x", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_x") == TRUE);
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_x") == true);
uiItemR(sub, ptr, "force_max_x", 0, NULL, ICON_NONE);
uiItemR(sub, ptr, "force_min_x", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(row, FALSE);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "use_servo_limit_y", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_y") == TRUE);
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_y") == true);
uiItemR(sub, ptr, "force_max_y", 0, NULL, ICON_NONE);
uiItemR(sub, ptr, "force_min_y", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(row, FALSE);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "use_servo_limit_z", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_z") == TRUE);
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_z") == true);
uiItemR(sub, ptr, "force_max_z", 0, NULL, ICON_NONE);
uiItemR(sub, ptr, "force_min_z", 0, NULL, ICON_NONE);
@@ -1846,27 +1872,27 @@ static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
//Layout designers willing to help on that, please compare with 2.49 ui
// (since the old code is going to be deleted ... soon)
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "proportional_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "integral_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "derivate_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
break;
case ACT_OBJECT_CHARACTER:
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(row, ptr, "use_add_character_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.9, FALSE);
- row = uiLayoutRow(split, FALSE);
- split = uiLayoutSplit(row, 0.7, FALSE);
+ split = uiLayoutSplit(layout, 0.9, false);
+ row = uiLayoutRow(split, false);
+ split = uiLayoutSplit(row, 0.7, false);
uiItemL(split, "", ICON_NONE); /*Just use this for some spacing */
uiItemR(split, ptr, "use_character_jump", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
break;
@@ -1882,10 +1908,10 @@ static void draw_actuator_parent(uiLayout *layout, PointerRNA *ptr)
if (RNA_enum_get(ptr, "mode") == ACT_PARENT_SET) {
uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "use_compound", 0, NULL, ICON_NONE);
- sub = uiLayoutRow(row, FALSE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_compound") == TRUE);
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_compound") == true);
uiItemR(sub, ptr, "use_ghost", 0, NULL, ICON_NONE);
}
}
@@ -1915,15 +1941,15 @@ static void draw_actuator_property(uiLayout *layout, PointerRNA *ptr)
uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
break;
case ACT_PROP_COPY:
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
if (ob_from) {
RNA_pointer_create((ID *)ob_from, &RNA_GameObjectSettings, ob_from, &obj_settings_ptr);
uiItemPointerR(row, ptr, "object_property", &obj_settings_ptr, "properties", NULL, ICON_NONE);
}
else {
- sub = uiLayoutRow(row, FALSE);
- uiLayoutSetActive(sub, FALSE);
+ sub = uiLayoutRow(row, false);
+ uiLayoutSetActive(sub, false);
uiItemR(sub, ptr, "object_property", 0, NULL, ICON_NONE);
}
break;
@@ -1939,15 +1965,15 @@ static void draw_actuator_random(uiLayout *layout, PointerRNA *ptr)
ob = (Object *)ptr->id.data;
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "seed", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "distribution", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
switch (RNA_enum_get(ptr, "distribution")) {
case ACT_RANDOM_BOOL_CONST:
@@ -2024,12 +2050,12 @@ static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "mode", 0, "", ICON_NONE);
uiItemR(row, ptr, "action", 0, "", ICON_NONE);
uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
if ((RNA_enum_get(ptr, "mode") == ACT_ACTION_FROM_PROP))
uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
@@ -2038,11 +2064,11 @@ static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
}
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
@@ -2061,28 +2087,28 @@ static void draw_actuator_sound(uiLayout *layout, PointerRNA *ptr, bContext *C)
}
uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "volume", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "pitch", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_sound_3d", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_sound_3d") == TRUE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_sound_3d") == true);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "gain_3d_min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "gain_3d_max", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "distance_3d_reference", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "distance_3d_max", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "rolloff_factor_3d", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "cone_outer_gain_3d", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "cone_outer_angle_3d", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "cone_inner_angle_3d", 0, NULL, ICON_NONE);
}
@@ -2094,7 +2120,7 @@ static void draw_actuator_state(uiLayout *layout, PointerRNA *ptr)
PointerRNA settings_ptr;
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
- split = uiLayoutSplit(layout, 0.35, FALSE);
+ split = uiLayoutSplit(layout, 0.35, false);
uiItemR(split, ptr, "operation", 0, NULL, ICON_NONE);
uiTemplateLayers(split, ptr, "states", &settings_ptr, "used_states", 0);
@@ -2103,7 +2129,7 @@ static void draw_actuator_state(uiLayout *layout, PointerRNA *ptr)
static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr)
{
uiLayout *row;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "use_visible", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "use_occlusion", 0, NULL, ICON_NONE);
@@ -2119,37 +2145,37 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "navmesh", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "velocity", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "acceleration", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "turn_speed", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
- col = uiLayoutColumn(row, FALSE);
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "facing", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(row, FALSE);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "facing_axis", 0, NULL, ICON_NONE);
if (!RNA_boolean_get(ptr, "facing")) {
- uiLayoutSetActive(col, FALSE);
+ uiLayoutSetActive(col, false);
}
- col = uiLayoutColumn(row, FALSE);
+ col = uiLayoutColumn(row, false);
uiItemR(col, ptr, "normal_up", 0, NULL, ICON_NONE);
if (!RNA_pointer_get(ptr, "navmesh").data) {
- uiLayoutSetActive(col, FALSE);
+ uiLayoutSetActive(col, false);
}
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "self_terminated", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING) {
uiItemR(row, ptr, "update_period", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
}
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "show_visualization", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "mode") != ACT_STEERING_PATHFOLLOWING) {
- uiLayoutSetActive(row, FALSE);
+ uiLayoutSetActive(row, false);
}
}
@@ -2161,6 +2187,7 @@ static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
return;
box = uiLayoutBox(layout);
+ uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
switch (RNA_enum_get(ptr, "type")) {
case ACT_ACTION:
@@ -2287,7 +2314,7 @@ void logic_buttons(bContext *C, ARegion *ar)
xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2312,10 +2339,10 @@ void logic_buttons(bContext *C, ARegion *ar)
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
- split = uiLayoutSplit(layout, 0.05f, FALSE);
+ split = uiLayoutSplit(layout, 0.05f, false);
uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
@@ -2325,21 +2352,21 @@ void logic_buttons(bContext *C, ARegion *ar)
if (RNA_boolean_get(&settings_ptr, "show_state_panel")) {
box = uiLayoutBox(layout);
- split = uiLayoutSplit(box, 0.2f, FALSE);
+ split = uiLayoutSplit(box, 0.2f, false);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiItemL(col, IFACE_("Visible"), ICON_NONE);
uiItemL(col, IFACE_("Initial"), ICON_NONE);
- subsplit = uiLayoutSplit(split, 0.85f, FALSE);
- col = uiLayoutColumn(subsplit, FALSE);
- row = uiLayoutRow(col, FALSE);
- uiLayoutSetActive(row, RNA_boolean_get(&settings_ptr, "use_all_states") == FALSE);
+ subsplit = uiLayoutSplit(split, 0.85f, false);
+ col = uiLayoutColumn(subsplit, false);
+ row = uiLayoutRow(col, false);
+ uiLayoutSetActive(row, RNA_boolean_get(&settings_ptr, "use_all_states") == false);
uiTemplateGameStates(row, &settings_ptr, "states_visible", &settings_ptr, "used_states", 0);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiTemplateGameStates(row, &settings_ptr, "states_initial", &settings_ptr, "used_states", 0);
- col = uiLayoutColumn(subsplit, FALSE);
+ col = uiLayoutColumn(subsplit, false);
uiItemR(col, &settings_ptr, "use_all_states", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
uiItemR(col, &settings_ptr, "show_debug_state", 0, "", ICON_NONE);
}
@@ -2358,18 +2385,22 @@ void logic_buttons(bContext *C, ARegion *ar)
continue;
/* use two nested splits to align inlinks/links properly */
- split = uiLayoutSplit(layout, 0.05f, FALSE);
+ split = uiLayoutSplit(layout, 0.05f, false);
/* put inlink button to the left */
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
+ uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
- uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
+ but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
+ if (!RNA_boolean_get(&ptr, "active")) {
+ uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ }
- //col = uiLayoutColumn(split, TRUE);
+ //col = uiLayoutColumn(split, true);
/* nested split for middle and right columns */
- subsplit = uiLayoutSplit(split, 0.95f, FALSE);
+ subsplit = uiLayoutSplit(split, 0.95f, false);
- col = uiLayoutColumn(subsplit, TRUE);
+ col = uiLayoutColumn(subsplit, true);
uiLayoutSetContextPointer(col, "controller", &ptr);
/* should make UI template for controller header.. function will do for now */
@@ -2379,12 +2410,17 @@ void logic_buttons(bContext *C, ARegion *ar)
/* draw the brick contents */
draw_brick_controller(col, &ptr);
-
/* put link button to the right */
- col = uiLayoutColumn(subsplit, FALSE);
+ col = uiLayoutColumn(subsplit, false);
+ uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ if (!RNA_boolean_get(&ptr, "active")) {
+ uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ }
+
uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
+
}
}
uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
@@ -2394,7 +2430,7 @@ void logic_buttons(bContext *C, ARegion *ar)
xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2412,7 +2448,7 @@ void logic_buttons(bContext *C, ARegion *ar)
/* only draw the sensor common header if "use_visible" */
if ((ob->scavisflag & OB_VIS_SENS) == 0) continue;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
@@ -2434,12 +2470,12 @@ void logic_buttons(bContext *C, ARegion *ar)
)
{ // gotta check if the current state is visible or not
uiLayout *split, *col;
-
+
/* make as visible, for move operator */
sens->flag |= SENS_VISIBLE;
- split = uiLayoutSplit(layout, 0.95f, FALSE);
- col = uiLayoutColumn(split, TRUE);
+ split = uiLayoutSplit(layout, 0.95f, false);
+ col = uiLayoutColumn(split, true);
uiLayoutSetContextPointer(col, "sensor", &ptr);
/* should make UI template for sensor header.. function will do for now */
@@ -2449,10 +2485,15 @@ void logic_buttons(bContext *C, ARegion *ar)
draw_brick_sensor(col, &ptr, C);
/* put link button to the right */
- col = uiLayoutColumn(split, FALSE);
- /* use old-school uiButtons for links for now */
+ col = uiLayoutColumn(split, false);
+ uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
+ if (!RNA_boolean_get(&ptr, "active")) {
+ uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ }
+
+ /* use old-school uiButtons for links for now */
+ uiSetButLink(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
}
}
}
@@ -2463,7 +2504,7 @@ void logic_buttons(bContext *C, ARegion *ar)
xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2483,7 +2524,7 @@ void logic_buttons(bContext *C, ARegion *ar)
continue;
}
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
@@ -2510,13 +2551,17 @@ void logic_buttons(bContext *C, ARegion *ar)
/* make as visible, for move operator */
act->flag |= ACT_VISIBLE;
- split = uiLayoutSplit(layout, 0.05f, FALSE);
+ split = uiLayoutSplit(layout, 0.05f, false);
/* put inlink button to the left */
- col = uiLayoutColumn(split, FALSE);
- uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
+ col = uiLayoutColumn(split, false);
+ uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
+ but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
+ if (!RNA_boolean_get(&ptr, "active")) {
+ uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ }
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiLayoutSetContextPointer(col, "actuator", &ptr);
/* should make UI template for actuator header.. function will do for now */
diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c
index 82e2e819dee..25d14774c97 100644
--- a/source/blender/editors/space_logic/space_logic.c
+++ b/source/blender/editors/space_logic/space_logic.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -183,7 +182,7 @@ static void logic_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "LOGIC_MT_logicbricks_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "LOGIC_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
-
+ WM_keymap_add_item(keymap, "LOGIC_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
}
static void logic_refresh(const bContext *UNUSED(C), ScrArea *UNUSED(sa))
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index ce7d537a518..808bd622c0d 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -40,7 +40,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLF_translation.h"
@@ -81,19 +80,19 @@ static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int UNUSED(eve
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM, NULL);
}
-static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
+bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
{
bAnimContext ac;
bAnimListElem *ale = NULL;
ListBase anim_data = {NULL, NULL};
- short found = 0;
+ short found = 0; /* not bool, since we need to indicate "found but not ideal" status */
int filter;
/* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
* to work correctly is able to be correctly retrieved. There's no point showing empty panels?
*/
if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
+ return false;
/* extract list of active channel(s), of which we should only take the first one
* - we need the channels flag to get the active AnimData block when there are no NLA Tracks
@@ -177,7 +176,7 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
/* free temp data */
BLI_freelistN(&anim_data);
- return found;
+ return (found != 0);
}
#if 0
@@ -269,7 +268,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
RNA_id_pointer_create(id, &id_ptr);
/* ID-block name > AnimData */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
uiItemL(row, id->name + 2, RNA_struct_ui_icon(id_ptr.type)); /* id-block (src) */
@@ -281,19 +280,19 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
/* Active Action Properties ------------------------------------- */
/* action */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, NULL /*"ACTION_OT_unlink"*/); // XXX: need to make these operators
/* extrapolation */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_extrapolation", 0, NULL, ICON_NONE);
/* blending */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_blend_type", 0, NULL, ICON_NONE);
/* influence */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_influence", 0, NULL, ICON_NONE);
}
@@ -313,7 +312,7 @@ static void nla_panel_track(const bContext *C, Panel *pa)
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
/* Info - Active NLA-Context:Track ---------------------- */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &nlt_ptr, "name", 0, NULL, ICON_NLA);
}
@@ -334,12 +333,12 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
/* Strip Properties ------------------------------------- */
/* strip type */
- row = uiLayoutColumn(layout, TRUE);
+ row = uiLayoutColumn(layout, true);
uiItemR(row, &strip_ptr, "name", 0, NULL, ICON_NLA); // XXX icon?
uiItemR(row, &strip_ptr, "type", 0, NULL, ICON_NONE);
/* strip extents */
- column = uiLayoutColumn(layout, TRUE);
+ column = uiLayoutColumn(layout, true);
uiItemL(column, IFACE_("Strip Extents:"), ICON_NONE);
uiItemR(column, &strip_ptr, "frame_start", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "frame_end", 0, NULL, ICON_NONE);
@@ -353,27 +352,27 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
/* only show if allowed to... */
if (showEvalProps) {
/* extrapolation */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "extrapolation", 0, NULL, ICON_NONE);
/* blending */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "blend_type", 0, NULL, ICON_NONE);
/* blend in/out + autoblending
* - blend in/out can only be set when autoblending is off
*/
- column = uiLayoutColumn(layout, TRUE);
- uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_influence") == FALSE);
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_influence") == false);
uiItemR(column, &strip_ptr, "use_auto_blend", 0, NULL, ICON_NONE); // XXX as toggle?
- sub = uiLayoutColumn(column, TRUE);
- uiLayoutSetActive(sub, RNA_boolean_get(&strip_ptr, "use_auto_blend") == FALSE);
+ sub = uiLayoutColumn(column, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&strip_ptr, "use_auto_blend") == false);
uiItemR(sub, &strip_ptr, "blend_in", 0, NULL, ICON_NONE);
uiItemR(sub, &strip_ptr, "blend_out", 0, NULL, ICON_NONE);
/* settings */
- column = uiLayoutColumn(layout, TRUE);
+ column = uiLayoutColumn(layout, true);
uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "use_animated_influence") || RNA_boolean_get(&strip_ptr, "use_animated_time")));
uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE);
uiItemR(column, &strip_ptr, "mute", 0, NULL, ICON_NONE);
@@ -399,24 +398,24 @@ static void nla_panel_actclip(const bContext *C, Panel *pa)
/* Strip Properties ------------------------------------- */
/* action pointer */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "action", 0, NULL, ICON_ACTION);
/* action extents */
// XXX custom names were used here (to avoid the prefixes)... probably not necessary in future?
- column = uiLayoutColumn(layout, TRUE);
+ column = uiLayoutColumn(layout, true);
uiItemL(column, IFACE_("Action Extents:"), ICON_NONE);
uiItemR(column, &strip_ptr, "action_frame_start", 0, IFACE_("Start Frame"), ICON_NONE);
uiItemR(column, &strip_ptr, "action_frame_end", 0, IFACE_("End Frame"), ICON_NONE);
// XXX: this layout may actually be too abstract and confusing, and may be better using standard column layout
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, &strip_ptr, "use_sync_length", 0, IFACE_("Sync Length"), ICON_NONE);
uiItemO(row, IFACE_("Now"), ICON_FILE_REFRESH, "NLA_OT_action_sync_length");
/* action usage */
- column = uiLayoutColumn(layout, TRUE);
- uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time") == FALSE);
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time") == false);
uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE);
uiItemR(column, &strip_ptr, "scale", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "repeat", 0, NULL, ICON_NONE);
@@ -437,19 +436,19 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa)
block = uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_influence"));
uiItemR(sub, &strip_ptr, "influence", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
- sub = uiLayoutRow(col, FALSE);
+ col = uiLayoutColumn(layout, true);
+ sub = uiLayoutRow(col, false);
uiItemR(sub, &strip_ptr, "use_animated_time", 0, NULL, ICON_NONE);
uiItemR(sub, &strip_ptr, "use_animated_time_cyclic", 0, NULL, ICON_NONE);
- sub = uiLayoutRow(col, FALSE);
+ sub = uiLayoutRow(col, false);
uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_time"));
uiItemR(sub, &strip_ptr, "strip_time", 0, NULL, ICON_NONE);
}
@@ -473,7 +472,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
/* 'add modifier' button at top of panel */
{
- row = uiLayoutRow(pa->layout, FALSE);
+ row = uiLayoutRow(pa->layout, false);
block = uiLayoutGetBlock(row);
// XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
@@ -482,14 +481,14 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
TIP_("Adds a new F-Modifier for the active NLA Strip"));
/* copy/paste (as sub-row)*/
- row = uiLayoutRow(row, TRUE);
+ row = uiLayoutRow(row, true);
uiItemO(row, "", ICON_COPYDOWN, "NLA_OT_fmodifier_copy");
uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste");
}
/* draw each modifier */
for (fcm = strip->modifiers.first; fcm; fcm = fcm->next) {
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.id.data, &strip->modifiers, fcm);
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 1f2fe6b1ecf..16572f1790b 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -39,7 +39,6 @@
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_animsys.h"
@@ -399,6 +398,106 @@ void NLA_OT_channels_click(wmOperatorType *ot)
/* *********************************************** */
/* Special Operators */
+/* ******************** Action Push Down ******************************** */
+
+static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ AnimData *adt = NULL;
+ int channel_index = RNA_int_get(op->ptr, "channel_index");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get anim-channel to use (or more specifically, the animdata block behind it) */
+ if (channel_index == -1) {
+ PointerRNA adt_ptr = {{NULL}};
+
+ /* active animdata block */
+ if (nla_panel_context(C, &adt_ptr, NULL, NULL) == 0 || (adt_ptr.data == NULL)) {
+ BKE_report(op->reports, RPT_ERROR, "No active AnimData block to use. "
+ "Select a datablock expander first or set the appropriate flags on an AnimData block");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ adt = adt_ptr.data;
+ }
+ }
+ else {
+ /* indexed channel */
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "No animation channel found at index = %d", channel_index);
+ BLI_freelistN(&anim_data);
+ return OPERATOR_CANCELLED;
+ }
+ else if (ale->type != ANIMTYPE_NLAACTION) {
+ BKE_reportf(op->reports, RPT_ERROR, "Animation channel at index = %d is not a NLA 'Active Action' channel", channel_index);
+ BLI_freelistN(&anim_data);
+ return OPERATOR_CANCELLED;
+ }
+
+ /* grab AnimData from the channel */
+ adt = ale->adt;
+
+ /* we don't need anything here anymore, so free it all */
+ BLI_freelistN(&anim_data);
+ }
+
+ /* double-check that we are free to push down here... */
+ if (adt == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
+ return OPERATOR_CANCELLED;
+ }
+ else if (nlaedit_is_tweakmode_on(&ac)) {
+ BKE_report(op->reports, RPT_WARNING, "Cannot push down actions while tweaking a strip's action. Exit tweakmode first");
+ return OPERATOR_CANCELLED;
+ }
+ else if (adt->action == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "No active action to push down");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* 'push-down' action - only usable when not in TweakMode */
+ BKE_nla_action_pushdown(adt);
+ }
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_action_pushdown(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Push Down Action";
+ ot->idname = "NLA_OT_action_pushdown";
+ ot->description = "Push action down onto the top of the NLA stack as a new strip";
+
+ /* callbacks */
+ ot->exec = nlachannels_pushdown_exec;
+ ot->poll = nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_int(ot->srna, "channel_index", -1, -1, INT_MAX, "Channel Index",
+ "Index of NLA action channel to perform pushdown operation on",
+ 0, INT_MAX);
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+}
+
/* ******************** Add Tracks Operator ***************************** */
/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 720d532f1ab..6998e715548 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -42,7 +42,6 @@
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_dlrbTree.h"
#include "BLI_utildefines.h"
@@ -80,7 +79,7 @@
/* get colors for drawing Action-Line
* NOTE: color returned includes fine-tuned alpha!
*/
-static void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
+void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
{
if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
/* greenish color (same as tweaking strip) */
@@ -136,7 +135,7 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, View2D *v2d,
/* get View2D scaling factor */
- UI_view2d_getscale(v2d, &xscale, NULL);
+ UI_view2d_scale_get(v2d, &xscale, NULL);
/* for now, color is hardcoded to be black */
gpuColor3P(CPACK_BLACK);
@@ -447,16 +446,17 @@ static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, i
{
short notSolo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) && (nlt->flag & NLATRACK_SOLO) == 0);
char str[256];
+ size_t str_len;
char col[4];
float xofs;
rctf rect;
/* just print the name and the range */
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
- BLI_snprintf(str, sizeof(str), "%d) Temp-Meta", index);
+ str_len = BLI_snprintf(str, sizeof(str), "%d) Temp-Meta", index);
}
else {
- BLI_strncpy(str, strip->name, sizeof(str));
+ str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
}
/* set text color - if colors (see above) are light, draw black text, otherwise draw white */
@@ -489,7 +489,7 @@ static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, i
rect.ymax = ymaxc;
/* add this string to the cache of texts to draw */
- UI_view2d_text_cache_rectf(v2d, &rect, str, col);
+ UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
/* add frame extents to cache of text-strings to draw in pixelspace
@@ -499,7 +499,8 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
{
const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
const char col[4] = {220, 220, 220, 255}; /* light gray */
- char numstr[32] = "";
+ char numstr[32];
+ size_t numstr_len;
/* Always draw times above the strip, whereas sequencer drew below + above.
@@ -509,12 +510,12 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
* while also preserving some accuracy, since we do use floats
*/
/* start frame */
- BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start);
- UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, col);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start);
+ UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
/* end frame */
- BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end);
- UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, col);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end);
+ UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col);
}
/* ---------------------- */
@@ -644,202 +645,6 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* *********************************************** */
/* Channel List */
-/* old code for drawing NLA channels using GL only */
-// TODO: depreceate this code...
-static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View2D *v2d, float y)
-{
- SpaceNla *snla = (SpaceNla *)ac->sl;
- bAnimListElem *ale;
- float x = 0.0f;
-
- /* loop through channels, and set up drawing depending on their type */
- for (ale = anim_data->first; ale; ale = ale->next) {
- const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
- const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
- const float ydatac = (float)(y - 0.35f * U.widget_unit);
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- AnimData *adt = ale->adt;
-
- short indent = 0, offset = 0, sel = 0, group = 0;
- int special = -1;
- char name[128];
- bool do_draw = false;
-
- /* determine what needs to be drawn */
- switch (ale->type) {
- case ANIMTYPE_NLAACTION: /* NLA Action-Line */
- {
- bAction *act = (bAction *)ale->data;
-
- group = 5;
-
- special = ICON_ACTION;
-
- BLI_strncpy(name, act ? act->id.name + 2 : "<No Action>", sizeof(name));
-
- /* draw manually still */
- do_draw = TRUE;
- break;
- }
- default: /* handled by standard channel-drawing API */
- /* (draw backdrops only...) */
- ANIM_channel_draw(ac, ale, yminc, ymaxc);
- break;
- }
-
- /* if special types, draw manually for now... */
- if (do_draw) {
- if (ale->id) {
- /* special exception for textures */
- if (GS(ale->id->name) == ID_TE) {
- offset = 0.7f * U.widget_unit;
- indent = 1;
- }
- /* special exception for nodetrees */
- else if (GS(ale->id->name) == ID_NT) {
- bNodeTree *ntree = (bNodeTree *)ale->id;
-
- switch (ntree->type) {
- case NTREE_SHADER:
- {
- /* same as for textures */
- offset = 0.7f * U.widget_unit;
- indent = 1;
- break;
- }
- case NTREE_TEXTURE:
- {
- /* even more */
- offset = U.widget_unit;
- indent = 1;
- break;
- }
- default:
- /* normal will do */
- offset = 0.7f * U.widget_unit;
- break;
- }
- }
- else {
- offset = 0.7f * U.widget_unit;
- }
- }
- else {
- offset = 0;
- }
-
- /* now, start drawing based on this information */
- glEnable(GL_BLEND);
-
- /* draw backing strip behind channel name */
- if (group == 5) {
- float color[4];
-
- /* Action Line
- * The alpha values action_get_color returns are only useful for drawing
- * strips backgrounds but here we're doing channel list backgrounds instead
- * so we ignore that and use our own when needed
- */
- nla_action_get_color(adt, (bAction *)ale->data, color);
-
- if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
- /* Yes, the color vector has 4 components, BUT we only want to be using 3 of them! */
- gpuColor3fv(color);
- }
- else {
- float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
- gpuColor4f(color[0], color[1], color[2], alpha);
- }
-
- offset += 0.35f * U.widget_unit * indent;
-
- /* only on top two corners, to show that this channel sits on top of the preceding ones */
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
-
- /* draw slightly shifted up vertically to look like it has more separation from other channels,
- * but we then need to slightly shorten it so that it doesn't look like it overlaps
- */
- uiDrawBox(GL_TRIANGLE_FAN, x + offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8);
-
- /* clear group value, otherwise we cause errors... */
- group = 0;
- }
-
-
- /* draw special icon indicating certain data-types */
- if (special > -1) {
- /* for normal channels */
- UI_icon_draw(x + offset, ydatac, special);
- offset += 0.85f * U.widget_unit;
- }
- glDisable(GL_BLEND);
-
- /* draw name */
- if (sel)
- UI_ThemeColor(TH_TEXT_HI);
- else
- UI_ThemeColor(TH_TEXT);
- offset += 3;
- UI_DrawString(x + offset, y - 4, name);
-
- /* reset offset - for RHS of panel */
- offset = 0;
-
- glEnable(GL_BLEND);
-
-
- /* draw NLA-action line 'status-icons' - only when there's an action */
- if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
- offset += 0.8f * U.widget_unit;
-
- /* now draw some indicator icons */
- if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
- /* toggle for tweaking with mapping/no-mapping (i.e. 'in place editing' toggle) */
- // for now, use pin icon to symbolise this
- if (adt->flag & ADT_NLA_EDIT_NOMAP)
- UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_PINNED);
- else
- UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_UNPINNED);
-
- // DOODLE: single line
- gpuSingleLinef(
- (float)(v2d->cur.xmax - offset), yminc,
- (float)(v2d->cur.xmax - offset), ymaxc);
-
- offset += 0.8f * U.widget_unit;
-
- /* 'tweaking action' indicator - not a button */
- UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_EDIT);
- }
- else {
- /* XXX firstly draw a little rect to help identify that it's different from the toggles */
- gpuImmediateFormat_V2(); // DOODLE: a line box
- gpuBegin(GL_LINE_LOOP);
- gpuVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit);
- gpuVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45f * U.widget_unit);
- gpuVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit);
- gpuVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit);
- gpuEnd();
- gpuImmediateUnformat();
-
- /* 'push down' icon for normal active-actions */
- UI_icon_draw((float)v2d->cur.xmax - offset, ydatac, ICON_FREEZE);
- }
- }
-
- glDisable(GL_BLEND);
- }
- }
-
- /* adjust y-position for next one */
- y -= NLACHANNEL_STEP(snla);
- }
-}
-
void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
@@ -871,10 +676,24 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY);
/* draw channels */
- { /* first pass: backdrops + oldstyle drawing */
+ { /* first pass: just the standard GL-drawing for backdrop + text */
y = (float)(-NLACHANNEL_HEIGHT(snla));
- draw_nla_channel_list_gl(ac, &anim_data, v2d, y);
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
+ float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
+ {
+ /* draw all channels using standard channel-drawing API */
+ ANIM_channel_draw(ac, ale, yminc, ymaxc);
+ }
+
+ /* adjust y-position for next one */
+ y -= NLACHANNEL_STEP(snla);
+ }
}
{ /* second pass: UI widgets */
uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
@@ -908,7 +727,7 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
glDisable(GL_BLEND);
}
- /* free tempolary channels */
+ /* free temporary channels */
BLI_freelistN(&anim_data);
}
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index f54ceeeb702..93d0f7527ef 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -49,6 +49,7 @@
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_context.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_screen.h"
@@ -110,7 +111,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
- int ok = 0;
+ bool ok = false;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -131,7 +132,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
AnimData *adt = ale->data;
/* try entering tweakmode if valid */
- ok += BKE_nla_tweakmode_enter(adt);
+ ok |= BKE_nla_tweakmode_enter(adt);
}
/* free temp data */
@@ -161,7 +162,7 @@ void NLA_OT_tweakmode_enter(wmOperatorType *ot)
/* identifiers */
ot->name = "Enter Tweak Mode";
ot->idname = "NLA_OT_tweakmode_enter";
- ot->description = "Enter tweaking mode for the action referenced by the active strip";
+ ot->description = "Enter tweaking mode for the action referenced by the active strip to edit its keyframes";
/* api callbacks */
ot->exec = nlaedit_enable_tweakmode_exec;
@@ -257,11 +258,12 @@ void NLA_OT_tweakmode_exit(wmOperatorType *ot)
/* *************************** Calculate Range ************************** */
/* Get the min/max strip extents */
-static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
+static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const bool only_sel)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
+ bool found_bounds = false;
/* get data to filter */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
@@ -280,10 +282,12 @@ static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* only consider selected strips? */
- if ((onlySel == 0) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
+ if ((only_sel == false) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
/* extend range if appropriate */
*min = min_ff(*min, strip->start);
*max = max_ff(*max, strip->end);
+
+ found_bounds = true;
}
}
}
@@ -291,8 +295,9 @@ static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const
/* free memory */
BLI_freelistN(&anim_data);
}
- else {
- /* set default range */
+
+ /* set default range if nothing happened */
+ if (found_bounds == false) {
if (ac->scene) {
*min = (float)ac->scene->r.sfra;
*max = (float)ac->scene->r.efra;
@@ -304,9 +309,109 @@ static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const
}
}
+/* ****************** Automatic Preview-Range Operator ****************** */
+
+static int nlaedit_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+ Scene *scene;
+ float min, max;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ if (ac.scene == NULL)
+ return OPERATOR_CANCELLED;
+ else
+ scene = ac.scene;
+
+ /* set the range directly */
+ get_nlastrip_extents(&ac, &min, &max, true);
+ scene->r.flag |= SCER_PRV_RANGE;
+ scene->r.psfra = iroundf(min);
+ scene->r.pefra = iroundf(max);
+
+ /* set notifier that things have changed */
+ // XXX err... there's nothing for frame ranges yet, but this should do fine too
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_previewrange_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Auto-Set Preview Range";
+ ot->idname = "NLA_OT_previewrange_set";
+ ot->description = "Automatically set Preview Range based on range of keyframes";
+
+ /* api callbacks */
+ ot->exec = nlaedit_previewrange_exec;
+ ot->poll = ED_operator_nla_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ****************** View-All Operator ****************** */
-static int nlaedit_viewall(bContext *C, const short onlySel)
+/* Find the extents of the active channel
+ * > min: (float) bottom y-extent of channel
+ * > max: (float) top y-extent of channel
+ * > returns: success of finding a selected channel
+ */
+static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, float *max)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceNla *snla = (SpaceNla *)ac->sl;
+ const float half_height = NLACHANNEL_HEIGHT_HALF(snla);
+ short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ float y;
+
+ /* get all items - we need to do it this way */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through all channels, finding the first one that's selected */
+ y = (float)NLACHANNEL_FIRST;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* must be selected... */
+ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
+ ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
+ {
+ /* update best estimate */
+ *min = (float)(y - half_height);
+ *max = (float)(y + half_height);
+
+ /* is this high enough priority yet? */
+ found = acf->channel_role;
+
+ /* only stop our search when we've found an actual channel
+ * - datablock expanders get less priority so that we don't abort prematurely
+ */
+ if (found == ACHANNEL_ROLE_CHANNEL) {
+ break;
+ }
+ }
+
+ /* adjust y-position for next one */
+ y -= NLACHANNEL_STEP(snla);
+ }
+
+ /* free all temp data */
+ BLI_freelistN(&anim_data);
+
+ return (found != 0);
+}
+
+static int nlaedit_viewall(bContext *C, const bool only_sel)
{
bAnimContext ac;
View2D *v2d;
@@ -318,15 +423,32 @@ static int nlaedit_viewall(bContext *C, const short onlySel)
v2d = &ac.ar->v2d;
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
- get_nlastrip_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, onlySel);
+ get_nlastrip_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel);
extra = 0.1f * BLI_rctf_size_x(&v2d->cur);
v2d->cur.xmin -= extra;
v2d->cur.xmax += extra;
/* set vertical range */
- v2d->cur.ymax = 0.0f;
- v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
+ if (only_sel == false) {
+ /* view all -> the summary channel is usually the shows everything, and resides right at the top... */
+ v2d->cur.ymax = 0.0f;
+ v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
+ }
+ else {
+ /* locate first selected channel (or the active one), and frame those */
+ float ymin = v2d->cur.ymin;
+ float ymax = v2d->cur.ymax;
+
+ if (nla_channels_get_selected_extents(&ac, &ymin, &ymax)) {
+ /* recenter the view so that this range is in the middle */
+ float ymid = (ymax - ymin) / 2.0f + ymin;
+ float x_center;
+
+ UI_view2d_center_get(v2d, &x_center, NULL);
+ UI_view2d_center_set(v2d, x_center, ymid);
+ }
+ }
/* do View2D syncing */
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
@@ -342,13 +464,13 @@ static int nlaedit_viewall(bContext *C, const short onlySel)
static int nlaedit_viewall_exec(bContext *C, wmOperator *UNUSED(op))
{
/* whole range */
- return nlaedit_viewall(C, FALSE);
+ return nlaedit_viewall(C, false);
}
static int nlaedit_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
{
/* only selected */
- return nlaedit_viewall(C, TRUE);
+ return nlaedit_viewall(C, true);
}
void NLA_OT_view_all(wmOperatorType *ot)
@@ -513,6 +635,7 @@ void NLA_OT_actionclip_add(wmOperatorType *ot)
// TODO: this would be nicer as an ID-pointer...
prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
RNA_def_enum_funcs(prop, RNA_action_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -527,7 +650,7 @@ static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
- int done = FALSE;
+ bool done = false;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -595,7 +718,7 @@ static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
BKE_nlastrip_validate_name(adt, strip);
/* make note of this */
- done++;
+ done = true;
}
}
@@ -838,7 +961,7 @@ void NLA_OT_meta_remove(wmOperatorType *ot)
* the originals were housed in.
*/
-static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
+static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
@@ -846,7 +969,8 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
bAnimListElem *ale;
int filter;
- short done = FALSE;
+ bool linked = RNA_boolean_get(op->ptr, "linked");
+ bool done = false;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -871,7 +995,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
/* if selected, split the strip at its midpoint */
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* make a copy (assume that this is possible) */
- nstrip = copy_nlastrip(strip);
+ nstrip = copy_nlastrip(strip, linked);
/* in case there's no space in the track above, or we haven't got a reference to it yet, try adding */
if (BKE_nlatrack_add_strip(nlt->next, nstrip) == 0) {
@@ -889,7 +1013,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
/* auto-name newly created strip */
BKE_nlastrip_validate_name(adt, nstrip);
- done++;
+ done = true;
}
}
}
@@ -936,6 +1060,9 @@ void NLA_OT_duplicate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* own properties */
+ ot->prop = RNA_def_boolean(ot->srna, "linked", false, "Linked", "When duplicating strips, assign new copies of the actions they use");
+
/* to give to transform */
RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
@@ -1053,7 +1180,7 @@ static void nlaedit_split_strip_actclip(AnimData *adt, NlaTrack *nlt, NlaStrip *
/* make a copy (assume that this is possible) and append
* it immediately after the current strip
*/
- nstrip = copy_nlastrip(strip);
+ nstrip = copy_nlastrip(strip, true);
BLI_insertlinkafter(&nlt->strips, strip, nstrip);
/* set the endpoint of the first strip and the start of the new strip
@@ -1656,6 +1783,80 @@ void NLA_OT_action_sync_length(wmOperatorType *ot)
ot->prop = RNA_def_boolean(ot->srna, "active", 1, "Active Strip Only", "Only sync the active length for the active strip");
}
+/* ******************** Make Single User ********************************* */
+/* Ensure that each strip has its own action */
+
+static int nlaedit_make_single_user_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get a list of the editable tracks being shown in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* Ensure that each action used only has a single user
+ * - This is done in reverse order so that the original strips are
+ * likely to still get to keep their action
+ */
+ for (ale = anim_data.last; ale; ale = ale->prev) {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+ NlaStrip *strip;
+
+ for (strip = nlt->strips.last; strip; strip = strip->prev) {
+ /* must be action-clip only (as only these have actions) */
+ if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) {
+ if (strip->act == NULL)
+ continue;
+
+ /* multi-user? */
+ if (ID_REAL_USERS(strip->act) > 1) {
+ /* make a new copy of the action for us to use (it will have 1 user already) */
+ bAction *new_action = BKE_action_copy(strip->act);
+
+ /* decrement user count of our existing action */
+ id_us_min(&strip->act->id);
+
+ /* switch to the new copy */
+ strip->act = new_action;
+ }
+ }
+ }
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_make_single_user(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Make Single User";
+ ot->idname = "NLA_OT_make_single_user";
+ ot->description = "Ensure that each action is only used once in the set of strips selected";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = nlaedit_make_single_user_exec;
+ ot->poll = nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ******************** Apply Scale Operator ***************************** */
/* Reset the scaling of the selected strips to 1.0f */
@@ -2087,7 +2288,8 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
bAnimContext ac;
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
- int filter, ok = 0;
+ int filter;
+ bool ok = false;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -2111,7 +2313,7 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
continue;
// TODO: when 'active' vs 'all' boolean is added, change last param!
- ok += ANIM_fmodifiers_copy_to_buf(&strip->modifiers, 0);
+ ok |= ANIM_fmodifiers_copy_to_buf(&strip->modifiers, 0);
}
}
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index dedd6404a2c..766ae28da6f 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -41,6 +41,8 @@
ARegion *nla_has_buttons_region(ScrArea *sa);
+bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr);
+
void nla_buttons_register(ARegionType *art);
void NLA_OT_properties(wmOperatorType *ot);
@@ -88,6 +90,8 @@ void NLA_OT_tweakmode_exit(wmOperatorType *ot);
/* --- */
+void NLA_OT_previewrange_set(wmOperatorType *ot);
+
void NLA_OT_view_all(wmOperatorType *ot);
void NLA_OT_view_selected(wmOperatorType *ot);
@@ -110,6 +114,8 @@ void NLA_OT_move_down(wmOperatorType *ot);
void NLA_OT_action_sync_length(wmOperatorType *ot);
+void NLA_OT_make_single_user(wmOperatorType *ot);
+
void NLA_OT_apply_scale(wmOperatorType *ot);
void NLA_OT_clear_scale(wmOperatorType *ot);
@@ -130,6 +136,8 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac);
void NLA_OT_channels_click(wmOperatorType *ot);
+void NLA_OT_action_pushdown(wmOperatorType *ot);
+
void NLA_OT_tracks_add(wmOperatorType *ot);
void NLA_OT_tracks_delete(wmOperatorType *ot);
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 149690e10f7..295a7ab2e04 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -36,7 +36,6 @@
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -118,6 +117,8 @@ void nla_operatortypes(void)
/* channels */
WM_operatortype_append(NLA_OT_channels_click);
+ WM_operatortype_append(NLA_OT_action_pushdown);
+
WM_operatortype_append(NLA_OT_tracks_add);
WM_operatortype_append(NLA_OT_tracks_delete);
@@ -133,6 +134,8 @@ void nla_operatortypes(void)
WM_operatortype_append(NLA_OT_view_all);
WM_operatortype_append(NLA_OT_view_selected);
+ WM_operatortype_append(NLA_OT_previewrange_set);
+
/* edit */
WM_operatortype_append(NLA_OT_tweakmode_enter);
WM_operatortype_append(NLA_OT_tweakmode_exit);
@@ -156,6 +159,8 @@ void nla_operatortypes(void)
WM_operatortype_append(NLA_OT_action_sync_length);
+ WM_operatortype_append(NLA_OT_make_single_user);
+
WM_operatortype_append(NLA_OT_apply_scale);
WM_operatortype_append(NLA_OT_clear_scale);
@@ -178,16 +183,16 @@ static void nla_keymap_channels(wmKeyMap *keymap)
/* click-select */
// XXX for now, only leftmouse....
kmi = WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
/* channel operations ------------------------------------------------------------ */
/* add tracks */
kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "above_selected", FALSE);
+ RNA_boolean_set(kmi->ptr, "above_selected", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "above_selected", TRUE);
+ RNA_boolean_set(kmi->ptr, "above_selected", true);
/* delete tracks */
WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", XKEY, KM_PRESS, 0, 0);
@@ -201,43 +206,45 @@ static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* selection ------------------------------------------------ */
/* click select */
kmi = WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
/* select left/right */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_TEST);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_RIGHT);
/* deselect all */
/* TODO: uniformize with other select_all ops? */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "invert", FALSE);
+ RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "invert", TRUE);
+ RNA_boolean_set(kmi->ptr, "invert", true);
/* borderselect */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", FALSE);
+ RNA_boolean_set(kmi->ptr, "axis_range", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "axis_range", TRUE);
+ RNA_boolean_set(kmi->ptr, "axis_range", true);
/* view ---------------------------------------------------- */
/* auto-set range */
- //WM_keymap_add_item(keymap, "NLA_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
+
WM_keymap_add_item(keymap, "NLA_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLA_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
/* editing ------------------------------------------------ */
@@ -252,7 +259,14 @@ static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "NLA_OT_meta_remove", GKEY, KM_PRESS, KM_ALT, 0);
/* duplicate */
- WM_keymap_add_item(keymap, "NLA_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ kmi = WM_keymap_add_item(keymap, "NLA_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "linked", false);
+
+ kmi = WM_keymap_add_item(keymap, "NLA_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0);
+ RNA_boolean_set(kmi->ptr, "linked", true);
+
+ /* single user */
+ WM_keymap_add_item(keymap, "NLA_OT_make_single_user", UKEY, KM_PRESS, 0, 0);
/* delete */
WM_keymap_add_item(keymap, "NLA_OT_delete", XKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index f723696de69..3e7a6f4578c 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -38,7 +38,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BKE_nla.h"
#include "BKE_context.h"
@@ -67,16 +66,13 @@ static short selmodes_to_flagmodes(short sel)
switch (sel) {
case SELECT_SUBTRACT:
return ACHANNEL_SETFLAG_CLEAR;
- break;
-
+
case SELECT_INVERT:
return ACHANNEL_SETFLAG_INVERT;
- break;
-
+
case SELECT_ADD:
default:
return ACHANNEL_SETFLAG_ADD;
- break;
}
}
@@ -467,7 +463,7 @@ static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wm
float x;
/* determine which side of the current frame mouse is on */
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL);
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
if (x < CFRA)
RNA_int_set(op->ptr, "mode", NLAEDIT_LRSEL_LEFT);
else
@@ -518,7 +514,7 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
Scene *scene = ac->scene;
NlaStrip *strip = NULL;
int channel_index;
- float xmin, xmax, dummy;
+ float xmin, xmax;
float x, y;
@@ -529,8 +525,8 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
* (that is the size of keyframe icons, so user should be expecting similar tolerances)
*/
- UI_view2d_region_to_view(v2d, mval[0] - 7, mval[1], &xmin, &dummy);
- UI_view2d_region_to_view(v2d, mval[0] + 7, mval[1], &xmax, &dummy);
+ xmin = UI_view2d_region_to_view_x(v2d, mval[0] - 7);
+ xmax = UI_view2d_region_to_view_x(v2d, mval[0] + 7);
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
@@ -579,14 +575,6 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* deselect all other channels first */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
- /* Highlight NLA-Track */
- if (ale->type == ANIMTYPE_NLATRACK) {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- nlt->flag |= NLATRACK_SELECTED;
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
- }
}
/* only select strip if we clicked on a valid channel and hit something */
@@ -598,10 +586,21 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* if we selected it, we can make it active too
* - we always need to clear the active strip flag though...
+ * - as well as selecting its track...
*/
deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0);
- if (strip->flag & NLASTRIP_FLAG_SELECT)
+
+ if (strip->flag & NLASTRIP_FLAG_SELECT) {
strip->flag |= NLASTRIP_FLAG_ACTIVE;
+
+ /* Highlight NLA-Track */
+ if (ale->type == ANIMTYPE_NLATRACK) {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ nlt->flag |= NLATRACK_SELECTED;
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
+ }
+ }
}
/* free this channel */
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index ce070ecb124..60ee2d1f5ec 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -38,7 +38,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index d656d950ec4..1c4ce3d57ce 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -37,13 +37,13 @@
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_scene.h"
#include "BKE_tracking.h"
#include "BLF_api.h"
@@ -58,8 +58,6 @@
#include "BIF_glutil.h"
-#include "MEM_guardedalloc.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -154,7 +152,7 @@ static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr
uiLayout *col;
RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiTemplateColorPicker(col, &sockptr, "default_value", 1, 0, 0, 0);
uiItemR(col, &sockptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE);
}
@@ -165,8 +163,8 @@ static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- col = uiLayoutColumn(layout, FALSE);
- row = uiLayoutRow(col, TRUE);
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRow(col, true);
uiItemR(row, ptr, "blend_type", 0, "", ICON_NONE);
if (ELEM(ntree->type, NTREE_COMPOSIT, NTREE_TEXTURE))
uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
@@ -191,7 +189,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "frame_start", 0, IFACE_("Sta"), ICON_NONE);
uiItemR(row, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
}
@@ -343,7 +341,7 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
{
const float margin = 1.5f * U.widget_unit;
NodeFrame *data = (NodeFrame *)node->storage;
- int bbinit;
+ bool bbinit;
bNode *tnode;
rctf rect, noderect;
float xmax, ymax;
@@ -407,7 +405,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */
/* title color */
- UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.8f, 10);
+ UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
width = BLF_width(fontid, label, sizeof(label));
ascender = BLF_ascender(fontid);
@@ -431,7 +429,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
float alpha;
/* skip if out of view */
- if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == FALSE) {
+ if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
uiEndBlock(C, node->block);
node->block = NULL;
return;
@@ -664,7 +662,7 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
if (!imaptr->data)
return;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, imaptr, "source", 0, "", ICON_NONE);
@@ -683,15 +681,15 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
}
if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE);
}
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER)
uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
@@ -706,7 +704,7 @@ static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA
if (!node->id) return;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE);
@@ -718,31 +716,31 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemL(col, IFACE_("Location:"), ICON_NONE);
uiItemR(col, ptr, "translation", 0, "", ICON_NONE);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemL(col, IFACE_("Rotation:"), ICON_NONE);
uiItemR(col, ptr, "rotation", 0, "", ICON_NONE);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemL(col, IFACE_("Scale:"), ICON_NONE);
uiItemR(col, ptr, "scale", 0, "", ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemR(col, ptr, "use_min", 0, IFACE_("Min"), ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
uiItemR(sub, ptr, "min", 0, "", ICON_NONE);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
uiItemR(col, ptr, "use_max", 0, IFACE_("Max"), ICON_NONE);
- sub = uiLayoutColumn(col, TRUE);
+ sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
uiItemR(sub, ptr, "max", 0, "", ICON_NONE);
}
@@ -764,7 +762,7 @@ static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
@@ -802,6 +800,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "projection") == SHD_PROJ_BOX) {
uiItemR(layout, ptr, "projection_blend", 0, "Blend", ICON_NONE);
@@ -856,11 +855,11 @@ static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), Po
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
}
@@ -890,6 +889,20 @@ static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), Pointer
uiItemR(layout, ptr, "invert", 0, NULL, 0);
}
+static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "from_dupli", 0, NULL, 0);
+
+ if (!RNA_boolean_get(ptr, "from_dupli")) {
+ PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
+
+ if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
+ PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
+ }
+ }
+}
+
static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiItemR(layout, ptr, "space", 0, "", 0);
@@ -910,11 +923,11 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *
{
uiLayout *split, *row;
- split = uiLayoutSplit(layout, 0.0f, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
uiItemR(split, ptr, "direction_type", 0, "", 0);
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
if (RNA_enum_get(ptr, "direction_type") == SHD_TANGENT_UVMAP) {
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
@@ -941,7 +954,7 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
PointerRNA scene = CTX_data_pointer_get(C, "scene");
if (scene.data) {
PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
- if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+ if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR);
}
@@ -951,12 +964,12 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
static void node_shader_buts_volume(uiLayout *layout, bContext *C, PointerRNA *UNUSED(ptr))
{
- /* SSS does not work on GPU yet */
+ /* Volume does not work on GPU yet */
PointerRNA scene = CTX_data_pointer_get(C, "scene");
if (scene.data) {
PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
- if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+ if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
uiItemL(layout, IFACE_("Volumes not supported on GPU"), ICON_ERROR);
}
}
@@ -975,10 +988,10 @@ static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), Point
{
uiLayout *row;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_INTERNAL)
uiItemR(row, ptr, "script", 0, "", ICON_NONE);
@@ -1120,6 +1133,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
ntype->draw_buttons = node_shader_buts_script;
ntype->draw_buttons_ex = node_shader_buts_script_ex;
break;
+ case SH_NODE_UVMAP:
+ ntype->draw_buttons = node_shader_buts_uvmap;
+ break;
}
}
@@ -1167,8 +1183,8 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
if (!node->id) return;
- col = uiLayoutColumn(layout, FALSE);
- row = uiLayoutRow(col, TRUE);
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRow(col, true);
uiItemR(row, ptr, "layer", 0, "", ICON_NONE);
prop = RNA_struct_find_property(ptr, "layer");
@@ -1192,7 +1208,7 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
int reference;
int filter;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
filter = RNA_enum_get(ptr, "filter_type");
reference = RNA_boolean_get(ptr, "use_variable_size");
@@ -1209,15 +1225,15 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
if (RNA_boolean_get(ptr, "use_relative")) {
uiItemL(col, IFACE_("Aspect Correction"), ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "aspect_correction", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "factor_x", 0, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "factor_y", 0, IFACE_("Y"), ICON_NONE);
}
else {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "size_x", 0, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "size_y", 0, IFACE_("Y"), ICON_NONE);
}
@@ -1230,14 +1246,14 @@ static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Center:"), ICON_NONE);
uiItemR(col, ptr, "center_x", 0, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "center_y", 0, IFACE_("Y"), ICON_NONE);
uiItemS(layout);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "distance", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE);
@@ -1251,7 +1267,7 @@ static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "iterations", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "sigma_space", 0, NULL, ICON_NONE);
@@ -1261,29 +1277,29 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA
{
uiLayout *sub, *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Bokeh Type:"), ICON_NONE);
uiItemR(col, ptr, "bokeh", 0, "", ICON_NONE);
uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer") == TRUE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer") == true);
uiItemR(col, ptr, "f_stop", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NONE);
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, FALSE);
- uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer") == FALSE);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer") == false);
uiItemR(sub, ptr, "z_scale", 0, NULL, ICON_NONE);
}
@@ -1322,7 +1338,7 @@ static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), Po
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "tonemap_type", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "tonemap_type") == 0) {
uiItemR(col, ptr, "key", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1341,11 +1357,11 @@ static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), P
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "use_projector", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(col, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == FALSE);
+ col = uiLayoutColumn(col, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == false);
uiItemR(col, ptr, "use_jitter", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_fit", 0, NULL, ICON_NONE);
}
@@ -1354,11 +1370,11 @@ static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), Po
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "samples", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "factor", 0, IFACE_("Blur"), ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Speed:"), ICON_NONE);
uiItemR(col, ptr, "speed_min", 0, IFACE_("Min"), ICON_NONE);
uiItemR(col, ptr, "speed_max", 0, IFACE_("Max"), ICON_NONE);
@@ -1383,7 +1399,7 @@ static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(layout, ptr, "use_crop_size", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "relative", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
if (RNA_boolean_get(ptr, "relative")) {
uiItemR(col, ptr, "rel_min_x", 0, IFACE_("Left"), ICON_NONE);
uiItemR(col, ptr, "rel_max_x", 0, IFACE_("Right"), ICON_NONE);
@@ -1402,8 +1418,8 @@ static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C)
{
uiLayout *row, *col;
- col = uiLayoutColumn(layout, FALSE);
- row = uiLayoutRow(col, FALSE);
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(col, ptr, "factor", 0, NULL, ICON_NONE);
}
@@ -1412,7 +1428,7 @@ static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUS
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Inner Edge:"), ICON_NONE);
uiItemR(col, ptr, "inner_mode", 0, "", ICON_NONE);
@@ -1424,7 +1440,7 @@ static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE);
}
@@ -1432,19 +1448,19 @@ static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *sub, *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "size", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_min", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, FALSE);
+ sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
uiItemR(sub, ptr, "min", 0, "", ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_max", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, FALSE);
+ sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
uiItemR(sub, ptr, "max", 0, "", ICON_NONE);
}
@@ -1453,7 +1469,7 @@ static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "premul", 0, NULL, ICON_NONE);
}
@@ -1462,7 +1478,7 @@ static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), P
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_antialias_z", 0, NULL, ICON_NONE);
}
@@ -1472,7 +1488,7 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1501,7 +1517,7 @@ static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "threshold_neighbor", 0, NULL, ICON_NONE);
}
@@ -1510,7 +1526,7 @@ static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
@@ -1519,10 +1535,10 @@ static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED
{
uiLayout *col, *row;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1534,21 +1550,21 @@ static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C)
uiLayout *row, *col;
uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "limit_method") == 0) {
uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "use_unspill", 0, NULL, ICON_NONE);
- if (RNA_boolean_get(ptr, "use_unspill") == TRUE) {
+ if (RNA_boolean_get(ptr, "use_unspill") == true) {
uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1559,11 +1575,11 @@ static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
/*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now */
uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
/*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now*/
@@ -1573,7 +1589,7 @@ static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C)
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1584,20 +1600,20 @@ static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(
uiLayout *col, *row;
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Key Channel:"), ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "matte_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "limit_method") == 0) {
uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
@@ -1609,7 +1625,7 @@ static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C),
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
@@ -1645,14 +1661,14 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER);
node_composit_buts_file_output(layout, C, ptr);
- uiTemplateImageSettings(layout, &imfptr, FALSE);
+ uiTemplateImageSettings(layout, &imfptr, false);
uiItemS(layout);
uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket");
- row = uiLayoutRow(layout, FALSE);
- col = uiLayoutColumn(row, TRUE);
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, true);
active_index = RNA_int_get(ptr, "active_input_index");
/* using different collection properties if multilayer format is enabled */
@@ -1671,7 +1687,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
/* XXX collection lookup does not return the ID part of the pointer, setting this manually here */
active_input_ptr.id.data = ptr->id.data;
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
op_ptr = uiItemFullO(col, "NODE_OT_output_file_move_active_socket", "",
ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&op_ptr, "direction", 1);
@@ -1681,19 +1697,19 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
if (active_input_ptr.data) {
if (multilayer) {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Layer:"), ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &active_input_ptr, "name", 0, "", ICON_NONE);
uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "",
ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY);
}
else {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("File Subpath:"), ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE);
uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "",
ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY);
@@ -1701,13 +1717,13 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
/* format details for individual files */
imfptr = RNA_pointer_get(&active_input_ptr, "format");
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Format:"), ICON_NONE);
uiItemR(col, &active_input_ptr, "use_node_format", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, FALSE);
- uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == FALSE);
- uiTemplateImageSettings(col, &imfptr, FALSE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == false);
+ uiTemplateImageSettings(col, &imfptr, false);
}
}
}
@@ -1719,7 +1735,7 @@ static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), Poin
if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) {
uiLayout *row;
uiItemR(layout, ptr, "frame_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "offset_x", 0, "X", ICON_NONE);
uiItemR(row, ptr, "offset_y", 0, "Y", ICON_NONE);
}
@@ -1734,7 +1750,7 @@ static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), Poi
{
uiLayout *col;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NONE);
}
@@ -1757,39 +1773,39 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C
if (RNA_enum_get(ptr, "correction_method") == 0) {
- split = uiLayoutSplit(layout, 0.0f, FALSE);
- col = uiLayoutColumn(split, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "lift", 1, 1, 0, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "lift", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "gamma", 1, 1, 1, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "gamma", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "gain", 1, 1, 1, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "gain", 0, NULL, ICON_NONE);
}
else {
- split = uiLayoutSplit(layout, 0.0f, FALSE);
- col = uiLayoutColumn(split, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "offset", 1, 1, 0, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "offset", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "power", 1, 1, 0, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "power", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "slope", 1, 1, 0, 1);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, ptr, "slope", 0, NULL, ICON_NONE);
}
@@ -1902,12 +1918,12 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
{
uiLayout *row;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, "", ICON_NONE);
uiItemL(row, IFACE_("Saturation"), ICON_NONE);
uiItemL(row, IFACE_("Contrast"), ICON_NONE);
@@ -1915,7 +1931,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemL(row, IFACE_("Gain"), ICON_NONE);
uiItemL(row, IFACE_("Lift"), ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, IFACE_("Master"), ICON_NONE);
uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
@@ -1923,7 +1939,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, IFACE_("Highlights"), ICON_NONE);
uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
@@ -1931,7 +1947,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, IFACE_("Midtones"), ICON_NONE);
uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
@@ -1939,7 +1955,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemL(row, IFACE_("Shadows"), ICON_NONE);
uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
@@ -1947,7 +1963,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
@@ -1956,7 +1972,7 @@ static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UN
{
uiLayout *row;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
@@ -1991,7 +2007,7 @@ static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UN
uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "midtones_start", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_end", 0, NULL, ICON_NONE);
}
@@ -2005,11 +2021,11 @@ static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), Po
{
uiLayout *row;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -2133,10 +2149,10 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop
static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -2161,7 +2177,7 @@ static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C),
uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "tile_order") == 0) {
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "center_x", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "center_y", 0, NULL, ICON_NONE);
}
@@ -2202,7 +2218,7 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point
RNA_pointer_create(&clip->id, &RNA_MovieTracking, &clip->tracking, &tracking_ptr);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
}
}
@@ -2241,7 +2257,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
object = BKE_tracking_object_get_named(tracking, data->tracking_object);
@@ -2280,7 +2296,7 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
object = BKE_tracking_object_get_named(tracking, data->tracking_object);
@@ -2297,6 +2313,10 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
}
}
+static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout), bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
+{
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2518,6 +2538,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_PLANETRACKDEFORM:
ntype->draw_buttons = node_composit_buts_planetrackdeform;
break;
+ case CMP_NODE_CORNERPIN:
+ ntype->draw_buttons = node_composit_buts_cornerpin;
+ break;
}
}
@@ -2527,11 +2550,11 @@ static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), Poin
{
uiLayout *col;
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
}
@@ -2546,23 +2569,23 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
switch (tex->type) {
case TEX_BLEND:
uiItemR(col, &tex_ptr, "progression", 0, "", ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "use_flip_axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
break;
case TEX_MARBLE:
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "marble_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
break;
@@ -2571,9 +2594,9 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
break;
case TEX_STUCCI:
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "stucci_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
break;
@@ -2581,18 +2604,18 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
case TEX_WOOD:
uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
uiItemR(col, &tex_ptr, "wood_type", 0, "", ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
break;
case TEX_CLOUDS:
uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "cloud_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- row = uiLayoutRow(col, FALSE);
+ row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, IFACE_("Depth"), ICON_NONE);
break;
@@ -2718,7 +2741,7 @@ static void node_template_properties_update(bNodeType *ntype)
static void node_socket_undefined_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(node_ptr),
const char *UNUSED(text))
{
- uiItemL(layout, "Undefined Socket Type", ICON_ERROR);
+ uiItemL(layout, IFACE_("Undefined Socket Type"), ICON_ERROR);
}
static void node_socket_undefined_draw_color(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(node_ptr), float *r_color)
@@ -2731,7 +2754,7 @@ static void node_socket_undefined_draw_color(bContext *UNUSED(C), PointerRNA *UN
static void node_socket_undefined_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(ptr))
{
- uiItemL(layout, "Undefined Socket Type", ICON_ERROR);
+ uiItemL(layout, IFACE_("Undefined Socket Type"), ICON_ERROR);
}
static void node_socket_undefined_interface_draw_color(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), float *r_color)
@@ -2843,7 +2866,7 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR
PointerRNA inputptr, imfptr;
int imtype;
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
imfptr = RNA_pointer_get(node_ptr, "format");
imtype = RNA_enum_get(&imfptr, "file_format");
@@ -2885,6 +2908,7 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
/* XXX not nice, eventually give this node its own socket type ... */
if (node->type == CMP_NODE_OUTPUT_FILE) {
node_file_output_socket_draw(C, layout, ptr, node_ptr);
+ return;
}
if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
@@ -2936,8 +2960,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
uiLayout *row;
uiItemR(layout, ptr, "default_value", 0, NULL, 0);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "min_value", 0, "Min", 0);
- uiItemR(row, ptr, "max_value", 0, "Max", 0);
+ uiItemR(row, ptr, "min_value", 0, IFACE_("Min"), 0);
+ uiItemR(row, ptr, "max_value", 0, IFACE_("Max"), 0);
break;
}
case SOCK_INT:
@@ -2945,8 +2969,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
uiLayout *row;
uiItemR(layout, ptr, "default_value", 0, NULL, 0);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "min_value", 0, "Min", 0);
- uiItemR(row, ptr, "max_value", 0, "Max", 0);
+ uiItemR(row, ptr, "min_value", 0, IFACE_("Min"), 0);
+ uiItemR(row, ptr, "max_value", 0, IFACE_("Max"), 0);
break;
}
case SOCK_BOOLEAN:
@@ -2959,8 +2983,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
uiLayout *row;
uiItemR(layout, ptr, "default_value", UI_ITEM_R_EXPAND, NULL, 0);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "min_value", 0, "Min", 0);
- uiItemR(row, ptr, "max_value", 0, "Max", 0);
+ uiItemR(row, ptr, "min_value", 0, IFACE_("Min"), 0);
+ uiItemR(row, ptr, "max_value", 0, IFACE_("Max"), 0);
break;
}
case SOCK_RGBA:
@@ -3437,7 +3461,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
/* new connection */
if (!link->fromsock || !link->tosock) {
th_col1 = TH_ACTIVE;
- do_triple = TRUE;
+ do_triple = true;
}
else {
/* going to give issues once... */
@@ -3458,8 +3482,8 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
if (link->tonode && link->tonode->flag & SELECT)
th_col2 = TH_EDGE_SELECT;
}
- do_shaded = TRUE;
- do_triple = TRUE;
+ do_shaded = true;
+ do_triple = true;
}
else {
th_col1 = TH_REDALERT;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 428495542c2..02e6f9b69f3 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -82,7 +82,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
/* generics */
node->locx = locx;
node->locy = locy + 60.0f; /* arbitrary... so its visible, (0,0) is top of node */
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(node, true);
node->locx = locx;
node->locy = locy + 60.0f;
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 035287c0411..ebff840dc9f 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -87,7 +87,7 @@ static void node_sockets_panel(const bContext *C, Panel *pa)
for (sock = node->inputs.first; sock; sock = sock->next) {
BLI_snprintf(name, sizeof(name), "%s:", sock->name);
- split = uiLayoutSplit(layout, 0.35f, FALSE);
+ split = uiLayoutSplit(layout, 0.35f, false);
uiItemL(split, name, ICON_NONE);
uiTemplateNodeLink(split, ntree, node, sock);
}
@@ -107,20 +107,20 @@ static bool node_tree_find_active_socket(bNodeTree *ntree, bNodeSocket **r_sock,
if (sock->flag & SELECT) {
*r_sock = sock;
*r_in_out = SOCK_IN;
- return TRUE;
+ return true;
}
}
for (sock = ntree->outputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
*r_sock = sock;
*r_in_out = SOCK_OUT;
- return TRUE;
+ return true;
}
}
*r_sock = NULL;
*r_in_out = 0;
- return FALSE;
+ return false;
}
static void node_tree_interface_panel(const bContext *C, Panel *pa)
@@ -140,31 +140,31 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
node_tree_find_active_socket(ntree, &sock, &in_out);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, sock, &sockptr);
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
- split = uiLayoutRow(row, TRUE);
- col = uiLayoutColumn(split, TRUE);
+ split = uiLayoutRow(row, true);
+ col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Inputs:"), ICON_NONE);
uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input",
0, 0, 0, 0);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "in_out", SOCK_IN);
- col = uiLayoutColumn(split, TRUE);
+ col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Outputs:"), ICON_NONE);
uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output",
0, 0, 0, 0);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "in_out", SOCK_OUT);
- col = uiLayoutColumn(row, TRUE);
+ col = uiLayoutColumn(row, true);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_move", "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "direction", 1);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_move", "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "direction", 2);
if (sock) {
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &sockptr, "name", 0, NULL, ICON_NONE);
uiItemO(row, "", ICON_X, "NODE_OT_tree_socket_remove");
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 95137de7a44..af228208764 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -32,11 +32,11 @@
#include "DNA_lamp_types.h"
#include "DNA_node_types.h"
#include "DNA_material_types.h"
-#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_linestyle_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -63,7 +63,6 @@
#include "ED_node.h"
#include "ED_gpencil.h"
-#include "ED_screen.h"
#include "ED_space_api.h"
#include "UI_resources.h"
@@ -113,6 +112,8 @@ static bNodeTree *node_tree_from_ID(ID *id)
return ((Scene *)id)->nodetree;
case ID_TE:
return ((Tex *)id)->nodetree;
+ case ID_LS:
+ return ((FreestyleLineStyle *)id)->nodetree;
}
}
@@ -595,17 +596,17 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
}
/* this might have some more generic use */
-static void node_circle_draw(float x, float y, float size, float *col, int highlight)
+static void node_circle_draw(float x, float y, float size, const float col[4], int highlight)
{
/* 16 values of sin function */
- static float si[16] = {
+ static const float si[16] = {
0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
-0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
-0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
};
/* 16 values of cos function */
- static float co[16] = {
+ static const float co[16] = {
1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
-0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
-0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
@@ -784,7 +785,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
nodeSynchronizeID(node, false);
/* skip if out of view */
- if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == FALSE) {
+ if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
uiEndBlock(C, node->block);
node->block = NULL;
return;
@@ -1259,7 +1260,7 @@ static void snode_setup_v2d(SpaceNode *snode, ARegion *ar, const float center[2]
View2D *v2d = &ar->v2d;
/* shift view to node tree center */
- UI_view2d_setcenter(v2d, center[0], center[1]);
+ UI_view2d_center_set(v2d, center[0], center[1]);
UI_view2d_view_ortho(v2d);
/* aspect+font, set each time */
@@ -1345,7 +1346,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
path = snode->treepath.last;
/* current View2D center, will be set temporarily for parent node trees */
- UI_view2d_getcenter(v2d, &center[0], &center[1]);
+ UI_view2d_center_get(v2d, &center[0], &center[1]);
/* store new view center in path and current edittree */
copy_v2_v2(path->view_center, center);
@@ -1404,7 +1405,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
if (snode->flag & SNODE_SHOW_GPENCIL) {
/* draw grease-pencil ('canvas' strokes) */
- draw_gpencil_view2d(C, TRUE);
+ draw_gpencil_view2d(C, true);
}
}
else {
@@ -1423,7 +1424,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
if (snode->treepath.last) {
if (snode->flag & SNODE_SHOW_GPENCIL) {
/* draw grease-pencil (screen strokes, and also paintbuffer) */
- draw_gpencil_view2d(C, FALSE);
+ draw_gpencil_view2d(C, false);
}
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 114b45ed174..fc0c82faba8 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -32,30 +32,24 @@
#include "MEM_guardedalloc.h"
#include "DNA_action_types.h"
-#include "DNA_anim_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_types.h"
#include "DNA_text_types.h"
#include "DNA_world_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_node.h"
-#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_texture.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -99,7 +93,7 @@ typedef struct CompoJob {
Scene *scene;
bNodeTree *ntree;
bNodeTree *localtree;
- short *stop;
+ const short *stop;
short *do_update;
float *progress;
short need_sync;
@@ -176,8 +170,8 @@ static void compo_statsdrawjob(void *cjv, char *UNUSED(str))
{
CompoJob *cj = cjv;
- *(cj->do_update) = TRUE;
- cj->need_sync = TRUE;
+ *(cj->do_update) = true;
+ cj->need_sync = true;
}
/* called by compo, wmJob sends notifier */
@@ -185,7 +179,7 @@ static void compo_redrawjob(void *cjv)
{
CompoJob *cj = cjv;
- *(cj->do_update) = TRUE;
+ *(cj->do_update) = true;
}
static void compo_freejob(void *cjv)
@@ -219,7 +213,7 @@ static void compo_updatejob(void *cjv)
/* was used by old compositor system only */
ntreeLocalSync(cj->localtree, cj->ntree);
- cj->need_sync = FALSE;
+ cj->need_sync = false;
}
WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, NULL);
@@ -240,7 +234,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
bNodeTree *ntree = cj->localtree;
Scene *scene = cj->scene;
- if (scene->use_nodes == FALSE)
+ if (scene->use_nodes == false)
return;
cj->stop = stop;
@@ -257,9 +251,8 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
ntree->udh = cj;
// XXX BIF_store_spare();
-
/* 1 is do_previews */
- ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, FALSE, TRUE, &scene->view_settings, &scene->display_settings);
+ ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings);
ntree->test_break = NULL;
ntree->stats_draw = NULL;
@@ -278,6 +271,7 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene
{
wmJob *wm_job;
CompoJob *cj;
+ Scene *scene = CTX_data_scene(C);
/* to fix bug: [#32272] */
if (G.is_rendering) {
@@ -285,15 +279,17 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene
}
#ifdef USE_ESC_COMPO
- G.is_break = FALSE;
+ G.is_break = false;
#endif
+ BKE_image_backup_render(scene, BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"));
+
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene_owner, "Compositing",
WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS, WM_JOB_TYPE_COMPOSITE);
cj = MEM_callocN(sizeof(CompoJob), "compo job");
/* customdata for preview thread */
- cj->scene = CTX_data_scene(C);
+ cj->scene = scene;
cj->ntree = nodetree;
cj->recalc_flags = compo_get_recalc_flags(C);
@@ -586,6 +582,14 @@ void snode_set_context(const bContext *C)
if (snode->nodetree != ntree || snode->id != id || snode->from != from) {
ED_node_tree_start(snode, ntree, id, from);
}
+
+ /* XXX Legacy hack to update render layer node outputs.
+ * This should be handled by the depsgraph eventually ...
+ */
+ if (ED_node_is_compositor(snode) && snode->nodetree) {
+ /* update output sockets based on available layers */
+ ntreeCompositForceHidden(snode->nodetree);
+ }
}
void snode_update(SpaceNode *snode, bNode *node)
@@ -619,7 +623,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
if (node->type != NODE_GROUP) {
const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0;
- int do_update = 0;
+ bool do_update = false;
/* generic node group output: set node as active output */
if (node->type == NODE_GROUP_OUTPUT) {
@@ -870,37 +874,38 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
dy = (my - nsw->mystart) / UI_DPI_FAC;
if (node) {
- if (node->flag & NODE_HIDDEN) {
- float widthmin = 0.0f;
- float widthmax = 100.0f;
- if (nsw->directions & NODE_RESIZE_RIGHT) {
- node->miniwidth = nsw->oldminiwidth + dx;
- CLAMP(node->miniwidth, widthmin, widthmax);
- }
- if (nsw->directions & NODE_RESIZE_LEFT) {
- float locmax = nsw->oldlocx + nsw->oldminiwidth;
-
- node->locx = nsw->oldlocx + dx;
- CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
- node->miniwidth = locmax - node->locx;
- }
+ /* width can use node->width or node->miniwidth (hidden nodes) */
+ float *pwidth;
+ float oldwidth, widthmin, widthmax;
+ /* ignore hidden flag for frame nodes */
+ bool use_hidden = (node->type != NODE_FRAME);
+ if (use_hidden && node->flag & NODE_HIDDEN) {
+ pwidth = &node->miniwidth;
+ oldwidth = nsw->oldminiwidth;
+ widthmin = 0.0f;
+ widthmax = 100.0f;
}
else {
- float widthmin = node->typeinfo->minwidth;
- float widthmax = node->typeinfo->maxwidth;
+ pwidth = &node->width;
+ oldwidth = nsw->oldwidth;
+ widthmin = node->typeinfo->minwidth;
+ widthmax = node->typeinfo->maxwidth;
+ }
+
+ {
if (nsw->directions & NODE_RESIZE_RIGHT) {
- node->width = nsw->oldwidth + dx;
- CLAMP(node->width, widthmin, widthmax);
+ *pwidth = oldwidth + dx;
+ CLAMP(*pwidth, widthmin, widthmax);
}
if (nsw->directions & NODE_RESIZE_LEFT) {
- float locmax = nsw->oldlocx + nsw->oldwidth;
+ float locmax = nsw->oldlocx + oldwidth;
node->locx = nsw->oldlocx + dx;
CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
- node->width = locmax - node->locx;
+ *pwidth = locmax - node->locx;
}
}
-
+
/* height works the other way round ... */
{
float heightmin = UI_DPI_FAC * node->typeinfo->minheight;
@@ -1205,9 +1210,9 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
/* has been set during copy above */
newnode = node->new_node;
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
node->flag &= ~NODE_ACTIVE;
- nodeSetSelected(newnode, TRUE);
+ nodeSetSelected(newnode, true);
}
/* make sure we don't copy new nodes again! */
@@ -1248,11 +1253,11 @@ bool ED_node_select_check(ListBase *lb)
for (node = lb->first; node; node = node->next) {
if (node->flag & NODE_SELECT) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/* ******************************** */
@@ -1368,7 +1373,6 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-
}
return OPERATOR_CANCELLED;
}
@@ -2013,15 +2017,15 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
}
/* only warn */
- if (is_clipboard_valid == FALSE) {
+ if (is_clipboard_valid == false) {
BKE_report(op->reports, RPT_WARNING, "Some nodes references could not be restored, will be left empty");
}
/* make sure all clipboard nodes would be valid in the target tree */
- all_nodes_valid = TRUE;
+ all_nodes_valid = true;
for (node = clipboard_nodes_lb->first; node; node = node->next) {
if (!node->typeinfo->poll_instance(node, ntree)) {
- all_nodes_valid = FALSE;
+ all_nodes_valid = false;
BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name + 2);
}
}
@@ -2049,7 +2053,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
id_us_plus(node->id);
/* pasted nodes are selected */
- nodeSetSelected(new_node, TRUE);
+ nodeSetSelected(new_node, true);
}
/* reparent copied nodes */
@@ -2316,12 +2320,12 @@ static int node_shader_script_update_poll(bContext *C)
}
/* recursively check for script nodes in groups using this text and update */
-static int node_shader_script_update_text_recursive(RenderEngine *engine, RenderEngineType *type, bNodeTree *ntree, Text *text)
+static bool node_shader_script_update_text_recursive(RenderEngine *engine, RenderEngineType *type, bNodeTree *ntree, Text *text)
{
- int found = FALSE;
+ bool found = false;
bNode *node;
- ntree->done = TRUE;
+ ntree->done = true;
/* update each script that is using this text datablock */
for (node = ntree->nodes.first; node; node = node->next) {
@@ -2332,7 +2336,7 @@ static int node_shader_script_update_text_recursive(RenderEngine *engine, Render
}
else if (node->type == SH_NODE_SCRIPT && node->id == &text->id) {
type->update_script_node(engine, ntree, node);
- found = TRUE;
+ found = true;
}
}
@@ -2349,7 +2353,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
bNode *node = NULL;
RenderEngine *engine;
RenderEngineType *type;
- int found = FALSE;
+ bool found = false;
/* setup render engine */
type = RE_engines_find(scene->r.engine);
@@ -2370,7 +2374,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
/* update single node */
type->update_script_node(engine, ntree, node);
- found = TRUE;
+ found = true;
}
else {
/* update all nodes using text datablock */
@@ -2380,7 +2384,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
/* clear flags for recursion check */
FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER)
- ntree->done = FALSE;
+ ntree->done = false;
} FOREACH_NODETREE_END
FOREACH_NODETREE(bmain, ntree, id) {
@@ -2515,5 +2519,5 @@ void NODE_OT_viewer_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 20e6900a268..39aba921f72 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -34,12 +34,9 @@
#include "MEM_guardedalloc.h"
#include "DNA_node_types.h"
-#include "DNA_object_types.h"
#include "DNA_anim_types.h"
#include "BLI_listbase.h"
-#include "BLI_string.h"
-#include "BLI_rect.h"
#include "BLI_math.h"
#include "BLF_translation.h"
@@ -179,7 +176,7 @@ void NODE_OT_group_edit(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "exit", FALSE, "Exit", "");
+ RNA_def_boolean(ot->srna, "exit", false, "Exit", "");
}
/* ******************** Ungroup operator ********************** */
@@ -203,7 +200,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
* - ngroup (i.e. the source NodeTree) is left unscathed
* - temp copy. don't change ID usercount
*/
- wgroup = ntreeCopyTree_ex(ngroup, FALSE);
+ wgroup = ntreeCopyTree_ex(ngroup, false);
/* Add the nodes into the ntree */
for (node = wgroup->nodes.first; node; node = nextnode) {
@@ -401,7 +398,7 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo
/* deselect all nodes in the target tree */
for (node = ntree->nodes.first; node; node = node->next)
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
/* clear new pointers, set in nodeCopyNode */
for (node = ngroup->nodes.first; node; node = node->next)
@@ -415,7 +412,7 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo
/* ignore interface nodes */
if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
continue;
}
@@ -684,7 +681,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
ListBase anim_basepaths = {NULL, NULL};
float min[2], max[2], center[2];
int totselect;
- int expose_all = FALSE;
+ bool expose_all = false;
bNode *input_node, *output_node;
/* XXX rough guess, not nice but we don't have access to UI constants here ... */
@@ -693,7 +690,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
/* deselect all nodes in the target tree */
for (node = ngroup->nodes.first; node; node = node->next)
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
totselect = node_get_selected_minmax(ntree, gnode, min, max);
add_v2_v2v2(center, min, max);
@@ -701,7 +698,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
/* auto-add interface for "solo" nodes */
if (totselect == 1)
- expose_all = TRUE;
+ expose_all = true;
/* move nodes over */
for (node = ntree->nodes.first; node; node = nextn) {
@@ -831,10 +828,10 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
if (node_group_make_use_node(node, gnode)) {
for (sock = node->inputs.first; sock; sock = sock->next) {
bNodeSocket *iosock, *input_sock;
- int skip = FALSE;
+ bool skip = false;
for (link = ngroup->links.first; link; link = link->next) {
if (link->tosock == sock) {
- skip = TRUE;
+ skip = true;
break;
}
}
@@ -852,10 +849,10 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
for (sock = node->outputs.first; sock; sock = sock->next) {
bNodeSocket *iosock, *output_sock;
- int skip = FALSE;
+ bool skip = false;
for (link = ngroup->links.first; link; link = link->next)
if (link->fromsock == sock)
- skip = TRUE;
+ skip = true;
if (skip)
continue;
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index edd422b8148..ac541ef6a28 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -143,7 +143,7 @@ void ED_operatormacros_node(void)
"Move nodes and attach to frame",
OPTYPE_UNDO | OPTYPE_REGISTER);
mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
- RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(mot->ptr, "release_confirm", true);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
ot = WM_operatortype_append_macro("NODE_OT_detach_translate_attach", "Detach and Move",
@@ -151,7 +151,7 @@ void ED_operatormacros_node(void)
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "NODE_OT_detach");
mot = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
- RNA_boolean_set(mot->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(mot->ptr, "release_confirm", true);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
ot = WM_operatortype_append_macro("NODE_OT_duplicate_move", "Duplicate",
@@ -165,7 +165,7 @@ void ED_operatormacros_node(void)
"Duplicate selected nodes keeping input links and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
- RNA_boolean_set(mot->ptr, "keep_inputs", TRUE);
+ RNA_boolean_set(mot->ptr, "keep_inputs", true);
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
ot = WM_operatortype_append_macro("NODE_OT_move_detach_links", "Detach", "Move a node to detach links",
@@ -222,24 +222,24 @@ void node_keymap(struct wmKeyConfig *keyconf)
* NOTE 3: select op is registered for various combinations of modifier key, so the specialized
* grab operators (unlink, attach, etc.) can work easily on single nodes.
*/
- node_select_keymap(keymap, FALSE);
- node_select_keymap(keymap, TRUE);
+ node_select_keymap(keymap, false);
+ node_select_keymap(keymap, true);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_boolean_set(kmi->ptr, "tweak", TRUE);
+ RNA_boolean_set(kmi->ptr, "tweak", true);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "NODE_OT_select_circle", CKEY, KM_PRESS, 0, 0);
/* each of these falls through if not handled... */
kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "detach", FALSE);
+ RNA_boolean_set(kmi->ptr, "detach", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "detach", TRUE);
+ RNA_boolean_set(kmi->ptr, "detach", true);
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
@@ -256,9 +256,9 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_backimage_sample", ACTIONMOUSE, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "replace", FALSE);
+ RNA_boolean_set(kmi->ptr, "replace", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "replace", TRUE);
+ RNA_boolean_set(kmi->ptr, "replace", true);
WM_keymap_add_menu(keymap, "NODE_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
@@ -275,10 +275,11 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_hide_socket_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "tweak", FALSE);
+ RNA_boolean_set(kmi->ptr, "tweak", false);
WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_delete", DELKEY, KM_PRESS, 0, 0);
@@ -294,9 +295,9 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_select_same_type", GKEY, KM_PRESS, KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_same_type_step", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "prev", FALSE);
+ RNA_boolean_set(kmi->ptr, "prev", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_same_type_step", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "prev", TRUE);
+ RNA_boolean_set(kmi->ptr, "prev", true);
WM_keymap_add_item(keymap, "NODE_OT_find_node", FKEY, KM_PRESS, KM_CTRL, 0);
@@ -305,9 +306,9 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_group_separate", PKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "exit", FALSE);
+ RNA_boolean_set(kmi->ptr, "exit", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "exit", TRUE);
+ RNA_boolean_set(kmi->ptr, "exit", true);
WM_keymap_add_item(keymap, "NODE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 3e1e605682f..6a0e1f35d24 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -29,17 +29,17 @@
* \ingroup spnode
*/
+#include <ctype.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_node_types.h"
-#include "DNA_object_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_node.h"
#include "ED_node.h" /* own include */
@@ -54,6 +54,8 @@
#include "UI_view2d.h"
+#include "BLF_translation.h"
+
#include "node_intern.h" /* own include */
#include "NOD_common.h"
@@ -206,7 +208,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const
for (nli = nodelist->first; nli; nli = nli->next) {
bNode *node_fr, *node_to;
bNodeSocket *sock_fr, *sock_to;
- int has_selected_inputs = 0;
+ bool has_selected_inputs = false;
if (nli->next == NULL) break;
@@ -395,12 +397,87 @@ void NODE_OT_link_viewer(wmOperatorType *ot)
/* *************************** add link op ******************** */
-static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
+static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
+{
+#define HEADER_LENGTH 256
+ char header[HEADER_LENGTH];
+
+ BLI_strncpy(header, IFACE_("LMB: drag node link, RMB: cancel"), HEADER_LENGTH);
+ ED_area_headerprint(CTX_wm_area(C), header);
+#undef HEADER_LENGTH
+}
+
+/* update link_count fields to avoid repeated link counting */
+static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
+{
+ bNodeLink *link;
+ int count = 0;
+ for (link = ntree->links.first; link; link = link->next) {
+ if (link->fromsock == sock)
+ ++count;
+ if (link->tosock == sock)
+ ++count;
+ }
+ return count;
+}
+
+/* test if two sockets are interchangeable
+ * XXX this could be made into a tree-type callback for flexibility
+ */
+static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
+{
+ /* tests if alphabetic prefix matches
+ * this allows for imperfect matches, such as numeric suffixes,
+ * like Color1/Color2
+ */
+ int prefix_len = 0;
+ char *ca = a->name, *cb = b->name;
+ for (; *ca != '\0' && *cb != '\0'; ++ca, ++cb) {
+ /* end of common prefix? */
+ if (*ca != *cb) {
+ /* prefix delimited by non-alphabetic char */
+ if (isalpha(*ca) || isalpha(*cb))
+ return false;
+ break;
+ }
+ ++prefix_len;
+ }
+ return prefix_len > 0;
+}
+
+/* find an eligible socket for linking */
+static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur, bool use_swap)
+{
+ int cur_link_count = node_count_links(ntree, cur);
+ if (cur_link_count <= cur->limit) {
+ /* current socket is fine, use it */
+ return cur;
+ }
+ else if (use_swap) {
+ /* link swapping: try to find a free slot with a matching name */
+
+ bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
+ bNodeSocket *sock;
+
+ sock = cur->next ? cur->next : first; /* wrap around the list end */
+ while (sock != cur) {
+ if (node_link_socket_match(sock, cur)) {
+ int link_count = node_count_links(ntree, sock);
+ /* take +1 into account since we would add a new link */
+ if (link_count + 1 <= sock->limit)
+ return sock; /* found a valid free socket we can swap to */
+ }
+
+ sock = sock->next ? sock->next : first; /* wrap around the list end */
+ }
+ }
+ return NULL;
+}
+
+static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link, bool use_swap)
{
bNodeTree *ntree = snode->edittree;
bNodeSocket *from = link->fromsock, *to = link->tosock;
- int max_from = from->limit, max_to = to->limit;
- int count_from = 1, count_to = 1; /* start at 1, link is included */
bNodeLink *tlink, *tlink_next;
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
@@ -409,16 +486,28 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
continue;
if (tlink && tlink->fromsock == from) {
- ++count_from;
- if (count_from > max_from) {
+ bNodeSocket *new_from = node_find_linkable_socket(ntree, tlink->fromnode, from, use_swap);
+ if (new_from && new_from != from) {
+ /* redirect existing link */
+ tlink->fromsock = new_from;
+ new_from->flag &= ~SOCK_HIDDEN;
+ }
+ else if (!new_from) {
+ /* no possible replacement, remove tlink */
nodeRemLink(ntree, tlink);
tlink = NULL;
}
}
if (tlink && tlink->tosock == to) {
- ++count_to;
- if (count_to > max_to) {
+ bNodeSocket *new_to = node_find_linkable_socket(ntree, tlink->tonode, to, use_swap);
+ if (new_to && new_to != to) {
+ /* redirect existing link */
+ tlink->tosock = new_to;
+ new_to->flag &= ~SOCK_HIDDEN;
+ }
+ else if (!new_to) {
+ /* no possible replacement, remove tlink */
nodeRemLink(ntree, tlink);
tlink = NULL;
}
@@ -426,82 +515,120 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
}
}
-/* loop that adds a nodelink, called by function below */
-/* in_out = starting socket */
-static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
{
SpaceNode *snode = CTX_wm_space_node(C);
- ARegion *ar = CTX_wm_region(C);
- bNodeLinkDrag *nldrag = op->customdata;
bNodeTree *ntree = snode->edittree;
+ bNodeLinkDrag *nldrag = op->customdata;
+ LinkData *linkdata;
+
+ for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
+ bNodeLink *link = linkdata->data;
+
+ if (apply_links && link->tosock && link->fromsock) {
+ /* add link to the node tree */
+ BLI_addtail(&ntree->links, link);
+
+ ntree->update |= NTREE_UPDATE_LINKS;
+
+ /* tag tonode for update */
+ link->tonode->update |= NODE_UPDATE;
+
+ /* we might need to remove a link */
+ node_remove_extra_links(snode, link, true);
+ }
+ else
+ nodeRemLink(ntree, link);
+ }
+
+ ntreeUpdateTree(CTX_data_main(C), ntree);
+ snode_notify(C, snode);
+ snode_dag_update(C, snode);
+
+ BLI_remlink(&snode->linkdrag, nldrag);
+ /* links->data pointers are either held by the tree or freed already */
+ BLI_freelistN(&nldrag->links);
+ MEM_freeN(nldrag);
+}
+
+static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeLinkDrag *nldrag = op->customdata;
bNode *tnode;
bNodeSocket *tsock = NULL;
- bNodeLink *link;
LinkData *linkdata;
- float cursor[2];
- int in_out;
- in_out = nldrag->in_out;
+ if (nldrag->in_out == SOCK_OUT) {
+ if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
+ for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
+ bNodeLink *link = linkdata->data;
+
+ /* skip if this is already the target socket */
+ if (link->tosock == tsock)
+ continue;
+ /* skip if socket is on the same node as the fromsock */
+ if (tnode && link->fromnode == tnode)
+ continue;
+
+ /* attach links to the socket */
+ link->tonode = tnode;
+ link->tosock = tsock;
+ }
+ }
+ else {
+ for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
+ bNodeLink *link = linkdata->data;
+
+ link->tonode = NULL;
+ link->tosock = NULL;
+ }
+ }
+ }
+ else {
+ if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
+ for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
+ bNodeLink *link = linkdata->data;
+
+ /* skip if this is already the target socket */
+ if (link->fromsock == tsock)
+ continue;
+ /* skip if socket is on the same node as the fromsock */
+ if (tnode && link->tonode == tnode)
+ continue;
+
+ /* attach links to the socket */
+ link->fromnode = tnode;
+ link->fromsock = tsock;
+ }
+ }
+ else {
+ for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
+ bNodeLink *link = linkdata->data;
+
+ link->fromnode = NULL;
+ link->fromsock = NULL;
+ }
+ }
+ }
+}
+
+/* loop that adds a nodelink, called by function below */
+/* in_out = starting socket */
+static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ bNodeLinkDrag *nldrag = op->customdata;
+ ARegion *ar = CTX_wm_region(C);
+ float cursor[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&cursor[0], &cursor[1]);
-
+
switch (event->type) {
case MOUSEMOVE:
+ node_link_find_socket(C, op, cursor);
- if (in_out == SOCK_OUT) {
- if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
- for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
- link = linkdata->data;
-
- /* skip if this is already the target socket */
- if (link->tosock == tsock)
- continue;
- /* skip if socket is on the same node as the fromsock */
- if (tnode && link->fromnode == tnode)
- continue;
-
- /* attach links to the socket */
- link->tonode = tnode;
- link->tosock = tsock;
- }
- }
- else {
- for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
- link = linkdata->data;
-
- link->tonode = NULL;
- link->tosock = NULL;
- }
- }
- }
- else {
- if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
- for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
- link = linkdata->data;
-
- /* skip if this is already the target socket */
- if (link->fromsock == tsock)
- continue;
- /* skip if socket is on the same node as the fromsock */
- if (tnode && link->tonode == tnode)
- continue;
-
- /* attach links to the socket */
- link->fromnode = tnode;
- link->fromsock = tsock;
- }
- }
- else {
- for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
- link = linkdata->data;
-
- link->fromnode = NULL;
- link->fromsock = NULL;
- }
- }
- }
-
+ node_link_update_header(C, nldrag);
ED_region_tag_redraw(ar);
break;
@@ -509,34 +636,10 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
case RIGHTMOUSE:
case MIDDLEMOUSE:
{
- for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
- link = linkdata->data;
-
- if (link->tosock && link->fromsock) {
- /* add link to the node tree */
- BLI_addtail(&ntree->links, link);
-
- ntree->update |= NTREE_UPDATE_LINKS;
-
- /* tag tonode for update */
- link->tonode->update |= NODE_UPDATE;
-
- /* we might need to remove a link */
- node_remove_extra_links(snode, link);
- }
- else
- nodeRemLink(ntree, link);
- }
-
- ntreeUpdateTree(CTX_data_main(C), ntree);
- snode_notify(C, snode);
- snode_dag_update(C, snode);
-
- BLI_remlink(&snode->linkdrag, nldrag);
- /* links->data pointers are either held by the tree or freed already */
- BLI_freelistN(&nldrag->links);
- MEM_freeN(nldrag);
+ node_link_exit(C, op, true);
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+ ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
}
@@ -545,7 +648,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* return 1 when socket clicked */
-static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], const bool detach)
+static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool detach)
{
bNode *node;
bNodeSocket *sock;
@@ -630,7 +733,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], const bo
BLI_addtail(&nldrag->links, linkdata);
}
}
-
+
return nldrag;
}
@@ -641,7 +744,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bNodeLinkDrag *nldrag;
float cursor[2];
- const bool detach = RNA_boolean_get(op->ptr, "detach");
+ bool detach = RNA_boolean_get(op->ptr, "detach");
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&cursor[0], &cursor[1]);
@@ -691,7 +794,7 @@ void NODE_OT_link(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
- RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links");
+ RNA_def_boolean(ot->srna, "detach", false, "Detach", "Detach and redirect existing links");
}
/* ********************** Make Link operator ***************** */
@@ -770,7 +873,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
RNA_END;
if (i > 1) {
- int found = FALSE;
+ bool found = false;
bNodeLink *link, *next;
ED_preview_kill_jobs(C);
@@ -782,9 +885,9 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (cut_links_intersect(link, mcoords, i)) {
- if (found == FALSE) {
+ if (found == false) {
ED_preview_kill_jobs(C);
- found = TRUE;
+ found = true;
}
snode_update(snode, link->tonode);
@@ -1057,7 +1160,7 @@ static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
if (node->flag & NODE_SELECT) {
if (node->parent == NULL) {
/* disallow moving a parent into its child */
- if (nodeAttachNodeCheck(frame, node) == FALSE) {
+ if (nodeAttachNodeCheck(frame, node) == false) {
/* attach all unparented nodes */
nodeAttachNode(node, frame);
}
@@ -1072,7 +1175,7 @@ static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
if (parent) {
/* disallow moving a parent into its child */
- if (nodeAttachNodeCheck(frame, node) == FALSE) {
+ if (nodeAttachNodeCheck(frame, node) == false) {
nodeDetachNode(node);
nodeAttachNode(node, frame);
}
@@ -1329,7 +1432,7 @@ void ED_node_link_insert(ScrArea *sa)
link->tonode = select;
link->tosock = best_input;
- node_remove_extra_links(snode, link);
+ node_remove_extra_links(snode, link, false);
link->flag &= ~NODE_LINKFLAG_HILITE;
nodeAddLink(snode->edittree, select, best_output, node, sockto);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 89f07950fe9..7371a3ef070 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -43,7 +43,6 @@
#include "ED_node.h" /* own include */
#include "ED_screen.h"
-#include "ED_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -141,7 +140,7 @@ void node_deselect_all(SpaceNode *snode)
bNode *node;
for (node = snode->edittree->nodes.first; node; node = node->next)
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
}
void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes)
@@ -227,12 +226,12 @@ int node_select_same_type(SpaceNode *snode)
if (p->type != nac->type && p->flag & SELECT) {
/* if it's selected but different type, unselect */
redraw = 1;
- nodeSetSelected(p, FALSE);
+ nodeSetSelected(p, false);
}
else if (p->type == nac->type && (!(p->flag & SELECT))) {
/* if it's the same type and is not selected, select! */
redraw = 1;
- nodeSetSelected(p, TRUE);
+ nodeSetSelected(p, true);
}
}
return(redraw);
@@ -274,8 +273,8 @@ int node_select_same_type_np(SpaceNode *snode, int dir)
if (p) {
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next)
if (tnode != p)
- nodeSetSelected(tnode, FALSE);
- nodeSetSelected(p, TRUE);
+ nodeSetSelected(tnode, false);
+ nodeSetSelected(p, true);
return(1);
}
return(0);
@@ -289,8 +288,8 @@ void node_select_single(bContext *C, bNode *node)
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next)
if (tnode != node)
- nodeSetSelected(tnode, FALSE);
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(tnode, false);
+ nodeSetSelected(node, true);
ED_node_set_active(bmain, snode->edittree, node);
ED_node_set_active_viewer_key(snode);
@@ -365,7 +364,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
nodeSetSelected(tnode, false);
}
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(node, true);
ED_node_set_active(bmain, snode->edittree, node);
selected = 1;
}
@@ -445,22 +444,19 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
bNode *node;
- rcti rect;
rctf rectf;
int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
const bool extend = RNA_boolean_get(op->ptr, "extend");
- WM_operator_properties_border_to_rcti(op, &rect);
-
- UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+ WM_operator_properties_border_to_rctf(op, &rectf);
+ UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (BLI_rctf_isect(&rectf, &node->totr, NULL)) {
nodeSetSelected(node, (gesture_mode == GESTURE_MODAL_SELECT));
}
else if (!extend) {
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
}
}
@@ -510,7 +506,7 @@ void NODE_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
RNA_def_boolean(ot->srna, "tweak", 0, "Tweak", "Only activate when mouse is not over a node - useful for tweak gesture");
}
@@ -593,11 +589,8 @@ static bool do_lasso_select_node(bContext *C, const int mcords[][2], short moves
BLI_rctf_cent_y(&node->totr)};
/* marker in screen coords */
- UI_view2d_view_to_region(&ar->v2d,
- cent[0], cent[1],
- &screen_co[0], &screen_co[1]);
-
- if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
+ if (UI_view2d_view_to_region_clip(&ar->v2d, cent[0], cent[1], &screen_co[0], &screen_co[1]) &&
+ BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX))
{
nodeSetSelected(node, select);
@@ -672,10 +665,10 @@ static int node_select_all_exec(bContext *C, wmOperator *op)
for (node = node_lb->first; node; node = node->next) {
switch (action) {
case SEL_SELECT:
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(node, true);
break;
case SEL_DESELECT:
- nodeSetSelected(node, FALSE);
+ nodeSetSelected(node, false);
break;
case SEL_INVERT:
nodeSetSelected(node, !(node->flag & SELECT));
@@ -726,7 +719,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST)
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(node, true);
}
ED_node_sort(snode->edittree);
@@ -770,7 +763,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST)
- nodeSetSelected(node, TRUE);
+ nodeSetSelected(node, true);
}
ED_node_sort(snode->edittree);
@@ -985,7 +978,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
- event.customdatafree = FALSE;
+ event.customdatafree = false;
wm_event_add(win, &event);
return block;
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index c75c16e61c5..44639b1295c 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -512,7 +512,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
bNodeTreeType *ntreetype = arg->ntree->typeinfo;
uiBlockSetCurLayout(block, layout);
- split = uiLayoutSplit(layout, 0.0f, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
arg->bmain = bmain;
arg->scene = scene;
@@ -521,7 +521,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
if (ntreetype && ntreetype->foreach_nodeclass)
ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb);
- column = uiLayoutColumn(split, FALSE);
+ column = uiLayoutColumn(split, false);
uiBlockSetCurLayout(block, column);
if (sock->link) {
@@ -588,9 +588,9 @@ static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, b
if (node->typeinfo->draw_buttons) {
if (node->type != NODE_GROUP) {
- split = uiLayoutSplit(layout, 0.35f, FALSE);
- col = uiLayoutColumn(split, FALSE);
- col = uiLayoutColumn(split, FALSE);
+ split = uiLayoutSplit(layout, 0.35f, false);
+ col = uiLayoutColumn(split, false);
+ col = uiLayoutColumn(split, false);
node->typeinfo->draw_buttons(col, C, &nodeptr);
}
@@ -632,9 +632,9 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, IFACE_(input->name));
/* split in label and value */
- split = uiLayoutSplit(layout, 0.35f, FALSE);
+ split = uiLayoutSplit(layout, 0.35f, false);
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
if (depth > 0) {
uiBlockSetEmboss(block, UI_EMBOSSN);
@@ -657,7 +657,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
bt->drawflag = UI_BUT_TEXT_LEFT;
if (dependency_loop) {
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
uiItemL(row, IFACE_("Dependency Loop"), ICON_ERROR);
}
else if (lnode) {
@@ -680,22 +680,22 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
case SOCK_BOOLEAN:
case SOCK_RGBA:
case SOCK_STRING:
- row = uiLayoutRow(split, TRUE);
+ row = uiLayoutRow(split, true);
uiItemR(row, &inputptr, "default_value", 0, "", ICON_NONE);
break;
case SOCK_VECTOR:
- row = uiLayoutRow(split, FALSE);
- col = uiLayoutColumn(row, FALSE);
+ row = uiLayoutRow(split, false);
+ col = uiLayoutColumn(row, false);
uiItemR(col, &inputptr, "default_value", 0, "", ICON_NONE);
break;
default:
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
break;
}
}
else
- row = uiLayoutRow(split, FALSE);
+ row = uiLayoutRow(split, false);
uiTemplateNodeLink(row, ntree, node, input);
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index c93dd7e9e0b..3491ecc86af 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -88,7 +88,7 @@ int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar,
tot++;
if (node->type == NODE_FRAME) {
- has_frame = TRUE;
+ has_frame = true;
}
}
}
@@ -102,7 +102,7 @@ int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar,
/* for single non-frame nodes, don't zoom in, just pan view,
* but do allow zooming out, this allows for big nodes to be zoomed out */
if ((tot == 1) &&
- (has_frame == FALSE) &&
+ (has_frame == false) &&
((oldwidth * oldheight) > (width * height)))
{
/* center, don't zoom */
@@ -411,33 +411,36 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
ImageSampleInfo *info = arg_info;
if (info->draw) {
- ED_image_draw_info(scene, ar, info->color_manage, FALSE, info->channels,
+ ED_image_draw_info(scene, ar, info->color_manage, false, info->channels,
info->x, info->y, info->col, info->colf, info->linearcol,
info->zp, info->zfp);
}
}
-/* returns color in SRGB */
-/* matching ED_space_image_color_sample() */
-int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
+/* Returns color in the display space, matching ED_space_image_color_sample().
+ * And here we've got recursion in the comments tips...
+ */
+bool ED_space_node_color_sample(Scene *scene, SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
{
+ const char *display_device = scene->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
void *lock;
Image *ima;
ImBuf *ibuf;
float fx, fy, bufx, bufy;
- int ret = FALSE;
+ bool ret = false;
if (STREQ(snode->tree_idname, ntreeType_Composite->idname) || (snode->flag & SNODE_BACKDRAW) == 0) {
/* use viewer image for color sampling only if we're in compositor tree
* with backdrop enabled
*/
- return FALSE;
+ return false;
}
ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (!ibuf) {
- return FALSE;
+ return false;
}
/* map the mouse coords to the backdrop image space */
@@ -447,7 +450,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
@@ -457,16 +460,21 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
/* IB_PROFILE_NONE is default but infact its linear */
- linearrgb_to_srgb_v3_v3(r_col, fp);
- ret = TRUE;
+ copy_v3_v3(r_col, fp);
+ ret = true;
}
else if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
- ret = TRUE;
+ IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
+ ret = true;
}
}
+ if (ret) {
+ IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
+ }
+
BKE_image_release_ibuf(ima, ibuf, lock);
return ret;
@@ -500,7 +508,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
fy = (bufy > 0.0f ? ((float)event->mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
@@ -531,7 +539,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
copy_v4_v4(info->linearcol, info->colf);
IMB_colormanagement_colorspace_to_scene_linear_v4(info->linearcol, false, ibuf->rect_colorspace);
- info->color_manage = TRUE;
+ info->color_manage = true;
}
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -541,7 +549,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->colf[2] = fp[2];
info->colf[3] = fp[3];
- info->color_manage = TRUE;
+ info->color_manage = true;
}
if (ibuf->zbuf) {
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ae6e09def57..ddfbe3bebf2 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -42,6 +42,7 @@
#include "BKE_context.h"
#include "BKE_library.h"
+#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_node.h"
@@ -383,11 +384,12 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
}
-static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
+static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
{
/* note, ED_area_tag_refresh will re-execute compositor */
SpaceNode *snode = sa->spacedata.first;
- short shader_type = snode->shaderfrom;
+ /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
+ short shader_type = BKE_scene_use_new_shading_nodes(sc->scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT;
/* preview renders */
switch (wmn->category) {
@@ -399,7 +401,7 @@ static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn
bNodeTreePath *path = snode->treepath.last;
/* shift view to node tree center */
if (ar && path)
- UI_view2d_setcenter(&ar->v2d, path->view_center[0], path->view_center[1]);
+ UI_view2d_center_set(&ar->v2d, path->view_center[0], path->view_center[1]);
ED_area_tag_refresh(sa);
break;
@@ -826,7 +828,7 @@ void ED_spacetype_node(void)
art->draw = node_main_area_draw;
art->listener = node_region_listener;
art->cursor = node_cursor;
- art->event_cursor = TRUE;
+ art->event_cursor = true;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_GPENCIL;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 008e1a83f21..dc3142f954c 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -41,7 +41,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
#include "BLI_mempool.h"
#include "BLF_translation.h"
@@ -486,7 +485,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(bone->name)];
/* always make current object active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
ob = OBACT;
/* restore bone name */
@@ -503,8 +502,10 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
char newname[sizeof(pchan->name)];
/* always make current pose-bone active */
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
ob = OBACT;
+
+ BLI_assert(ob->type == OB_ARMATURE);
/* restore bone name */
BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
@@ -764,10 +765,21 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
if (tselem->type == TSE_RNA_PROPERTY) {
ptr = &te->rnaptr;
prop = te->directdata;
-
- if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops)))) {
- uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
- UI_UNIT_Y - 1);
+
+ if (!TSELEM_OPEN(tselem, soops)) {
+ if (RNA_property_type(prop) == PROP_POINTER) {
+ uiBut *but = uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys,
+ OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
+ uiButSetFlag(but, UI_BUT_DISABLED);
+ }
+ else if (RNA_property_type(prop) == PROP_ENUM) {
+ uiDefAutoButR(block, ptr, prop, -1, NULL, ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
+ else {
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
}
}
else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
@@ -1133,7 +1145,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
case ID_LI:
tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break;
case ID_LS:
- tselem_draw_icon_uibut(&arg, ICON_BRUSH_DATA); break; /* FIXME proper icon */
+ tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break;
}
}
}
@@ -1165,7 +1177,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
active = OL_DRAWSEL_NORMAL;
}
else {
- active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE);
+ active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false);
}
}
else {
@@ -1305,7 +1317,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
active = OL_DRAWSEL_ACTIVE;
}
else {
- if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE)) {
+ if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false)) {
gpuColor4ub(220, 220, 255, alpha);
active = OL_DRAWSEL_ACTIVE;
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 91b8554a789..17e1e032bbf 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -185,7 +185,7 @@ static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *e
float fmval[2];
const bool all = RNA_boolean_get(op->ptr, "all");
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_item_openclose(C, soops, te, all, fmval))
@@ -275,7 +275,7 @@ static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), const wmEve
float fmval[2];
bool changed = false;
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_item_rename(C, ar, soops, te, fmval)) {
@@ -1657,7 +1657,7 @@ static int outliner_parenting_poll(bContext *C)
return ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS);
}
- return FALSE;
+ return false;
}
static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index b1278c7cc07..317d33dd3e2 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -180,9 +180,8 @@ void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
eOLDrawState tree_element_type_active(
struct bContext *C, struct Scene *scene, struct SpaceOops *soops,
TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive);
-eOLDrawState tree_element_active(
- struct bContext *C, struct Scene *scene, SpaceOops *soops,
- TreeElement *te, const eOLSetState set);
+eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops,
+ TreeElement *te, const eOLSetState set, const bool handle_all_types);
int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
/* outliner_edit.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index b9e3942a7ce..d735b5e75cf 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -88,28 +88,28 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0);
- RNA_boolean_set(kmi->ptr, "recursive", FALSE);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "recursive", false);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "recursive", FALSE);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "recursive", false);
+ RNA_boolean_set(kmi->ptr, "extend", true);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "recursive", TRUE);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "recursive", true);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "recursive", TRUE);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "recursive", true);
+ RNA_boolean_set(kmi->ptr, "extend", true);
WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "all", FALSE);
+ RNA_boolean_set(kmi->ptr, "all", false);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "all", TRUE);
+ RNA_boolean_set(kmi->ptr, "all", true);
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_operation", RIGHTMOUSE, KM_PRESS, 0, 0);
@@ -121,11 +121,11 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEDOWNKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEUPKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "up", TRUE);
+ RNA_boolean_set(kmi->ptr, "up", true);
WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADPLUSKEY, KM_PRESS, 0, 0); /* open */
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADMINUS, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "open", FALSE); /* close */
+ RNA_boolean_set(kmi->ptr, "open", false); /* close */
WM_keymap_verify_item(keymap, "OUTLINER_OT_selected_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_expanded_toggle", AKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 688695e3ded..d7521edd57a 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -31,8 +31,6 @@
#include <stdlib.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_armature_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
@@ -47,7 +45,6 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
@@ -618,19 +615,19 @@ static eOLDrawState tree_element_active_ebone(
if (set == OL_SETSEL_NORMAL) {
if (!(ebone->flag & BONE_HIDDEN_A)) {
ED_armature_deselect_all(scene->obedit, 0); // deselect
- tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
+ tree_element_active_ebone__sel(C, scene, arm, ebone, true);
status = OL_DRAWSEL_NORMAL;
}
}
else if (set == OL_SETSEL_EXTEND) {
if (!(ebone->flag & BONE_HIDDEN_A)) {
if (!(ebone->flag & BONE_SELECTED)) {
- tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
+ tree_element_active_ebone__sel(C, scene, arm, ebone, true);
status = OL_DRAWSEL_NORMAL;
}
else {
/* entirely selected, so de-select */
- tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE);
+ tree_element_active_ebone__sel(C, scene, arm, ebone, false);
status = OL_DRAWSEL_NONE;
}
}
@@ -724,7 +721,7 @@ static eOLDrawState tree_element_active_sequence(
bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
{
Sequence *seq = (Sequence *) te->directdata;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (set != OL_SETSEL_NONE) {
/* only check on setting */
@@ -757,7 +754,7 @@ static eOLDrawState tree_element_active_sequence_dup(
Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
{
Sequence *seq, *p;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
seq = (Sequence *)te->directdata;
if (set == OL_SETSEL_NONE) {
@@ -801,14 +798,17 @@ static eOLDrawState tree_element_active_keymap_item(
/* ---------------------------------------------- */
/* generic call for ID data check or make/check active in UI */
-eOLDrawState tree_element_active(
- bContext *C, Scene *scene, SpaceOops *soops,
- TreeElement *te, const eOLSetState set)
+eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te,
+ const eOLSetState set, const bool handle_all_types)
{
-
switch (te->idcode) {
- /* Note: no ID_OB: objects are handled specially to allow multiple
+ /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple
* selection. See do_outliner_item_activate. */
+ case ID_OB:
+ if (handle_all_types) {
+ return tree_element_set_active_object(C, scene, soops, te, set, false);
+ }
+ break;
case ID_MA:
return tree_element_active_material(C, scene, soops, te, set);
case ID_WO:
@@ -952,7 +952,7 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp
WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
}
else { // rest of types
- tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+ tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false);
}
}
@@ -982,7 +982,7 @@ int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recur
TreeElement *te;
float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, x, y, fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, x, y, &fmval[0], &fmval[1]);
if (!ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF) &&
!(soops->flag & SO_HIDE_RESTRICTCOLS) &&
@@ -1076,14 +1076,11 @@ static int outliner_border_select_exec(bContext *C, wmOperator *op)
SpaceOops *soops = CTX_wm_space_outliner(C);
ARegion *ar = CTX_wm_region(C);
TreeElement *te;
- rcti rect;
rctf rectf;
int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
- WM_operator_properties_border_to_rcti(op, &rect);
-
- UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+ WM_operator_properties_border_to_rctf(op, &rectf);
+ UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
for (te = soops->tree.first; te; te = te->next) {
outliner_item_border_select(scene, soops, &rectf, te, gesture_mode);
@@ -1114,7 +1111,7 @@ void OUTLINER_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, FALSE);
+ WM_operator_properties_gesture_border(ot, false);
}
/* ****************************************************** */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index cdc7178e767..8f5e2ad3693 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -35,6 +35,7 @@
#include "DNA_armature_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
@@ -45,7 +46,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
@@ -57,7 +57,6 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
-#include "BKE_treehash.h"
#include "ED_armature.h"
#include "ED_object.h"
@@ -193,6 +192,10 @@ static void unlink_texture_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEle
World *wrld = (World *)tsep->id;
mtex = wrld->mtex;
}
+ else if (GS(tsep->id->name) == ID_LS) {
+ FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id;
+ mtex = ls->mtex;
+ }
else {
return;
}
@@ -419,7 +422,7 @@ static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te)
{
Group *group = (Group *)tselem->id;
- Object *ob = ED_object_add_type(C, OB_EMPTY, scene->cursor, NULL, FALSE, scene->layact);
+ Object *ob = ED_object_add_type(C, OB_EMPTY, scene->cursor, NULL, false, scene->layact);
rename_id(&ob->id, group->id.name + 2);
ob->dup_group = group;
ob->transflag |= OB_DUPLIGROUP;
@@ -1064,6 +1067,7 @@ void OUTLINER_OT_action_set(wmOperatorType *ot)
// TODO: this would be nicer as an ID-pointer...
prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
RNA_def_enum_funcs(prop, RNA_action_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -1345,7 +1349,7 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent
TreeElement *te;
float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) {
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 4231dc6f9f8..520cd9a544d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -54,8 +54,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_math.h"
-#include "BLI_ghash.h"
#include "BLI_mempool.h"
#include "BLI_fnmatch.h"
@@ -79,6 +77,10 @@
#include "outliner_intern.h"
+#ifdef WIN32
+# include "BLI_math_base.h" /* M_PI */
+#endif
+
/* ********************************************************* */
/* Persistent Data */
@@ -377,6 +379,7 @@ static bool outliner_animdata_test(AnimData *adt)
return false;
}
+#ifdef WITH_FREESTYLE
static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te)
{
SceneRenderLayer *srl;
@@ -402,6 +405,7 @@ static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce,
}
}
}
+#endif
static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te)
{
@@ -429,8 +433,10 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
outliner_add_element(soops, lb, sce->world, te, 0, 0);
+#ifdef WITH_FREESTYLE
if (STREQ(sce->r.engine, "BLENDER_RENDER") && (sce->r.mode & R_EDGE_FRS))
outliner_add_line_styles(soops, lb, sce, te);
+#endif
}
// can be inlined if necessary
@@ -792,9 +798,15 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_LS:
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
+ int a;
if (outliner_animdata_test(linestyle->adt))
outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a])
+ outliner_add_element(soops, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
+ }
break;
}
}
@@ -1402,7 +1414,7 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
TreeElement *te, *ten;
TreeStoreElem *tselem;
- /* although we don't have any search string, we return TRUE
+ /* although we don't have any search string, we return true
* since the entire tree is ok then...
*/
if (soops->search_string[0] == 0)
@@ -1630,7 +1642,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
}
else if (soops->outlinevis == SO_SEQUENCE) {
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
int op;
if (ed == NULL)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 3c8489b5f49..57dc0c83ffb 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -35,10 +35,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_mempool.h"
-#include "BLI_ghash.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -146,7 +144,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if (!ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS)) {
- return FALSE;
+ return false;
}
if (drag->type == WM_DRAG_ID) {
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index 5754af2c83c..9077d0cf8ed 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -83,6 +83,8 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot)
ot->exec = run_pyfile_exec;
ot->poll = ED_operator_areaactive;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "Path", "");
}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 156df05c03d..8fe9dbe3eb9 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -27,18 +27,10 @@
* \ingroup spseq
*/
-
#include <stdlib.h>
#include <math.h>
#include <string.h>
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include <sys/types.h>
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -47,13 +39,11 @@
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
-#include "DNA_userdef_types.h"
#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_movieclip.h"
@@ -130,7 +120,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
Sequence *tgt = NULL;
Sequence *seq;
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
int cfra = (int) CFRA;
int proximity = INT_MAX;
@@ -240,7 +230,7 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op)
static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
Scene *sce_seq;
@@ -284,7 +274,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
seq->flag |= SELECT;
}
- if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if (RNA_boolean_get(op->ptr, "overlap") == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -296,11 +286,6 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
if (!RNA_struct_property_is_set(op->ptr, "scene"))
return WM_enum_search_invoke(C, op, event);
@@ -324,7 +309,7 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_scene_strip_invoke;
ot->exec = sequencer_add_scene_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -332,6 +317,7 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
RNA_def_enum_funcs(prop, RNA_scene_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -339,7 +325,7 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
MovieClip *clip;
@@ -383,7 +369,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
seq->flag |= SELECT;
}
- if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if (RNA_boolean_get(op->ptr, "overlap") == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -394,11 +380,6 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
if (!RNA_struct_property_is_set(op->ptr, "clip"))
return WM_enum_search_invoke(C, op, event);
@@ -421,7 +402,7 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_movieclip_strip_invoke;
ot->exec = sequencer_add_movieclip_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -429,14 +410,14 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", "");
RNA_def_enum_funcs(prop, RNA_movieclip_itemf);
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
Mask *mask;
@@ -480,7 +461,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
seq->flag |= SELECT;
}
- if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if (RNA_boolean_get(op->ptr, "overlap") == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -491,11 +472,6 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
if (!RNA_struct_property_is_set(op->ptr, "mask"))
return WM_enum_search_invoke(C, op, event);
@@ -519,7 +495,7 @@ void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_mask_strip_invoke;
ot->exec = sequencer_add_mask_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -527,6 +503,7 @@ void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot)
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "mask", DummyRNA_NULL_items, 0, "Mask", "");
RNA_def_enum_funcs(prop, RNA_mask_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
@@ -534,11 +511,11 @@ void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot)
static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func)
{
Scene *scene = CTX_data_scene(C); /* only for sound */
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
SeqLoadInfo seq_load;
Sequence *seq;
int tot_files;
- const short overlap = RNA_boolean_get(op->ptr, "overlap");
+ const bool overlap = RNA_boolean_get(op->ptr, "overlap");
seq_load_operator_info(&seq_load, op);
@@ -567,7 +544,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
seq = seq_load_func(C, ed->seqbasep, &seq_load);
if (seq) {
- if (overlap == FALSE) {
+ if (overlap == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq))
BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -579,7 +556,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
/* single file */
seq = seq_load_func(C, ed->seqbasep, &seq_load);
if (seq) {
- if (overlap == FALSE) {
+ if (overlap == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq))
BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -608,12 +585,6 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
-
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
/* This is for drag and drop */
if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
RNA_struct_property_is_set(op->ptr, "filepath"))
@@ -643,7 +614,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_movie_strip_invoke;
ot->exec = sequencer_add_movie_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -651,7 +622,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
- RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
+ RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie");
}
/* add sound operator */
@@ -663,12 +634,6 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
-
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
/* This is for drag and drop */
if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
RNA_struct_property_is_set(op->ptr, "filepath"))
@@ -698,7 +663,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_sound_strip_invoke;
ot->exec = sequencer_add_sound_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -706,7 +671,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
- RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
+ RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
}
/* add image operator */
@@ -715,7 +680,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* cant use the generic function for this */
Scene *scene = CTX_data_scene(C); /* only for sound */
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
SeqLoadInfo seq_load;
Sequence *seq;
@@ -763,7 +728,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* last active name */
BLI_strncpy(ed->act_imagedir, strip->dir, sizeof(ed->act_imagedir));
- if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if (RNA_boolean_get(op->ptr, "overlap") == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq))
BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -775,13 +740,6 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
-
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
-
/* drag drop has set the names */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_ENDFRAME | SEQPROP_NOPATHS, SEQ_TYPE_IMAGE);
@@ -807,7 +765,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_image_strip_invoke;
ot->exec = sequencer_add_image_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -822,7 +780,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+ Editing *ed = BKE_sequencer_editing_get(scene, true);
Sequence *seq; /* generic strip vars */
Strip *strip;
@@ -901,7 +859,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
}
}
- if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if (RNA_boolean_get(op->ptr, "overlap") == false) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
@@ -927,15 +885,10 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
/* add color */
static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- short is_type_set = RNA_struct_property_is_set(op->ptr, "type");
+ bool is_type_set = RNA_struct_property_is_set(op->ptr, "type");
int type = -1;
int prop_flag = SEQPROP_ENDFRAME;
- if (!ED_operator_sequencer_active(C)) {
- BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
- return OPERATOR_CANCELLED;
- }
-
if (is_type_set) {
type = RNA_enum_get(op->ptr, "type");
@@ -964,7 +917,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
ot->invoke = sequencer_add_effect_strip_invoke;
ot->exec = sequencer_add_effect_strip_exec;
- ot->poll = ED_operator_scene_editable;
+ ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 0643e1c5697..df12d58d0a2 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -32,7 +32,6 @@
/* my library */
-#include "ED_anim_api.h"
#include "ED_gpencil.h"
#include "ED_markers.h"
#include "ED_mask.h"
@@ -52,7 +51,6 @@
#include "BKE_global.h"
#include "BKE_sequencer.h"
#include "BKE_sound.h"
-
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -80,7 +78,6 @@
#include "MEM_guardedalloc.h"
#include "WM_api.h"
-#include "WM_types.h"
/* standard */
#include <string.h>
@@ -356,7 +353,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
{
float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
float x1, x2, y1, y2;
- char numstr[32];
unsigned int whichsel = 0;
x1 = seq->startdisp;
@@ -428,17 +424,20 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
if ((G.moving & G_TRANSFORM_SEQ) || (seq->flag & whichsel)) {
const char col[4] = {255, 255, 255, 255};
+ char numstr[32];
+ size_t numstr_len;
+
if (direction == SEQ_LEFTHANDLE) {
- BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp);
x1 = rx1;
y1 -= 0.45f;
}
else {
- BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
x1 = x2 - handsize_clamped * 0.75f;
y1 = y2 + 0.05f;
}
- UI_view2d_text_cache_add(v2d, x1, y1, numstr, col);
+ UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
}
}
@@ -559,6 +558,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
{
rctf rect;
char str[32 + FILE_MAX];
+ size_t str_len;
const char *name = seq->name + 2;
char col[4];
@@ -567,67 +567,76 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
name = BKE_sequence_give_name(seq);
if (seq->type == SEQ_TYPE_META || seq->type == SEQ_TYPE_ADJUSTMENT) {
- BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len);
}
else if (seq->type == SEQ_TYPE_SCENE) {
if (seq->scene) {
if (seq->scene_camera) {
- BLI_snprintf(str, sizeof(str), "%s: %s (%s) | %d",
- name, seq->scene->id.name + 2, ((ID *)seq->scene_camera)->name + 2, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s (%s) | %d",
+ name, seq->scene->id.name + 2, ((ID *)seq->scene_camera)->name + 2, seq->len);
}
else {
- BLI_snprintf(str, sizeof(str), "%s: %s | %d",
- name, seq->scene->id.name + 2, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
+ name, seq->scene->id.name + 2, seq->len);
}
}
else {
- BLI_snprintf(str, sizeof(str), "%s | %d",
- name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
}
}
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) {
- BLI_snprintf(str, sizeof(str), "%s: %s | %d",
- name, seq->clip->id.name + 2, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
+ name, seq->clip->id.name + 2, seq->len);
}
else {
- BLI_snprintf(str, sizeof(str), "%s | %d",
- name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
}
}
else if (seq->type == SEQ_TYPE_MASK) {
if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) {
- BLI_snprintf(str, sizeof(str), "%s: %s | %d",
- name, seq->mask->id.name + 2, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
+ name, seq->mask->id.name + 2, seq->len);
}
else {
- BLI_snprintf(str, sizeof(str), "%s | %d",
- name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
}
}
else if (seq->type == SEQ_TYPE_MULTICAM) {
- BLI_snprintf(str, sizeof(str), "Cam %s: %d",
- name, seq->multicam_source);
+ str_len = BLI_snprintf(str, sizeof(str), "Cam %s: %d",
+ name, seq->multicam_source);
}
else if (seq->type == SEQ_TYPE_IMAGE) {
- BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
- name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
+ name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
}
else if (seq->type & SEQ_TYPE_EFFECT) {
- BLI_snprintf(str, sizeof(str), "%s | %d",
- name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
}
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
- if (seq->sound)
- BLI_snprintf(str, sizeof(str), "%s: %s | %d",
- name, seq->sound->name, seq->len);
- else
- BLI_snprintf(str, sizeof(str), "%s | %d",
- name, seq->len);
+ if (seq->sound) {
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
+ name, seq->sound->name, seq->len);
+ }
+ else {
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
+ }
}
else if (seq->type == SEQ_TYPE_MOVIE) {
- BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
- name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
+ str_len = BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
+ name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
+ }
+ else {
+ /* should never get here!, but might with files from future */
+ BLI_assert(0);
+
+ str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
+ name, seq->len);
}
if (seq->flag & SELECT) {
@@ -645,7 +654,8 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
rect.ymin = y1;
rect.xmax = x2;
rect.ymax = y2;
- UI_view2d_text_cache_rectf(v2d, &rect, str, col);
+
+ UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
/* draws a shaded strip, made from gradient + flat color + gradient */
@@ -738,8 +748,8 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
/* draw the main strip body */
if (is_single_image) { /* single image */
draw_shadedstrip(seq, background_col,
- BKE_sequence_tx_get_final_left(seq, 0), y1,
- BKE_sequence_tx_get_final_right(seq, 0), y2);
+ BKE_sequence_tx_get_final_left(seq, false), y1,
+ BKE_sequence_tx_get_final_right(seq, false), y2);
}
else { /* normal operation */
draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
@@ -894,7 +904,7 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
/* sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
* by Esc pressed somewhere in the past
*/
- G.is_break = FALSE;
+ G.is_break = false;
if (special_seq_update)
ibuf = BKE_sequencer_give_ibuf_direct(&context, cfra + frame_ofs, special_seq_update);
@@ -954,7 +964,7 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
return scope;
}
-void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, int draw_overlay)
+void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay)
{
struct Main *bmain = CTX_data_main(C);
struct ImBuf *ibuf = NULL;
@@ -968,11 +978,11 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
GLuint texid;
void *display_buffer;
void *cache_handle = NULL;
- const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
+ const bool is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
int format, type;
bool glsl_used = false;
- if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
+ if (G.is_rendering == false && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
@@ -1334,7 +1344,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
0, 0, 0, /* TODO */
width, height,
aspx, aspy,
- FALSE, TRUE,
+ false, true,
NULL, C);
}
}
@@ -1486,7 +1496,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
void draw_timeline_seq(const bContext *C, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
SpaceSeq *sseq = CTX_wm_space_seq(C);
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 92d8a0ae066..50efa881b39 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1,5 +1,5 @@
/*
- * ***** BEGIN 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
@@ -32,24 +32,15 @@
#include <math.h>
#include <string.h>
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include <sys/types.h>
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_threads.h"
#include "BLF_translation.h"
#include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -57,7 +48,6 @@
#include "BKE_sequencer.h"
#include "BKE_report.h"
#include "BKE_sound.h"
-#include "BKE_movieclip.h"
#include "IMB_imbuf.h"
@@ -165,14 +155,14 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
static void proxy_endjob(void *pjv)
{
ProxyJob *pj = pjv;
- Editing *ed = BKE_sequencer_editing_get(pj->scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(pj->scene, false);
LinkData *link;
for (link = pj->queue.first; link; link = link->next) {
BKE_sequencer_proxy_rebuild_finish(link->data, pj->stop);
}
- BKE_sequencer_free_imbuf(pj->scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(pj->scene, &ed->seqbase, false);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
}
@@ -182,7 +172,7 @@ static void seq_proxy_build_job(const bContext *C)
wmJob *wm_job;
ProxyJob *pj;
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ScrArea *sa = CTX_wm_area(C);
struct SeqIndexBuildContext *context;
LinkData *link;
@@ -215,11 +205,11 @@ static void seq_proxy_build_job(const bContext *C)
SEQ_END
if (!WM_jobs_is_running(wm_job)) {
- G.is_break = FALSE;
+ G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(sa);
}
/* ********************************************************************** */
@@ -237,7 +227,7 @@ void seq_rectf(Sequence *seq, rctf *rectf)
void boundbox_seq(Scene *scene, rctf *rect)
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
float min[2], max[2];
@@ -284,7 +274,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se
{
/* sel - 0==unselected, 1==selected, -1==done care*/
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL) return NULL;
@@ -316,7 +306,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
{
/* sel - 0==unselected, 1==selected, -1==done care*/
Sequence *seq, *best_seq = NULL;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
int dist, best_dist;
best_dist = MAXFRAME * 2;
@@ -364,7 +354,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2])
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
float x, y;
float pixelx;
float handsize;
@@ -439,7 +429,7 @@ static bool seq_is_predecessor(Sequence *pred, Sequence *seq)
void ED_sequencer_deselect_all(Scene *scene)
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL) return;
@@ -481,7 +471,7 @@ bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene)
return (BKE_sequencer_mask_get(scene) != NULL);
}
- return FALSE;
+ return false;
}
int ED_space_sequencer_maskedit_poll(bContext *C)
@@ -493,7 +483,7 @@ int ED_space_sequencer_maskedit_poll(bContext *C)
return ED_space_sequencer_check_show_maskedit(sseq, scene);
}
- return FALSE;
+ return false;
}
/* are we displaying the seq output (not channels or histogram)*/
@@ -505,7 +495,7 @@ bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
*error_str = NULL;
@@ -614,6 +604,26 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
return seq;
}
+static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence)
+{
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *current_sequence;
+
+ SEQP_BEGIN(ed, current_sequence)
+ {
+ if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) {
+ SequenceModifierData *smd;
+
+ for (smd = current_sequence->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence == deleting_sequence) {
+ smd->mask_sequence = NULL;
+ }
+ }
+ }
+ }
+ SEQ_END
+}
+
static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
{
Sequence *seq, *seqn;
@@ -637,7 +647,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
{
TransSeq ts;
Sequence *seqn = NULL;
- int skip_dup = FALSE;
+ bool skip_dup = false;
/* backup values */
ts.start = seq->start;
@@ -658,7 +668,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
if ((seq->startstill) && (cutframe < seq->start)) {
/* don't do funny things with METAs ... */
if (seq->type == SEQ_TYPE_META) {
- skip_dup = TRUE;
+ skip_dup = true;
seq->startstill = seq->start - cutframe;
}
else {
@@ -679,11 +689,11 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
seq->endstill -= seq->enddisp - cutframe;
/* don't do funny things with METAs ... */
if (seq->type == SEQ_TYPE_META) {
- skip_dup = TRUE;
+ skip_dup = true;
}
}
- BKE_sequence_reload_new_file(scene, seq, FALSE);
+ BKE_sequence_reload_new_file(scene, seq, false);
BKE_sequence_calc(scene, seq);
if (!skip_dup) {
@@ -723,7 +733,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
seqn->startstill = 0;
}
- BKE_sequence_reload_new_file(scene, seqn, FALSE);
+ BKE_sequence_reload_new_file(scene, seqn, false);
BKE_sequence_calc(scene, seqn);
}
return seqn;
@@ -733,7 +743,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
{
TransSeq ts;
Sequence *seqn = NULL;
- int skip_dup = FALSE;
+ bool skip_dup = false;
/* backup values */
ts.start = seq->start;
@@ -754,7 +764,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
if ((seq->startstill) && (cutframe < seq->start)) {
/* don't do funny things with METAs ... */
if (seq->type == SEQ_TYPE_META) {
- skip_dup = TRUE;
+ skip_dup = true;
seq->startstill = seq->start - cutframe;
}
else {
@@ -773,7 +783,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
seq->endstill -= seq->enddisp - cutframe;
/* don't do funny things with METAs ... */
if (seq->type == SEQ_TYPE_META) {
- skip_dup = TRUE;
+ skip_dup = true;
}
}
@@ -871,7 +881,7 @@ static bool cut_seq_list(Scene *scene, ListBase *slist, int cutframe,
static bool sequence_offset_after_frame(Scene *scene, const int delta, const int cfra)
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
bool done = false;
/* all strips >= cfra are shifted */
@@ -892,7 +902,7 @@ static bool sequence_offset_after_frame(Scene *scene, const int delta, const int
static void UNUSED_FUNCTION(touch_seq_files) (Scene *scene)
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
char str[256];
/* touch all strips with movies */
@@ -924,7 +934,7 @@ static void UNUSED_FUNCTION(touch_seq_files) (Scene *scene)
static void set_filter_seq(Scene *scene)
{
Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL) return;
@@ -936,7 +946,7 @@ static void set_filter_seq(Scene *scene)
if (seq->flag & SELECT) {
if (seq->type == SEQ_TYPE_MOVIE) {
seq->flag |= SEQ_FILTERY;
- reload_sequence_new_file(scene, seq, FALSE);
+ BKE_sequence_reload_new_file(scene, seq, false);
BKE_sequence_calc(scene, seq);
}
@@ -949,7 +959,7 @@ static void set_filter_seq(Scene *scene)
static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
{
Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
@@ -1100,14 +1110,14 @@ static int seq_get_snaplimit(View2D *v2d)
/* Operator functions */
int sequencer_edit_poll(bContext *C)
{
- return (BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL);
+ return (BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL);
}
#if 0 /* UNUSED */
int sequencer_strip_poll(bContext *C)
{
Editing *ed;
- return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE)) != NULL) && (ed->act_seq != NULL));
+ return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && (ed->act_seq != NULL));
}
#endif
@@ -1115,13 +1125,13 @@ int sequencer_strip_has_path_poll(bContext *C)
{
Editing *ed;
Sequence *seq;
- return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
+ return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
}
int sequencer_view_poll(bContext *C)
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
- Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE);
+ Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false);
if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF))
return 1;
@@ -1133,7 +1143,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
int snap_frame;
@@ -1224,9 +1234,9 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot)
static int sequencer_mute_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
- int selected;
+ bool selected;
selected = !RNA_boolean_get(op->ptr, "unselected");
@@ -1275,9 +1285,9 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot)
static int sequencer_unmute_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
- int selected;
+ bool selected;
selected = !RNA_boolean_get(op->ptr, "unselected");
@@ -1326,7 +1336,7 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -1359,7 +1369,7 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot)
static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -1392,7 +1402,7 @@ void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
static int sequencer_reload_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
@@ -1438,9 +1448,9 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot)
static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
- BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1492,7 +1502,7 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
static int sequencer_effect_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *last_seq = BKE_sequencer_active_get(scene);
@@ -1566,7 +1576,7 @@ static EnumPropertyItem prop_cut_types[] = {
static int sequencer_cut_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
int cut_side, cut_hard, cut_frame;
bool changed;
@@ -1679,7 +1689,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt)
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase nseqbase = {NULL, NULL};
@@ -1725,19 +1735,19 @@ void SEQUENCER_OT_duplicate(wmOperatorType *ot)
static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
MetaStack *ms;
- int nothingSelected = TRUE;
+ bool nothingSelected = true;
seq = BKE_sequencer_active_get(scene);
if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
- nothingSelected = FALSE;
+ nothingSelected = false;
}
else {
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- nothingSelected = FALSE;
+ nothingSelected = false;
break;
}
}
@@ -1746,10 +1756,17 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
if (nothingSelected)
return OPERATOR_FINISHED;
- /* for effects, try to find a replacement input */
- for (seq = ed->seqbasep->first; seq; seq = seq->next)
- if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SELECT))
- del_seq_find_replace_recurs(scene, seq);
+ /* for effects and modifiers, try to find a replacement input */
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ if (!(seq->flag & SELECT)) {
+ if ((seq->type & SEQ_TYPE_EFFECT)) {
+ del_seq_find_replace_recurs(scene, seq);
+ }
+ }
+ else {
+ del_seq_clear_modifiers_recurs(scene, seq);
+ }
+ }
/* delete all selected strips */
recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
@@ -1810,7 +1827,7 @@ void SEQUENCER_OT_delete(wmOperatorType *ot)
static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
/* for effects, try to find a replacement input */
@@ -1862,7 +1879,7 @@ void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seq_new;
Strip *strip_new;
@@ -1874,14 +1891,16 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
while (seq) {
if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
+ Sequence *seq_next;
+
/* remove seq so overlap tests don't conflict,
* see seq_free_sequence below for the real free'ing */
BLI_remlink(ed->seqbasep, seq);
/* if (seq->ipo) seq->ipo->id.us--; */
/* XXX, remove fcurve and assign to split image strips */
- start_ofs = cfra = BKE_sequence_tx_get_final_left(seq, 0);
- frame_end = BKE_sequence_tx_get_final_right(seq, 0);
+ start_ofs = cfra = BKE_sequence_tx_get_final_left(seq, false);
+ frame_end = BKE_sequence_tx_get_final_right(seq, false);
while (cfra < frame_end) {
/* new seq */
@@ -1917,8 +1936,9 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
start_ofs += step;
}
+ seq_next = seq->next;
BKE_sequence_free(scene, seq);
- seq = seq->next;
+ seq = seq_next;
}
else {
seq = seq->next;
@@ -1959,7 +1979,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *last_seq = BKE_sequencer_active_get(scene);
MetaStack *ms;
@@ -2030,12 +2050,12 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
int channel_max = 1;
- if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == FALSE) {
+ if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
return OPERATOR_CANCELLED;
}
@@ -2105,7 +2125,7 @@ static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */
@@ -2266,7 +2286,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
float facx = BLI_rcti_size_x(&v2d->mask) / winx;
float facy = BLI_rcti_size_y(&v2d->mask) / winy;
- BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1);
+ BLI_rctf_resize(&v2d->cur, floorf(winx * facx / ratio + 0.5f), floorf(winy * facy / ratio + 0.5f));
ED_region_tag_redraw(CTX_wm_region(C));
@@ -2334,7 +2354,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
ARegion *ar = CTX_wm_region(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *last_seq = BKE_sequencer_active_get(scene);
Sequence *seq;
rctf cur_new = v2d->cur;
@@ -2415,7 +2435,7 @@ static int find_next_prev_edit(Scene *scene, int cfra,
const short side,
const bool do_skip_mute, const bool do_center)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *best_seq = NULL, *frame_seq = NULL;
int dist, best_dist;
@@ -2517,8 +2537,8 @@ static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
const bool next = RNA_boolean_get(op->ptr, "next");
const bool center = RNA_boolean_get(op->ptr, "center");
- /* currently do_skip_mute is always TRUE */
- if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, TRUE, center)) {
+ /* currently do_skip_mute is always true */
+ if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) {
return OPERATOR_CANCELLED;
}
@@ -2542,8 +2562,8 @@ void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "next", TRUE, "Next Strip", "");
- RNA_def_boolean(ot->srna, "center", TRUE, "Use strip center", "");
+ RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
+ RNA_def_boolean(ot->srna, "center", true, "Use strip center", "");
}
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
@@ -2564,7 +2584,7 @@ static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
#if 0
static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *parent = NULL;
Sequence *seq;
@@ -2584,7 +2604,7 @@ static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
static int sequencer_swap_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *active_seq = BKE_sequencer_active_get(scene);
Sequence *seq, *iseq;
int side = RNA_enum_get(op->ptr, "side");
@@ -2732,13 +2752,13 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq)
static int sequencer_copy_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase nseqbase = {NULL, NULL};
BKE_sequencer_free_clipboard();
- if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == FALSE) {
+ if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
return OPERATOR_CANCELLED;
}
@@ -2804,7 +2824,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, TRUE); /* create if needed */
+ Editing *ed = BKE_sequencer_editing_get(scene, true); /* create if needed */
ListBase nseqbase = {NULL, NULL};
int ofs;
Sequence *iseq, *iseq_first;
@@ -2925,17 +2945,13 @@ void SEQUENCER_OT_swap_data(wmOperatorType *ot)
static int view_ghost_border_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
View2D *v2d = UI_view2d_fromcontext(C);
rctf rect;
/* convert coordinates of rect to 'tot' rect coordinates */
- UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmin"), RNA_int_get(op->ptr, "ymin"), &rect.xmin, &rect.ymin);
- UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmax"), RNA_int_get(op->ptr, "ymax"), &rect.xmax, &rect.ymax);
-
- if (ed == NULL)
- return OPERATOR_CANCELLED;
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
rect.xmin /= fabsf(BLI_rctf_size_x(&v2d->tot));
rect.ymin /= fabsf(BLI_rctf_size_y(&v2d->tot));
@@ -2979,7 +2995,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
ot->flag = 0;
/* rna */
- WM_operator_properties_gesture_border(ot, FALSE);
+ WM_operator_properties_gesture_border(ot, false);
}
/* rebuild_proxy operator */
@@ -3017,7 +3033,7 @@ static EnumPropertyItem prop_change_effect_input_types[] = {
static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = BKE_sequencer_active_get(scene);
Sequence **seq_1, **seq_2;
@@ -3048,7 +3064,7 @@ static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
/* important else we don't get the imbuf cache flushed */
- BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -3075,7 +3091,7 @@ void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot)
static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = BKE_sequencer_active_get(scene);
const int new_type = RNA_enum_get(op->ptr, "type");
@@ -3108,7 +3124,7 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
/* important else we don't get the imbuf cache flushed */
- BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -3136,9 +3152,9 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = BKE_sequencer_active_get(scene);
- const int is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
+ const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
if (seq->type == SEQ_TYPE_IMAGE) {
char directory[FILE_MAX];
@@ -3176,12 +3192,12 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
/* correct start/end frames so we don't move
* important not to set seq->len = len; allow the function to handle it */
- BKE_sequence_reload_new_file(scene, seq, TRUE);
+ BKE_sequence_reload_new_file(scene, seq, true);
BKE_sequence_calc(scene, seq);
/* important else we don't get the imbuf cache flushed */
- BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
}
else {
/* lame, set rna filepath */
@@ -3215,10 +3231,10 @@ static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEve
/* set default display depending on seq type */
if (seq->type == SEQ_TYPE_IMAGE) {
- RNA_boolean_set(op->ptr, "filter_movie", FALSE);
+ RNA_boolean_set(op->ptr, "filter_movie", false);
}
else {
- RNA_boolean_set(op->ptr, "filter_image", FALSE);
+ RNA_boolean_set(op->ptr, "filter_image", false);
}
WM_event_add_fileselect(C, op);
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index a0212bd17fa..60fc300da1f 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -52,7 +52,7 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
/* sequencer_draw.c */
void draw_timeline_seq(const struct bContext *C, struct ARegion *ar);
-void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, int draw_overlay);
+void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay);
/* UNUSED */
// void seq_reset_imageofs(struct SpaceSeq *sseq);
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index 9850c7c3493..ff40bf1e638 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -65,7 +65,7 @@
static int strip_modifier_active_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq = BKE_sequencer_active_get(scene);
@@ -74,7 +74,7 @@ static int strip_modifier_active_poll(bContext *C)
return BKE_sequence_supports_modifiers(seq);
}
- return FALSE;
+ return false;
}
static int strip_modifier_add_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 8229b89fb94..e69a02aa3df 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -28,18 +28,11 @@
* \ingroup spseq
*/
-
#include <stdlib.h>
#include <math.h>
-
#include "DNA_space_types.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-
-
-
#include "WM_api.h"
#include "WM_types.h"
@@ -160,14 +153,14 @@ void sequencer_keymap(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "type", SEQ_CUT_HARD);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_lock", LKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_unlock", LKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
@@ -176,7 +169,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SEQUENCER_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_reload", RKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "adjust_length", TRUE);
+ RNA_boolean_set(kmi->ptr, "adjust_length", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_offset_clear", OKEY, KM_PRESS, KM_ALT, 0);
@@ -200,28 +193,29 @@ void sequencer_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_separate", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_strip_jump", PAGEUPKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", TRUE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
+ RNA_boolean_set(kmi->ptr, "next", true);
+ RNA_boolean_set(kmi->ptr, "center", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_strip_jump", PAGEDOWNKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "next", FALSE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
+ RNA_boolean_set(kmi->ptr, "next", false);
+ RNA_boolean_set(kmi->ptr, "center", false);
/* alt for center */
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_strip_jump", PAGEUPKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "next", TRUE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
+ RNA_boolean_set(kmi->ptr, "next", true);
+ RNA_boolean_set(kmi->ptr, "center", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_strip_jump", PAGEDOWNKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "next", FALSE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
+ RNA_boolean_set(kmi->ptr, "next", false);
+ RNA_boolean_set(kmi->ptr, "center", true);
RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_swap", LEFTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "side", SEQ_SIDE_LEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_swap", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "side", SEQ_SIDE_RIGHT);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "all", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "all", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "all", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "all", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_insert", EQUALKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
@@ -241,76 +235,76 @@ void sequencer_keymap(wmKeyConfig *keyconf)
/* Mouse selection, a bit verbose :/ */
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_handle", FALSE);
- RNA_boolean_set(kmi->ptr, "left_right", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_time", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "linked_handle", false);
+ RNA_boolean_set(kmi->ptr, "left_right", false);
+ RNA_boolean_set(kmi->ptr, "linked_time", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_handle", FALSE);
- RNA_boolean_set(kmi->ptr, "left_right", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_time", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_handle", false);
+ RNA_boolean_set(kmi->ptr, "left_right", false);
+ RNA_boolean_set(kmi->ptr, "linked_time", false);
/* 2.4x method, now use Alt for handles and select the side based on which handle was selected */
#if 0
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "linked_left", TRUE);
+ RNA_boolean_set(kmi->ptr, "linked_left", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "linked_right", TRUE);
+ RNA_boolean_set(kmi->ptr, "linked_right", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "linked_left", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_right", TRUE);
+ RNA_boolean_set(kmi->ptr, "linked_left", true);
+ RNA_boolean_set(kmi->ptr, "linked_right", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_left", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_right", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_left", true);
+ RNA_boolean_set(kmi->ptr, "linked_right", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_left", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_left", true);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_right", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_right", true);
#endif
/* 2.5 method, Alt and use selected handle */
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_handle", TRUE);
- RNA_boolean_set(kmi->ptr, "left_right", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_time", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "linked_handle", true);
+ RNA_boolean_set(kmi->ptr, "left_right", false);
+ RNA_boolean_set(kmi->ptr, "linked_time", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_handle", TRUE);
- RNA_boolean_set(kmi->ptr, "left_right", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_time", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_handle", true);
+ RNA_boolean_set(kmi->ptr, "left_right", false);
+ RNA_boolean_set(kmi->ptr, "linked_time", false);
/* match action editor */
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_handle", FALSE);
- RNA_boolean_set(kmi->ptr, "left_right", TRUE); /* grr, these conflict - only use left_right if not over an active seq */
- RNA_boolean_set(kmi->ptr, "linked_time", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "linked_handle", false);
+ RNA_boolean_set(kmi->ptr, "left_right", true); /* grr, these conflict - only use left_right if not over an active seq */
+ RNA_boolean_set(kmi->ptr, "linked_time", true);
/* adjusted since 2.4 */
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "linked_handle", FALSE);
- RNA_boolean_set(kmi->ptr, "left_right", FALSE);
- RNA_boolean_set(kmi->ptr, "linked_time", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "linked_handle", false);
+ RNA_boolean_set(kmi->ptr, "left_right", false);
+ RNA_boolean_set(kmi->ptr, "linked_time", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
@@ -335,6 +329,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
/* Preview Region ----------------------------------------------------------- */
keymap = WM_keymap_find(keyconf, "SequencerPreview", SPACE_SEQ, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_all_preview", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_view_all_preview", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_ghost_border", OKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 9199c6de343..9b3b9f23036 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -206,7 +206,7 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
unsigned char *last_p = NULL;
for (x = 0; x < ibuf->x; x++) {
- float *rgb = src + 4 * (ibuf->x * y + x);
+ const float *rgb = src + 4 * (ibuf->x * y + x);
float v = rgb_to_luma(rgb);
unsigned char *p = tgt;
@@ -309,7 +309,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
for (x = 0; x < ibuf->x; x++) {
int c;
- float *rgb = src + 4 * (ibuf->x * y + x);
+ const float *rgb = src + 4 * (ibuf->x * y + x);
for (c = 0; c < 3; c++) {
unsigned char *p = tgt;
float v = rgb[c];
@@ -379,7 +379,7 @@ static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
static void draw_zebra_float(ImBuf *src, ImBuf *ibuf, float perc)
{
float limit = perc / 100.0f;
- float *p = src->rect_float;
+ const float *p = src->rect_float;
unsigned char *o = (unsigned char *) ibuf->rect;
int x;
int y;
@@ -545,7 +545,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
memset(cur_bins, 0, sizeof(cur_bins));
for (x = 0; x < ibuf->x; x++) {
- float *pixel = src + (y * ibuf->x + x) * 4;
+ const float *pixel = src + (y * ibuf->x + x) * 4;
cur_bins[0][get_bin_float(pixel[0])]++;
cur_bins[1][get_bin_float(pixel[1])]++;
@@ -658,8 +658,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
- char *src1 = src + 4 * (ibuf->x * y + x);
- char *p;
+ const char *src1 = src + 4 * (ibuf->x * y + x);
+ const char *p;
rgb[0] = (float)src1[0] / 255.0f;
rgb[1] = (float)src1[1] / 255.0f;
@@ -704,8 +704,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
- float *src1 = src + 4 * (ibuf->x * y + x);
- char *p;
+ const float *src1 = src + 4 * (ibuf->x * y + x);
+ const char *p;
memcpy(rgb, src1, 3 * sizeof(float));
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index c8178259dc2..9826ef10902 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -32,15 +32,7 @@
#include <math.h>
#include <string.h>
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include <sys/types.h>
-
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
@@ -56,7 +48,6 @@
/* for menu/popup icons etc etc*/
-#include "ED_types.h"
#include "ED_screen.h"
#include "ED_sequencer.h"
@@ -164,7 +155,7 @@ void select_surround_from_last(Scene *scene)
void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (deselect_all)
ED_sequencer_deselect_all(scene);
@@ -221,7 +212,7 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op)
int action = RNA_enum_get(op->ptr, "action");
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
if (action == SEL_TOGGLE) {
@@ -282,7 +273,7 @@ void SEQUENCER_OT_select_all(struct wmOperatorType *ot)
static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -319,7 +310,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
{
View2D *v2d = UI_view2d_fromcontext(C);
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle");
const bool linked_time = RNA_boolean_get(op->ptr, "linked_time");
@@ -338,7 +329,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
// XXX - not nice, Ctrl+RMB needs to do left_right only when not over a strip
if (seq && linked_time && left_right)
- left_right = FALSE;
+ left_right = false;
if (marker) {
@@ -361,7 +352,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* use different logic for this */
float x;
ED_sequencer_deselect_all(scene);
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL);
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
SEQP_BEGIN (ed, seq)
{
@@ -555,7 +546,7 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
/* run recursively to select linked */
static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *neighbor;
bool changed = false;
int isel;
@@ -723,11 +714,11 @@ void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot)
static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- int selected;
+ bool selected;
- selected = 1;
+ selected = true;
while (selected) {
- selected = select_more_less_seq__internal(scene, 1, 1);
+ selected = select_more_less_seq__internal(scene, true, true);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
@@ -757,7 +748,7 @@ void SEQUENCER_OT_select_linked(wmOperatorType *ot)
static int sequencer_select_handles_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, 0);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
int sel_side = RNA_enum_get(op->ptr, "side");
@@ -807,7 +798,7 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot)
static int sequencer_select_active_side_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, 0);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq_act = BKE_sequencer_active_get(scene);
if (ed == NULL || seq_act == NULL)
@@ -845,27 +836,19 @@ void SEQUENCER_OT_select_active_side(wmOperatorType *ot)
static int sequencer_borderselect_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
View2D *v2d = UI_view2d_fromcontext(C);
Sequence *seq;
- rcti rect;
rctf rectf, rq;
const bool select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT);
const bool extend = RNA_boolean_get(op->ptr, "extend");
- int mval[2];
if (ed == NULL)
return OPERATOR_CANCELLED;
- WM_operator_properties_border_to_rcti(op, &rect);
-
- mval[0] = rect.xmin;
- mval[1] = rect.ymin;
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmin, &rectf.ymin);
- mval[0] = rect.xmax;
- mval[1] = rect.ymax;
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmax, &rectf.ymax);
+ WM_operator_properties_border_to_rctf(op, &rectf);
+ UI_view2d_region_to_view_rctf(v2d, &rectf, &rectf);
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
seq_rectf(seq, &rq);
@@ -907,7 +890,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/* ****** Selected Grouped ****** */
@@ -952,7 +935,7 @@ static bool select_grouped_type_basic(Editing *ed, Sequence *actseq)
{
Sequence *seq;
bool changed = false;
- short is_sound = SEQ_IS_SOUND(actseq);
+ const bool is_sound = SEQ_IS_SOUND(actseq);
SEQP_BEGIN (ed, seq)
{
@@ -988,7 +971,7 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq)
{
Sequence *seq;
bool changed = false;
- char *dir = actseq->strip ? actseq->strip->dir : NULL;
+ const char *dir = actseq->strip ? actseq->strip->dir : NULL;
if (!SEQ_USE_DATA(actseq))
return changed;
@@ -1044,16 +1027,16 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq)
{
Sequence *seq;
bool changed = false;
- short effects[SEQ_TYPE_EFFECT_MAX + 1];
+ bool effects[SEQ_TYPE_EFFECT_MAX + 1];
int i;
for (i = 0; i <= SEQ_TYPE_EFFECT_MAX; i++)
- effects[i] = FALSE;
+ effects[i] = false;
SEQP_BEGIN (ed, seq)
{
if (ELEM3(actseq, seq->seq1, seq->seq2, seq->seq3)) {
- effects[seq->type] = TRUE;
+ effects[seq->type] = true;
}
}
SEQ_END;
@@ -1105,9 +1088,9 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq)
}
SEQ_END;
- actseq->tmp = SET_INT_IN_POINTER(TRUE);
+ actseq->tmp = SET_INT_IN_POINTER(true);
- for (BKE_sequence_iterator_begin(ed, &iter, TRUE); iter.valid; BKE_sequence_iterator_next(&iter)) {
+ for (BKE_sequence_iterator_begin(ed, &iter, true); iter.valid; BKE_sequence_iterator_next(&iter)) {
seq = iter.seq;
/* Ignore all seqs already selected! */
@@ -1129,14 +1112,14 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq)
if (enddisp < seq->enddisp) enddisp = seq->enddisp;
if (machine < seq->machine) machine = seq->machine;
- seq->tmp = SET_INT_IN_POINTER(TRUE);
+ seq->tmp = SET_INT_IN_POINTER(true);
seq->flag |= SELECT;
changed = true;
/* Unfortunately, we must restart checks from the beginning. */
BKE_sequence_iterator_end(&iter);
- BKE_sequence_iterator_begin(ed, &iter, TRUE);
+ BKE_sequence_iterator_begin(ed, &iter, true);
}
/* Video strips bellow active one, or any strip for audio (order do no matters here!). */
@@ -1157,7 +1140,7 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq)
static int sequencer_select_grouped_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Editing *ed = BKE_sequencer_editing_get(scene, 0);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *actseq = BKE_sequencer_active_get(scene);
int type = RNA_enum_get(op->ptr, "type");
bool changed = false, extend;
@@ -1210,7 +1193,7 @@ void SEQUENCER_OT_select_grouped(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_select_grouped_types, 0, "Type", "");
}
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index f39b30adf37..7fdbc9cc7de 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -70,7 +70,7 @@ typedef struct ImageSampleInfo {
float linearcol[4];
unsigned char *colp;
- float *colfp;
+ const float *colfp;
int draw;
int color_manage;
@@ -82,7 +82,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
ImageSampleInfo *info = arg_info;
if (info->draw) {
- ED_image_draw_info(scene, ar, info->color_manage, FALSE, info->channels,
+ ED_image_draw_info(scene, ar, info->color_manage, false, info->channels,
info->x, info->y, info->colp, info->colfp,
info->linearcol, NULL, NULL);
}
@@ -110,7 +110,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
fy += (float) ibuf->y / 2.0f;
if (fx >= 0.0f && fy >= 0.0f && fx < ibuf->x && fy < ibuf->y) {
- float *fp;
+ const float *fp;
unsigned char *cp;
int x = (int) fx, y = (int) fy;
@@ -140,7 +140,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
copy_v4_v4(info->linearcol, info->colf);
IMB_colormanagement_colorspace_to_scene_linear_v4(info->linearcol, false, ibuf->rect_colorspace);
- info->color_manage = TRUE;
+ info->color_manage = true;
}
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -155,7 +155,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
copy_v4_v4(info->linearcol, info->colf);
BKE_sequencer_pixel_from_sequencer_space_v4(scene, info->linearcol);
- info->color_manage = TRUE;
+ info->color_manage = true;
}
}
else {
@@ -219,7 +219,7 @@ static void sample_cancel(bContext *C, wmOperator *op)
static int sample_poll(bContext *C)
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
- return sseq && BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL;
+ return sseq && BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL;
}
void SEQUENCER_OT_sample(wmOperatorType *ot)
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 1f7b70a52a9..a94b73802b2 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -38,7 +38,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -47,7 +46,6 @@
#include "BKE_global.h"
#include "ED_space_api.h"
-#include "ED_sequencer.h"
#include "ED_screen.h"
#include "ED_view3d.h" /* only for sequencer view3d drawing callback */
@@ -458,17 +456,17 @@ static int sequencer_context(const bContext *C, const char *member, bContextData
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, sequencer_context_dir);
- return TRUE;
+ return true;
}
else if (CTX_data_equals(member, "edit_mask")) {
Mask *mask = BKE_sequencer_mask_get(scene);
if (mask) {
CTX_data_id_pointer_set(result, &mask->id);
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
@@ -544,7 +542,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE)
- draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, FALSE);
+ draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false);
if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
int over_cfra;
@@ -555,7 +553,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
over_cfra = scene->r.cfra + scene->ed->over_ofs;
if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT)
- draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, TRUE);
+ draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true);
}
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index d6c459594f9..6815402d404 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -62,4 +62,4 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-blender_add_lib(bf_editor_text "${SRC}" "${INC}" "${INC_SYS}")
+blender_add_lib(bf_editor_space_text "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 857b9cf82b7..df3e813d920 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -275,19 +275,19 @@ static void text_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", FALSE);
+ RNA_boolean_set(kmi->ptr, "reverse", false);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", TRUE);
+ RNA_boolean_set(kmi->ptr, "reverse", true);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", FALSE);
+ RNA_boolean_set(kmi->ptr, "reverse", false);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
- RNA_boolean_set(kmi->ptr, "reverse", TRUE);
+ RNA_boolean_set(kmi->ptr, "reverse", true);
WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
@@ -309,14 +309,9 @@ static void text_keymap(struct wmKeyConfig *keyconf)
if (U.uiflag & USER_MMB_PASTE) { // XXX not dynamic
kmi = WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "selection", TRUE);
+ RNA_boolean_set(kmi->ptr, "selection", true);
}
- kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "split_lines", FALSE);
- kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "split_lines", TRUE);
-
WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_select_word", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
@@ -373,7 +368,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_selection_set", EVT_TWEAK_L, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "TEXT_OT_selection_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "select", TRUE);
+ RNA_boolean_set(kmi->ptr, "select", true);
RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1);
RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1);
@@ -449,9 +444,16 @@ static void text_main_area_draw(const bContext *C, ARegion *ar)
/* scrollers? */
}
-static void text_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
+static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
{
- WM_cursor_set(win, BC_TEXTEDITCURSOR);
+ SpaceText *st = sa->spacedata.first;
+ int wmcursor = BC_TEXTEDITCURSOR;
+
+ if (st->text && BLI_rcti_isect_pt(&st->txtbar, win->eventstate->x - ar->winrct.xmin, st->txtbar.ymin)) {
+ wmcursor = CURSOR_STD;
+ }
+
+ WM_cursor_set(win, wmcursor);
}
@@ -570,6 +572,7 @@ void ED_spacetype_text(void)
art->init = text_main_area_init;
art->draw = text_main_area_draw;
art->cursor = text_cursor;
+ art->event_cursor = true;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 692cefd3ee9..99e1606c9bd 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -232,7 +232,7 @@ static GHash *text_autocomplete_build(Text *text)
static void get_suggest_prefix(Text *text, int offset)
{
int i, len;
- char *line;
+ const char *line;
if (!text) return;
if (!texttool_text_is_active(text)) return;
@@ -280,7 +280,7 @@ static int text_autocomplete_invoke(bContext *C, wmOperator *op, const wmEvent *
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
- st->doplugins = TRUE;
+ st->doplugins = true;
op->customdata = text_autocomplete_build(text);
if (texttool_suggest_first()) {
@@ -494,7 +494,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
}
if (draw) {
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(sa);
}
// if (swallow) {
@@ -524,7 +524,7 @@ static void text_autocomplete_free(bContext *C, wmOperator *op)
/* other stuff */
{
SpaceText *st = CTX_wm_space_text(C);
- st->doplugins = FALSE;
+ st->doplugins = false;
texttool_text_clear();
}
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 2b913fb2c49..f28bfedf234 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -932,7 +932,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
/* the scrollbar is non-linear sized */
if (pix_bardiff > 0) {
/* the start of the highlight is in the current viewport */
- if (ltexth && st->viewlines && lhlstart >= st->top && lhlstart <= st->top + st->viewlines) {
+ if (st->viewlines && lhlstart >= st->top && lhlstart <= st->top + st->viewlines) {
/* speed the progresion of the start of the highlight through the scrollbar */
hlstart = ( ( (pix_available - pix_bardiff) * lhlstart) / ltexth) + (pix_bardiff * (lhlstart - st->top) / st->viewlines);
}
@@ -950,7 +950,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
}
/* the end of the highlight is in the current viewport */
- if (ltexth && st->viewlines && lhlend >= st->top && lhlend <= st->top + st->viewlines) {
+ if (st->viewlines && lhlend >= st->top && lhlend <= st->top + st->viewlines) {
/* speed the progresion of the end of the highlight through the scrollbar */
hlend = (((pix_available - pix_bardiff) * lhlend) / ltexth) + (pix_bardiff * (lhlend - st->top) / st->viewlines);
}
@@ -1464,7 +1464,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
lineno = 0;
for (i = 0; i < st->top && tmp; i++) {
if (st->showsyntax && !tmp->format)
- tft->format_line(st, tmp, 0);
+ tft->format_line(st, tmp, false);
if (st->wordwrap) {
int lines = text_get_visible_lines_no(st, lineno);
@@ -1517,7 +1517,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
- tft->format_line(st, tmp, 0);
+ tft->format_line(st, tmp, false);
if (st->showlinenrs && !wrap_skip) {
/* draw line number */
diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h
index 808311cbb62..daed3b3e447 100644
--- a/source/blender/editors/space_text/text_format.h
+++ b/source/blender/editors/space_text/text_format.h
@@ -77,7 +77,7 @@ typedef struct TextFormatType {
*
* See: FMT_TYPE_ enums below
*/
- void (*format_line)(SpaceText *st, TextLine *line, int do_next);
+ void (*format_line)(SpaceText *st, TextLine *line, const bool do_next);
const char **ext; /* NULL terminated extensions */
} TextFormatType;
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index d9d2a9213a3..1e842729ab3 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -150,7 +150,7 @@ static char txtfmt_lua_format_identifier(const char *str)
return fmt;
}
-static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const int do_next)
+static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const bool do_next)
{
FlattenString fs;
const char *str;
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 2e863f2a569..97dc1be3b9a 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -174,7 +174,7 @@ static char txtfmt_osl_format_identifier(const char *str)
return fmt;
}
-static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const int do_next)
+static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const bool do_next)
{
FlattenString fs;
const char *str;
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 50425e258e3..2f6962f0493 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -157,7 +157,7 @@ static char txtfmt_py_format_identifier(const char *str)
return fmt;
}
-static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const int do_next)
+static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const bool do_next)
{
FlattenString fs;
const char *str;
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index aaeea40c1a5..b1d57f5a75e 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -28,14 +28,6 @@
* \ingroup sptext
*/
-
-
-/* file time checking */
-
-#ifndef _WIN32
-#else
-#endif
-
#include "DNA_windowmanager_types.h"
#include "MEM_guardedalloc.h"
@@ -51,10 +43,6 @@
#include "WM_types.h"
-#ifdef WITH_PYTHON
-// XXX #include "BPY_menus.h"
-#endif
-
#include "text_intern.h"
/* ************************ header area region *********************** */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 43776f28c62..0263b6cd912 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -38,7 +38,6 @@
#include "DNA_text_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLF_translation.h"
@@ -272,7 +271,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
static int text_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
- char *path = (text && text->name) ? text->name : G.main->name;
+ const char *path = (text && text->name) ? text->name : G.main->name;
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return text_open_exec(C, op);
@@ -472,18 +471,18 @@ static void txt_write_file(Text *text, ReportList *reports)
return;
}
- tmp = text->lines.first;
- while (tmp) {
- if (tmp->next) fprintf(fp, "%s\n", tmp->line);
- else fprintf(fp, "%s", tmp->line);
-
- tmp = tmp->next;
+ for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+ fputs(tmp->line, fp);
+ fputc('\n', fp);
}
fclose(fp);
if (BLI_stat(filepath, &st) == 0) {
text->mtime = st.st_mtime;
+
+ /* report since this can be called from key-shortcuts */
+ BKE_reportf(reports, RPT_INFO, "Saved Text '%s'", filepath);
}
else {
text->mtime = 0;
@@ -545,7 +544,7 @@ static int text_save_as_exec(bContext *C, wmOperator *op)
static int text_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
- char *str;
+ const char *str;
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return text_save_as_exec(C, op);
@@ -1571,7 +1570,7 @@ static int cursor_skip_find_line(SpaceText *st, ARegion *ar,
return 1;
}
-static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
+static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, const bool sel)
{
Text *text = st->text;
TextLine **linep;
@@ -1643,7 +1642,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
if (!sel) txt_pop_sel(text);
}
-static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
+static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, const bool sel)
{
Text *text = st->text;
TextLine **linep;
@@ -1713,7 +1712,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
if (!sel) txt_pop_sel(text);
}
-static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
+static void txt_wrap_move_up(SpaceText *st, ARegion *ar, const bool sel)
{
Text *text = st->text;
TextLine **linep;
@@ -1746,7 +1745,7 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
if (!sel) txt_pop_sel(text);
}
-static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
+static void txt_wrap_move_down(SpaceText *st, ARegion *ar, const bool sel)
{
Text *text = st->text;
TextLine **linep;
@@ -1783,7 +1782,7 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
*
* This is to replace screen_skip for PageUp/Down operations.
*/
-static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int sel)
+static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, const bool sel)
{
TextLine **linep;
int *charp;
@@ -1814,7 +1813,7 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int s
if (!sel) txt_pop_sel(text);
}
-static int text_move_cursor(bContext *C, int type, int select)
+static int text_move_cursor(bContext *C, int type, bool select)
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -2465,7 +2464,7 @@ static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y)
return linep;
}
-static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, int sel)
+static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, const bool sel)
{
Text *text = st->text;
int max = wrap_width(st, ar); /* column */
@@ -2582,7 +2581,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
}
}
-static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
+static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, const bool sel)
{
Text *text = st->text;
text_update_character_width(st);
@@ -2845,7 +2844,7 @@ static int text_insert_exec(bContext *C, wmOperator *op)
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
char *str;
- int done = FALSE;
+ bool done = false;
size_t i = 0;
unsigned int code;
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index fe02ff53578..c116f997164 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -42,7 +42,6 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_pointcache.h"
@@ -341,12 +340,12 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
}
/* draw keyframe lines for timeline */
-static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar)
+static void time_draw_keyframes(const bContext *C, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
View2D *v2d = &ar->v2d;
- short onlysel = (stime->flag & TIME_ONLYACTSEL);
+ bool onlysel = ((scene->flag & SCE_KEYS_NO_SELONLY) == 0);
gpuImmediateFormat_C4_V2();
gpuBegin(GL_LINES);
@@ -355,7 +354,7 @@ static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar
* - don't try to do this when only drawing active/selected data keyframes,
* since this can become quite slow
*/
- if (scene && onlysel == 0) {
+ if (onlysel == 0) {
/* set draw color */
gpuColor3P(0xDDA700);
time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel);
@@ -373,7 +372,7 @@ static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar
time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel);
}
else {
- short active_done = FALSE;
+ bool active_done = false;
/* draw keyframes from all selected objects */
CTX_DATA_BEGIN (C, Object *, obsel, selected_objects)
@@ -383,7 +382,7 @@ static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar
/* if this object is the active one, set flag so that we don't draw again */
if (obsel == ob)
- active_done = TRUE;
+ active_done = true;
}
CTX_DATA_END;
@@ -527,7 +526,7 @@ static void time_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_view_ortho(v2d);
/* keyframes */
- time_draw_keyframes(C, stime, ar);
+ time_draw_keyframes(C, ar);
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c
index 9067fb6933f..e2e861fda38 100644
--- a/source/blender/editors/space_time/time_ops.c
+++ b/source/blender/editors/space_time/time_ops.c
@@ -192,5 +192,6 @@ void time_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TIME_OT_start_frame_set", SKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TIME_OT_end_frame_set", EKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TIME_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "TIME_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
}
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index d1edd1d1544..bd9ef177252 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -253,22 +253,25 @@ void draw_motion_path_instance(Scene *scene,
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
int frame = sfra + i;
char numstr[32];
+ size_t numstr_len;
float co[3];
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (i == 0) {
- sprintf(numstr, " %d", frame);
+ numstr_len = sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
- view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
+ view3d_cached_text_draw_add(co, numstr, numstr_len,
+ 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
else if ((i >= stepsize) && (i < len - stepsize)) {
bMotionPathVert *mpvP = (mpv - stepsize);
bMotionPathVert *mpvN = (mpv + stepsize);
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
- sprintf(numstr, " %d", frame);
+ numstr_len = sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
- view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
+ view3d_cached_text_draw_add(co, numstr, numstr_len,
+ 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
}
}
@@ -330,10 +333,12 @@ void draw_motion_path_instance(Scene *scene,
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
char numstr[32];
+ size_t numstr_len;
- sprintf(numstr, " %d", (sfra + i));
+ numstr_len = sprintf(numstr, " %d", (sfra + i));
mul_v3_m4v3(co, ob->imat, mpv->co);
- view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
+ view3d_cached_text_draw_add(co, numstr, numstr_len,
+ 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
}
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 614cb53a5fe..1dc0730f387 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -285,7 +285,7 @@ static bool set_pchan_gpuColor(short colCode, int boneflag, short constflag)
}
else {
if (bcolor) {
- char *cp = bcolor->solid;
+ const char *cp = bcolor->solid;
gpuColor4ub(cp[0], cp[1], cp[2], 204);
}
else
@@ -1500,7 +1500,7 @@ static void bgl_sphere_project(float ax, float az)
float dir[3], sine, q3;
sine = 1.0f - ax * ax - az * az;
- q3 = (sine < 0.0f) ? 0.0f : (float)(2.0 * sqrt(sine));
+ q3 = (sine < 0.0f) ? 0.0f : (2.0f * sqrtf(sine));
dir[0] = -az * q3;
dir[1] = 1.0f - 2.0f * sine;
@@ -1511,7 +1511,7 @@ static void bgl_sphere_project(float ax, float az)
static void draw_dof_ellipse(float ax, float az)
{
- static float staticSine[16] = {
+ const float staticSine[16] = {
0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f,
0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f,
0.743144825477f, 0.809016994375f, 0.866025403784f,
@@ -1711,6 +1711,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
short do_dashed = 3;
bool draw_wire = false;
int flag;
+ bool is_cull_enabled;
/* being set below */
arm->layer_used = 0;
@@ -1758,9 +1759,15 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* little speedup, also make sure transparent only draws once */
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
-
+ glCullFace(GL_BACK);
+ if (v3d->flag2 & V3D_BACKFACE_CULLING) {
+ glEnable(GL_CULL_FACE);
+ is_cull_enabled = true;
+ }
+ else {
+ is_cull_enabled = false;
+ }
+
/* if solid we draw that first, with selection codes, but without names, axes etc */
if (dt > OB_WIRE) {
if (arm->flag & ARM_POSEMODE)
@@ -1809,26 +1816,38 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
draw_wire = true;
}
else {
+ if (is_cull_enabled && (v3d->flag2 & V3D_BACKFACE_CULLING) == 0) {
+ is_cull_enabled = false;
+ glDisable(GL_CULL_FACE);
+ }
+
draw_custom_bone(scene, v3d, rv3d, pchan->custom,
OB_SOLID, arm->flag, flag, index, bone->length);
}
}
- else if (arm->drawtype == ARM_LINE) {
- /* nothing in solid */
- }
- else if (arm->drawtype == ARM_WIRE) {
- /* nothing in solid */
- }
- else if (arm->drawtype == ARM_ENVELOPE) {
- draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
- }
- else if (arm->drawtype == ARM_B_BONE) {
- draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
- }
else {
- draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
+ if (is_cull_enabled == false) {
+ is_cull_enabled = true;
+ glEnable(GL_CULL_FACE);
+ }
+
+ if (arm->drawtype == ARM_LINE) {
+ /* nothing in solid */
+ }
+ else if (arm->drawtype == ARM_WIRE) {
+ /* nothing in solid */
+ }
+ else if (arm->drawtype == ARM_ENVELOPE) {
+ draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
+ }
+ else if (arm->drawtype == ARM_B_BONE) {
+ draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
+ }
+ else {
+ draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
+ }
}
-
+
gpuPopMatrix();
}
}
@@ -1929,7 +1948,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (arm->flag & ARM_POSEMODE)
index = base->selcol;
}
-
+
+ if (is_cull_enabled == false) {
+ is_cull_enabled = true;
+ glEnable(GL_CULL_FACE);
+ }
+
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
arm->layer_used |= bone->layer;
@@ -2041,7 +2065,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* restore */
- glDisable(GL_CULL_FACE);
+ if (is_cull_enabled) {
+ glDisable(GL_CULL_FACE);
+ }
/* draw DoFs */
if (arm->flag & ARM_POSEMODE) {
@@ -2090,7 +2116,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* Draw names of bone */
if (arm->flag & ARM_DRAWNAMES) {
mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail);
- view3d_cached_text_draw_add(vec, pchan->name, 10, 0, col);
+ view3d_cached_text_draw_add(vec, pchan->name, strlen(pchan->name), 10, 0, col);
}
/* Draw additional axes on the bone tail */
@@ -2301,7 +2327,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
if (arm->flag & ARM_DRAWNAMES) {
mid_v3_v3v3(vec, eBone->head, eBone->tail);
//glRasterPos3fv(vec); // XXX jwilkins: is this needed? the next function doesn't seem to actually draw anything anymore
- view3d_cached_text_draw_add(vec, eBone->name, 10, 0, col);
+ view3d_cached_text_draw_add(vec, eBone->name, strlen(eBone->name), 10, 0, col);
}
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
@@ -2424,7 +2450,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
/* draw from first frame of range to last */
for (CFRA = (int)start; CFRA < end; CFRA += (int)stepsize) {
colfac = (end - (float)CFRA) / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0 * sqrt(colfac)));
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
BKE_pose_where_is(scene, ob);
@@ -2504,7 +2530,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
/* draw from first frame of range to last */
for (ak = keys.first, i = 0; ak; ak = ak->next, i++) {
colfac = i / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0 * sqrt(colfac)));
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
CFRA = (int)ak->cfra;
@@ -2574,7 +2600,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
for (cur = stepsize; cur < range; cur += stepsize) {
ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0 * sqrt(colfac)));
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
/* only within action range */
if (actframe + ctime >= start && actframe + ctime <= end) {
@@ -2589,7 +2615,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */
colfac = ctime / range;
- UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0 * sqrt(colfac)));
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
/* only within action range */
if ((actframe - ctime >= start) && (actframe - ctime <= end)) {
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 6da006718ce..764c9b65b7b 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -41,7 +41,6 @@
#include "BIF_glutil.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_material.h"
@@ -51,7 +50,6 @@
#include "BKE_scene.h"
#include "BLI_utildefines.h"
-#include "BLI_blenlib.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
@@ -64,7 +62,6 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
-#include "DNA_windowmanager_types.h"
#include "GPU_basic.h"
#include "GPU_blender_aspect.h"
@@ -79,7 +76,7 @@
#include "GPU_raster.h"
#include "GPU_state_latch.h"
-#include "MEM_guardedalloc.h"
+#include "RE_engine.h"
/* standard */
#include <string.h>
@@ -245,13 +242,14 @@ static Material *give_current_material_or_def(Object *ob, int matnr)
typedef struct TextureDrawState {
Object *ob;
+ bool use_game_mat;
int is_lit, is_tex;
int color_profile;
bool use_backface_culling;
unsigned char obcol[4];
} TextureDrawState;
-static TextureDrawState Gtexdraw = {NULL, 0, 0, 0, false, {0, 0, 0, 0}};
+static TextureDrawState Gtexdraw = {NULL, false, 0, 0, 0, false, {0, 0, 0, 0}};
static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
{
@@ -265,7 +263,7 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */
int backculled = 1;
- int alphablend = 0;
+ int alphablend = GPU_BLEND_SOLID;
int textured = 0;
int lit = 0;
int has_texface = texface != NULL;
@@ -285,10 +283,13 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
/* convert number of lights into boolean */
if (gtexdraw.is_lit) lit = 1;
+ backculled = gtexdraw.use_backface_culling;
if (ma) {
- alphablend = ma->game.alpha_blend;
if (ma->mode & MA_SHLESS) lit = 0;
- backculled = (ma->game.flag & GEMAT_BACKCULL) || gtexdraw.use_backface_culling;
+ if (gtexdraw.use_game_mat) {
+ backculled = backculled || (ma->game.flag & GEMAT_BACKCULL);
+ alphablend = ma->game.alpha_blend;
+ }
}
if (texface) {
@@ -397,6 +398,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
Gtexdraw.is_tex = is_tex;
Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
+ Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
@@ -678,7 +680,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
if (ob->mode & OB_MODE_EDIT)
return;
else if (ob == OBACT)
- if (paint_facesel_test(ob) || paint_vertsel_test(ob))
+ if (BKE_paint_select_elem_test(ob))
return;
ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
@@ -1090,20 +1092,33 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
}
/* Vertex Paint and Weight Paint */
-void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light,
- void *facemask_cb, void *user_data)
+static void draw_mesh_paint_light_begin(void)
{
- if (use_light) {
- const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
+ const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
- /* but set default spec */
- GPU_set_basic_material_specular(spec); // XXX jwilkins: couldn't find where specular is returned to default
- // XXX jwilkins: is this supposed to use the default shininess?
+ GPU_enable_material(0, NULL);
- /* diffuse */
+ /* but set default spec */
+ GPU_set_basic_material_specular(spec); // XXX jwilkins: couldn't find where specular is returned to default
+ // XXX jwilkins: is this supposed to use the default shininess?
- // SSS Enable Lighting
- GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_LIGHTING);
+ /* diffuse */
+ // SSS Enable Lighting
+ GPU_aspect_enable(GPU_ASPECT_BASIC, GPU_BASIC_LIGHTING);
+}
+static void draw_mesh_paint_light_end(void)
+{
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_LIGHTING);
+
+ GPU_disable_material();
+}
+
+void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light,
+ void *facemask_cb, void *user_data)
+{
+ if (use_light) {
+ draw_mesh_paint_light_begin();
}
if (use_light) {
@@ -1124,16 +1139,35 @@ void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light,
gpuImmediateUnformat();
if (use_light) {
- // SSS Disable Lighting
- GPU_aspect_disable(GPU_ASPECT_BASIC, GPU_BASIC_LIGHTING);
-
- GPU_disable_material();
+ draw_mesh_paint_light_end();
}
}
+void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light,
+ void *facemask_cb, void *user_data,
+ const Mesh *me)
+{
+ if (use_light) {
+ draw_mesh_paint_light_begin();
+ }
+
+ if (me->mloopcol) {
+ dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
+ DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+ }
+ else {
+ glColor3f(1.0f, 1.0f, 1.0f);
+ dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
+ DM_DRAW_ALWAYS_SMOOTH);
+ }
+ if (use_light) {
+ draw_mesh_paint_light_end();
+ }
+}
-void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const bool use_depth,
+void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm,
+ const bool use_depth, const bool use_alpha,
void *edgemask_cb, void *user_data)
{
/* weight paint in solid mode, special case. focus on making the weights clear
@@ -1148,8 +1182,10 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const boo
}
gpuColor4P(CPACK_WHITE, 0.376f);
-
- glEnable(GL_BLEND);
+
+ if (use_alpha) {
+ glEnable(GL_BLEND);
+ }
GPU_raster_begin();
@@ -1172,6 +1208,10 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const boo
else {
glEnable(GL_DEPTH_TEST);
}
+
+ if (use_alpha) {
+ glDisable(GL_BLEND);
+ }
}
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
@@ -1186,22 +1226,10 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
facemask = (DMSetDrawOptions)wpaint__setSolidDrawOptions_facemask;
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
- if (use_light) {
- GPU_enable_material(0, NULL);
- }
-
draw_mesh_paint_weight_faces(dm, use_light, facemask, me);
}
else if (ob->mode & OB_MODE_VERTEX_PAINT) {
- if (me->mloopcol) {
- dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
- DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
- }
- else {
- gpuColor3P(CPACK_WHITE);
- dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
- DM_DRAW_ALWAYS_SMOOTH);
- }
+ draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me);
}
/* draw face selection on top */
@@ -1210,6 +1238,16 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
}
else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) {
const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
- draw_mesh_paint_weight_edges(rv3d, dm, use_depth, NULL, NULL);
+ const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0;
+
+ if (use_alpha == false) {
+ set_inverted_drawing(1);
+ }
+
+ draw_mesh_paint_weight_edges(rv3d, dm, use_depth, use_alpha, NULL, NULL);
+
+ if (use_alpha == false) {
+ set_inverted_drawing(0);
+ }
}
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 5794a17a1c1..d50728c134b 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -43,8 +43,11 @@
#include "DNA_world_types.h"
#include "DNA_object_types.h"
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_link_utils.h"
+#include "BLI_string.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BKE_anim.h" /* for the where_on_path function */
#include "BKE_armature.h"
@@ -64,6 +67,7 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
+#include "BKE_movieclip.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -161,8 +165,8 @@ typedef struct drawDMFacesSel_userData {
BMesh *bm;
BMFace *efa_act;
- int *orig_index_mf_to_mpoly;
- int *orig_index_mp_to_orig;
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
} drawDMFacesSel_userData;
typedef struct drawDMNormal_userData {
@@ -683,11 +687,9 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
}
}
-static ListBase CachedText[3];
-static int CachedTextLevel = 0;
typedef struct ViewCachedString {
- struct ViewCachedString *next, *prev;
+ struct ViewCachedString *next;
float vec[3];
union {
unsigned char ub[4];
@@ -700,44 +702,62 @@ typedef struct ViewCachedString {
/* str is allocated past the end */
} ViewCachedString;
+/* one arena for all 3 string lists */
+static MemArena *g_v3d_strings_arena = NULL;
+static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL};
+static int g_v3d_string_level = -1;
+
void view3d_cached_text_draw_begin(void)
{
- ListBase *strings = &CachedText[CachedTextLevel];
- BLI_listbase_clear(strings);
- CachedTextLevel++;
+ g_v3d_string_level++;
+
+ BLI_assert(g_v3d_string_level >= 0);
+
+ if (g_v3d_string_level == 0) {
+ BLI_assert(g_v3d_strings_arena == NULL);
+ }
}
void view3d_cached_text_draw_add(const float co[3],
- const char *str,
+ const char *str, const size_t str_len,
short xoffs, short flag,
const unsigned char col[4])
{
- int alloc_len = strlen(str) + 1;
- ListBase *strings = &CachedText[CachedTextLevel - 1];
+ int alloc_len = str_len + 1;
/* TODO, replace with more efficient malloc, perhaps memarena per draw? */
- ViewCachedString *vos = MEM_callocN(sizeof(ViewCachedString) + alloc_len, "ViewCachedString");
+ ViewCachedString *vos;
+
+ BLI_assert(str_len == strlen(str));
+
+ if (g_v3d_strings_arena == NULL) {
+ g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
+ }
+
+ vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len);
+
+ BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos);
- BLI_addtail(strings, vos);
copy_v3_v3(vos->vec, co);
copy_v4_v4_char((char *)vos->col.ub, (const char *)col);
vos->xoffs = xoffs;
vos->flag = flag;
- vos->str_len = alloc_len - 1;
+ vos->str_len = str_len;
/* allocate past the end */
- memcpy(++vos, str, alloc_len);
+ memcpy(vos + 1, str, alloc_len);
}
void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
- ListBase *strings = &CachedText[CachedTextLevel - 1];
ViewCachedString *vos;
int tot = 0;
+ BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2);
+
/* project first and test */
- for (vos = strings->first; vos; vos = vos->next) {
+ for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
mul_m4_v3(mat, vos->vec);
@@ -782,7 +802,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
gpuDepthMask(GL_FALSE);
}
- for (vos = strings->first; vos; vos = vos->next) {
+ for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
if (vos->sco[0] != IS_CLIPPED) {
const char *str = (char *)(vos + 1);
@@ -801,7 +821,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
vos->str_len);
}
}
-
+
if (depth_write) {
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -818,11 +838,17 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
ED_view3d_clipping_enable();
}
}
-
- if (strings->first)
- BLI_freelistN(strings);
-
- CachedTextLevel--;
+
+ g_v3d_strings[g_v3d_string_level] = NULL;
+
+ if (g_v3d_string_level == 0) {
+ if (g_v3d_strings_arena) {
+ BLI_memarena_free(g_v3d_strings_arena);
+ g_v3d_strings_arena = NULL;
+ }
+ }
+
+ g_v3d_string_level--;
}
/* ******************** primitive drawing ******************* */
@@ -920,7 +946,7 @@ static void spotvolume(float lvec[3], float vvec[3], const float inp)
static void draw_spot_cone(Lamp *la, float x, float z)
{
- z = fabs(z);
+ z = fabsf(z);
gpuBegin(GL_TRIANGLE_FAN);
gpuVertex3f(0.0f, 0.0f, -x);
@@ -975,8 +1001,8 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z)
glCullFace(GL_BACK);
}
-static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
{
Object *ob = base->object;
const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
@@ -1032,8 +1058,8 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
gpuImmediateFormat_V3();
if (lampsize > 0.0f) {
- if (!(dflag & DRAW_CONSTCOLOR) && ob->id.us > 1) {
- if (ob == OBACT || (ob->flag & SELECT)) {
+ if (!(dflag & DRAW_CONSTCOLOR) && ob->id.us > 1) {
+ if (is_obact || (ob->flag & SELECT)) {
gpuColor4P(0x88FFFF, 0.608f);
}
else {
@@ -1077,7 +1103,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
short axis;
/* setup a 45 degree rotation matrix */
- axis_angle_normalized_to_mat3(mat, imat[2], (float)M_PI / 4.0f);
+ axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2);
/* vectors */
mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
@@ -1117,7 +1143,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f);
copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]);
- mul_mat3_m4_v3(ob->obmat, vvec);
+ mul_transposed_mat3_m4_v3(ob->obmat, vvec);
x = -la->dist;
y = cosf(la->spotsize * 0.5f);
@@ -1140,7 +1166,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
gpuTranslate(0.0, 0.0, x);
if (la->mode & LA_SQUARE) {
float tvec[3];
- float z_abs = fabs(z);
+ float z_abs = fabsf(z);
tvec[0] = tvec[1] = z_abs;
tvec[2] = 0.0;
@@ -1161,7 +1187,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
/* draw the circle/square representing spotbl */
if (la->type == LA_SPOT) {
- float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2));
+ float spotblcirc = fabsf(z) * (1.0f - powf(la->spotblend, 2));
/* hide line if it is zero size or overlaps with outer border,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
@@ -1407,15 +1433,16 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
}
else {
float obmat[4][4];
+ int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
- BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, scene->r.cfra, obmat);
+ BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
invert_m4_m4(imat, obmat);
gpuMultMatrix(imat[0]);
}
for (track = tracksbase->first; track; track = track->next) {
- int selected = TRACK_SELECTED(track);
+ bool selected = TRACK_SELECTED(track);
if (draw_selected && !selected)
continue;
@@ -1507,7 +1534,10 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
float pos[3];
mul_v3_m4v3(pos, mat, track->bundle_pos);
- view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, selected ? col_sel : col_unsel);
+ view3d_cached_text_draw_add(pos,
+ track->name, strlen(track->name),
+ 10, V3D_CACHE_TEXT_GLOBALSPACE,
+ selected ? col_sel : col_unsel);
}
tracknr++;
@@ -1776,7 +1806,7 @@ static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D
static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
{
BPoint *bp = lt->def;
- float *co = dl ? dl->verts : NULL;
+ const float *co = dl ? dl->verts : NULL;
int u, v, w;
const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
@@ -1841,7 +1871,7 @@ static void ensure_curve_cache(Scene *scene, Object *object)
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- BKE_displist_make_curveTypes(scene, object, FALSE);
+ BKE_displist_make_curveTypes(scene, object, false);
break;
case OB_MBALL:
BKE_displist_make_mball(G.main->eval_ctx, scene, object);
@@ -2372,6 +2402,47 @@ static int draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa)
#endif
+/* Draw loop normals. */
+static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index,
+ const float co[3], const float no[3])
+{
+ if (no) {
+ const drawDMNormal_userData *data = userData;
+ const BMVert *eve = BM_vert_at_index(data->bm, vertex_index);
+ const BMFace *efa = BM_face_at_index(data->bm, face_index);
+ float vec[3];
+
+ if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
+ if (!data->uniform_scale) {
+ mul_v3_m3v3(vec, (float(*)[3])data->tmat, no);
+ normalize_v3(vec);
+ mul_m3_v3((float(*)[3])data->imat, vec);
+ }
+ else {
+ copy_v3_v3(vec, no);
+ }
+ mul_v3_fl(vec, data->normalsize);
+ add_v3_v3(vec, co);
+ glVertex3fv(co);
+ glVertex3fv(vec);
+ }
+ }
+}
+
+static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
+{
+ drawDMNormal_userData data;
+
+ data.bm = em->bm;
+ data.normalsize = scene->toolsettings->normalsize;
+
+ calcDrawDMNormalScale(ob, &data);
+
+ glBegin(GL_LINES);
+ dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
+ glEnd();
+}
+
/* Draw faces with color set based on selection
* return 2 for the active face so it renders with stipple enabled */
static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
@@ -2730,6 +2801,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
Mesh *me = ob->data;
float v1[3], v2[3], v3[3], vmid[3], fvec[3];
char numstr[32]; /* Stores the measurement display text here */
+ size_t numstr_len;
const char *conv_float; /* Use a float conversion matching the grid size */
unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */
float area; /* area of the face */
@@ -2807,14 +2879,14 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
}
if (unit->system) {
- bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3,
- unit->system, B_UNIT_LENGTH, do_split, false);
+ numstr_len = bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3,
+ unit->system, B_UNIT_LENGTH, do_split, false);
}
else {
- BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
}
- view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
+ view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
}
}
}
@@ -2890,9 +2962,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
angle = angle_normalized_v3v3(no_a, no_b);
- BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
- view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
+ view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
}
}
}
@@ -2909,14 +2981,15 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \
mul_v3_fl(vmid, 1.0f / (float)n); \
if (unit->system) { \
- bUnit_AsString(numstr, sizeof(numstr), \
- (double)(area * unit->scale_length * unit->scale_length), \
- 3, unit->system, B_UNIT_AREA, do_split, false); \
+ numstr_len = bUnit_AsString( \
+ numstr, sizeof(numstr), \
+ (double)(area * unit->scale_length * unit->scale_length), \
+ 3, unit->system, B_UNIT_AREA, do_split, false); \
} \
else { \
- BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
} \
- view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \
+ view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \
} (void)0
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
@@ -3032,9 +3105,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
angle = angle_v3v3v3(v1, v2, v3);
- BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
- view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
+ view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col);
}
}
}
@@ -3050,6 +3123,7 @@ static void draw_em_indices(BMEditMesh *em)
BMVert *v;
int i;
char numstr[32];
+ size_t numstr_len;
float pos[3];
unsigned char col[4];
@@ -3062,8 +3136,8 @@ static void draw_em_indices(BMEditMesh *em)
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BLI_snprintf(numstr, sizeof(numstr), "%d", i);
- view3d_cached_text_draw_add(v->co, numstr, 0, txt_flag, col);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col);
}
i++;
}
@@ -3074,9 +3148,9 @@ static void draw_em_indices(BMEditMesh *em)
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
mid_v3_v3v3(pos, e->v1->co, e->v2->co);
- view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col);
+ view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
}
i++;
}
@@ -3088,8 +3162,8 @@ static void draw_em_indices(BMEditMesh *em)
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
BM_face_calc_center_mean(f, pos);
- BLI_snprintf(numstr, sizeof(numstr), "%d", i);
- view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
}
i++;
}
@@ -3172,7 +3246,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
else {
glEnable(GL_DEPTH_TEST);
draw_mesh_paint_weight_faces(finalDM, false, draw_em_fancy__setFaceOpts, me->edit_btmesh);
- draw_mesh_paint_weight_edges(rv3d, finalDM, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm);
+ draw_mesh_paint_weight_edges(rv3d, finalDM, true, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm);
glDisable(GL_DEPTH_TEST);
}
}
@@ -3360,6 +3434,10 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
UI_ThemeColor(TH_VNORMAL);
draw_dm_vert_normals(em, scene, ob, cageDM);
}
+ if (me->drawflag & ME_DRAW_LNORMALS) {
+ UI_ThemeColor(TH_VNORMAL);
+ draw_dm_loop_normals(em, scene, ob, cageDM);
+ }
if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN |
ME_DRAWEXTRA_FACEAREA |
@@ -3429,7 +3507,11 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
- Object *ob = BKE_object_lod_meshob_get(base->object, scene);
+#ifdef WITH_GAMEENGINE
+ Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, scene) : base->object;
+#else
+ Object *ob = base->object;
+#endif
Mesh *me = ob->data;
Material *ma = give_current_material(ob, 1);
const bool hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
@@ -3437,11 +3519,13 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
int /* totvert,*/ totedge, totface;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
const bool is_obact = (ob == OBACT);
- int draw_flags = (is_obact && paint_facesel_test(ob)) ? DRAW_FACE_SELECT : 0;
+ int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
if (!dm)
return;
+ DM_update_materials(dm, ob);
+
/* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
* Note: Last "preview-active" modifier in stack will win! */
if (DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL) && modifiers_isPreview(ob))
@@ -3477,6 +3561,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
check_object_draw_texture(scene, v3d, dt))
{
+ bool draw_loose = true;
+
if ((v3d->flag & V3D_SELECT_OUTLINE) &&
((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
(base->flag & SELECT) &&
@@ -3487,9 +3573,31 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ Paint *p;
+
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- dm->drawFacesGLSL(dm, GPU_enable_material);
+ if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
+ GPUVertexAttribs gattribs;
+ float planes[4][4];
+ float (*fpl)[4] = NULL;
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+
+ if (ob->sculpt->partial_redraw) {
+ if (ar->do_draw & RGN_DRAW_PARTIAL) {
+ sculpt_get_redraw_planes(planes, ar, rv3d, ob);
+ fpl = planes;
+ ob->sculpt->partial_redraw = 0;
+ }
+ }
+
+ GPU_enable_material(1, &gattribs);
+ dm->drawFacesSolid(dm, fpl, fast, NULL);
+ draw_loose = false;
+ }
+ else
+ dm->drawFacesGLSL(dm, GPU_enable_material);
+
// if (BKE_bproperty_object_get(ob, "Text"))
// XXX draw_mesh_text(ob, 1);
GPU_disable_material();
@@ -3503,7 +3611,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
}
- if (!(draw_flags & DRAW_FACE_SELECT)) {
+ if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
gpuColor3ubv(ob_wire_col);
@@ -3589,7 +3697,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
float planes[4][4];
float (*fpl)[4] = NULL;
- int fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
+ const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
if (ob->sculpt->partial_redraw) {
if (ar->do_draw & RGN_DRAW_PARTIAL) {
@@ -3657,7 +3765,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
gpuDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
}
- dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES));
+ dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
gpuDepthMask(GL_TRUE);
@@ -3665,7 +3773,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
}
- if (is_obact && paint_vertsel_test(ob)) {
+ if (is_obact && BKE_paint_select_vert_test(ob)) {
const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
gpuColor3P(CPACK_BLACK);
@@ -3698,7 +3806,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
if (v3d->flag2 & V3D_RENDER_SHADOW) {
for (i = 0; i < ob->totcol; ++i) {
Material *ma = give_current_material(ob, i);
- if (ma && !(ma->mode & MA_SHADBUF)) {
+ if (ma && !(ma->mode2 & MA_CASTSHADOW)) {
return true;
}
}
@@ -3725,6 +3833,9 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
scene->customdata_mask);
+ DM_update_materials(finalDM, ob);
+ DM_update_materials(cageDM, ob);
+
if (dt > OB_WIRE) {
const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
@@ -3740,7 +3851,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
}
else {
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
- if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb))) {
+ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
const bool check_alpha = check_alpha_pass(base);
@@ -4043,6 +4154,8 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
return true;
}
+ DM_update_materials(dm, ob);
+
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
if (dt > OB_WIRE && dm->getNumTessFaces(dm)) {
@@ -4205,7 +4318,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
break;
}
- return FALSE;
+ return false;
}
static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
@@ -4499,8 +4612,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
float cfra;
float ma_col[3] = {0.0f, 0.0f, 0.0f};
int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0;
- int select = ob->flag & SELECT, create_cdata = 0, need_v = 0;
+ bool select = (ob->flag & SELECT) != 0, create_cdata = false, need_v = false;
char numstr[32];
+ size_t numstr_len;
unsigned char tcol[4] = {0, 0, 0, 255};
/* 1. */
@@ -4751,8 +4865,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
else
pa_health = -1.0;
- r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
+ r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
if (part->draw_col > PART_DRAW_COL_MAT) {
switch (part->draw_col) {
@@ -4779,8 +4893,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_health = -1.0;
- r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
+ r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
}
drawn = 0;
@@ -4848,28 +4962,32 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if ((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) &&
(v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
{
+ size_t numstr_len;
float vec_txt[3];
char *val_pos = numstr;
numstr[0] = '\0';
if (part->draw & PART_DRAW_NUM) {
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
- BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
+ numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
}
else {
- BLI_snprintf(val_pos, sizeof(numstr), "%d", a);
+ numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d", a);
}
}
else {
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
- BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health);
+ numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health);
}
}
- /* in path drawing state.co is the end point */
- /* use worldspace beause object matrix is already applied */
- mul_v3_m4v3(vec_txt, ob->imat, state.co);
- view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
+ if (numstr[0]) {
+ /* in path drawing state.co is the end point */
+ /* use worldspace beause object matrix is already applied */
+ mul_v3_m4v3(vec_txt, ob->imat, state.co);
+ view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
+ 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
+ }
}
}
}
@@ -4973,10 +5091,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
float vec_txt[3];
- BLI_snprintf(numstr, sizeof(numstr), "%i", a);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%i", a);
/* use worldspace beCause object matrix is already applied */
mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
- view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
+ view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
+ 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
}
}
}
@@ -5492,7 +5611,7 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
{
BezTriple *bezt;
- float *fp;
+ const float *fp;
int a;
if (nu->hide || hide_handles) return;
@@ -5552,7 +5671,7 @@ static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
static void drawhandlesN_active(Nurb *nu)
{
BezTriple *bezt;
- float *fp;
+ const float *fp;
int a;
if (nu->hide) return;
@@ -6601,6 +6720,12 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
DerivedMesh *dm = ob->derivedFinal;
bool has_faces = false;
+ if (dm)
+ DM_update_materials(dm, ob);
+#ifdef SEQUENCER_DAG_WORKAROUND
+ ensure_curve_cache(scene, ob);
+#endif
+
if (dm) {
has_faces = dm->getNumTessFaces(dm) > 0;
}
@@ -6608,7 +6733,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
has_faces = BKE_displist_has_faces(&ob->curve_cache->disp);
}
- if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) {
+ if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) {
draw_index_wire = false;
if (dm) {
draw_mesh_object_outline(v3d, ob, dm);
@@ -6634,7 +6759,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
gpuDepthMask(GL_TRUE);
}
-static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsigned char ob_wire_col[4])
+static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
{
if (ELEM4(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
@@ -6649,7 +6774,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign
gpuDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */
if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
- if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) {
+ if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
if (ob->type == OB_CURVE)
draw_index_wire = false;
@@ -6713,7 +6838,8 @@ static void draw_hooks(Object *ob)
gpuImmediateUnformat();
}
-static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const short dflag, unsigned char ob_wire_col[4])
+static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
+ const short dflag, const unsigned char ob_wire_col[4])
{
const char *axis_str[3] = {"px", "py", "pz"};
int axis;
@@ -6745,7 +6871,7 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const short d
/* when const color is set wirecolor is NULL - we could get the current color but
* with selection and group instancing its not needed to draw the text */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
+ view3d_cached_text_draw_add(v, axis_str[axis], 2, 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
}
}
@@ -6899,14 +7025,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
Curve *cu;
RegionView3D *rv3d = ar->regiondata;
float vec1[3], vec2[3];
- unsigned char _ob_wire_col[4]; /* dont initialize this */
- unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
+ unsigned char _ob_wire_col[4]; /* dont initialize this */
+ const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
int i, selstart, selend, empty_object = 0;
short dtx;
char dt;
bool zbufoff = false, is_paint = false;
const bool is_obact = (ob == OBACT);
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
+ const bool is_picking = (G.f & G_PICKSEL) != 0;
bool particle_skip_object = false; /* Draw particles but not their emitter object. */
if (ob != scene->obedit) {
@@ -7005,21 +7132,20 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (dt < OB_SOLID) {
zbufoff = 1;
dt = OB_SOLID;
- is_paint = true;
}
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
dt = OB_PAINT;
- is_paint = true;
}
+ is_paint = true;
glEnable(GL_DEPTH_TEST);
}
}
}
/* matcap check - only when not painting color */
- if ((v3d->flag2 & V3D_SOLID_MATCAP) && (dt == OB_SOLID) && (is_paint == false)) {
+ if ((v3d->flag2 & V3D_SOLID_MATCAP) && (dt == OB_SOLID) && (is_paint == false && is_picking == false)) {
draw_object_matcap_check(v3d, ob);
}
@@ -7046,7 +7172,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
switch (ob->type) {
case OB_MESH:
empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
- if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+ /* mesh draws wire itself */
+ dtx &= ~OB_DRAWWIRE;
+ }
break;
case OB_FONT:
@@ -7192,7 +7321,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
draw_bounding_volume(ob, ob->boundtype);
}
}
- else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) {
+ else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
@@ -7213,7 +7342,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
draw_bounding_volume(ob, ob->boundtype);
}
}
- else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) {
+ else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
//XXX old animsys if (cu->path)
@@ -7250,7 +7379,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
break;
case OB_LAMP:
if (!render_override) {
- drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawlamp(v3d, rv3d, base, dt, dflag, ob_wire_col, is_obact);
}
break;
case OB_CAMERA:
@@ -7540,7 +7669,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* but, we also don't draw names for sets or duplicators */
if (dflag == 0) {
const float zero[3] = {0, 0, 0};
- view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, ob_wire_col);
+ view3d_cached_text_draw_add(zero, ob->id.name + 2, strlen(ob->id.name + 2), 10, 0, ob_wire_col);
}
}
/*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -7712,7 +7841,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
else {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) {
ListBase targets = {NULL, NULL};
@@ -7983,6 +8112,8 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
gpuColor3P(CPACK_BLACK);
+ DM_update_materials(dm, ob);
+
dm->drawMappedFaces(dm, (DMSetDrawOptions)bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
bbs_obmode_mesh_verts(ob, dm, 1);
@@ -7997,6 +8128,8 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
gpuImmediateFormat_C4_V3();
+ DM_update_materials(dm, ob);
+
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
dm->drawMappedFaces(dm, (DMSetDrawOptions)bbs_mesh_solid_hide__setDrawOpts, GPU_enable_material, NULL, me, 0);
else
@@ -8027,6 +8160,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
+ DM_update_materials(dm, ob);
+
bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
if (ts->selectmode & SCE_SELECT_FACE)
bm_solidoffs = 1 + em->bm->totface;
@@ -8085,10 +8220,14 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
DerivedMesh *dm = NULL, *edm = NULL;
int glsl;
- if (ob->mode & OB_MODE_EDIT)
+ if (ob->mode & OB_MODE_EDIT) {
edm = editbmesh_get_derived_base(ob, me->edit_btmesh);
- else
+ DM_update_materials(edm, ob);
+ }
+ else {
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ DM_update_materials(dm, ob);
+ }
if (dt <= OB_WIRE) {
if (dm)
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 55dcca5e0ab..0eaa8620f31 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -41,29 +41,9 @@
#include "DNA_property_types.h"
#include "BLI_utildefines.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
-
-#include "BKE_curve.h"
-#include "BKE_constraint.h" /* for the get_constraint_target function */
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
-#include "BKE_effect.h"
-#include "BKE_font.h"
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_key.h"
-#include "BKE_lattice.h"
-#include "BKE_mesh.h"
-#include "BKE_material.h"
-#include "BKE_mball.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
-#include "BKE_paint.h"
+
#include "BKE_particle.h"
-#include "BKE_property.h"
-#include "BKE_smoke.h"
#include "smoke_API.h"
@@ -117,8 +97,8 @@ static bool convex(const float p0[3], const float up[3], const float a[3], const
}
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
- GPUTexture *tex, float min[3], float max[3],
- int res[3], float dx, float UNUSED(base_scale), float viewnormal[3],
+ GPUTexture *tex, const float min[3], const float max[3],
+ const int res[3], float dx, float UNUSED(base_scale), const float viewnormal[3],
GPUTexture *tex_shadow, GPUTexture *tex_flame)
{
const float ob_sizei[3] = {
@@ -412,9 +392,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
}
if (!GPU_non_power_of_two_support()) {
- cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]);
- cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]);
- cor[2] = (float)res[2] / (float)power_of_2_max_i(res[2]);
+ cor[0] = (float)res[0] / (float)power_of_2_max_u(res[0]);
+ cor[1] = (float)res[1] / (float)power_of_2_max_u(res[1]);
+ cor[2] = (float)res[2] / (float)power_of_2_max_u(res[2]);
}
cor[0] /= size[0];
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 5b2853e6cbc..3cc1d2f8375 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -49,10 +49,8 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "ED_render.h"
#include "ED_space_api.h"
#include "ED_screen.h"
-#include "ED_object.h"
#include "GPU_glew.h"
#include "GPU_extensions.h"
@@ -320,7 +318,7 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->lay = v3d->layact = scene->lay;
v3d->camera = scene->camera;
}
- v3d->scenelock = TRUE;
+ v3d->scenelock = true;
v3d->grid = 1.0f;
v3d->gridlines = 16;
v3d->gridsubdiv = 10;
@@ -708,7 +706,6 @@ static void *view3d_main_area_duplicate(void *poin)
new->gpuoffscreen = NULL;
new->ri = NULL;
new->render_engine = NULL;
- new->gpd = NULL;
new->sms = NULL;
new->smooth_timer = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 70f05770452..dfbae90655c 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -56,8 +56,6 @@
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
#include "BKE_deform.h"
@@ -73,8 +71,6 @@
#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_transform.h"
-#include "ED_curve.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -402,12 +398,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by SubSurf modifier"));
/* customdata layer added on demand */
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Weight used by Bevel modifier"));
}
if (totskinradius) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
@@ -930,7 +926,7 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
{
uiLayout *split, *colsub;
- split = uiLayoutSplit(layout, 0.8f, FALSE);
+ split = uiLayoutSplit(layout, 0.8f, false);
if (ptr->type == &RNA_PoseBone) {
PointerRNA boneptr;
@@ -940,19 +936,19 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
bone = boneptr.data;
uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
}
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "location", 0, NULL, ICON_NONE);
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemL(colsub, "", ICON_NONE);
uiItemR(colsub, ptr, "lock_location", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- split = uiLayoutSplit(layout, 0.8f, FALSE);
+ split = uiLayoutSplit(layout, 0.8f, false);
switch (RNA_enum_get(ptr, "rotation_mode")) {
case ROT_MODE_QUAT: /* quaternion */
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "rotation_quaternion", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
if (RNA_boolean_get(ptr, "lock_rotations_4d"))
uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE + UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
@@ -961,9 +957,9 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
break;
case ROT_MODE_AXISANGLE: /* axis angle */
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "rotation_axis_angle", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, IFACE_("4L"), ICON_NONE);
if (RNA_boolean_get(ptr, "lock_rotations_4d"))
uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
@@ -972,19 +968,19 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
break;
default: /* euler rotations */
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "rotation_euler", 0, IFACE_("Rotation"), ICON_NONE);
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemL(colsub, "", ICON_NONE);
uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
break;
}
uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NONE);
- split = uiLayoutSplit(layout, 0.8f, FALSE);
- colsub = uiLayoutColumn(split, TRUE);
+ split = uiLayoutSplit(layout, 0.8f, false);
+ colsub = uiLayoutColumn(split, true);
uiItemR(colsub, ptr, "scale", 0, NULL, ICON_NONE);
- colsub = uiLayoutColumn(split, TRUE);
+ colsub = uiLayoutColumn(split, true);
uiItemL(colsub, "", ICON_NONE);
uiItemR(colsub, ptr, "lock_scale", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
@@ -1013,7 +1009,7 @@ static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &pchanptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
/* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
* but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
@@ -1037,7 +1033,7 @@ static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, &eboneptr, "head", 0, NULL, ICON_NONE);
if (ebone->parent && ebone->flag & BONE_CONNECTED) {
PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
@@ -1067,7 +1063,7 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr);
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
uiItemR(col, &ptr, "co", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "radius", 0, NULL, ICON_NONE);
@@ -1075,7 +1071,7 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
uiItemR(col, &ptr, "type", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, TRUE);
+ col = uiLayoutColumn(layout, true);
switch (RNA_enum_get(&ptr, "type")) {
case MB_BALL:
break;
@@ -1144,7 +1140,7 @@ static void view3d_panel_transform(const bContext *C, Panel *pa)
block = uiLayoutGetBlock(pa->layout);
uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
- col = uiLayoutColumn(pa->layout, FALSE);
+ col = uiLayoutColumn(pa->layout, false);
if (ob == obedit) {
if (ob->type == OB_ARMATURE) {
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 2797125485c..230df49f386 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -185,7 +185,6 @@ struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
rv3d->dist = 0.0;
}
else {
- float tvec[3];
/* perspective or ortho */
if (rv3d->persp == RV3D_ORTHO)
rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */
@@ -200,11 +199,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
* but to correct the dist removal we must
* alter offset so the view doesn't jump. */
- rv3d->dist = 0.0f;
-
- copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup);
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
- sub_v3_v3(rv3d->ofs, tvec);
+ ED_view3d_distance_set(rv3d, 0.0f);
/* Done with correcting for the dist */
}
@@ -316,7 +311,6 @@ void ED_view3d_cameracontrol_release(
View3D *v3d = vctrl->ctx_v3d;
RegionView3D *rv3d = vctrl->ctx_rv3d;
- rv3d->dist = vctrl->dist_backup;
if (restore) {
/* Revert to original view? */
if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */
@@ -334,21 +328,19 @@ void ED_view3d_cameracontrol_release(
}
/* always, is set to zero otherwise */
copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
}
else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */
DAG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB);
/* always, is set to zero otherwise */
copy_v3_v3(rv3d->ofs, vctrl->ofs_backup);
+ rv3d->dist = vctrl->dist_backup;
}
else { /* not camera */
- float tvec[3];
-
/* Apply the fly mode view */
/* restore the dist */
- copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup);
- mul_mat3_m4_v3(rv3d->viewinv, tvec);
- add_v3_v3(rv3d->ofs, tvec);
+ ED_view3d_distance_set(rv3d, vctrl->dist_backup);
/* Done with correcting for the dist */
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 89bef9bc5fd..6e795fa39ea 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -578,6 +578,8 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
GPU_raster_begin();
+ UI_ThemeColor(TH_VIEW_OVERLAY);
+
gpuImmediateFormat_V2(); // DOODLE: view3d cursor, 2 stippled circles, 4 mono lines
GPU_raster_set_line_style(0);
@@ -589,7 +591,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
gpuRepeat();
GPU_raster_set_line_style(0);
- gpuColor3P(CPACK_BLACK);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
gpuBegin(GL_LINES);
gpuAppendLinei(co[0] - f20, co[1], co[0] - f5, co[1]);
@@ -932,11 +934,11 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
const char *name = view3d_get_name(v3d, rv3d);
- /* XXX 24 may be a bit small for unicode languages (Chinese in utf-8...) */
+ /* increase size for unicode languages (Chinese in utf-8...) */
#ifdef WITH_INTERNATIONAL
- char tmpstr[64];
+ char tmpstr[96];
#else
- char tmpstr[24];
+ char tmpstr[32];
#endif
if (v3d->localvd) {
@@ -963,7 +965,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
const char *msg_sep = " : ";
char info[300];
- char *markern;
+ const char *markern;
char *s = info;
short offset = 1.5f * UI_UNIT_X + rect->xmin;
@@ -1077,6 +1079,9 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV
/* get camera viewplane */
BKE_camera_params_init(&params);
+ /* fallback for non camera objects */
+ params.clipsta = v3d->near;
+ params.clipend = v3d->far;
BKE_camera_params_from_object(&params, v3d->camera);
if (no_shift) {
params.shiftx = 0.0f;
@@ -1166,10 +1171,10 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
float hmargin, vmargin;
float x1, x2, y1, y2;
float x1i, x2i, y1i, y2i;
- float x3, y3, x4, y4;
+
rctf viewborder;
Camera *ca = NULL;
- RegionView3D *rv3d = (RegionView3D *)ar->regiondata;
+ RegionView3D *rv3d = ar->regiondata;
GPU_raster_begin();
@@ -1244,16 +1249,18 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
gpuDrawWireRectf(x1i - 1, y1i - 1, x2i + 1, y2i + 1);
}
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
gpuDrawWireRectf(x1i, y1i, x2i, y2i);
/* border */
if (scene->r.mode & R_BORDER) {
+ float x3, y3, x4, y4;
+
x3 = x1 + scene->r.border.xmin * (x2 - x1);
y3 = y1 + scene->r.border.ymin * (y2 - y1);
x4 = x1 + scene->r.border.xmax * (x2 - x1);
y4 = y1 + scene->r.border.ymax * (y2 - y1);
-
+
gpuColor3P(0x4040FF);
gpuDrawWireRecti(x3, y3, x4, y4);
}
@@ -1265,7 +1272,9 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
gpuImmediateFormat_V2();
if (ca->dtx & CAM_DTX_CENTER) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ float x3, y3;
+
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
x3 = x1 + 0.5f * (x2 - x1);
y3 = y1 + 0.5f * (y2 - y1);
@@ -1277,7 +1286,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
}
if (ca->dtx & CAM_DTX_CENTER_DIAG) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
gpuBegin(GL_LINES);
gpuAppendLinef(x1, y1, x2, y2);
@@ -1286,39 +1295,39 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
}
if (ca->dtx & CAM_DTX_THIRDS) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_grid3(x1, x2, y1, y2, 1.0f / 3.0f);
}
if (ca->dtx & CAM_DTX_GOLDEN) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_grid3(x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_triangle(x1, x2, y1, y2, 0, 'A');
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_triangle(x1, x2, y1, y2, 0, 'B');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_triangle(x1, x2, y1, y2, 1, 'A');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
}
gpuImmediateUnformat();
if (ca->flag & CAM_SHOWTITLESAFE) {
- UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
hmargin = 0.1f * (x2 - x1);
vmargin = 0.05f * (y2 - y1);
@@ -1328,7 +1337,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
vmargin = 0.035f * (y2 - y1);
uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
}
- if (ca && (ca->flag & CAM_SHOWSENSOR)) {
+ if (ca->flag & CAM_SHOWSENSOR) {
/* determine sensor fit, and get sensor x/y, for auto fit we
* assume and square sensor and only use sensor_x */
float sizex = scene->r.xsch * scene->r.xasp;
@@ -1360,7 +1369,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
}
/* draw */
- UI_ThemeColorShade(TH_WIRE, 100);
+ UI_ThemeColorShade(TH_VIEW_OVERLAY, 100);
uiDrawBox(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
}
}
@@ -1390,7 +1399,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
if (base && (base->object->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) ||
- paint_facesel_test(base->object)))
+ BKE_paint_select_face_test(base->object)))
{
/* do nothing */
}
@@ -1421,7 +1430,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
}
#endif
- if (v3d->drawtype > OB_WIRE) v3d->zbuf = TRUE;
+ if (v3d->drawtype > OB_WIRE) v3d->zbuf = true;
/* dithering and AA break color coding, so disable */
glDisable(GL_DITHER);
@@ -1491,7 +1500,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
v3d->flag &= ~V3D_INVALID_BACKBUF;
G.f &= ~G_BACKBUFSEL;
- v3d->zbuf = FALSE;
+ v3d->zbuf = false;
glDisable(GL_DEPTH_TEST);
glEnable(GL_DITHER);
@@ -1924,7 +1933,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
gpuColor4P(CPACK_WHITE, 1 - bgpic->blend);
/* could not use glaDrawPixelsAuto because it could fallback to
- * glaDrawPixelsSafe in some cases, which will end up in misssing
+ * glaDrawPixelsSafe in some cases, which will end up in missing
* alpha transparency for the background image (sergey)
*/
glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
@@ -1998,7 +2007,7 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
View3DAfter *v3da, *next;
gpuDepthMask(GL_FALSE);
- v3d->transp = TRUE;
+ v3d->transp = true;
for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) {
next = v3da->next;
@@ -2006,41 +2015,41 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
BLI_remlink(&v3d->afterdraw_transp, v3da);
MEM_freeN(v3da);
}
- v3d->transp = FALSE;
+ v3d->transp = false;
gpuDepthMask(GL_TRUE);
}
/* clears zbuffer and draws it over */
-static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear)
+static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
{
View3DAfter *v3da, *next;
if (clear && v3d->zbuf)
glClear(GL_DEPTH_BUFFER_BIT);
- v3d->xray = TRUE;
+ v3d->xray = true;
for (v3da = v3d->afterdraw_xray.first; v3da; v3da = next) {
next = v3da->next;
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
BLI_remlink(&v3d->afterdraw_xray, v3da);
MEM_freeN(v3da);
}
- v3d->xray = FALSE;
+ v3d->xray = false;
}
/* clears zbuffer and draws it over */
-static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int clear)
+static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
{
View3DAfter *v3da, *next;
if (clear && v3d->zbuf)
glClear(GL_DEPTH_BUFFER_BIT);
- v3d->xray = TRUE;
- v3d->transp = TRUE;
+ v3d->xray = true;
+ v3d->transp = true;
for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) {
next = v3da->next;
@@ -2049,8 +2058,8 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int c
MEM_freeN(v3da);
}
- v3d->transp = FALSE;
- v3d->xray = FALSE;
+ v3d->transp = false;
+ v3d->xray = false;
}
@@ -2087,7 +2096,6 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
RegionView3D *rv3d = ar->regiondata;
ListBase *lb;
LodLevel *savedlod;
- float savedobmat[4][4];
DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
Base tbase = {NULL};
short transflag;
@@ -2098,13 +2106,16 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
#endif
char dt;
short dtx;
-
+ DupliApplyData *apply_data;
+
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
tbase.flag = OB_FROMDUPLI | base->flag;
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
// BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+ apply_data = duplilist_apply_matrix(lb);
+
dob = dupli_step(lb->first);
if (dob) dob_next = dupli_step(dob->next);
@@ -2113,11 +2124,13 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
/* Make sure lod is updated from dupli's position */
- copy_m4_m4(savedobmat, dob->ob->obmat);
- copy_m4_m4(dob->ob->obmat, dob->mat);
savedlod = dob->ob->currentlod;
- BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
-
+
+#ifdef WITH_GAMEENGINE
+ if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
+ BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
+ }
+#endif
/* extra service: draw the duplicator in drawtype of parent, minimum taken
* to allow e.g. boundbox box objects in groups for LOD */
@@ -2193,14 +2206,16 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
#if defined(WITH_GL_PROFILE_COMPAT)
if (use_displist) {
- gpuMultMatrix(dob->mat[0]);
- if (ED_view3d_boundbox_clip(rv3d, dob->mat, &bb))
+ if (ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
+ gpuMultMatrix(dob->mat[0]);
glCallList(displist);
- gpuLoadMatrix(rv3d->viewmat[0]);
+ gpuLoadMatrix(rv3d->viewmat[0]);
+ }
}
else
#endif
{
+ copy_m4_m4(dob->ob->obmat, dob->mat);
draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
}
@@ -2208,11 +2223,13 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
tbase.object->dtx = dtx;
tbase.object->transflag = transflag;
tbase.object->currentlod = savedlod;
- copy_m4_m4(tbase.object->obmat, savedobmat);
}
-
- /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
-
+
+ if (apply_data) {
+ duplilist_restore_matrix(lb, apply_data);
+ duplilist_free_apply_data(apply_data);
+ }
+
free_object_duplilist(lb);
#if defined(WITH_GL_PROFILE_COMPAT)
@@ -2349,8 +2366,8 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
short zbuf = v3d->zbuf;
RegionView3D *rv3d = ar->regiondata;
- setwinmatrixview3d(ar, v3d, NULL);
- setviewmatrixview3d(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+ view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
invert_m4_m4(rv3d->persinv, rv3d->persmat);
@@ -2360,7 +2377,7 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
gpuLoadMatrix(rv3d->viewmat[0]);
- v3d->zbuf = TRUE;
+ v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
@@ -2386,8 +2403,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
U.obcenter_dia = 0;
- setwinmatrixview3d(ar, v3d, NULL);
- setviewmatrixview3d(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+ view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
invert_m4_m4(rv3d->persinv, rv3d->persmat);
@@ -2402,7 +2419,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
ED_view3d_clipping_set(rv3d);
}
- v3d->zbuf = TRUE;
+ v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
/* draw set first */
@@ -2440,7 +2457,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
View3DAfter *v3da, *next;
int mask_orig;
- v3d->xray = TRUE;
+ v3d->xray = true;
/* transp materials can change the depth mask, see #21388 */
mask_orig = gpuGetDepthWriteMask();
@@ -2456,8 +2473,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
}
/* draw 3 passes, transp/xray/xraytransp */
- v3d->xray = FALSE;
- v3d->transp = TRUE;
+ v3d->xray = false;
+ v3d->transp = true;
for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) {
next = v3da->next;
draw_object(scene, ar, v3d, v3da->base, 0);
@@ -2465,8 +2482,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
MEM_freeN(v3da);
}
- v3d->xray = TRUE;
- v3d->transp = FALSE;
+ v3d->xray = true;
+ v3d->transp = false;
for (v3da = v3d->afterdraw_xray.first; v3da; v3da = next) {
next = v3da->next;
draw_object(scene, ar, v3d, v3da->base, 0);
@@ -2474,8 +2491,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
MEM_freeN(v3da);
}
- v3d->xray = TRUE;
- v3d->transp = TRUE;
+ v3d->xray = true;
+ v3d->transp = true;
for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) {
next = v3da->next;
draw_object(scene, ar, v3d, v3da->base, 0);
@@ -2484,8 +2501,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
}
- v3d->xray = FALSE;
- v3d->transp = FALSE;
+ v3d->xray = false;
+ v3d->transp = false;
gpuDepthMask(mask_orig);
}
@@ -2507,11 +2524,12 @@ typedef struct View3DShadow {
} View3DShadow;
static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par,
- float obmat[4][4], ListBase *shadows)
+ float obmat[4][4], ListBase *shadows, SceneRenderLayer *srl)
{
GPULamp *lamp;
Lamp *la = (Lamp *)ob->data;
View3DShadow *shadow;
+ unsigned int layers;
lamp = GPU_lamp_from_blender(scene, ob, par);
@@ -2519,7 +2537,11 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
- if ((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) {
+ layers = ob->lay & v3d->lay;
+ if (srl)
+ layers &= srl->lay;
+
+ if (layers && GPU_lamp_override_visible(lamp, srl, NULL) && GPU_lamp_has_shadow_buffer(lamp)) {
shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
shadow->lamp = lamp;
BLI_addtail(shadows, shadow);
@@ -2534,6 +2556,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
Scene *sce_iter;
Base *base;
Object *ob;
+ SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
BLI_listbase_clear(&shadows);
@@ -2542,7 +2565,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
ob = base->object;
if (ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, &shadows);
+ gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, &shadows, srl);
if (ob->transflag & OB_DUPLI) {
DupliObject *dob;
@@ -2550,7 +2573,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
for (dob = lb->first; dob; dob = dob->next)
if (dob->ob->type == OB_LAMP)
- gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, &shadows);
+ gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, &shadows, srl);
free_object_duplilist(lb);
}
@@ -2645,13 +2668,13 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
if (winmat)
copy_m4_m4(rv3d->winmat, winmat);
else
- setwinmatrixview3d(ar, v3d, NULL);
+ view3d_winmatrix_set(ar, v3d, NULL);
/* setup view matrix */
if (viewmat)
copy_m4_m4(rv3d->viewmat, viewmat);
else
- setviewmatrixview3d(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
/* update utilitity matrices */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
@@ -2680,6 +2703,172 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
}
}
+
+
+/**
+ * Shared by #ED_view3d_draw_offscreen and #view3d_main_area_draw_objects
+ *
+ * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set.
+ * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here.
+ */
+static void view3d_draw_objects(
+ const bContext *C,
+ Scene *scene, View3D *v3d, ARegion *ar,
+ const char **grid_unit,
+ const bool do_bgpic, const bool draw_offscreen)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ Base *base;
+ const bool do_camera_frame = !draw_offscreen;
+
+ if (!draw_offscreen) {
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ view3d_draw_clipping(rv3d);
+
+ /* set zbuffer after we draw clipping region */
+ if (v3d->drawtype > OB_WIRE) {
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
+ }
+ else {
+ v3d->zbuf = false;
+ }
+
+ if (!draw_offscreen) {
+ /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
+ rv3d->gridview = v3d->grid;
+ if (scene->unit.system) {
+ rv3d->gridview /= scene->unit.scale_length;
+ }
+
+ if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ drawfloor(scene, v3d, grid_unit);
+ }
+ }
+ else {
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ ED_region_pixelspace(ar);
+ drawgrid(&scene->unit, ar, v3d, grid_unit);
+ /* XXX make function? replaces persp(1) */
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(rv3d->winmat);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(rv3d->viewmat);
+ }
+ }
+ }
+
+ /* important to do before clipping */
+ if (do_bgpic) {
+ view3d_draw_bgpic_test(scene, ar, v3d, false, do_camera_frame);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+
+ /* draw set first */
+ if (scene->set) {
+ Scene *sce_iter;
+ for (SETLOOPER(scene->set, sce_iter, base)) {
+ if (v3d->lay & base->lay) {
+ UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
+ draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET);
+
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE);
+ }
+ }
+ }
+
+ /* Transp and X-ray afterdraw stuff for sets is done later */
+ }
+
+
+ if (draw_offscreen) {
+ for (base = scene->base.first; base; base = base->next) {
+ if (v3d->lay & base->lay) {
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI)
+ draw_dupli_objects(scene, ar, v3d, base);
+
+ draw_object(scene, ar, v3d, base, 0);
+ }
+ }
+ }
+ else {
+ unsigned int lay_used = 0;
+
+ /* then draw not selected and the duplis, but skip editmode object */
+ for (base = scene->base.first; base; base = base->next) {
+ lay_used |= base->lay;
+
+ if (v3d->lay & base->lay) {
+
+ /* dupli drawing */
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(scene, ar, v3d, base);
+ }
+ if ((base->flag & SELECT) == 0) {
+ if (base->object != scene->obedit)
+ draw_object(scene, ar, v3d, base, 0);
+ }
+ }
+ }
+
+ /* mask out localview */
+ v3d->lay_used = lay_used & ((1 << 20) - 1);
+
+ /* draw selected and editmode */
+ for (base = scene->base.first; base; base = base->next) {
+ if (v3d->lay & base->lay) {
+ if (base->object == scene->obedit || (base->flag & SELECT)) {
+ draw_object(scene, ar, v3d, base, 0);
+ }
+ }
+ }
+ }
+
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* must be before xray draw which clears the depth buffer */
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ draw_gpencil_view3d(scene, v3d, ar, true);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+
+ /* transp and X-ray afterdraw stuff */
+ if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
+ if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, true);
+ if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, true);
+
+ if (!draw_offscreen) {
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING)
+ ED_view3d_clipping_disable();
+
+ /* important to do after clipping */
+ if (do_bgpic) {
+ view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
+ }
+
+ if (!draw_offscreen) {
+ BIF_draw_manipulator(C);
+ }
+
+ /* cleanup */
+ if (v3d->zbuf) {
+ v3d->zbuf = false;
+ glDisable(GL_DEPTH_TEST);
+ }
+}
+
static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -2704,10 +2893,9 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
* stuff like shadow buffers
*/
void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
- float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky)
+ float viewmat[4][4], float winmat[4][4],
+ bool do_bgpic, bool do_sky)
{
- RegionView3D *rv3d = ar->regiondata;
- Base *base;
int bwinx, bwiny;
rcti brect;
@@ -2717,7 +2905,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
bwinx = ar->winx;
bwiny = ar->winy;
brect = ar->winrct;
-
+
ar->winx = winx;
ar->winy = winy;
ar->winrct.xmin = 0;
@@ -2727,13 +2915,15 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
/* set theme */
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
+
/* set flags */
G.f |= G_RENDER_OGL;
- /* free images which can have changed on frame-change
- * warning! can be slow so only free animated images - campbell */
- GPU_free_images_anim();
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ /* free images which can have changed on frame-change
+ * warning! can be slow so only free animated images - campbell */
+ GPU_free_images_anim();
+ }
/* clear opengl buffers */
if (do_sky) {
@@ -2748,91 +2938,28 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
- if (rv3d->rflag & RV3D_CLIPPING)
- view3d_draw_clipping(rv3d);
- /* set zbuffer */
- if (v3d->drawtype > OB_WIRE) {
- v3d->zbuf = TRUE;
- glEnable(GL_DEPTH_TEST);
- }
- else
- v3d->zbuf = FALSE;
+ /* main drawing call */
+ view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true);
- /* important to do before clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, false, false);
- }
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_set(rv3d);
+ if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
+ /* draw grease-pencil stuff */
+ ED_region_pixelspace(ar);
- /* draw set first */
- if (scene->set) {
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
- if (v3d->lay & base->lay) {
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET);
-
- if (base->object->transflag & OB_DUPLI)
- draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE);
- }
- }
- }
-
- /* then draw not selected and the duplis, but skip editmode object */
- for (base = scene->base.first; base; base = base->next) {
- if (v3d->lay & base->lay) {
- /* dupli drawing */
- if (base->object->transflag & OB_DUPLI)
- draw_dupli_objects(scene, ar, v3d, base);
- draw_object(scene, ar, v3d, base, 0);
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ draw_gpencil_view3d(scene, v3d, ar, false);
}
- }
- /* must be before xray draw which clears the depth buffer */
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, true);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ /* freeing the images again here could be done after the operator runs, leaving for now */
+ GPU_free_images_anim();
}
- /* transp and X-ray afterdraw stuff */
- if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
- if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); /* clears zbuffer if it is used! */
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1);
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
-
- /* important to do after clipping */
- if (do_bgpic) {
- view3d_draw_bgpic_test(scene, ar, v3d, true, false);
- }
-
- /* cleanup */
- if (v3d->zbuf) {
- v3d->zbuf = FALSE;
- glDisable(GL_DEPTH_TEST);
- }
-
- /* draw grease-pencil stuff */
- ED_region_pixelspace(ar);
-
-
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- draw_gpencil_view3d(scene, v3d, ar, false);
- }
-
- /* freeing the images again here could be done after the operator runs, leaving for now */
- GPU_free_images_anim();
-
/* restore size */
ar->winx = bwinx;
ar->winy = bwiny;
@@ -2888,6 +3015,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
CameraParams params;
BKE_camera_params_init(&params);
+ /* fallback for non camera objects */
+ params.clipsta = v3d->near;
+ params.clipend = v3d->far;
BKE_camera_params_from_object(&params, v3d->camera);
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -3027,8 +3157,6 @@ void ED_scene_draw_fps(Scene *scene, rcti *rect)
#endif
}
-static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit);
-
static bool view3d_main_area_do_render_draw(Scene *scene)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
@@ -3077,11 +3205,11 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *
return true;
}
-static bool view3d_main_area_draw_engine(const bContext *C, ARegion *ar, bool clip_border, rcti *border_rect)
+static bool view3d_main_area_draw_engine(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ bool clip_border, const rcti *border_rect)
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
RenderEngineType *type;
GLint scissor[4];
@@ -3351,6 +3479,8 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
}
+
+#ifdef WITH_GAMEENGINE
static void update_lods(Scene *scene, float camera_pos[3])
{
Scene *sce_iter;
@@ -3362,15 +3492,14 @@ static void update_lods(Scene *scene, float camera_pos[3])
BKE_object_lod_update(ob, camera_pos);
}
}
+#endif
+
-/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
-static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
+static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
+ ARegion *ar, const char **grid_unit)
{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- Base *base;
- unsigned int lay_used;
+ RegionView3D *rv3d = ar->regiondata;
+ unsigned int lay_used = v3d->lay_used;
/* shadow buffers, before we setup matrices */
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
@@ -3385,93 +3514,31 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
- /* Make sure LoDs are up to date */
- update_lods(scene, rv3d->viewinv[3]);
+ rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
+#ifdef WITH_GAMEENGINE
+ if (STREQ(scene->r.engine, "BLENDER_GAME")) {
+ rv3d->rflag |= RV3D_IS_GAME_ENGINE;
+
+ /* Make sure LoDs are up to date */
+ update_lods(scene, rv3d->viewinv[3]);
+ }
+#endif
/* clear the background */
view3d_main_area_clear(scene, v3d, ar);
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
- if (rv3d->rflag & RV3D_CLIPPING)
- view3d_draw_clipping(rv3d);
-
- /* set zbuffer after we draw clipping region */
- if (v3d->drawtype > OB_WIRE) {
- v3d->zbuf = TRUE;
- glEnable(GL_DEPTH_TEST);
- }
- else
- v3d->zbuf = FALSE;
-
#if defined(WITH_GL_PROFILE_COMPAT) || defined(WITH_GL_PROFILE_CORE)
/* enables anti-aliasing for 3D view drawing */
if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
glEnable(GL_MULTISAMPLE);
}
#endif
+ /* main drawing call */
+ view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false);
- /* needs to be done always, gridview is adjusted in drawgrid() now */
- rv3d->gridview = v3d->grid;
-
- if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- drawfloor(scene, v3d, grid_unit);
- }
- }
- else {
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- ED_region_pixelspace(ar);
- drawgrid(&scene->unit, ar, v3d, grid_unit);
- /* XXX make function? replaces persp(1) */
- gpuMatrixMode(GL_PROJECTION);
- gpuLoadMatrix(rv3d->winmat[0]);
- gpuMatrixMode(GL_MODELVIEW);
- gpuLoadMatrix(rv3d->viewmat[0]);
- }
- }
-
- view3d_draw_bgpic_test(scene, ar, v3d, false, true);
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_set(rv3d);
-
- /* draw set first */
- if (scene->set) {
- Scene *sce_iter;
- for (SETLOOPER(scene->set, sce_iter, base)) {
-
- if (v3d->lay & base->lay) {
-
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR | DRAW_SCENESET);
-
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE);
- }
- }
- }
-
- /* Transp and X-ray afterdraw stuff for sets is done later */
- }
-
- lay_used = 0;
-
- /* then draw not selected and the duplis, but skip editmode object */
- for (base = scene->base.first; base; base = base->next) {
- lay_used |= base->lay & ((1 << 20) - 1);
-
- if (v3d->lay & base->lay) {
-
- /* dupli drawing */
- if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects(scene, ar, v3d, base);
- }
- if ((base->flag & SELECT) == 0) {
- if (base->object != scene->obedit)
- draw_object(scene, ar, v3d, base, 0);
- }
- }
+ /* Disable back anti-aliasing */
+ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
+ glDisable(GL_MULTISAMPLE_ARB);
}
if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */
@@ -3479,52 +3546,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
ScrArea *sa = CTX_wm_area(C);
ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
ED_region_tag_redraw(ar_header); /* can be NULL */
- v3d->lay_used = lay_used;
- }
-
- /* draw selected and editmode */
- for (base = scene->base.first; base; base = base->next) {
- if (v3d->lay & base->lay) {
- if (base->object == scene->obedit || (base->flag & SELECT)) {
- draw_object(scene, ar, v3d, base, 0);
- }
- }
- }
-
-// REEB_draw();
-
- if (v3d->flag2 & V3D_SHOW_GPENCIL) {
- /* must be before xray draw which clears the depth buffer */
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, true);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- }
-
- /* Transp and X-ray afterdraw stuff */
- if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
- if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); /* clears zbuffer if it is used! */
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1);
-
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
-
- if (rv3d->rflag & RV3D_CLIPPING)
- ED_view3d_clipping_disable();
-
- /* important to do after clipping */
- view3d_draw_bgpic_test(scene, ar, v3d, true, true);
-
- BIF_draw_manipulator(C);
-
-#if defined(WITH_GL_PROFILE_COMPAT) || defined(WITH_GL_PROFILE_CORE)
- /* Disable back anti-aliasing */
- if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
- glDisable(GL_MULTISAMPLE);
- }
-#endif
-
- if (v3d->zbuf) {
- v3d->zbuf = FALSE;
- glDisable(GL_DEPTH_TEST);
}
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
@@ -3537,12 +3558,11 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
}
-static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const char *grid_unit, bool render_border)
+static void view3d_main_area_draw_info(const bContext *C, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ const char *grid_unit, bool render_border)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
rcti rect;
/* local coordinate visible rect inside region, to accomodate overlapping ui */
@@ -3595,6 +3615,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
}
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ wmWindowManager *wm = CTX_wm_manager(C);
+
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
ED_scene_draw_fps(scene, &rect);
}
@@ -3632,7 +3654,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(scene) || clip_border) {
- view3d_main_area_draw_objects(C, ar, &grid_unit);
+ view3d_main_area_draw_objects(C, scene, v3d, ar, &grid_unit);
#ifdef DEBUG_DRAW
bl_debug_draw();
#endif
@@ -3641,9 +3663,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
/* draw viewport using external renderer */
if (v3d->drawtype == OB_RENDER)
- view3d_main_area_draw_engine(C, ar, clip_border, &border_rect);
+ view3d_main_area_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
- view3d_main_area_draw_info(C, ar, grid_unit, render_border);
+ view3d_main_area_draw_info(C, scene, ar, v3d, grid_unit, render_border);
v3d->flag |= V3D_INVALID_BACKBUF;
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ab86badf9ff..1524337d6c7 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -35,10 +35,10 @@
#include <float.h>
#include "DNA_armature_types.h"
+#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_camera_types.h"
-#include "DNA_lamp_types.h"
#include "MEM_guardedalloc.h"
@@ -48,6 +48,7 @@
#include "BKE_camera.h"
#include "BKE_context.h"
+#include "BKE_font.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_object.h"
@@ -56,7 +57,6 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_action.h"
-#include "BKE_armature.h"
#include "BKE_depsgraph.h" /* for ED_view3d_camera_lock_sync */
#include "GPU_glew.h"
@@ -83,9 +83,6 @@
#include "view3d_intern.h" /* own include */
-/* for ndof prints */
-// #define DEBUG_NDOF_MOTION
-
bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d)
{
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
@@ -114,15 +111,22 @@ bool ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
(rv3d->persp == RV3D_CAMOB));
}
-void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
+void ED_view3d_camera_lock_init_ex(View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
{
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
- rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ if (calc_dist) {
+ /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
+ rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ }
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
}
+void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
+{
+ ED_view3d_camera_lock_init_ex(v3d, rv3d, true);
+}
+
/* return true if the camera is moved */
bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
{
@@ -489,9 +493,9 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3])
y = BLI_rcti_cent_y(rect) - my;
y /= (float)(BLI_rcti_size_y(rect) / 2);
- d = sqrt(x * x + y * y);
+ d = sqrtf(x * x + y * y);
if (d < radius * (float)M_SQRT1_2) { /* Inside sphere */
- z = sqrt(radius * radius - d * d);
+ z = sqrtf(radius * radius - d * d);
}
else { /* On hyperbola */
t = radius / (float)M_SQRT2;
@@ -525,13 +529,77 @@ static void viewops_data_alloc(bContext *C, wmOperator *op)
vod->rv3d = vod->ar->regiondata;
}
+static void view3d_orbit_apply_dyn_ofs(
+ float r_ofs[3], const float dyn_ofs[3],
+ const float oldquat[4], const float viewquat[4])
+{
+ float q1[4];
+ conjugate_qt_qt(q1, oldquat);
+ mul_qt_qtqt(q1, q1, viewquat);
+
+ conjugate_qt(q1); /* conj == inv for unit quat */
+
+ sub_v3_v3(r_ofs, dyn_ofs);
+ mul_qt_v3(q1, r_ofs);
+ add_v3_v3(r_ofs, dyn_ofs);
+}
+
+static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
+{
+ static float lastofs[3] = {0, 0, 0};
+ bool is_set = false;
+
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = OBACT;
+
+ if (ob && (ob->mode & OB_MODE_ALL_PAINT) && (BKE_object_pose_armature_get(ob) == NULL)) {
+ /* in case of sculpting use last average stroke position as a rotation
+ * center, in other cases it's not clear what rotation center shall be
+ * so just rotate around object origin
+ */
+ if (ob->mode & OB_MODE_SCULPT) {
+ float stroke[3];
+ ED_sculpt_get_average_stroke(ob, stroke);
+ copy_v3_v3(lastofs, stroke);
+ }
+ else {
+ copy_v3_v3(lastofs, ob->obmat[3]);
+ }
+ is_set = true;
+ }
+ else if (ob && (ob->mode & OB_MODE_EDIT) && (ob->type == OB_FONT)) {
+ Curve *cu = ob->data;
+ EditFont *ef = cu->editfont;
+ int i;
+
+ zero_v3(lastofs);
+ for (i = 0; i < 4; i++) {
+ add_v2_v2(lastofs, ef->textcurs[i]);
+ }
+ mul_v2_fl(lastofs, 1.0f / 4.0f);
+
+ mul_m4_v3(ob->obmat, lastofs);
+
+ is_set = true;
+ }
+ else {
+ /* If there's no selection, lastofs is unmodified and last value since static */
+ is_set = calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
+ }
+
+ copy_v3_v3(r_dyn_ofs, lastofs);
+
+ return is_set;
+}
+
/**
* Calculate the values for #ViewOpsData
*/
-static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
+static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *event,
+ const bool use_orbit_select,
+ const bool use_orbit_zbuf)
{
ViewOpsData *vod = op->customdata;
- static float lastofs[3] = {0, 0, 0};
RegionView3D *rv3d = vod->rv3d;
/* set the view from the camera, if view locking is enabled.
@@ -545,35 +613,18 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
vod->origx = vod->oldx = event->x;
vod->origy = vod->oldy = event->y;
vod->origkey = event->type; /* the key that triggered the operator. */
- vod->use_dyn_ofs = (U.uiflag & USER_ORBIT_SELECTION) != 0;
+ vod->use_dyn_ofs = false;
copy_v3_v3(vod->ofs, rv3d->ofs);
- if (vod->use_dyn_ofs) {
- Scene *scene = CTX_data_scene(C);
- Object *ob = OBACT;
-
- if (ob && (ob->mode & OB_MODE_ALL_PAINT) && (BKE_object_pose_armature_get(ob) == NULL)) {
- /* in case of sculpting use last average stroke position as a rotation
- * center, in other cases it's not clear what rotation center shall be
- * so just rotate around object origin
- */
- if (ob->mode & OB_MODE_SCULPT) {
- float stroke[3];
- ED_sculpt_get_average_stroke(ob, stroke);
- copy_v3_v3(lastofs, stroke);
- }
- else {
- copy_v3_v3(lastofs, ob->obmat[3]);
- }
- }
- else {
- /* If there's no selection, lastofs is unmodified and last value since static */
- calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
- }
+ if (use_orbit_select) {
+
+ vod->use_dyn_ofs = true;
+
+ view3d_orbit_calc_center(C, vod->dyn_ofs);
- negate_v3_v3(vod->dyn_ofs, lastofs);
+ negate_v3(vod->dyn_ofs);
}
- else if (U.uiflag & USER_ZBUF_ORBIT) {
+ else if (use_orbit_zbuf) {
Scene *scene = CTX_data_scene(C);
float fallback_depth_pt[3];
@@ -614,7 +665,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
negate_v3_v3(rv3d->ofs, dvec);
}
else {
- float mval_ar_mid[2] = {
+ const float mval_ar_mid[2] = {
(float)vod->ar->winx / 2.0f,
(float)vod->ar->winy / 2.0f};
@@ -652,6 +703,14 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
rv3d->rflag |= RV3D_NAVIGATING;
}
+static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ viewops_data_create_ex(
+ C, op, event,
+ (U.uiflag & USER_ORBIT_SELECTION) != 0,
+ (U.uiflag & USER_ZBUF_ORBIT) != 0);
+}
+
static void viewops_data_free(bContext *C, wmOperator *op)
{
ARegion *ar;
@@ -680,56 +739,6 @@ static void viewops_data_free(bContext *C, wmOperator *op)
/* ************************** viewrotate **********************************/
-#define COS45 0.7071068
-#define SIN45 COS45
-
-#define NUM_SNAP_QUATS 39
-
-static const float snapquats[NUM_SNAP_QUATS][5] = {
- /*{q0, q1, q3, q4, view}*/
- {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},
- {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK},
- {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},
- {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},
- {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},
- {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},
-
- /* some more 45 deg snaps */
- { 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0},
- { 0.9238795, 0.0, 0.0, 0.3826834, 0},
- { 0.0, -0.9238795, 0.3826834, 0.0, 0},
- { 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0},
- { 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0},
- { 0.4999999, -0.4999999, 0.5, 0.5, 0},
- { 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0},
- { 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0},
- { 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0},
- { 0.3826834, 0.0, 0.0, 0.9238794, 0},
- { 0.0, -0.3826834, 0.9238794, 0.0, 0},
- { 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0},
- { 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0},
- { 0.0, 0.0, 0.9238794, 0.3826834, 0},
- {-0.0, 0.0, 0.3826834, 0.9238794, 0},
- {-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0},
- {-0.3826834, 0.0, 0.0, 0.9238794, 0},
- { 0.0, 0.3826834, 0.9238794, 0.0, 0},
- {-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0},
- {-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0},
- {-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0},
- {-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0},
- {-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0},
- {-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0},
- {-0.9238793, 0.0, 0.0, 0.3826833, 0},
- { 0.0, 0.9238793, 0.3826833, 0.0, 0},
- {-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0},
- {-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0},
- {-0.3826833, 0.9238794, 0.0, 0.0, 0},
- {-0.9238794, 0.3826833, 0.0, 0.0, 0},
- {-COS45, 0.0, 0.0, SIN45, 0},
- { COS45, 0.0, 0.0, SIN45, 0},
- { 0.0, 0.0, 0.0, 1.0, 0}
-};
-
enum {
VIEW_PASS = 0,
VIEW_APPLY,
@@ -785,6 +794,117 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
}
+static void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat[4])
+{
+ if (vod->use_dyn_ofs) {
+ RegionView3D *rv3d = vod->rv3d;
+ copy_v3_v3(rv3d->ofs, vod->ofs);
+ view3d_orbit_apply_dyn_ofs(rv3d->ofs, vod->dyn_ofs, vod->oldquat, viewquat);
+ }
+}
+
+static void viewrotate_apply_snap(ViewOpsData *vod)
+{
+ const float axis_limit = DEG2RADF(45 / 3);
+
+ RegionView3D *rv3d = vod->rv3d;
+
+ float viewquat_inv[4];
+ float zaxis[3] = {0, 0, 1};
+ float zaxis_best[3];
+ int x, y, z;
+ bool found = false;
+
+ invert_qt_qt(viewquat_inv, vod->viewquat);
+
+ mul_qt_v3(viewquat_inv, zaxis);
+ normalize_v3(zaxis);
+
+
+ for (x = -1; x < 2; x++) {
+ for (y = -1; y < 2; y++) {
+ for (z = -1; z < 2; z++) {
+ if (x || y || z) {
+ float zaxis_test[3] = {x, y, z};
+
+ normalize_v3(zaxis_test);
+
+ if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) {
+ copy_v3_v3(zaxis_best, zaxis_test);
+ found = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (found) {
+
+ /* find the best roll */
+ float quat_roll[4], quat_final[4], quat_best[4], quat_snap[4];
+ float viewquat_align[4]; /* viewquat aligned to zaxis_best */
+ float viewquat_align_inv[4]; /* viewquat aligned to zaxis_best */
+ float best_angle = axis_limit;
+ int j;
+
+ /* viewquat_align is the original viewquat aligned to the snapped axis
+ * for testing roll */
+ rotation_between_vecs_to_quat(viewquat_align, zaxis_best, zaxis);
+ normalize_qt(viewquat_align);
+ mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
+ normalize_qt(viewquat_align);
+ invert_qt_qt(viewquat_align_inv, viewquat_align);
+
+ vec_to_quat(quat_snap, zaxis_best, OB_NEGZ, OB_POSY);
+ invert_qt(quat_snap);
+ normalize_qt(quat_snap);
+
+ /* check if we can find the roll */
+ found = false;
+
+ /* find best roll */
+ for (j = 0; j < 8; j++) {
+ float angle;
+ float xaxis1[3] = {1, 0, 0};
+ float xaxis2[3] = {1, 0, 0};
+ float quat_final_inv[4];
+
+ axis_angle_to_quat(quat_roll, zaxis_best, (float)j * DEG2RADF(45.0f));
+ normalize_qt(quat_roll);
+
+ mul_qt_qtqt(quat_final, quat_snap, quat_roll);
+ normalize_qt(quat_final);
+
+ /* compare 2 vector angles to find the least roll */
+ invert_qt_qt(quat_final_inv, quat_final);
+ mul_qt_v3(viewquat_align_inv, xaxis1);
+ mul_qt_v3(quat_final_inv, xaxis2);
+ angle = angle_v3v3(xaxis1, xaxis2);
+
+ if (angle <= best_angle) {
+ found = true;
+ best_angle = angle;
+ copy_qt_qt(quat_best, quat_final);
+ }
+ }
+
+ if (found) {
+ /* lock 'quat_best' to an axis view if we can */
+ rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f);
+ if (rv3d->view != RV3D_VIEW_USER) {
+ ED_view3d_quat_from_axis_view(rv3d->view, quat_best);
+ }
+ }
+ else {
+ copy_qt_qt(quat_best, viewquat_align);
+ }
+
+ copy_qt_qt(rv3d->viewquat, quat_best);
+
+ viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
+ }
+}
+
static void viewrotate_apply(ViewOpsData *vod, int x, int y)
{
RegionView3D *rv3d = vod->rv3d;
@@ -819,21 +939,11 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
mul_v3_fl(q1 + 1, sin(phi));
mul_qt_qtqt(vod->viewquat, q1, vod->oldquat);
- if (vod->use_dyn_ofs) {
- /* compute the post multiplication quat, to rotate the offset correctly */
- conjugate_qt_qt(q1, vod->oldquat);
- mul_qt_qtqt(q1, q1, vod->viewquat);
-
- conjugate_qt(q1); /* conj == inv for unit quat */
- copy_v3_v3(rv3d->ofs, vod->ofs);
- sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, vod->dyn_ofs);
- }
+ viewrotate_apply_dyn_ofs(vod, vod->viewquat);
}
else {
/* New turntable view code by John Aughey */
- float q1[4];
+ float quat_local_x[4], quat_global_z[4];
float m[3][3];
float m_inv[3][3];
const float zvec_global[3] = {0.0f, 0.0f, 1.0f};
@@ -873,97 +983,15 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
/* This can likely be computed directly from the quaternion. */
/* Perform the up/down rotation */
- axis_angle_to_quat(q1, xaxis, sensitivity * -(y - vod->oldy));
- mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
-
- if (vod->use_dyn_ofs) {
- conjugate_qt(q1); /* conj == inv for unit quat */
- sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, vod->dyn_ofs);
- }
+ axis_angle_to_quat(quat_local_x, xaxis, sensitivity * -(y - vod->oldy));
+ mul_qt_qtqt(quat_local_x, vod->viewquat, quat_local_x);
/* Perform the orbital rotation */
- axis_angle_normalized_to_quat(q1, zvec_global, sensitivity * vod->reverse * (x - vod->oldx));
- mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
-
- if (vod->use_dyn_ofs) {
- conjugate_qt(q1);
- sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, vod->dyn_ofs);
- }
- }
-
- /* check for view snap */
- if (vod->axis_snap) {
- int i;
- float viewquat_inv[4];
- float zaxis[3] = {0, 0, 1};
- invert_qt_qt(viewquat_inv, vod->viewquat);
-
- mul_qt_v3(viewquat_inv, zaxis);
-
- for (i = 0; i < NUM_SNAP_QUATS; i++) {
-
- float view = (int)snapquats[i][4];
- float viewquat_inv_test[4];
- float zaxis_test[3] = {0, 0, 1};
-
- invert_qt_qt(viewquat_inv_test, snapquats[i]);
- mul_qt_v3(viewquat_inv_test, zaxis_test);
-
- if (angle_v3v3(zaxis_test, zaxis) < DEG2RADF(45 / 3)) {
- /* find the best roll */
- float quat_roll[4], quat_final[4], quat_best[4];
- float viewquat_align[4]; /* viewquat aligned to zaxis_test */
- float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
- float best_angle = FLT_MAX;
- int j;
-
- /* viewquat_align is the original viewquat aligned to the snapped axis
- * for testing roll */
- rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
- normalize_qt(viewquat_align);
- mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
- normalize_qt(viewquat_align);
- invert_qt_qt(viewquat_align_inv, viewquat_align);
-
- /* find best roll */
- for (j = 0; j < 8; j++) {
- float angle;
- float xaxis1[3] = {1, 0, 0};
- float xaxis2[3] = {1, 0, 0};
- float quat_final_inv[4];
-
- axis_angle_to_quat(quat_roll, zaxis_test, (float)j * DEG2RADF(45.0f));
- normalize_qt(quat_roll);
-
- mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
- normalize_qt(quat_final);
-
- /* compare 2 vector angles to find the least roll */
- invert_qt_qt(quat_final_inv, quat_final);
- mul_qt_v3(viewquat_align_inv, xaxis1);
- mul_qt_v3(quat_final_inv, xaxis2);
- angle = angle_v3v3(xaxis1, xaxis2);
-
- if (angle <= best_angle) {
- best_angle = angle;
- copy_qt_qt(quat_best, quat_final);
- if (j) view = 0; /* view grid assumes certain up axis */
- }
- }
-
- copy_qt_qt(vod->viewquat, quat_best);
- rv3d->view = view; /* if we snap to a rolled camera the grid is invalid */
+ axis_angle_normalized_to_quat(quat_global_z, zvec_global, sensitivity * vod->reverse * (x - vod->oldx));
+ mul_qt_qtqt(vod->viewquat, quat_local_x, quat_global_z);
- break;
- }
- }
+ viewrotate_apply_dyn_ofs(vod, vod->viewquat);
}
- vod->oldx = x;
- vod->oldy = y;
/* avoid precision loss over time */
normalize_qt(vod->viewquat);
@@ -972,6 +1000,14 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
* rotation back into the view we calculate with */
copy_qt_qt(rv3d->viewquat, vod->viewquat);
+ /* check for view snap,
+ * note: don't apply snap to vod->viewquat so the view wont jam up */
+ if (vod->axis_snap) {
+ viewrotate_apply_snap(vod);
+ }
+ vod->oldx = x;
+ vod->oldy = y;
+
ED_view3d_camera_lock_sync(vod->v3d, rv3d);
ED_region_tag_redraw(vod->ar);
@@ -1035,17 +1071,21 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
+ const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
+ if (ED_view3d_camera_lock_check(v3d, rv3d))
+ return;
+
if (rv3d->persp != RV3D_PERSP) {
if (rv3d->persp == RV3D_CAMOB) {
- view3d_persp_switch_from_camera(v3d, rv3d, rv3d->lpersp);
+ /* If autopersp and previous view was an axis one, switch back to PERSP mode, else reuse previous mode. */
+ char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
+ view3d_persp_switch_from_camera(v3d, rv3d, persp);
}
- else if ((U.uiflag & USER_AUTOPERSP) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
- if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->persp = RV3D_PERSP;
- }
+ else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ rv3d->persp = RV3D_PERSP;
}
}
}
@@ -1148,25 +1188,51 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
}
-/* NDOF utility functions
- * (should these functions live in this file?)
- */
+/** \name NDOF Utility Functions
+ * \{ */
-#define NDOF_HAS_TRANSLATE ((!view3d_operator_offset_lock_check(C, op)) && !is_zero_v3(ndof->tvec))
+#define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
#define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
-float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3])
+/**
+ * \param depth_pt: A point to calculate the depth (in perspective mode)
+ */
+static float view3d_ndof_pan_speed_calc_ex(RegionView3D *rv3d, const float depth_pt[3])
{
- return ndof->dt * normalize_v3_v3(axis, ndof->rvec);
+ float speed = rv3d->pixsize * NDOF_PIXELS_PER_SECOND;
+
+ if (rv3d->is_persp) {
+ speed *= ED_view3d_calc_zfac(rv3d, depth_pt, NULL);
+ }
+
+ return speed;
}
-void ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
+static float view3d_ndof_pan_speed_calc_from_dist(RegionView3D *rv3d, const float dist)
{
- float axis[3];
- float angle;
+ float viewinv[4];
+ float tvec[3];
- angle = ndof_to_axis_angle(ndof, axis);
- axis_angle_to_quat(q, axis, angle);
+ BLI_assert(dist >= 0.0f);
+
+ copy_v3_fl3(tvec, 0.0f, 0.0f, dist);
+ /* rv3d->viewinv isn't always valid */
+#if 0
+ mul_mat3_m4_v3(rv3d->viewinv, tvec);
+#else
+ invert_qt_qt(viewinv, rv3d->viewquat);
+ mul_qt_v3(viewinv, tvec);
+#endif
+
+ return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
+}
+
+static float view3d_ndof_pan_speed_calc(RegionView3D *rv3d)
+{
+ float tvec[3];
+ negate_v3_v3(tvec, rv3d->ofs);
+
+ return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
}
/**
@@ -1178,13 +1244,6 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
const bool has_translate, const bool has_zoom)
{
RegionView3D *rv3d = ar->regiondata;
- const float dt = ndof->dt;
-
- /* tune these until everything feels right */
- const float forward_sensitivity = 1.f;
- const float vertical_sensitivity = 0.4f;
- const float lateral_sensitivity = 0.6f;
-
float view_inv[4];
float pan_vec[3];
@@ -1192,9 +1251,7 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
return;
}
- pan_vec[0] = lateral_sensitivity * ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
- pan_vec[1] = vertical_sensitivity * ndof->tvec[1] * ((U.ndof_flag & NDOF_PANZ_INVERT_AXIS) ? -1.0f : 1.0f);
- pan_vec[2] = forward_sensitivity * ndof->tvec[2] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+ WM_event_ndof_pan_get(ndof, pan_vec, false);
if (has_zoom) {
/* zoom with Z */
@@ -1205,14 +1262,11 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
* proportional to arclength = radius * angle
*/
- /* tune these until everything feels right */
- const float zoom_sensitivity = 1.f;
-
pan_vec[2] = 0.0f;
/* "zoom in" or "translate"? depends on zoom mode in user settings? */
- if (ndof->tz) {
- float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+ if (ndof->tvec[2]) {
+ float zoom_distance = rv3d->dist * ndof->dt * ndof->tvec[2];
if (U.ndof_flag & NDOF_ZOOM_INVERT)
zoom_distance = -zoom_distance;
@@ -1230,9 +1284,9 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
}
if (has_translate) {
- const float speed = rv3d->dist; /* uses distance from pivot to define dolly */
+ const float speed = view3d_ndof_pan_speed_calc(rv3d);
- mul_v3_fl(pan_vec, speed * dt);
+ mul_v3_fl(pan_vec, speed * ndof->dt);
/* transform motion from view to world coordinates */
invert_qt_qt(view_inv, rv3d->viewquat);
@@ -1248,42 +1302,44 @@ static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *s
}
-static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D *rv3d, const float dt,
+static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
/* optional, can be NULL*/
ViewOpsData *vod)
{
- const float rot_sensitivity = 1.0f;
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+
float view_inv[4];
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
- view3d_ensure_persp(vod->v3d, vod->ar);
+ view3d_ensure_persp(v3d, ar);
rv3d->view = RV3D_VIEW_USER;
invert_qt_qt(view_inv, rv3d->viewquat);
if (U.ndof_flag & NDOF_TURNTABLE) {
+ float rot[3];
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
- float angle, rot[4];
+ float angle, quat[4];
float xvec[3] = {1, 0, 0};
+ /* only use XY, ignore Z */
+ WM_event_ndof_rotate_get(ndof, rot);
+
/* Determine the direction of the x vector (for rotating up and down) */
mul_qt_v3(view_inv, xvec);
/* Perform the up/down rotation */
- angle = rot_sensitivity * dt * ndof->rx;
- if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
- angle = -angle;
- rot[0] = cosf(angle);
- mul_v3_v3fl(rot + 1, xvec, sin(angle));
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ angle = ndof->dt * rot[0];
+ quat[0] = cosf(angle);
+ mul_v3_v3fl(quat + 1, xvec, sin(angle));
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
/* Perform the orbital rotation */
- angle = rot_sensitivity * dt * ndof->ry;
- if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
- angle = -angle;
+ angle = ndof->dt * rot[1];
/* update the onscreen doo-dad */
rv3d->rot_angle = angle;
@@ -1291,21 +1347,17 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
rv3d->rot_axis[1] = 0;
rv3d->rot_axis[2] = 1;
- rot[0] = cosf(angle);
- rot[1] = rot[2] = 0.0;
- rot[3] = sinf(angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ quat[0] = cosf(angle);
+ quat[1] = 0.0f;
+ quat[2] = 0.0f;
+ quat[3] = sinf(angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
}
else {
- float rot[4];
+ float quat[4];
float axis[3];
- float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
-
- if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS) axis[2] = -axis[2];
- if (U.ndof_flag & NDOF_TILT_INVERT_AXIS) axis[0] = -axis[0];
- if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS) axis[1] = -axis[1];
-
+ float angle = WM_event_ndof_to_axis_angle(ndof, axis);
/* transform rotation axis from view to world coordinates */
mul_qt_v3(view_inv, axis);
@@ -1314,28 +1366,134 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
rv3d->rot_angle = angle;
copy_v3_v3(rv3d->rot_axis, axis);
- axis_angle_to_quat(rot, axis, angle);
+ axis_angle_to_quat(quat, axis, angle);
/* apply rotation */
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
}
- /* rotate around custom center */
- if (vod && vod->use_dyn_ofs) {
- float q1[4];
+ if (vod) {
+ viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
+ }
+}
- /* compute the post multiplication quat, to rotate the offset correctly */
- conjugate_qt_qt(q1, vod->oldquat);
- mul_qt_qtqt(q1, q1, rv3d->viewquat);
+/**
+ * Called from both fly mode and walk mode,
+ */
+void view3d_ndof_fly(
+ const wmNDOFMotionData *ndof,
+ View3D *v3d, RegionView3D *rv3d,
+ const bool use_precision, const short protectflag,
+ bool *r_has_translate, bool *r_has_rotate)
+{
+ bool has_translate = NDOF_HAS_TRANSLATE;
+ bool has_rotate = NDOF_HAS_ROTATE;
- conjugate_qt(q1); /* conj == inv for unit quat */
- copy_v3_v3(rv3d->ofs, vod->ofs);
- sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, vod->dyn_ofs);
+ float view_inv[4];
+ invert_qt_qt(view_inv, rv3d->viewquat);
+
+ rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
+
+ if (has_translate) {
+ /* ignore real 'dist' since fly has its own speed settings,
+ * also its overwritten at this point. */
+ float speed = view3d_ndof_pan_speed_calc_from_dist(rv3d, 1.0f);
+ float trans[3], trans_orig_y;
+
+ if (use_precision)
+ speed *= 0.2f;
+
+ WM_event_ndof_pan_get(ndof, trans, false);
+ mul_v3_fl(trans, speed * ndof->dt);
+ trans_orig_y = trans[1];
+
+ if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
+ trans[1] = 0.0f;
+ }
+
+ /* transform motion from view to world coordinates */
+ mul_qt_v3(view_inv, trans);
+
+ if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
+ /* replace world z component with device y (yes it makes sense) */
+ trans[2] = trans_orig_y;
+ }
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ /* respect camera position locks */
+ if (protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
+ if (protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
+ if (protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
+ }
+
+ if (!is_zero_v3(trans)) {
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, trans);
+ has_translate = true;
+ }
+ else {
+ has_translate = false;
+ }
}
+
+ if (has_rotate) {
+ const float turn_sensitivity = 1.0f;
+
+ float rotation[4];
+ float axis[3];
+ float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
+
+ if (fabsf(angle) > 0.0001f) {
+ has_rotate = true;
+
+ if (use_precision)
+ angle *= 0.2f;
+
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
+
+ /* apply rotation to view */
+ axis_angle_to_quat(rotation, axis, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
+
+ if (U.ndof_flag & NDOF_LOCK_HORIZON) {
+ /* force an upright viewpoint
+ * TODO: make this less... sudden */
+ float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
+ float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
+
+ /* find new inverse since viewquat has changed */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ /* could apply reverse rotation to existing view_inv to save a few cycles */
+
+ /* transform view vectors to world coordinates */
+ mul_qt_v3(view_inv, view_horizon);
+ mul_qt_v3(view_inv, view_direction);
+
+
+ /* find difference between view & world horizons
+ * true horizon lives in world xy plane, so look only at difference in z */
+ angle = -asinf(view_horizon[2]);
+
+ /* rotate view so view horizon = world horizon */
+ axis_angle_to_quat(rotation, view_direction, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
+ }
+
+ rv3d->view = RV3D_VIEW_USER;
+ }
+ else {
+ has_rotate = false;
+ }
+ }
+
+ *r_has_translate = has_translate;
+ *r_has_rotate = has_rotate;
}
+/** \} */
+
+
/* -- "orbit" navigation (trackball/turntable)
* -- zooming
* -- panning in rotationally-locked views
@@ -1351,37 +1509,33 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
View3D *v3d;
RegionView3D *rv3d;
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create_ex(C, op, event,
+ (U.uiflag & USER_ORBIT_SELECTION) != 0, false);
vod = op->customdata;
v3d = vod->v3d;
rv3d = vod->rv3d;
- ED_view3d_camera_lock_init(v3d, rv3d);
-
/* off by default, until changed later this function */
rv3d->rot_angle = 0.0f;
+ ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
+
if (ndof->progress != P_FINISHING) {
const bool has_rotation = NDOF_HAS_ROTATE;
/* if we can't rotate, fallback to translate (locked axis views) */
const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
- const bool has_zoom = !rv3d->is_persp;
-
-#ifdef DEBUG_NDOF_MOTION
- printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
- ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
-#endif
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
if (has_translate || has_zoom) {
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
}
if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
}
}
@@ -1421,39 +1575,67 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
View3D *v3d;
RegionView3D *rv3d;
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create_ex(C, op, event,
+ (U.uiflag & USER_ORBIT_SELECTION) != 0, false);
vod = op->customdata;
v3d = vod->v3d;
rv3d = vod->rv3d;
- ED_view3d_camera_lock_init(v3d, rv3d);
-
/* off by default, until changed later this function */
rv3d->rot_angle = 0.0f;
- if (ndof->progress != P_FINISHING) {
- const bool has_rotation = NDOF_HAS_ROTATE;
+ ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
+
+ if (ndof->progress == P_FINISHING) {
+ /* pass */
+ }
+ else if ((rv3d->persp == RV3D_ORTHO) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
/* if we can't rotate, fallback to translate (locked axis views) */
- const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
- /* always zoom since this is the main purpose of the function */
- const bool has_zoom = true;
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && ED_view3d_offset_lock_check(v3d, rv3d);
-#ifdef DEBUG_NDOF_MOTION
- printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
- ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
-#endif
if (has_translate || has_zoom) {
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, true);
}
+ }
+ else if ((U.ndof_flag & NDOF_MODE_ORBIT) ||
+ ED_view3d_offset_lock_check(v3d, rv3d))
+ {
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f);
+
+ if (has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
+ }
if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
}
}
+ else { /* free/explore (like fly mode) */
+ const bool has_rotation = NDOF_HAS_ROTATE;
+ const bool has_translate = NDOF_HAS_TRANSLATE;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
+
+ float dist_backup;
+
+ if (has_translate || has_zoom) {
+ view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
+ }
+
+ dist_backup = rv3d->dist;
+ ED_view3d_distance_set(rv3d, 0.0f);
+
+ if (has_rotation) {
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, NULL);
+ }
+
+ ED_view3d_distance_set(rv3d, dist_backup);
+ }
ED_view3d_camera_lock_sync(v3d, rv3d);
@@ -1483,7 +1665,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
/* -- "pan" navigation
* -- zoom or dolly?
*/
-static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
@@ -1491,17 +1673,18 @@ static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = !rv3d->is_persp;
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
- if (has_translate == false)
- return OPERATOR_CANCELLED;
+ /* we're panning here! so erase any leftover rotation from other operators */
+ rv3d->rot_angle = 0.0f;
- ED_view3d_camera_lock_init(v3d, rv3d);
+ if (!(has_translate || has_zoom))
+ return OPERATOR_CANCELLED;
- rv3d->rot_angle = 0.f; /* we're panning here! so erase any leftover rotation from other operators */
+ ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
if (ndof->progress != P_FINISHING) {
ScrArea *sa = CTX_wm_area(C);
@@ -1536,52 +1719,22 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
}
-/*
- * this is basically just the pan only code + the rotate only code crammed into one function that does both
+/**
+ * wraps #ndof_orbit_zoom but never restrict to orbit.
*/
static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION) {
- return OPERATOR_CANCELLED;
- }
- else {
- ViewOpsData *vod;
- View3D *v3d;
- RegionView3D *rv3d;
-
- wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ /* weak!, but it works */
+ const int ndof_flag = U.ndof_flag;
+ int ret;
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ U.ndof_flag &= ~NDOF_MODE_ORBIT;
- vod = op->customdata;
- v3d = vod->v3d;
- rv3d = vod->rv3d;
-
- ED_view3d_camera_lock_init(v3d, rv3d);
-
- if (ndof->progress != P_FINISHING) {
- const bool has_rotation = NDOF_HAS_ROTATE;
- const bool has_translate = NDOF_HAS_TRANSLATE;
- const bool has_zoom = !rv3d->is_persp;
-
- if (has_translate || has_zoom) {
- view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
- }
+ ret = ndof_orbit_zoom_invoke(C, op, event);
- if (has_rotation) {
- view3d_ndof_orbit(ndof, rv3d, ndof->dt, vod);
- }
- }
-
- ED_view3d_camera_lock_sync(v3d, rv3d);
-
- ED_region_tag_redraw(vod->ar);
+ U.ndof_flag = ndof_flag;
- viewops_data_free(C, op);
-
- return OPERATOR_FINISHED;
- }
+ return ret;
}
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
@@ -1844,7 +1997,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
}
-static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const short viewzoom, const short zoom_invert)
+static void viewzoom_apply(ViewOpsData *vod, const int xy[2], const short viewzoom, const short zoom_invert)
{
float zfac = 1.0;
bool use_cam_zoom;
@@ -1853,7 +2006,7 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho
if (use_cam_zoom) {
float delta;
- delta = (x - vod->origx + y - vod->origy) / 10.0f;
+ delta = (xy[0] - vod->origx + xy[1] - vod->origy) / 10.0f;
vod->rv3d->camzoom = vod->camzoom_prev + (zoom_invert ? -delta : delta);
CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
@@ -1865,10 +2018,10 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho
float fac;
if (U.uiflag & USER_ZOOM_HORIZ) {
- fac = (float)(vod->origx - x);
+ fac = (float)(vod->origx - xy[0]);
}
else {
- fac = (float)(vod->origy - y);
+ fac = (float)(vod->origy - xy[1]);
}
if (zoom_invert) {
@@ -1880,26 +2033,25 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho
vod->timer_lastdraw = time;
}
else if (viewzoom == USER_ZOOM_SCALE) {
- int ctr[2], len1, len2;
/* method which zooms based on how far you move the mouse */
- ctr[0] = BLI_rcti_cent_x(&vod->ar->winrct);
- ctr[1] = BLI_rcti_cent_y(&vod->ar->winrct);
-
- len1 = (int)sqrt((ctr[0] - x) * (ctr[0] - x) + (ctr[1] - y) * (ctr[1] - y)) + 5;
- len2 = (int)sqrt((ctr[0] - vod->origx) * (ctr[0] - vod->origx) + (ctr[1] - vod->origy) * (ctr[1] - vod->origy)) + 5;
-
- zfac = vod->dist_prev * ((float)len2 / len1) / vod->rv3d->dist;
+ const int ctr[2] = {
+ BLI_rcti_cent_x(&vod->ar->winrct),
+ BLI_rcti_cent_y(&vod->ar->winrct),
+ };
+ const float len_new = 5 + len_v2v2_int(ctr, xy);
+ const float len_old = 5 + len_v2v2_int(ctr, &vod->origx);
+ zfac = vod->dist_prev * ((len_old + 5) / (len_new + 5)) / vod->rv3d->dist;
}
else { /* USER_ZOOM_DOLLY */
float len1, len2;
if (U.uiflag & USER_ZOOM_HORIZ) {
- len1 = (vod->ar->winrct.xmax - x) + 5;
+ len1 = (vod->ar->winrct.xmax - xy[0]) + 5;
len2 = (vod->ar->winrct.xmax - vod->origx) + 5;
}
else {
- len1 = (vod->ar->winrct.ymax - y) + 5;
+ len1 = (vod->ar->winrct.ymax - xy[1]) + 5;
len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
}
if (zoom_invert) {
@@ -1971,7 +2123,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (event_code == VIEW_APPLY) {
- viewzoom_apply(vod, event->x, event->y, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ viewzoom_apply(vod, &event->x, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
else if (event_code == VIEW_CONFIRM) {
ED_view3d_depth_tag_update(vod->rv3d);
@@ -2106,12 +2258,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ viewzoom_apply(vod, &event->prevx, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ viewzoom_apply(vod, &event->prevx, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
@@ -2425,6 +2577,8 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
CameraParams params;
BKE_camera_params_init(&params);
+ params.clipsta = v3d->near;
+ params.clipend = v3d->far;
BKE_camera_params_from_object(&params, v3d->camera);
lens = params.lens;
@@ -2637,7 +2791,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
}
}
- else if (paint_facesel_test(ob)) {
+ else if (BKE_paint_select_face_test(ob)) {
ok = paintface_minmax(ob, min, max);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
@@ -2893,7 +3047,7 @@ static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was
rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(min_ff(xfac, yfac));
CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
return OPERATOR_FINISHED;
}
@@ -3459,9 +3613,8 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
if (!rv3d->smooth_timer) {
/* store settings of current view before allowing overwriting with camera view
* only if we're not currently in a view transition */
- copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
- rv3d->lview = rv3d->view;
- rv3d->lpersp = rv3d->persp;
+
+ ED_view3d_lastview_store(rv3d);
}
#if 0
@@ -3569,10 +3722,14 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
float angle = DEG2RADF((float)U.pad_rot_angle);
float quat_mul[4];
float quat_new[4];
+ float ofs_new[3];
+ float *ofs_new_pt = NULL;
+
+ view3d_ensure_persp(v3d, ar);
if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
@@ -3597,8 +3754,24 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
rv3d->view = RV3D_VIEW_USER;
- ED_view3d_smooth_view(C, CTX_wm_view3d(C), ar, NULL, NULL,
- NULL, quat_new, NULL, NULL,
+ if (U.uiflag & USER_ORBIT_SELECTION) {
+ float dyn_ofs[3];
+
+ view3d_orbit_calc_center(C, dyn_ofs);
+ negate_v3(dyn_ofs);
+
+ copy_v3_v3(ofs_new, rv3d->ofs);
+
+ view3d_orbit_apply_dyn_ofs(ofs_new, dyn_ofs, rv3d->viewquat, quat_new);
+ ofs_new_pt = ofs_new;
+
+ /* disable smoothview in this case
+ * although it works OK, it looks a little odd. */
+ smooth_viewtx = 0;
+ }
+
+ ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
+ ofs_new_pt, quat_new, NULL, NULL,
smooth_viewtx);
return OPERATOR_FINISHED;
@@ -4472,6 +4645,31 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float
}
/**
+ * Set the dist without moving the view (compensate with #RegionView3D.ofs)
+ *
+ * \note take care that viewinv is up to date, #ED_view3d_update_viewmat first.
+ */
+void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
+{
+ float viewinv[4];
+ float tvec[3];
+
+ BLI_assert(dist >= 0.0f);
+
+ copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
+ /* rv3d->viewinv isn't always valid */
+#if 0
+ mul_mat3_m4_v3(rv3d->viewinv, tvec);
+#else
+ invert_qt_qt(viewinv, rv3d->viewquat);
+ mul_qt_v3(viewinv, tvec);
+#endif
+ sub_v3_v3(rv3d->ofs, tvec);
+
+ rv3d->dist = dist;
+}
+
+/**
* Set the view transformation from a 4x4 matrix.
*
* \param mat The view 4x4 transformation matrix to assign.
@@ -4561,6 +4759,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co
BKE_object_apply_mat4(ob, mat, true, true);
}
+/**
+ * Use to store the last view, before entering camera view.
+ */
+void ED_view3d_lastview_store(RegionView3D *rv3d)
+{
+ copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
+ rv3d->lview = rv3d->view;
+ if (rv3d->persp != RV3D_CAMOB) {
+ rv3d->lpersp = rv3d->persp;
+ }
+}
+
BGpic *ED_view3D_background_image_new(View3D *v3d)
{
BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 423f0c33b76..ccf874e7feb 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -53,6 +53,8 @@
#include "PIL_time.h" /* smoothview */
+#include "UI_resources.h"
+
#include "view3d_intern.h" /* own include */
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
@@ -154,6 +156,10 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD);
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT);
WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT);
+ WM_modalkeymap_add_item(keymap, EKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP);
+ WM_modalkeymap_add_item(keymap, QKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN);
+
+ /* for legacy reasons, leave R/F working */
WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP);
WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN);
@@ -165,6 +171,10 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X);
WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z);
+ WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE);
+
+ /* for legacy reasons, leave shift working */
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE);
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE);
@@ -243,7 +253,7 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
x2 = xoff + 0.55f * fly->width;
y2 = yoff + 0.55f * fly->height;
- gpuColor3P(CPACK_BLACK);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
gpuImmediateFormat_V2();
@@ -290,12 +300,12 @@ static void fly_update_header(bContext *C, FlyInfo *fly)
BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB/Return: confirm, "
"RMB/Esc: cancel, "
"MMB: pan, "
- "WASDRF: direction, "
- "Shift: slow, "
+ "WASDQE: direction, "
+ "Alt: slow, "
"Ctrl: free look, "
"X: Upright x axis (%s), "
"Z: Upright z axis (%s), "
- "(+/- | Wheel): speed, "),
+ "(+/- | Wheel): speed"),
WM_bool_as_string(fly->xlock != FLY_AXISLOCK_STATE_OFF),
WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF));
@@ -461,7 +471,7 @@ static void flyEvent(bContext *C, FlyInfo *fly, const wmEvent *event)
// puts("ndof motion detected in fly mode!");
// static const char *tag_name = "3D mouse position";
- wmNDOFMotionData *incoming_ndof = (wmNDOFMotionData *)event->customdata;
+ const wmNDOFMotionData *incoming_ndof = event->customdata;
switch (incoming_ndof->progress) {
case P_STARTING:
/* start keeping track of 3D mouse position */
@@ -945,133 +955,23 @@ static int flyApply(bContext *C, FlyInfo *fly)
return OPERATOR_FINISHED;
}
-static int flyApply_ndof(bContext *C, FlyInfo *fly)
+static void flyApply_ndof(bContext *C, FlyInfo *fly)
{
- /* shorthand for oft-used variables */
- wmNDOFMotionData *ndof = fly->ndof;
- const float dt = ndof->dt;
- RegionView3D *rv3d = fly->rv3d;
- const int flag = U.ndof_flag;
-
-#if 0
- bool do_rotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == false);
- bool do_translate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)) != 0;
-#endif
-
- bool do_rotate = (fly->pan_view == false);
- bool do_translate = true;
-
- float view_inv[4];
- invert_qt_qt(view_inv, rv3d->viewquat);
-
- rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
-
- if (do_translate) {
- const float forward_sensitivity = 1.0f;
- const float vertical_sensitivity = 0.4f;
- const float lateral_sensitivity = 0.6f;
-
- float speed = 10.0f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
-
- float trans[3] = {lateral_sensitivity * ndof->tvec[0],
- vertical_sensitivity * ndof->tvec[1],
- forward_sensitivity * ndof->tvec[2]};
-
- if (fly->use_precision)
- speed *= 0.2f;
-
- mul_v3_fl(trans, speed * dt);
-
- /* transform motion from view to world coordinates */
- mul_qt_v3(view_inv, trans);
-
- if (flag & NDOF_FLY_HELICOPTER) {
- /* replace world z component with device y (yes it makes sense) */
- trans[2] = speed * dt * vertical_sensitivity * ndof->tvec[1];
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- /* respect camera position locks */
- Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
- if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
- if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
- }
-
- if (!is_zero_v3(trans)) {
- /* move center of view opposite of hand motion (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, trans);
- do_translate = true;
- }
- else {
- do_translate = false;
- }
- }
-
- if (do_rotate) {
- const float turn_sensitivity = 1.0f;
-
- float rotation[4];
- float axis[3];
- float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
-
- if (fabsf(angle) > 0.0001f) {
- do_rotate = true;
-
- if (fly->use_precision)
- angle *= 0.2f;
-
- /* transform rotation axis from view to world coordinates */
- mul_qt_v3(view_inv, axis);
-
- /* apply rotation to view */
- axis_angle_to_quat(rotation, axis, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
-
- if (flag & NDOF_LOCK_HORIZON) {
- /* force an upright viewpoint
- * TODO: make this less... sudden */
- float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
- float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
-
- /* find new inverse since viewquat has changed */
- invert_qt_qt(view_inv, rv3d->viewquat);
- /* could apply reverse rotation to existing view_inv to save a few cycles */
-
- /* transform view vectors to world coordinates */
- mul_qt_v3(view_inv, view_horizon);
- mul_qt_v3(view_inv, view_direction);
-
- /* find difference between view & world horizons
- * true horizon lives in world xy plane, so look only at difference in z */
- angle = -asinf(view_horizon[2]);
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
+ bool has_translate, has_rotate;
-#ifdef NDOF_FLY_DEBUG
- printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
-#endif
-
- /* rotate view so view horizon = world horizon */
- axis_angle_to_quat(rotation, view_direction, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
- }
-
- rv3d->view = RV3D_VIEW_USER;
- }
- else {
- do_rotate = false;
- }
- }
+ view3d_ndof_fly(fly->ndof,
+ fly->v3d, fly->rv3d,
+ fly->use_precision, lock_ob ? lock_ob->protectflag : 0,
+ &has_translate, &has_rotate);
- if (do_translate || do_rotate) {
+ if (has_translate || has_rotate) {
fly->redraw = true;
- if (rv3d->persp == RV3D_CAMOB) {
- flyMoveCamera(C, fly, do_rotate, do_translate);
+ if (fly->rv3d->persp == RV3D_CAMOB) {
+ flyMoveCamera(C, fly, has_rotate, has_translate);
}
}
-
- return OPERATOR_FINISHED;
}
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 204054b24cd..e3d0e87066b 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -34,9 +34,6 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-
-#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -46,11 +43,8 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_effect.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_paint.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
@@ -64,8 +58,6 @@
#include "ED_mesh.h"
#include "ED_util.h"
#include "ED_screen.h"
-#include "ED_transform.h"
-#include "ED_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -197,7 +189,7 @@ static int view3d_layers_invoke(bContext *C, wmOperator *op, const wmEvent *even
return OPERATOR_PASS_THROUGH;
if (event->shift)
- RNA_boolean_set(op->ptr, "extend", TRUE);
+ RNA_boolean_set(op->ptr, "extend", true);
else
RNA_boolean_set(op->ptr, "extend", false);
@@ -274,14 +266,14 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
uiLayout *row;
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- TIP_("Vertex select - Shift-Click for multiple modes"));
+ TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
+ TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection"));
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
@@ -322,7 +314,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
modeselect = OB_MODE_OBJECT;
}
- row = uiLayoutRow(layout, FALSE);
+ row = uiLayoutRow(layout, false);
{
EnumPropertyItem *item = object_mode_items;
const char *name = "";
@@ -347,7 +339,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
/* Only for Weight Paint. makes no sense in other paint modes. */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
@@ -361,14 +353,14 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
else {
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
}
}
else {
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
/* pose/object only however we want to allow in weight paint mode too
@@ -380,7 +372,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
/* Transform widget / manipulators */
- row = uiLayoutRow(layout, TRUE);
+ row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
if (v3d->twflag & V3D_USE_MANIPULATOR) {
uiItemR(row, &v3dptr, "transform_manipulators", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 217c97d5e83..a0ca518dbb8 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -110,8 +110,12 @@ void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
void view3d_boxview_copy(struct ScrArea *sa, struct ARegion *ar);
-void ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4]);
-float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
+
+void view3d_ndof_fly(
+ const struct wmNDOFMotionData *ndof,
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ const bool use_precision, const short protectflag,
+ bool *r_has_translate, bool *r_has_rotate);
/* view3d_fly.c */
void view3d_keymap(struct wmKeyConfig *keyconf);
@@ -140,9 +144,12 @@ void draw_object_backbufsel(struct Scene *scene, struct View3D *v3d, struct Regi
void drawaxes(float size, char drawtype);
void view3d_cached_text_draw_begin(void);
-void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]);
+void view3d_cached_text_draw_add(const float co[3],
+ const char *str, const size_t str_len,
+ short xoffs, short flag, const unsigned char col[4]);
void view3d_cached_text_draw_end(struct View3D *v3d, struct ARegion *ar, bool depth_write, float mat[4][4]);
+
bool check_object_draw_texture(struct Scene *scene, struct View3D *v3d, const char drawtype);
enum {
@@ -166,7 +173,11 @@ void draw_mesh_paint(struct View3D *v3d, struct RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
void draw_mesh_paint_weight_faces(struct DerivedMesh *dm, const bool do_light,
void *facemask_cb, void *user_data);
-void draw_mesh_paint_weight_edges(struct RegionView3D *rv3d, struct DerivedMesh *dm, const bool use_depth,
+void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light,
+ void *facemask_cb, void *user_data,
+ const struct Mesh *me);
+void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm,
+ const bool use_depth, const bool use_alpha,
void *edgemask_cb, void *user_data);
/* view3d_draw.c */
@@ -193,14 +204,25 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
-bool ED_view3d_boundbox_clip(struct RegionView3D *rv3d, float obmat[4][4], const struct BoundBox *bb);
+bool ED_view3d_boundbox_clip_ex(struct RegionView3D *rv3d, const struct BoundBox *bb, float obmat[4][4]);
+bool ED_view3d_boundbox_clip(struct RegionView3D *rv3d, const struct BoundBox *bb);
+
+void ED_view3d_smooth_view_ex(
+ struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa,
+ struct View3D *v3d, struct ARegion *ar,
+ struct Object *camera_old, struct Object *camera,
+ const float *ofs, const float *quat, const float *dist, const float *lens,
+ const int smooth_viewtx);
-void ED_view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *,
- float *ofs, float *quat, float *dist, float *lens,
- const int smooth_viewtx);
+void ED_view3d_smooth_view(
+ struct bContext *C,
+ struct View3D *v3d, struct ARegion *ar,
+ struct Object *camera_old, struct Object *camera,
+ const float *ofs, const float *quat, const float *dist, const float *lens,
+ const int smooth_viewtx);
-void setwinmatrixview3d(struct ARegion *ar, struct View3D *v3d, struct rctf *rect);
-void setviewmatrixview3d(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
+void view3d_winmatrix_set(struct ARegion *ar, struct View3D *v3d, struct rctf *rect);
+void view3d_viewmatrix_set(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
@@ -250,8 +272,8 @@ extern const char *view3d_context_dir[]; /* doc access */
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
- struct GPUTexture *tex, float min[3], float max[3],
- int res[3], float dx, float base_scale, float viewnormal[3],
+ struct GPUTexture *tex, const float min[3], const float max[3],
+ const int res[3], float dx, float base_scale, const float viewnormal[3],
struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame);
//#define SMOKE_DEBUG_VELOCITY
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 4df8010be9d..ce4b7f7deeb 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -33,7 +33,6 @@
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BKE_armature.h"
@@ -44,10 +43,8 @@
#include "bmesh.h"
-#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_armature.h"
-#include "ED_object.h"
#include "ED_view3d.h"
typedef struct foreachScreenObjectVert_userData {
@@ -370,7 +367,7 @@ void lattice_foreachScreenVert(
Lattice *lt = obedit->data;
BPoint *bp = lt->editlatt->latt->def;
DispList *dl = obedit->curve_cache ? BKE_displist_find(&obedit->curve_cache->disp, DL_VERTS) : NULL;
- float *co = dl ? dl->verts : NULL;
+ const float *co = dl ? dl->verts : NULL;
int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
ED_view3d_check_mats_rv3d(vc->rv3d);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index c087fe72fdb..a8128ba7ae8 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -39,7 +39,6 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -58,6 +57,10 @@
#include "view3d_intern.h"
+#ifdef WIN32
+# include "BLI_math_base.h" /* M_PI */
+#endif
+
/* ************************** copy paste ***************************** */
static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
@@ -71,7 +74,6 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
BKE_copybuffer_tag_ID(&ob->id);
-
}
CTX_DATA_END;
@@ -99,15 +101,19 @@ static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
{
char str[FILE_MAX];
-
+
BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend");
- BKE_copybuffer_paste(C, str, op->reports);
+ if (BKE_copybuffer_paste(C, str, op->reports)) {
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-
- BKE_report(op->reports, RPT_INFO, "Objects pasted from buffer");
+ BKE_report(op->reports, RPT_INFO, "Objects pasted from buffer");
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
+
+ BKE_report(op->reports, RPT_INFO, "No buffer to paste from");
+
+ return OPERATOR_CANCELLED;
}
static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
@@ -207,7 +213,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(kmi->ptr, "release_confirm", true);
/*
* Doesn't work with KM_SHIFT, have to use KM_ANY and filter in invoke
* */
@@ -220,9 +226,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_dolly", MIDDLEMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", false);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0);
@@ -265,12 +271,12 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_pick", FKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */
+ RNA_boolean_set(kmi->ptr, "center", false); /* only without camera view */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE);
- RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */
+ RNA_boolean_set(kmi->ptr, "use_all_regions", true);
+ RNA_boolean_set(kmi->ptr, "center", false); /* only without camera view */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
+ RNA_boolean_set(kmi->ptr, "center", true);
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
@@ -309,22 +315,22 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* active aligned, replaces '*' key in 2.4x */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BACK);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_LEFT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
@@ -336,7 +342,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, KM_CTRL | KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", false);
RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CCW, KM_PRESS, 0, 0)->ptr, "angle", M_PI / -2);
RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CW, KM_PRESS, 0, 0)->ptr, "angle", M_PI / 2);
@@ -351,13 +357,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* 3D mouse align */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ RNA_boolean_set(kmi->ptr, "align_active", true);
/* NDOF: end */
@@ -393,78 +399,78 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* selection*/
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", FALSE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
+ RNA_boolean_set(kmi->ptr, "center", false);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+ RNA_boolean_set(kmi->ptr, "center", false);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", FALSE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
- RNA_boolean_set(kmi->ptr, "object", TRUE); /* use Ctrl+Select for 2 purposes */
- RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
+ RNA_boolean_set(kmi->ptr, "center", true);
+ RNA_boolean_set(kmi->ptr, "object", true); /* use Ctrl+Select for 2 purposes */
+ RNA_boolean_set(kmi->ptr, "enumerate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", FALSE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
+ RNA_boolean_set(kmi->ptr, "center", false);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", true);
/* selection key-combinations */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+ RNA_boolean_set(kmi->ptr, "center", true);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", FALSE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", false);
+ RNA_boolean_set(kmi->ptr, "center", true);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
- RNA_boolean_set(kmi->ptr, "center", FALSE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+ RNA_boolean_set(kmi->ptr, "center", false);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", FALSE);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
- RNA_boolean_set(kmi->ptr, "toggle", TRUE);
- RNA_boolean_set(kmi->ptr, "center", TRUE);
- RNA_boolean_set(kmi->ptr, "object", FALSE);
- RNA_boolean_set(kmi->ptr, "enumerate", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", false);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+ RNA_boolean_set(kmi->ptr, "center", true);
+ RNA_boolean_set(kmi->ptr, "object", false);
+ RNA_boolean_set(kmi->ptr, "enumerate", true);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "camera_only", TRUE);
+ RNA_boolean_set(kmi->ptr, "camera_only", true);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "camera_only", FALSE);
+ RNA_boolean_set(kmi->ptr, "camera_only", false);
WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index 68c0c64217a..c31a89eb16c 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -226,7 +226,7 @@ static void ruler_item_active_set(RulerInfo *ruler_info, RulerItem *ruler_item)
static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
char *numstr, size_t numstr_size, int prec)
{
- const int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
+ const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
const float ruler_angle = angle_v3v3v3(ruler_item->co[0],
@@ -286,9 +286,11 @@ static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
ruler_item_best = ruler_item;
{
- float dist_points[3] = {len_squared_v2v2(co_ss[0], mval),
- len_squared_v2v2(co_ss[1], mval),
- len_squared_v2v2(co_ss[2], mval)};
+ const float dist_points[3] = {
+ len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[1], mval),
+ len_squared_v2v2(co_ss[2], mval),
+ };
if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
co_index_best = min_axis_v3(dist_points);
}
@@ -305,8 +307,10 @@ static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
ruler_item_best = ruler_item;
{
- float dist_points[2] = {len_squared_v2v2(co_ss[0], mval),
- len_squared_v2v2(co_ss[2], mval)};
+ const float dist_points[2] = {
+ len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[2], mval),
+ };
if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 7a553869dbe..b53426b21d6 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -66,7 +66,6 @@
#include "BKE_depsgraph.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
-#include "BKE_movieclip.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
@@ -100,6 +99,11 @@
#include "view3d_intern.h" /* own include */
+float ED_view3d_select_dist_px(void)
+{
+ return 75.0f * U.pixelsize;
+}
+
/* TODO: should return whether there is valid context to continue */
void view3d_set_viewcontext(bContext *C, ViewContext *vc)
{
@@ -277,7 +281,7 @@ static int view3d_selectable_data(bContext *C)
}
else {
if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) &&
- !paint_facesel_test(ob) && !paint_vertsel_test(ob))
+ !BKE_paint_select_elem_test(ob))
{
return 0;
}
@@ -570,8 +574,10 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
- if (extend == false && select)
- ED_curve_deselect_all(vc->obedit->data);
+ if (extend == false && select) {
+ Curve *curve = (Curve *) vc->obedit->data;
+ ED_curve_deselect_all(curve->editnurb);
+ }
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -822,9 +828,9 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
Object *ob = CTX_data_active_object(C);
if (vc->obedit == NULL) { /* Object Mode */
- if (paint_facesel_test(ob))
+ if (BKE_paint_select_face_test(ob))
do_lasso_select_paintface(vc, mcords, moves, extend, select);
- else if (paint_vertsel_test(ob))
+ else if (BKE_paint_select_vert_test(ob))
do_lasso_select_paintvert(vc, mcords, moves, extend, select);
else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
/* pass */
@@ -1061,7 +1067,7 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "name", DummyRNA_NULL_items, 0, "Object Name", "");
RNA_def_enum_funcs(prop, object_select_menu_enum_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
@@ -1136,7 +1142,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
for (node = linklist, i = 0; node; node = node->next, i++) {
Base *base = node->link;
Object *ob = base->object;
- char *name = ob->id.name + 2;
+ const char *name = ob->id.name + 2;
BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
object_mouse_select_menu_data[i].icon = uiIconFromID(&ob->id);
@@ -1382,8 +1388,8 @@ static bool mouse_select(bContext *C, const int mval[2],
Scene *scene = CTX_data_scene(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
bool is_obedit;
- float dist = 100.0f;
- int retval = false;
+ float dist = ED_view3d_select_dist_px() * 1.3333f;
+ bool retval = false;
short hits;
const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
@@ -1739,8 +1745,10 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, bool select, bool ex
view3d_userdata_boxselect_init(&data, vc, rect, select);
- if (extend == false && select)
- ED_curve_deselect_all(vc->obedit->data);
+ if (extend == false && select) {
+ Curve *curve = (Curve *) vc->obedit->data;
+ ED_curve_deselect_all(curve->editnurb);
+ }
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -2126,10 +2134,10 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
ret = do_sculpt_mask_box_select(&vc, &rect, select, extend);
}
- else if (vc.obact && paint_facesel_test(vc.obact)) {
+ else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
ret = do_paintface_box_select(&vc, &rect, select, extend);
}
- else if (vc.obact && paint_vertsel_test(vc.obact)) {
+ else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
ret = do_paintvert_box_select(&vc, &rect, select, extend);
}
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
@@ -2223,7 +2231,14 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
bool toggle = RNA_boolean_get(op->ptr, "toggle");
bool center = RNA_boolean_get(op->ptr, "center");
bool enumerate = RNA_boolean_get(op->ptr, "enumerate");
- bool object = (RNA_boolean_get(op->ptr, "object") && obedit); /* only force object select for editmode */
+ /* only force object select for editmode to support vertex parenting,
+ * or paint-select to allow pose bone select with vert/face select */
+ bool object = (RNA_boolean_get(op->ptr, "object") &&
+ (obedit ||
+ BKE_paint_select_elem_test(obact) ||
+ /* so its possible to select bones in weightpaint mode (LMB select) */
+ (obact && (obact->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(obact))));
+
bool retval = false;
int location[2];
@@ -2252,15 +2267,15 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
retval = mouse_nurb(C, location, extend, deselect, toggle);
else if (obedit->type == OB_MBALL)
retval = mouse_mball(C, location, extend, deselect, toggle);
+ else if (obedit->type == OB_FONT)
+ retval = mouse_font(C, location, extend, deselect, toggle);
}
- else if (obact && obact->mode & OB_MODE_SCULPT)
- return OPERATOR_CANCELLED;
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, location, extend, deselect, toggle);
- else if (obact && paint_facesel_test(obact))
+ else if (obact && BKE_paint_select_face_test(obact))
retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
- else if (paint_vertsel_test(obact))
+ else if (BKE_paint_select_vert_test(obact))
retval = mouse_weight_paint_vertex_select(C, location, extend, deselect, toggle, obact);
else
retval = mouse_select(C, location, extend, deselect, toggle, center, enumerate, object);
@@ -2772,7 +2787,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
const int mval[2] = {RNA_int_get(op->ptr, "x"),
RNA_int_get(op->ptr, "y")};
- if (CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) ||
+ if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) ||
(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) )
{
ViewContext vc;
@@ -2785,11 +2800,11 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
obedit_circle_select(&vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (paint_facesel_test(obact)) {
+ else if (BKE_paint_select_face_test(obact)) {
paint_facesel_circle_select(&vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (paint_vertsel_test(obact)) {
+ else if (BKE_paint_select_vert_test(obact)) {
paint_vertsel_circle_select(&vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 3486e930466..8e6deeddc39 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -413,8 +413,8 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
MovieTracking *tracking;
MovieTrackingObject *object;
- int ok = 0;
- float min[3], max[3], mat[4][4], pos[3], cammat[4][4] = MAT4_UNITY;
+ bool ok = false;
+ float min[3], max[3], mat[4][4], pos[3], cammat[4][4];
if (!clip)
return;
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index bdb203ab003..3f7f12d2020 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -47,8 +47,6 @@
#include "BLF_translation.h"
#include "BKE_context.h"
-#include "BKE_idprop.h"
-#include "BKE_global.h"
#include "BKE_screen.h"
@@ -117,7 +115,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
uiBlock *block = uiLayoutGetBlock(pa->layout);
if (!WM_operator_check_ui_enabled(C, op->type->name))
- uiLayoutSetEnabled(pa->layout, FALSE);
+ uiLayoutSetEnabled(pa->layout, false);
/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
@@ -199,7 +197,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
- event.customdatafree = FALSE;
+ event.customdatafree = false;
wm_event_add(win, &event);
return block;
@@ -221,12 +219,12 @@ static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
for (ct = st->toolshelf.first; ct; ct = ct->next) {
if (0 == strncmp(context, ct->context, OP_MAX_TYPENAME)) {
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0);
}
}
}
- col = uiLayoutColumn(pa->layout, TRUE);
+ col = uiLayoutColumn(pa->layout, true);
uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &st->toolshelf, "Add Tool", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add Tool in shelf, gets saved in files");
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index a3b43a154b1..13a191f4cbb 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -32,7 +32,6 @@
#include "DNA_camera_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_lamp_types.h"
#include "MEM_guardedalloc.h"
@@ -52,7 +51,6 @@
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "BIF_glutil.h"
@@ -170,14 +168,14 @@ static void view3d_smooth_view_state_restore(const struct SmoothView3DState *sms
/* will start timer if appropriate */
/* the arguments are the desired situation */
-void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
- float *ofs, float *quat, float *dist, float *lens,
- const int smooth_viewtx)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa = CTX_wm_area(C);
+void ED_view3d_smooth_view_ex(
+ /* avoid passing in the context */
+ wmWindowManager *wm, wmWindow *win, ScrArea *sa,
+ View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
+ const float *ofs, const float *quat, const float *dist, const float *lens,
+ const int smooth_viewtx)
+{
RegionView3D *rv3d = ar->regiondata;
struct SmoothView3DStore sms = {{0}};
bool ok = false;
@@ -272,7 +270,11 @@ void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcam
/* ensure it shows correct */
if (sms.to_camera) {
- rv3d->persp = RV3D_PERSP;
+ /* use ortho if we move from an ortho view to an ortho camera */
+ rv3d->persp = (((rv3d->is_persp == false) &&
+ (camera->type == OB_CAMERA) &&
+ (((Camera *)camera->data)->type == CAM_ORTHO)) ?
+ RV3D_ORTHO : RV3D_PERSP);
}
rv3d->rflag |= RV3D_NAVIGATING;
@@ -315,6 +317,22 @@ void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcam
}
}
+void ED_view3d_smooth_view(
+ bContext *C,
+ View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
+ const float *ofs, const float *quat, const float *dist, const float *lens,
+ const int smooth_viewtx)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ ED_view3d_smooth_view_ex(
+ wm, win, sa,
+ v3d, ar, oldcamera, camera,
+ ofs, quat, dist, lens, smooth_viewtx);
+}
+
/* only meant for timer usage */
static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
@@ -411,15 +429,16 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ View3D *v3d;
+ ARegion *ar;
+ RegionView3D *rv3d;
+
ObjectTfmProtectedChannels obtfm;
- copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
- rv3d->lview = rv3d->view;
- if (rv3d->persp != RV3D_CAMOB) {
- rv3d->lpersp = rv3d->persp;
- }
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+
+ ED_view3d_lastview_store(rv3d);
BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
@@ -438,11 +457,17 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
static int view3d_camera_to_view_poll(bContext *C)
{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d && v3d->camera && v3d->camera->id.lib == NULL) {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) {
- return 1;
+ View3D *v3d;
+ ARegion *ar;
+
+ if (ED_view3d_context_user_region(C, &v3d, &ar)) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (v3d && v3d->camera && v3d->camera->id.lib == NULL) {
+ if (rv3d && (rv3d->viewlock & RV3D_LOCKED) == 0) {
+ if (rv3d->persp != RV3D_CAMOB) {
+ return 1;
+ }
+ }
}
}
@@ -549,7 +574,10 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
if (v3d->scenelock)
scene->camera = ob;
- if (camera_old != ob) { /* unlikely but looks like a glitch when set to the same */
+ /* unlikely but looks like a glitch when set to the same */
+ if (camera_old != ob) {
+ ED_view3d_lastview_store(rv3d);
+
ED_view3d_smooth_view(C, v3d, ar, camera_old, v3d->camera,
rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens,
smooth_viewtx);
@@ -637,24 +665,15 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
}
}
-
-bool ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], const BoundBox *bb)
+static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
{
- /* return 1: draw */
-
- float mat[4][4];
- float vec[4], min, max;
int a, flag = -1, fl;
- if (bb == NULL) return true;
- if (bb->flag & BOUNDBOX_DISABLED) return true;
-
- mul_m4_m4m4(mat, rv3d->persmat, obmat);
-
for (a = 0; a < 8; a++) {
+ float vec[4], min, max;
copy_v3_v3(vec, bb->vec[a]);
vec[3] = 1.0;
- mul_m4_v4(mat, vec);
+ mul_m4_v4(persmatob, vec);
max = vec[3];
min = -vec[3];
@@ -673,6 +692,28 @@ bool ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], const BoundB
return false;
}
+bool ED_view3d_boundbox_clip_ex(RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
+{
+ /* return 1: draw */
+
+ float persmatob[4][4];
+
+ if (bb == NULL) return true;
+ if (bb->flag & BOUNDBOX_DISABLED) return true;
+
+ mul_m4_m4m4(persmatob, rv3d->persmat, obmat);
+
+ return view3d_boundbox_clip_m4(bb, persmatob);
+}
+
+bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
+{
+ if (bb == NULL) return true;
+ if (bb->flag & BOUNDBOX_DISABLED) return true;
+
+ return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
+}
+
float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y)
{
ViewDepths *vd = vc->rv3d->depths;
@@ -750,10 +791,10 @@ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
bglPolygonOffset(viewdist, dist);
}
-/*!
- * \param rect for picking, NULL not to use.
+/**
+ * \param rect, optional for picking (can be NULL).
*/
-void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect)
+void view3d_winmatrix_set(ARegion *ar, View3D *v3d, rctf *rect)
{
RegionView3D *rv3d = ar->regiondata;
rctf viewplane;
@@ -813,39 +854,40 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
mat3_to_quat(rv3d->viewquat, tmat);
}
-bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
-{
- /* quat values are all unit length */
-
- switch (view) {
- case RV3D_VIEW_BOTTOM:
- copy_v4_fl4(quat, 0.0, -1.0, 0.0, 0.0);
- break;
+static float view3d_quat_axis[6][4] = {
+ {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f}, /* RV3D_VIEW_FRONT */
+ {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2}, /* RV3D_VIEW_BACK */
+ {0.5f, -0.5f, 0.5f, 0.5f}, /* RV3D_VIEW_LEFT */
+ {0.5f, -0.5f, -0.5f, -0.5f}, /* RV3D_VIEW_RIGHT */
+ {1.0f, 0.0f, 0.0f, 0.0f}, /* RV3D_VIEW_TOP */
+ {0.0f, -1.0f, 0.0f, 0.0f}, /* RV3D_VIEW_BOTTOM */
+};
- case RV3D_VIEW_BACK:
- copy_v4_fl4(quat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2);
- break;
- case RV3D_VIEW_LEFT:
- copy_v4_fl4(quat, 0.5, -0.5, 0.5, 0.5);
- break;
+bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
+{
+ if (RV3D_VIEW_IS_AXIS(view)) {
+ copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
- case RV3D_VIEW_TOP:
- copy_v4_fl4(quat, 1.0, 0.0, 0.0, 0.0);
- break;
+char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
+{
+ /* quat values are all unit length */
- case RV3D_VIEW_FRONT:
- copy_v4_fl4(quat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0);
- break;
+ char view;
- case RV3D_VIEW_RIGHT:
- copy_v4_fl4(quat, 0.5, -0.5, -0.5, -0.5);
- break;
- default:
- return false;
+ for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
+ if (angle_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]) < epsilon) {
+ return view;
+ }
}
- return true;
+ return RV3D_VIEW_USER;
}
char ED_view3d_lock_view_from_index(int index)
@@ -865,7 +907,7 @@ bool ED_view3d_lock(RegionView3D *rv3d)
}
/* don't set windows active in here, is used by renderwin too */
-void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
+void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
if (v3d->camera) {
@@ -962,11 +1004,11 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
BLI_rctf_rcti_copy(&rect, input);
}
- setwinmatrixview3d(ar, v3d, &rect);
+ view3d_winmatrix_set(ar, v3d, &rect);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
if (v3d->drawtype > OB_WIRE) {
- v3d->zbuf = TRUE;
+ v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
}
@@ -995,7 +1037,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
else {
Base *base;
- v3d->xray = TRUE; /* otherwise it postpones drawing */
+ v3d->xray = true; /* otherwise it postpones drawing */
for (base = scene->base.first; base; base = base->next) {
if (base->lay & v3d->lay) {
@@ -1055,7 +1097,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
GPU_aspect_begin(GPU_ASPECT_BASIC, NULL); /* restarting in render mode (assuming was basic aspect before) */
G.f &= ~G_PICKSEL;
- setwinmatrixview3d(ar, v3d, NULL);
+ view3d_winmatrix_set(ar, v3d, NULL);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
if (v3d->drawtype > OB_WIRE) {
@@ -1146,11 +1188,14 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active)
return lay;
}
-static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportList *reports)
+static bool view3d_localview_init(
+ wmWindowManager *wm, wmWindow *win,
+ Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx,
+ ReportList *reports)
{
View3D *v3d = sa->spacedata.first;
Base *base;
- float min[3], max[3], box[3];
+ float min[3], max[3], box[3], mid[3];
float size = 0.0f, size_persp = 0.0f, size_ortho = 0.0f;
unsigned int locallay;
bool ok = false;
@@ -1205,34 +1250,48 @@ static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, Report
memcpy(v3d->localvd, v3d, sizeof(View3D));
+ mid_v3_v3v3(mid, min, max);
+
+ copy_v3_v3(v3d->cursor, mid);
+
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
+ /* new view values */
+ Object *camera_old = NULL;
+ float dist_new, ofs_new[3];
+
rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
-
- mid_v3_v3v3(v3d->cursor, min, max);
- negate_v3_v3(rv3d->ofs, v3d->cursor);
+
+ negate_v3_v3(ofs_new, mid);
if (rv3d->persp == RV3D_CAMOB) {
rv3d->persp = RV3D_PERSP;
+ camera_old = v3d->camera;
}
/* perspective should be a bit farther away to look nice */
if (rv3d->persp != RV3D_ORTHO) {
- rv3d->dist = size_persp;
+ dist_new = size_persp;
}
else {
- rv3d->dist = size_ortho;
+ dist_new = size_ortho;
}
/* correction for window aspect ratio */
if (ar->winy > 2 && ar->winx > 2) {
float asp = (float)ar->winx / (float)ar->winy;
if (asp < 1.0f) asp = 1.0f / asp;
- rv3d->dist *= asp;
+ dist_new *= asp;
}
+
+ ED_view3d_smooth_view_ex(
+ wm, win, sa,
+ v3d, ar, camera_old, NULL,
+ ofs_new, NULL, &dist_new, NULL,
+ smooth_viewtx);
}
}
@@ -1253,13 +1312,18 @@ static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, Report
return ok;
}
-static void restore_localviewdata(Main *bmain, ScrArea *sa, int free)
+static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, ScrArea *sa, const int smooth_viewtx)
{
+ const bool free = true;
ARegion *ar;
View3D *v3d = sa->spacedata.first;
+ Object *camera_old, *camera_new;
if (v3d->localvd == NULL) return;
+ camera_old = v3d->camera;
+ camera_new = v3d->localvd->camera;
+
v3d->near = v3d->localvd->near;
v3d->far = v3d->localvd->far;
v3d->lay = v3d->localvd->lay;
@@ -1277,13 +1341,21 @@ static void restore_localviewdata(Main *bmain, ScrArea *sa, int free)
RegionView3D *rv3d = ar->regiondata;
if (rv3d->localvd) {
- rv3d->dist = rv3d->localvd->dist;
- copy_v3_v3(rv3d->ofs, rv3d->localvd->ofs);
- copy_qt_qt(rv3d->viewquat, rv3d->localvd->viewquat);
+ Object *camera_old_rv3d, *camera_new_rv3d;
+
+ camera_old_rv3d = (rv3d->persp == RV3D_CAMOB) ? camera_old : NULL;
+ camera_new_rv3d = (rv3d->localvd->persp == RV3D_CAMOB) ? camera_new : NULL;
+
rv3d->view = rv3d->localvd->view;
rv3d->persp = rv3d->localvd->persp;
rv3d->camzoom = rv3d->localvd->camzoom;
+ ED_view3d_smooth_view_ex(
+ wm, win, sa,
+ v3d, ar, camera_old_rv3d, camera_new_rv3d,
+ rv3d->localvd->ofs, rv3d->localvd->viewquat, &rv3d->localvd->dist, NULL,
+ smooth_viewtx);
+
if (free) {
MEM_freeN(rv3d->localvd);
rv3d->localvd = NULL;
@@ -1295,7 +1367,9 @@ static void restore_localviewdata(Main *bmain, ScrArea *sa, int free)
}
}
-static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa)
+static bool view3d_localview_exit(
+ wmWindowManager *wm, wmWindow *win,
+ Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
{
View3D *v3d = sa->spacedata.first;
struct Base *base;
@@ -1304,8 +1378,8 @@ static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa)
if (v3d->localvd) {
locallay = v3d->lay & 0xFF000000;
-
- restore_localviewdata(bmain, sa, 1); /* 1 = free */
+
+ restore_localviewdata(wm, win, bmain, sa, smooth_viewtx);
/* for when in other window the layers have changed */
if (v3d->scenelock) v3d->lay = scene->lay;
@@ -1333,6 +1407,9 @@ static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa)
static int localview_exec(bContext *C, wmOperator *op)
{
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
@@ -1340,15 +1417,20 @@ static int localview_exec(bContext *C, wmOperator *op)
bool changed;
if (v3d->localvd) {
- changed = view3d_localview_exit(bmain, scene, sa);
+ changed = view3d_localview_exit(wm, win, bmain, scene, sa, smooth_viewtx);
}
else {
- changed = view3d_localview_init(bmain, scene, sa, op->reports);
+ changed = view3d_localview_init(wm, win, bmain, scene, sa, smooth_viewtx, op->reports);
}
if (changed) {
DAG_id_type_tag(bmain, ID_OB);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(sa);
+
+ /* unselected objects become selected when exiting */
+ if (v3d->localvd == NULL) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 71169ba617f..a695a6dd7fc 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -30,7 +30,6 @@
//#define NDOF_WALK_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_camera_types.h"
#include "MEM_guardedalloc.h"
@@ -57,6 +56,8 @@
#include "PIL_time.h" /* smoothview */
+#include "UI_resources.h"
+
#include "view3d_intern.h" /* own include */
#include "GPU_colors.h"
@@ -319,7 +320,9 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a
}
gpuImmediateFormat_V2();
-
+
+ UI_ThemeColor(TH_VIEW_OVERLAY);
+
gpuColor3P(CPACK_BLACK);
gpuBegin(GL_LINES);
@@ -355,6 +358,7 @@ static void walk_update_header(bContext *C, WalkInfo *walk)
BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB/Return: confirm, Esc/RMB: cancel, "
"Tab: gravity (%s), "
"WASD: move around, "
+ "Shift: fast, Alt: slow, "
"QE: up and down, MMB/Space: teleport, V: jump, "
"Pad +/Wheel Up: increase speed, Pad -/Wheel Down: decrease speed"),
WM_bool_as_string(gravity));
@@ -377,9 +381,9 @@ static void walk_navigation_mode_set(bContext *C, WalkInfo *walk, eWalkMethod mo
}
/**
- * \param ray_distance Distance to the hit point
+ * \param r_distance Distance to the hit point
*/
-static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, float dvec[3], float *ray_distance)
+static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance)
{
float dummy_dist_px = 0;
float ray_normal[3] = {0, 0, -1}; /* down */
@@ -389,22 +393,20 @@ static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *w
float dvec_tmp[3];
bool ret;
- *ray_distance = TRANSFORM_DIST_MAX_RAY;
+ *r_distance = TRANSFORM_DIST_MAX_RAY;
copy_v3_v3(ray_start, rv3d->viewinv[3]);
- if (dvec) {
- mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
- add_v3_v3(ray_start, dvec_tmp);
- }
+ mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
+ add_v3_v3(ray_start, dvec_tmp);
ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE,
NULL, NULL,
- ray_start, ray_normal, ray_distance,
+ ray_start, ray_normal, r_distance,
NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL);
/* artifically scale the distance to the scene size */
- *ray_distance /= walk->grid;
+ *r_distance /= walk->grid;
return ret;
}
@@ -550,7 +552,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
copy_v2_v2_int(walk->prev_mval, walk->center_mval);
- WM_cursor_warp(CTX_wm_window(C),
+ WM_cursor_warp(win,
walk->ar->winrct.xmin + walk->center_mval[0],
walk->ar->winrct.ymin + walk->center_mval[1]);
@@ -651,7 +653,7 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
// puts("ndof motion detected in walk mode!");
// static const char *tag_name = "3D mouse position";
- wmNDOFMotionData *incoming_ndof = (wmNDOFMotionData *)event->customdata;
+ const wmNDOFMotionData *incoming_ndof = event->customdata;
switch (incoming_ndof->progress) {
case P_STARTING:
/* start keeping track of 3D mouse position */
@@ -1101,7 +1103,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
}
/* the distance we would fall naturally smoothly enough that we
- can manually drop the object without activating gravity */
+ * can manually drop the object without activating gravity */
fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
if (fabsf(difference) < fall_distance) {
@@ -1127,7 +1129,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
/* Falling or jumping) */
if (ELEM(walk->gravity, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) {
float t;
- float z_old, z_new;
+ float z_cur, z_new;
bool ret;
float ray_distance, difference = -100.0f;
@@ -1137,16 +1139,15 @@ static int walkApply(bContext *C, WalkInfo *walk)
/* keep moving if we were moving */
copy_v2_v2(dvec, walk->teleport.direction);
- z_old = walk->rv3d->viewinv[3][2];
+ z_cur = walk->rv3d->viewinv[3][2];
z_new = walk->teleport.origin[2] - getFreeFallDistance(t) * walk->grid;
/* jump */
z_new += t * walk->speed_jump * walk->grid;
- dvec[2] = z_old - z_new;
-
/* duration is the jump duration */
if (t > walk->teleport.duration) {
+
/* check to see if we are landing */
ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance);
@@ -1154,12 +1155,20 @@ static int walkApply(bContext *C, WalkInfo *walk)
difference = walk->view_height - ray_distance;
}
- if (ray_distance < walk->view_height) {
- /* quit falling */
+ if (difference > 0.0f) {
+ /* quit falling, lands at "view_height" from the floor */
dvec[2] -= difference;
walk->gravity = WALK_GRAVITY_STATE_OFF;
walk->speed_jump = 0.0f;
}
+ else {
+ /* keep falling */
+ dvec[2] = z_cur - z_new;
+ }
+ }
+ else {
+ /* keep going up (jump) */
+ dvec[2] = z_cur - z_new;
}
}
@@ -1223,134 +1232,23 @@ static int walkApply(bContext *C, WalkInfo *walk)
#undef WALK_BOOST_FACTOR
}
-static int walkApply_ndof(bContext *C, WalkInfo *walk)
+static void walkApply_ndof(bContext *C, WalkInfo *walk)
{
- /* shorthand for oft-used variables */
- wmNDOFMotionData *ndof = walk->ndof;
- const float dt = ndof->dt;
- RegionView3D *rv3d = walk->rv3d;
- const int flag = U.ndof_flag;
-
-#if 0
- bool do_rotate = (flag & NDOF_SHOULD_ROTATE) && (walk->pan_view == false);
- bool do_translate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)) != 0;
-#endif
-
- bool do_rotate = true;
- bool do_translate = true;
-
- float view_inv[4];
- invert_qt_qt(view_inv, rv3d->viewquat);
-
- rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
-
- if (do_translate) {
- const float forward_sensitivity = 1.0f;
- const float vertical_sensitivity = 0.4f;
- const float lateral_sensitivity = 0.6f;
-
- float speed = 10.0f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
-
- float trans[3] = {lateral_sensitivity * ndof->tvec[0],
- vertical_sensitivity * ndof->tvec[1],
- forward_sensitivity * ndof->tvec[2]};
-
- if (walk->is_slow)
- speed *= 0.2f;
-
- mul_v3_fl(trans, speed * dt);
-
- /* transform motion from view to world coordinates */
- mul_qt_v3(view_inv, trans);
-
- if (flag & NDOF_FLY_HELICOPTER) {
- /* replace world z component with device y (yes it makes sense) */
- trans[2] = speed * dt * vertical_sensitivity * ndof->tvec[1];
- }
-
- if (rv3d->persp == RV3D_CAMOB) {
- /* respect camera position locks */
- Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
- if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
- if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
- }
-
- if (!is_zero_v3(trans)) {
- /* move center of view opposite of hand motion (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, trans);
- do_translate = true;
- }
- else {
- do_translate = false;
- }
- }
-
- if (do_rotate) {
- const float turn_sensitivity = 1.0f;
-
- float rotation[4];
- float axis[3];
- float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
-
- if (fabsf(angle) > 0.0001f) {
- do_rotate = true;
-
- if (walk->is_slow)
- angle *= 0.2f;
-
- /* transform rotation axis from view to world coordinates */
- mul_qt_v3(view_inv, axis);
-
- /* apply rotation to view */
- axis_angle_to_quat(rotation, axis, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
-
- if (flag & NDOF_LOCK_HORIZON) {
- /* force an upright viewpoint
- * TODO: make this less... sudden */
- float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
- float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
-
- /* find new inverse since viewquat has changed */
- invert_qt_qt(view_inv, rv3d->viewquat);
- /* could apply reverse rotation to existing view_inv to save a few cycles */
-
- /* transform view vectors to world coordinates */
- mul_qt_v3(view_inv, view_horizon);
- mul_qt_v3(view_inv, view_direction);
+ Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
+ bool has_translate, has_rotate;
+ view3d_ndof_fly(walk->ndof,
+ walk->v3d, walk->rv3d,
+ walk->is_slow, lock_ob ? lock_ob->protectflag : 0,
+ &has_translate, &has_rotate);
- /* find difference between view & world horizons
- * true horizon lives in world xy plane, so look only at difference in z */
- angle = -asinf(view_horizon[2]);
-
-#ifdef NDOF_WALK_DEBUG
- printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
-#endif
-
- /* rotate view so view horizon = world horizon */
- axis_angle_to_quat(rotation, view_direction, angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
- }
-
- rv3d->view = RV3D_VIEW_USER;
- }
- else {
- do_rotate = false;
- }
- }
-
- if (do_translate || do_rotate) {
+ if (has_translate || has_rotate) {
walk->redraw = true;
- if (rv3d->persp == RV3D_CAMOB) {
- walkMoveCamera(C, walk, do_rotate, do_translate);
+ if (walk->rv3d->persp == RV3D_CAMOB) {
+ walkMoveCamera(C, walk, has_rotate, has_translate);
}
}
-
- return OPERATOR_FINISHED;
}
/****** walk operator ******/
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 32c0d4e74b0..f8fb075ca6f 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -35,19 +35,11 @@
#include <math.h>
#include <float.h>
-#ifndef WIN32
-# include <unistd.h>
-#else
-# include <io.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
@@ -58,15 +50,12 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
-#include "BLI_linklist.h"
#include "BKE_nla.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
-#include "BKE_global.h"
#include "BKE_particle.h"
-#include "BKE_pointcache.h"
#include "BKE_unit.h"
#include "BKE_mask.h"
@@ -81,7 +70,6 @@
#include "ED_mesh.h"
#include "ED_clip.h"
#include "ED_node.h"
-#include "ED_mask.h"
#include "ED_node.h"
#include "WM_types.h"
@@ -379,7 +367,7 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
v[0] = vec[0] / aspx;
v[1] = vec[1] / aspy;
- UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1);
+ UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
}
}
else if (t->spacetype == SPACE_ACTION) {
@@ -390,12 +378,12 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
if (sact->flag & SACTION_DRAWTIME) {
//vec[0] = vec[0]/((t->scene->r.frs_sec / t->scene->r.frs_sec_base));
/* same as below */
- UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1);
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
}
else
#endif
{
- UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1);
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
}
adr[0] = out[0];
@@ -404,14 +392,14 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
else if (ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
int out[2] = {0, 0};
- UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1);
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
adr[0] = out[0];
adr[1] = out[1];
}
else if (t->spacetype == SPACE_SEQ) { /* XXX not tested yet, but should work */
int out[2] = {0, 0};
- UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], out, out + 1);
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &out[0], &out[1]);
adr[0] = out[0];
adr[1] = out[1];
}
@@ -419,26 +407,34 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
SpaceClip *sc = t->sa->spacedata.first;
if (t->options & CTX_MASK) {
- /* not working quite right, TODO (see above too) */
- float aspx, aspy;
- float v[2];
+ MovieClip *clip = ED_space_clip_get_clip(sc);
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
+ if (clip) {
+ /* not working quite right, TODO (see above too) */
+ float aspx, aspy;
+ float v[2];
- copy_v2_v2(v, vec);
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
- v[0] = v[0] / aspx;
- v[1] = v[1] / aspy;
+ copy_v2_v2(v, vec);
- BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
+ v[0] = v[0] / aspx;
+ v[1] = v[1] / aspy;
- v[0] = v[0] / aspx;
- v[1] = v[1] / aspy;
+ BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v);
- ED_clip_point_stable_pos__reverse(sc, t->ar, v, v);
+ v[0] = v[0] / aspx;
+ v[1] = v[1] / aspy;
- adr[0] = v[0];
- adr[1] = v[1];
+ ED_clip_point_stable_pos__reverse(sc, t->ar, v, v);
+
+ adr[0] = v[0];
+ adr[1] = v[1];
+ }
+ else {
+ adr[0] = 0;
+ adr[1] = 0;
+ }
}
else if (t->options & CTX_MOVIECLIP) {
float v[2], aspx, aspy;
@@ -449,14 +445,14 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
v[0] /= aspx;
v[1] /= aspy;
- UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1);
+ UI_view2d_view_to_region(t->view, v[0], v[1], &adr[0], &adr[1]);
}
else {
BLI_assert(0);
}
}
else if (t->spacetype == SPACE_NODE) {
- UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], adr, adr + 1);
+ UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], &adr[0], &adr[1]);
}
}
void projectIntView(TransInfo *t, const float vec[3], int adr[2])
@@ -942,7 +938,6 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
int transformEvent(TransInfo *t, const wmEvent *event)
{
- float mati[3][3] = MAT3_UNITY;
char cmode = constraintModeToChar(t);
bool handled = false;
@@ -1004,7 +999,11 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
else {
if (t->obedit && t->obedit->type == OB_MESH) {
- if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
+ if ((t->mode == TFM_TRANSLATION) &&
+ (t->spacetype == SPACE_VIEW3D) &&
+ /* prevents accidental select-tweak, gkey. see: T40102 */
+ (ISMOUSE(t->launch_event) == 0))
+ {
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
@@ -1064,6 +1063,12 @@ int transformEvent(TransInfo *t, const wmEvent *event)
case TFM_MODAL_RESIZE:
/* only switch when... */
if (ELEM5(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+
+ /* Scale isn't normally very useful after extrude along normals, see T39756 */
+ if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_MANIP_NORMAL)) {
+ stopConstraint(t);
+ }
+
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
@@ -1297,7 +1302,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
else {
/* bit hackish... but it prevents mmb select to print the orientation from menu */
+ float mati[3][3];
strcpy(t->spacename, "global");
+ unit_m3(mati);
initSelectConstraint(t, mati);
}
postSelectConstraint(t);
@@ -1443,13 +1450,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
- case HKEY:
- if (t->spacetype == SPACE_NODE) {
- t->flag ^= T_TOGGLE_HIDDEN;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
default:
break;
}
@@ -1488,16 +1488,21 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* confirm transform if launch key is released after mouse move */
if (t->flag & T_RELEASE_CONFIRM) {
- /* XXX Keyrepeat bug in Xorg fucks this up, will test when fixed */
+ /* XXX Keyrepeat bug in Xorg messes this up, will test when fixed */
if (event->type == t->launch_event && (t->launch_event == LEFTMOUSE || t->launch_event == RIGHTMOUSE)) {
t->state = TRANS_CONFIRM;
}
}
}
- // Per transform event, if present
- if (t->handleEvent && !handled)
+ /* Per transform event, if present */
+ if (t->handleEvent &&
+ (!handled ||
+ /* Needed for vertex slide, see [#38756] */
+ (event->type == MOUSEMOVE)))
+ {
t->redraw |= t->handleEvent(t, event);
+ }
/* Try to init modal numinput now, if possible. */
if (!(handled || t->redraw) && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
@@ -1515,10 +1520,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
-int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
+bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
{
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
- int success;
+ bool success;
t->state = TRANS_RUNNING;
@@ -1537,10 +1542,10 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float
t->around = centerMode; // override userdefined mode
if (t->total == 0) {
- success = FALSE;
+ success = false;
}
else {
- success = TRUE;
+ success = true;
calculateCenter(t);
@@ -1555,7 +1560,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float
}
- /* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */
+ /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
special_aftertrans_update(C, t);
postTrans(C, t);
@@ -1682,7 +1687,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
switch (t->helpline) {
case HLP_SPRING:
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
GPU_raster_set_line_style(3);
gpuBegin(GL_LINE_STRIP);
@@ -1701,7 +1706,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
break;
case HLP_HARROW:
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
gpuTranslate(mval[0], mval[1], 0);
@@ -1712,7 +1717,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
break;
case HLP_VARROW:
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
gpuTranslate(mval[0], mval[1], 0);
@@ -1729,7 +1734,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
float dist = sqrtf(dx * dx + dy * dy);
float delta_angle = min_ff(15.0f / dist, (float)M_PI / 4.0f);
float spacing_angle = min_ff(5.0f / dist, (float)M_PI / 12.0f);
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
GPU_raster_set_line_style(3);
gpuBegin(GL_LINE_STRIP);
@@ -2083,7 +2088,7 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
if (t->flag & TFM_EDGE_SLIDE) {
EdgeSlideData *sld = t->customData;
/* Non-Prop mode */
- if (sld && sld->is_proportional == FALSE) {
+ if (sld && sld->is_proportional == false) {
View3D *v3d = CTX_wm_view3d(C);
float marker[3];
float v1[3], v2[3];
@@ -2244,7 +2249,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
if ((prop = RNA_struct_find_property(op->ptr, "value"))) {
- float *values = (t->flag & T_AUTOVALUES) ? t->auto_values : t->values;
+ const float *values = (t->flag & T_AUTOVALUES) ? t->auto_values : t->values;
if (RNA_property_array_check(prop)) {
RNA_property_float_set_array(op->ptr, prop, values);
}
@@ -2360,7 +2365,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
/* note: caller needs to free 't' on a 0 return */
-int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
+bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
{
int options = 0;
PropertyRNA *prop;
@@ -2697,7 +2702,7 @@ int transformEnd(bContext *C, TransInfo *t)
exit_code = OPERATOR_FINISHED;
}
- /* aftertrans does insert keyframes, and clears base flags, doesnt read transdata */
+ /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
special_aftertrans_update(C, t);
/* free data */
@@ -2845,8 +2850,8 @@ static void protectedQuaternionBits(short protectflag, float quat[4], const floa
static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *ctiLoc = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
- bConstraintTypeInfo *ctiDist = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
+ bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_LOCLIMIT);
+ bConstraintTypeInfo *ctiDist = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_DISTLIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
@@ -2896,7 +2901,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
/* get constraint targets if needed */
- BKE_get_constraint_targets_for_solving(con, &cob, &targets, ctime);
+ BKE_constraint_targets_for_solving_get(con, &cob, &targets, ctime);
/* do constraint */
cti->evaluate_constraint(con, &cob, &targets);
@@ -2948,10 +2953,10 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
- int do_limit = FALSE;
+ bool do_limit = false;
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
@@ -2972,9 +2977,9 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
continue;
/* only do conversion if necessary, to preserve quats and eulers */
- if (do_limit == FALSE) {
+ if (do_limit == false) {
constraintob_from_transdata(&cob, td);
- do_limit = TRUE;
+ do_limit = true;
}
/* do space conversions */
@@ -3015,7 +3020,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
static void constraintSizeLim(TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
- bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
float size_sign[3], size_abs[3];
@@ -3142,7 +3147,7 @@ static void initBend(TransInfo *t)
t->flag |= T_NO_CONSTRAINT;
//copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view));
- calculateCenterCursor(t);
+ calculateCenterCursor(t, t->center);
t->val = 0.0f;
@@ -3212,20 +3217,20 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
values.scale /= snap_hack;
}
#endif
-
+
+ if (applyNumInput(&t->num, values.vector)) {
+ values.scale = values.scale / data->warp_init_dist;
+ }
+
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
-
- applyNumInput(&t->num, values.vector);
outputNumInput(&(t->num), c);
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bend Angle: %s Radius: %s Alt, Clamp %s"),
&c[0], &c[NUM_STR_REP_LEN],
WM_bool_as_string(is_clamp));
-
- values.scale = values.scale / data->warp_init_dist;
}
else {
/* default header print */
@@ -3679,8 +3684,7 @@ static void applyResize(TransInfo *t, const int mval[2])
snapGridIncrement(t, size);
- if (hasNumInput(&t->num)) {
- applyNumInput(&t->num, size);
+ if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
@@ -3789,8 +3793,7 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
snapGridIncrement(t, size);
- if (hasNumInput(&t->num)) {
- applyNumInput(&t->num, size);
+ if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
@@ -4251,17 +4254,17 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
applySnapping(t, &final);
+ if (applyNumInput(&t->num, &final)) {
+ /* Clamp between -PI and PI */
+ final = angle_wrap_rad(final);
+ }
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
- applyNumInput(&t->num, &final);
-
outputNumInput(&(t->num), c);
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
-
- /* Clamp between -PI and PI */
- final = angle_wrap_rad(final);
}
else {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %.2f%s %s"),
@@ -4358,11 +4361,11 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
snapGridIncrement(t, phi);
+ applyNumInput(&t->num, phi);
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN * 2];
- applyNumInput(&t->num, phi);
-
outputNumInput(&(t->num), c);
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"),
@@ -4442,10 +4445,18 @@ static void initTranslation(TransInfo *t)
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;
- t->num.unit_type[0] = B_UNIT_LENGTH;
- t->num.unit_type[1] = B_UNIT_LENGTH;
- t->num.unit_type[2] = B_UNIT_LENGTH;
-
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* Handling units makes only sense in 3Dview... See T38877. */
+ t->num.unit_type[0] = B_UNIT_LENGTH;
+ t->num.unit_type[1] = B_UNIT_LENGTH;
+ t->num.unit_type[2] = B_UNIT_LENGTH;
+ }
+ else {
+ /* SPACE_IPO, SPACE_ACTION, etc. could use some time units, when we have them... */
+ t->num.unit_type[0] = B_UNIT_NONE;
+ t->num.unit_type[1] = B_UNIT_NONE;
+ t->num.unit_type[2] = B_UNIT_NONE;
+ }
}
static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
@@ -4468,7 +4479,8 @@ static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]
dist = len_v3(vec);
if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
- int i, do_split = t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1 : 0;
+ const bool do_split = (t->scene->unit.flag & USER_UNIT_OPT_SPLIT) != 0;
+ int i;
for (i = 0; i < 3; i++) {
bUnit_AsString(&tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length,
@@ -4482,13 +4494,18 @@ static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]
}
}
- if (!(t->flag & T_2D_EDIT) && t->scene->unit.system)
+ if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
+ const bool do_split = (t->scene->unit.flag & USER_UNIT_OPT_SPLIT) != 0;
bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system,
- B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, false);
- else if (dist > 1e10f || dist < -1e10f) /* prevent string buffer overflow */
+ B_UNIT_LENGTH, do_split, false);
+ }
+ else if (dist > 1e10f || dist < -1e10f) {
+ /* prevent string buffer overflow */
BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
- else
+ }
+ else {
BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4f", dist);
+ }
if (t->flag & T_AUTOIK) {
short chainlen = t->settings->autoik_chainlen;
@@ -4551,7 +4568,7 @@ static void applyTranslationValue(TransInfo *t, float vec[3])
/* handle snapping rotation before doing the translation */
if (usingSnappingNormal(t)) {
if (validSnappingNormal(t)) {
- float *original_normal;
+ const float *original_normal;
float axis[3];
float quat[4];
float mat[3][3];
@@ -4609,7 +4626,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
float tvec[3];
- if (hasNumInput(&t->num)) {
+ if (applyNumInput(&t->num, t->values)) {
removeAspectRatio(t, t->values);
}
applySnapping(t, t->values);
@@ -4619,8 +4636,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
}
else {
snapGridIncrement(t, t->values);
- applyNumInput(&t->num, t->values);
- if (hasNumInput(&t->num)) {
+ if (applyNumInput(&t->num, t->values)) {
removeAspectRatio(t, t->values);
}
applySnapping(t, t->values);
@@ -4790,11 +4806,11 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
snapGridIncrement(t, &final);
+ applyNumInput(&t->num, &final);
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
- applyNumInput(&t->num, &final);
-
outputNumInput(&(t->num), c);
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
@@ -4933,7 +4949,8 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float ratio;
- int i, initial_feather = FALSE;
+ int i;
+ bool initial_feather = false;
char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4955,7 +4972,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
/* detect if no points have feather yet */
if (ratio > 1.0f) {
- initial_feather = TRUE;
+ initial_feather = true;
for (td = t->data, i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -4965,7 +4982,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
continue;
if (td->ival >= 0.001f)
- initial_feather = FALSE;
+ initial_feather = false;
}
}
@@ -5345,8 +5362,7 @@ static void applyBoneSize(TransInfo *t, const int mval[2])
snapGridIncrement(t, size);
- if (hasNumInput(&t->num)) {
- applyNumInput(&t->num, size);
+ if (applyNumInput(&t->num, size)) {
constraintNumInput(t, size);
}
@@ -5720,7 +5736,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
sld->is_proportional = true;
sld->curr_sv_index = 0;
- sld->flipped_vtx = FALSE;
+ sld->flipped_vtx = false;
if (!rv3d) {
/* ok, let's try to survive this */
@@ -6366,7 +6382,7 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
case FKEY:
{
if (event->val == KM_PRESS) {
- if (sld->is_proportional == FALSE) {
+ if (sld->is_proportional == false) {
sld->flipped_vtx = !sld->flipped_vtx;
}
return TREDRAW_HARD;
@@ -6406,7 +6422,7 @@ static int doEdgeSlide(TransInfo *t, float perc)
sld->perc = perc;
sv = svlist;
- if (sld->is_proportional == TRUE) {
+ if (sld->is_proportional == true) {
for (i = 0; i < sld->totsv; i++, sv++) {
float vec[3];
if (perc > 0.0f) {
@@ -6473,11 +6489,11 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
/* only do this so out of range values are not displayed */
CLAMP(final, -1.0f, 1.0f);
+ applyNumInput(&t->num, &final);
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
- applyNumInput(&t->num, &final);
-
outputNumInput(&(t->num), c);
if (is_proportional) {
@@ -6522,8 +6538,8 @@ static void calcVertSlideCustomPoints(struct TransInfo *t)
{
VertSlideData *sld = t->customData;
TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
- float *co_orig = sv->co_orig_2d;
- float *co_curr = sv->co_link_orig_2d[sv->co_link_curr];
+ const float *co_orig = sv->co_orig_2d;
+ const float *co_curr = sv->co_link_orig_2d[sv->co_link_curr];
const int mval_start[2] = {co_orig[0], co_orig[1]};
const int mval_end[2] = {co_curr[0], co_curr[1]};
@@ -6920,7 +6936,7 @@ static void drawVertSlide(const struct bContext *C, TransInfo *t)
GPU_sprite_size(ctrl_size);
GPU_sprite_begin();
- GPU_sprite_3fv((sld->flipped_vtx && sld->is_proportional == FALSE) ?
+ GPU_sprite_3fv((sld->flipped_vtx && sld->is_proportional == false) ?
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
curr_sv->co_orig_3d);
GPU_sprite_end();
@@ -6952,7 +6968,7 @@ static int doVertSlide(TransInfo *t, float perc)
sld->perc = perc;
sv = svlist;
- if (sld->is_proportional == TRUE) {
+ if (sld->is_proportional == true) {
for (i = 0; i < sld->totsv; i++, sv++) {
interp_v3_v3v3(sv->v->co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
}
@@ -7006,11 +7022,12 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
CLAMP(final, 0.0f, 1.0f);
}
+ applyNumInput(&t->num, &final);
+
/* header string */
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
- applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs);
}
@@ -7073,11 +7090,11 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
snapGridIncrement(t, &final);
+ applyNumInput(&t->num, &final);
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
- applyNumInput(&t->num, &final);
-
outputNumInput(&(t->num), c);
BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]);
@@ -7484,55 +7501,15 @@ static short getAnimEdit_SnapMode(TransInfo *t)
return autosnap;
}
-/* This function is used for testing if an Animation Editor is displaying
- * its data in frames or seconds (and the data needing to be edited as such).
- * Returns 1 if in seconds, 0 if in frames
- */
-static short getAnimEdit_DrawTime(TransInfo *t)
-{
- short drawtime;
-
- if (t->spacetype == SPACE_ACTION) {
- SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
-
- drawtime = (saction->flag & SACTION_DRAWTIME) ? 1 : 0;
- }
- else if (t->spacetype == SPACE_NLA) {
- SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
-
- drawtime = (snla->flag & SNLA_DRAWTIME) ? 1 : 0;
- }
- else if (t->spacetype == SPACE_IPO) {
- SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first;
-
- drawtime = (sipo->flag & SIPO_DRAWTIME) ? 1 : 0;
- }
- else {
- drawtime = 0;
- }
-
- return drawtime;
-}
-
-
/* This function is used by Animation Editor specific transform functions to do
* the Snap Keyframe to Nearest Frame/Marker
*/
static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
{
- /* snap key to nearest frame? */
- if (autosnap == SACTSNAP_FRAME) {
-
-#if 0 /* 'do_time' disabled for now */
-
+ /* snap key to nearest frame or second? */
+ if (ELEM(autosnap, SACTSNAP_FRAME, SACTSNAP_SECOND)) {
const Scene *scene = t->scene;
-#if 0 /* NOTE: this works, but may be confusing behavior given the option's label, hence disabled */
- const short do_time = getAnimEdit_DrawTime(t);
-#else
- const short do_time = 0;
-#endif
const double secf = FPS;
-#endif
double val;
/* convert frame to nla-action time (if needed) */
@@ -7541,16 +7518,12 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d,
else
val = *(td->val);
-#if 0 /* 'do_time' disabled for now */
-
/* do the snapping to nearest frame/second */
- if (do_time) {
- val = (float)(floor((val / secf) + 0.5f) * secf);
+ if (autosnap == SACTSNAP_FRAME) {
+ val = floorf(val + 0.5);
}
- else
-#endif
- {
- val = floor(val + 0.5);
+ else if (autosnap == SACTSNAP_SECOND) {
+ val = (float)(floor((val / secf) + 0.5) * secf);
}
/* convert frame out of nla-action time */
@@ -7638,20 +7611,21 @@ static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
else {
const Scene *scene = t->scene;
const short autosnap = getAnimEdit_SnapMode(t);
- const short do_time = getAnimEdit_DrawTime(t);
const double secf = FPS;
float val = t->values[0];
/* apply snapping + frame->seconds conversions */
if (autosnap == SACTSNAP_STEP) {
- if (do_time)
- val = floorf((double)val / secf + 0.5);
- else
- val = floorf(val + 0.5f);
+ /* frame step */
+ val = floorf(val + 0.5f);
+ }
+ else if (autosnap == SACTSNAP_TSTEP) {
+ /* second step */
+ val = floorf((double)val / secf + 0.5);
}
else {
- if (do_time)
- val = (float)((double)val / secf);
+ /* nearest frame/second/marker */
+ val = (float)((double)val / secf);
}
if (autosnap == SACTSNAP_FRAME)
@@ -7669,11 +7643,9 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
TransData2D *td2d = t->data2d;
Scene *scene = t->scene;
int i;
-
- const short do_time = getAnimEdit_DrawTime(t);
- const double secf = FPS;
-
+
const short autosnap = getAnimEdit_SnapMode(t);
+ const double secf = FPS;
float deltax, val /* , valprev */;
@@ -7688,14 +7660,14 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
/* valprev = *td->val; */ /* UNUSED */
/* check if any need to apply nla-mapping */
- if (adt && t->spacetype != SPACE_SEQ) {
+ if (adt && (t->spacetype != SPACE_SEQ)) {
deltax = t->values[0];
- if (autosnap == SACTSNAP_STEP) {
- if (do_time)
- deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
- else
- deltax = (float)(floor(deltax + 0.5f));
+ if (autosnap == SACTSNAP_TSTEP) {
+ deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
+ }
+ else if (autosnap == SACTSNAP_STEP) {
+ deltax = (float)(floor(deltax + 0.5f));
}
val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
@@ -7705,11 +7677,11 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
else {
deltax = val = t->values[0];
- if (autosnap == SACTSNAP_STEP) {
- if (do_time)
- val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
- else
- val = (float)(floor(val + 0.5f));
+ if (autosnap == SACTSNAP_TSTEP) {
+ val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
+ }
+ else if (autosnap == SACTSNAP_STEP) {
+ val = (float)(floor(val + 0.5f));
}
*(td->val) = td->ival + val;
@@ -7957,7 +7929,6 @@ static void applyTimeScaleValue(TransInfo *t)
int i;
const short autosnap = getAnimEdit_SnapMode(t);
- const short do_time = getAnimEdit_DrawTime(t);
const double secf = FPS;
@@ -7970,11 +7941,11 @@ static void applyTimeScaleValue(TransInfo *t)
float startx = CFRA;
float fac = t->values[0];
- if (autosnap == SACTSNAP_STEP) {
- if (do_time)
- fac = (float)(floor((double)fac / secf + 0.5) * secf);
- else
- fac = (float)(floor(fac + 0.5f));
+ if (autosnap == SACTSNAP_TSTEP) {
+ fac = (float)(floor((double)fac / secf + 0.5) * secf);
+ }
+ else if (autosnap == SACTSNAP_STEP) {
+ fac = (float)(floor(fac + 0.5f));
}
/* check if any need to apply nla-mapping */
@@ -8011,12 +7982,13 @@ static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2]))
/* TODO, move to: transform_queries.c */
bool checkUseLocalCenter_GraphEdit(TransInfo *t)
{
- return ((t->around == V3D_LOCAL) && !ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE));
+ return ((t->around == V3D_LOCAL) &&
+ !ELEM4(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE, TFM_TIME_DUPLICATE));
}
bool checkUseAxisMatrix(TransInfo *t)
{
- /* currenly only checks for editmode */
+ /* currently only checks for editmode */
if (t->flag & T_EDIT) {
if ((t->around == V3D_LOCAL) && (ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) {
/* not all editmode supports axis-matrix */
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index c6ce485d572..f0845eaec28 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -80,9 +80,9 @@ typedef struct TransSnap {
short modePoint;
short modeSelect;
bool align;
- char project;
- char snap_self;
- short peel;
+ bool project;
+ bool snap_self;
+ bool peel;
short status;
float snapPoint[3]; /* snapping from this point */
float snapTarget[3]; /* to this point */
@@ -96,7 +96,8 @@ typedef struct TransSnap {
void (*applySnap)(struct TransInfo *, float *);
void (*calcSnap)(struct TransInfo *, float *);
void (*targetSnap)(struct TransInfo *);
- float (*distance)(struct TransInfo *, float p1[3], float p2[3]); // Get the transform distance between two points (used by Closest snap)
+ /* Get the transform distance between two points (used by Closest snap) */
+ float (*distance)(struct TransInfo *, const float p1[3], const float p2[3]);
} TransSnap;
typedef struct TransCon {
@@ -276,7 +277,7 @@ typedef struct MouseInput {
void (*post)(struct TransInfo *t, float values[3]);
int imval[2]; /* initial mouse position */
- char precision;
+ bool precision;
int precision_mval[2]; /* mouse position when precision key was pressed */
float center[2];
float factor;
@@ -349,7 +350,7 @@ typedef struct TransInfo {
float axis[3];
float axis_orig[3]; /* TransCon can change 'axis', store the original value here */
- short remove_on_cancel; /* remove elements if operator is canceled */
+ bool remove_on_cancel; /* remove elements if operator is canceled */
void *view;
struct bContext *context; /* Only valid (non null) during an operator called function. */
@@ -384,6 +385,7 @@ typedef struct TransInfo {
#define T_EDIT (1 << 1)
#define T_POSE (1 << 2)
#define T_TEXTURE (1 << 3)
+ /* transforming the camera while in camera view */
#define T_CAMERA (1 << 4)
// trans on points, having no rotation/scale
#define T_POINTS (1 << 6)
@@ -424,7 +426,6 @@ typedef struct TransInfo {
/* alternative transformation. used to add offset to tracking markers */
#define T_ALT_TRANSFORM (1 << 24)
-#define T_TOGGLE_HIDDEN (1 << 25) /* node editor: toggle state of the hidden flags */
/* TransInfo->modifiers */
#define MOD_CONSTRAINT_SELECT 0x01
@@ -460,7 +461,6 @@ typedef struct TransInfo {
/* transdata->flag */
#define TD_SELECTED 1
-#define TD_ACTIVE (1 << 1)
#define TD_NOACTION (1 << 2)
#define TD_USEQUAT (1 << 3)
#define TD_NOTCONNECTED (1 << 4)
@@ -478,7 +478,6 @@ typedef struct TransInfo {
#define TD_MOVEHANDLE2 (1 << 18)
#define TD_PBONE_LOCAL_MTX_P (1 << 19) /* exceptional case with pose bone rotating when a parent bone has 'Local Location' option enabled and rotating also transforms it. */
#define TD_PBONE_LOCAL_MTX_C (1 << 20) /* same as above but for a child bone */
-#define TD_HIDDEN (1 << 21) /* for hide toggling node editor */
/* transsnap->status */
#define SNAP_FORCED 1
@@ -486,7 +485,7 @@ typedef struct TransInfo {
#define POINT_INIT 4
#define MULTI_POINTS 8
-int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, const struct wmEvent *event, int mode);
+bool initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, const struct wmEvent *event, int mode);
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
int transformEvent(TransInfo *t, const struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
@@ -499,8 +498,8 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]);
void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag);
void projectFloatView(TransInfo *t, const float vec[3], float adr[2]);
-void applyAspectRatio(TransInfo *t, float *vec);
-void removeAspectRatio(TransInfo *t, float *vec);
+void applyAspectRatio(TransInfo *t, float vec[2]);
+void removeAspectRatio(TransInfo *t, float vec[2]);
void drawPropCircle(const struct bContext *C, TransInfo *t);
@@ -523,7 +522,7 @@ void flushTransTracking(TransInfo *t);
void flushTransMasking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
-int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
+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 *********** */
@@ -633,13 +632,18 @@ void applyTransObjects(TransInfo *t);
void restoreTransObjects(TransInfo *t);
void recalcData(TransInfo *t);
-void calculateCenter(TransInfo *t);
void calculateCenter2D(TransInfo *t);
-void calculateCenterBound(TransInfo *t);
-void calculateCenterMedian(TransInfo *t);
-void calculateCenterCursor(TransInfo *t);
-void calculateCenterCursor2D(TransInfo *t);
+void calculateCenter(TransInfo *t);
+
+/* API functions for getting center points */
+void calculateCenterBound(TransInfo *t, float r_center[3]);
+void calculateCenterMedian(TransInfo *t, float r_center[3]);
+void calculateCenterCursor(TransInfo *t, float r_center[3]);
+void calculateCenterCursor2D(TransInfo *t, float r_center[2]);
+void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2]);
+bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]);
+
void calculatePropRatio(TransInfo *t);
void getViewVector(TransInfo *t, float coord[3], float vec[3]);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index acf60a3bf07..1fa3c592148 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -34,12 +34,6 @@
#include <string.h>
#include <math.h>
-#ifndef WIN32
-# include <unistd.h>
-#else
-# include <io.h>
-#endif
-
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -140,7 +134,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
snapGridIncrement(t, vec);
- if (t->num.flag & T_NULL_ONE) {
+ if (t->flag & T_NULL_ONE) {
if (!(t->con.mode & CON_AXIS0))
vec[0] = 1.0f;
@@ -151,8 +145,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
vec[2] = 1.0f;
}
- if (hasNumInput(&t->num)) {
- applyNumInput(&t->num, vec);
+ if (applyNumInput(&t->num, vec)) {
constraintNumInput(t, vec);
removeAspectRatio(t, vec);
}
@@ -629,8 +622,9 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
switch (orientation) {
case V3D_MANIP_GLOBAL:
{
- float mtx[3][3] = MAT3_UNITY;
+ float mtx[3][3];
BLI_snprintf(text, sizeof(text), ftext, IFACE_("global"));
+ unit_m3(mtx);
setConstraint(t, mtx, mode, text);
break;
}
@@ -924,13 +918,13 @@ static void setNearestAxis3d(TransInfo *t)
sub_v2_v2v2(axis, axis_2d, t->center2d);
axis[2] = 0.0f;
- if (normalize_v3(axis) != 0.0f) {
+ if (normalize_v3(axis) > 1e-3f) {
project_v3_v3v3(proj, mvec, axis);
sub_v3_v3v3(axis, mvec, proj);
len[i] = normalize_v3(axis);
}
else {
- len[i] = 10000000000.0f;
+ len[i] = 1e10f;
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 053a69faaaf..949ee79a3dc 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -29,12 +29,6 @@
* \ingroup edtransform
*/
-
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
#include <string.h>
#include <math.h>
@@ -63,13 +57,14 @@
#include "BLI_listbase.h"
#include "BLI_linklist_stack.h"
#include "BLI_string.h"
-#include "BLI_rect.h"
+#include "BLI_bitmap.h"
#include "BKE_DerivedMesh.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
+#include "BKE_crazyspace.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
@@ -107,11 +102,9 @@
#include "ED_markers.h"
#include "ED_mesh.h"
#include "ED_node.h"
-#include "ED_types.h"
#include "ED_uvedit.h"
#include "ED_clip.h"
#include "ED_mask.h"
-#include "ED_util.h" /* for crazyspace correction */
#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
#include "WM_types.h"
@@ -883,7 +876,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
}
- con = BKE_add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
+ con = BKE_constraint_add_for_pose(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */
data = con->data;
if (targetless) {
@@ -1619,7 +1612,7 @@ static void createTransLatticeVerts(TransInfo *t)
{
Lattice *latt = ((Lattice *)t->obedit->data)->editlatt->latt;
TransData *td = NULL;
- BPoint *bp, *actbp = BKE_lattice_active_point_get(latt);
+ BPoint *bp;
float mtx[3][3], smtx[3][3];
int a;
int count = 0, countsel = 0;
@@ -1656,7 +1649,6 @@ static void createTransLatticeVerts(TransInfo *t)
copy_v3_v3(td->center, td->loc);
if (bp->f1 & SELECT) {
td->flag = TD_SELECTED;
- if (actbp && bp == actbp) td->flag |= TD_ACTIVE;
}
else td->flag = 0;
copy_m3_m3(td->smtx, smtx);
@@ -2058,9 +2050,13 @@ static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r
/* pass */
}
else {
- normalize_v3(no);
- axis_dominant_v3_to_m3(trans_islands[i].axismtx, no);
- invert_m3(trans_islands[i].axismtx);
+ if (normalize_v3(no) != 0.0f) {
+ axis_dominant_v3_to_m3(trans_islands[i].axismtx, no);
+ invert_m3(trans_islands[i].axismtx);
+ }
+ else {
+ unit_m3(trans_islands[i].axismtx);
+ }
}
}
@@ -2141,7 +2137,6 @@ static void createTransEditVerts(TransInfo *t)
BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
- BMVert *eve_act = NULL;
float (*mappedcos)[3] = NULL, (*quats)[4] = NULL;
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
float *dists = NULL;
@@ -2181,10 +2176,6 @@ static void createTransEditVerts(TransInfo *t)
BLI_assert(0);
}
-
- /* check active */
- eve_act = BM_mesh_active_vert_get(bm);
-
if (t->mode == TFM_BWEIGHT) {
BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT);
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
@@ -2250,9 +2241,9 @@ static void createTransEditVerts(TransInfo *t)
if (totleft > 0)
#endif
{
- mappedcos = crazyspace_get_mapped_editverts(t->scene, t->obedit);
+ mappedcos = BKE_crazyspace_get_mapped_editverts(t->scene, t->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
- crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats);
+ BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !propmode);
if (mappedcos)
MEM_freeN(mappedcos);
}
@@ -2290,9 +2281,6 @@ static void createTransEditVerts(TransInfo *t)
if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
tob->flag |= TD_SELECTED;
- /* active */
- if (eve == eve_act) tob->flag |= TD_ACTIVE;
-
if (propmode) {
if (propmode & T_PROP_CONNECTED) {
tob->dist = dists[a];
@@ -2374,7 +2362,6 @@ cleanup:
void flushTransNodes(TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
- bool hidden_state;
int a;
TransData *td;
TransData2D *td2d;
@@ -2384,26 +2371,24 @@ void flushTransNodes(TransInfo *t)
/* flush to 2d vector from internally used 3d vector */
for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
bNode *node = td->extra;
+ float locx, locy;
/* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
#ifdef USE_NODE_CENTER
- node->locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
- node->locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
+ locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
+ locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
#else
- node->locx = td2d->loc[0] / dpi_fac;
- node->locy = td2d->loc[1] / dpi_fac;
+ locx = td2d->loc[0] / dpi_fac;
+ locy = td2d->loc[1] / dpi_fac;
#endif
- /* update node hidden state with transform data TD_HIDDEN + transformInfo T_TOGGLE_HIDDEN */
- hidden_state = (td->flag & TD_HIDDEN) != 0;
- if (t->state != TRANS_CANCEL) {
- hidden_state ^= (t->flag & T_TOGGLE_HIDDEN) > 0;
- }
-
- if (hidden_state) {
- node->flag |= NODE_HIDDEN;
+
+ /* account for parents (nested nodes) */
+ if (node->parent) {
+ nodeFromView(node->parent, locx, locy, &node->locx, &node->locy);
}
else {
- node->flag &= ~NODE_HIDDEN;
+ node->locx = locx;
+ node->locy = locy;
}
}
@@ -2438,7 +2423,7 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s
void flushTransSeq(TransInfo *t)
{
- ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, FALSE)->seqbasep; /* Editing null check already done */
+ ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep; /* Editing null check already done */
int a, new_frame;
TransData *td = NULL;
TransData2D *td2d = NULL;
@@ -2601,10 +2586,10 @@ static void createTransUVs(bContext *C, TransInfo *t)
BMLoop *l;
BMIter iter, liter;
UvElementMap *elementmap = NULL;
- char *island_enabled = NULL;
+ BLI_bitmap *island_enabled = NULL;
int count = 0, countsel = 0, count_rejected = 0;
- int propmode = t->flag & T_PROP_EDIT;
- int propconnected = t->flag & T_PROP_CONNECTED;
+ const bool propmode = (t->flag & T_PROP_EDIT) != 0;
+ const bool propconnected = (t->flag & T_PROP_CONNECTED) != 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
@@ -2619,7 +2604,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
else {
elementmap = BM_uv_element_map_create(em->bm, true, true);
}
- island_enabled = MEM_callocN(sizeof(*island_enabled) * elementmap->totalIslands, "TransIslandData(UV Editing)");
+ island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -2637,7 +2622,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
if (propconnected) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
- island_enabled[element->island] = TRUE;
+ BLI_BITMAP_SET(island_enabled, element->island);
}
}
@@ -2649,7 +2634,12 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
/* note: in prop mode we need at least 1 selected */
- if (countsel == 0) return;
+ if (countsel == 0) {
+ if (propconnected) {
+ MEM_freeN(island_enabled);
+ }
+ return;
+ }
t->total = (propmode) ? count : countsel;
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(UV Editing)");
@@ -2673,7 +2663,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
if (propconnected) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
- if (!island_enabled[element->island]) {
+ if (!BLI_BITMAP_GET(island_enabled, element->island)) {
count_rejected++;
continue;
}
@@ -3009,6 +2999,40 @@ static void createTransNlaData(bContext *C, TransInfo *t)
/* ********************* ACTION EDITOR ****************** */
+static int gpf_cmp_frame(void *thunk, void *a, void *b)
+{
+ bGPDframe *frame_a = a;
+ bGPDframe *frame_b = b;
+
+ if (frame_a->framenum < frame_b->framenum) return -1;
+ if (frame_a->framenum > frame_b->framenum) return 1;
+ *((bool *)thunk) = true;
+ /* selected last */
+ if ((frame_a->flag & GP_FRAME_SELECT) &&
+ ((frame_b->flag & GP_FRAME_SELECT) == 0))
+ {
+ return 1;
+ }
+ return 0;
+}
+
+static int masklay_shape_cmp_frame(void *thunk, void *a, void *b)
+{
+ MaskLayerShape *frame_a = a;
+ MaskLayerShape *frame_b = b;
+
+ if (frame_a->frame < frame_b->frame) return -1;
+ if (frame_a->frame > frame_b->frame) return 1;
+ *((bool *)thunk) = true;
+ /* selected last */
+ if ((frame_a->flag & MASK_SHAPE_SELECT) &&
+ ((frame_b->flag & MASK_SHAPE_SELECT) == 0))
+ {
+ return 1;
+ }
+ return 0;
+}
+
/* Called by special_aftertrans_update to make sure selected gp-frames replace
* any other gp-frames which may reside on that frame (that are not selected).
* It also makes sure gp-frames are still stored in chronological order after
@@ -3019,175 +3043,52 @@ static void posttrans_gpd_clean(bGPdata *gpd)
bGPDlayer *gpl;
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ListBase sel_buffer = {NULL, NULL};
bGPDframe *gpf, *gpfn;
- bGPDframe *gfs, *gfsn;
-
- /* loop 1: loop through and isolate selected gp-frames to buffer
- * (these need to be sorted as they are isolated)
- */
- for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
- short added = 0;
- gpfn = gpf->next;
-
- if (gpf->flag & GP_FRAME_SELECT) {
- BLI_remlink(&gpl->frames, gpf);
-
- /* find place to add them in buffer
- * - go backwards as most frames will still be in order,
- * so doing it this way will be faster
- */
- for (gfs = sel_buffer.last; gfs; gfs = gfs->prev) {
- /* if current (gpf) occurs after this one in buffer, add! */
- if (gfs->framenum < gpf->framenum) {
- BLI_insertlinkafter(&sel_buffer, gfs, gpf);
- added = 1;
- break;
- }
- }
- if (added == 0)
- BLI_addhead(&sel_buffer, gpf);
- }
- }
-
- /* error checking: it is unlikely, but may be possible to have none selected */
- if (BLI_listbase_is_empty(&sel_buffer))
- continue;
-
- /* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */
- if (BLI_listbase_is_empty(&gpl->frames)) {
- gpl->frames.first = sel_buffer.first;
- gpl->frames.last = sel_buffer.last;
-
- continue;
- }
-
- /* loop 2: remove duplicates of frames in buffers */
- for (gpf = gpl->frames.first; gpf && sel_buffer.first; gpf = gpfn) {
- gpfn = gpf->next;
-
- /* loop through sel_buffer, emptying stuff from front of buffer if ok */
- for (gfs = sel_buffer.first; gfs && gpf; gfs = gfsn) {
- gfsn = gfs->next;
-
- /* if this buffer frame needs to go before current, add it! */
- if (gfs->framenum < gpf->framenum) {
- /* transfer buffer frame to frames list (before current) */
- BLI_remlink(&sel_buffer, gfs);
- BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
- }
- /* if this buffer frame is on same frame, replace current with it and stop */
- else if (gfs->framenum == gpf->framenum) {
- /* transfer buffer frame to frames list (before current) */
- BLI_remlink(&sel_buffer, gfs);
- BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
-
- /* get rid of current frame */
+ bool is_double = false;
+
+ BLI_sortlist_r(&gpl->frames, &is_double, gpf_cmp_frame);
+
+ if (is_double) {
+ for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
+ gpfn = gpf->next;
+ if (gpfn && gpf->framenum == gpfn->framenum) {
gpencil_layer_delframe(gpl, gpf);
}
}
}
-
- /* if anything is still in buffer, append to end */
- for (gfs = sel_buffer.first; gfs; gfs = gfsn) {
- gfsn = gfs->next;
-
- BLI_remlink(&sel_buffer, gfs);
- BLI_addtail(&gpl->frames, gfs);
+
+#ifdef DEBUG
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ BLI_assert(!gpf->next || gpf->framenum < gpf->next->framenum);
}
+#endif
}
}
-
-/* Called by special_aftertrans_update to make sure selected gp-frames replace
- * any other gp-frames which may reside on that frame (that are not selected).
- * It also makes sure sorted are still stored in chronological order after
- * transform.
- */
static void posttrans_mask_clean(Mask *mask)
{
MaskLayer *masklay;
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- ListBase sel_buffer = {NULL, NULL};
- MaskLayerShape *masklay_shape, *masklay_shape_new;
- MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new;
-
- /* loop 1: loop through and isolate selected gp-frames to buffer
- * (these need to be sorted as they are isolated)
- */
- for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_new) {
- short added = 0;
- masklay_shape_new = masklay_shape->next;
-
- if (masklay_shape->flag & MASK_SHAPE_SELECT) {
- BLI_remlink(&masklay->splines_shapes, masklay_shape);
-
- /* find place to add them in buffer
- * - go backwards as most frames will still be in order,
- * so doing it this way will be faster
- */
- for (masklay_shape_sort = sel_buffer.last; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort->prev) {
- /* if current (masklay_shape) occurs after this one in buffer, add! */
- if (masklay_shape_sort->frame < masklay_shape->frame) {
- BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape);
- added = 1;
- break;
- }
- }
- if (added == 0)
- BLI_addhead(&sel_buffer, masklay_shape);
- }
- }
-
- /* error checking: it is unlikely, but may be possible to have none selected */
- if (BLI_listbase_is_empty(&sel_buffer))
- continue;
-
- /* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */
- if (BLI_listbase_is_empty(&masklay->splines_shapes)) {
- masklay->splines_shapes.first = sel_buffer.first;
- masklay->splines_shapes.last = sel_buffer.last;
-
- continue;
- }
-
- /* loop 2: remove duplicates of splines_shapes in buffers */
- for (masklay_shape = masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape = masklay_shape_new) {
- masklay_shape_new = masklay_shape->next;
-
- /* loop through sel_buffer, emptying stuff from front of buffer if ok */
- for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort = masklay_shape_sort_new) {
- masklay_shape_sort_new = masklay_shape_sort->next;
+ MaskLayerShape *masklay_shape, *masklay_shape_next;
+ bool is_double = false;
- /* if this buffer frame needs to go before current, add it! */
- if (masklay_shape_sort->frame < masklay_shape->frame) {
- /* transfer buffer frame to splines_shapes list (before current) */
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
- }
- /* if this buffer frame is on same frame, replace current with it and stop */
- else if (masklay_shape_sort->frame == masklay_shape->frame) {
- /* transfer buffer frame to splines_shapes list (before current) */
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
+ BLI_sortlist_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
- /* get rid of current frame */
+ if (is_double) {
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
+ masklay_shape_next = masklay_shape->next;
+ if (masklay_shape_next && masklay_shape->frame == masklay_shape_next->frame) {
BKE_mask_layer_shape_unlink(masklay, masklay_shape);
}
}
}
- /* if anything is still in buffer, append to end */
- for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort_new) {
- masklay_shape_sort_new = masklay_shape_sort->next;
-
- BLI_remlink(&sel_buffer, masklay_shape_sort);
- BLI_addtail(&masklay->splines_shapes, masklay_shape_sort);
+#ifdef DEBUG
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+ BLI_assert(!masklay_shape->next || masklay_shape->frame < masklay_shape->next->frame);
}
-
- /* NOTE: this is the only difference to grease pencil code above */
- BKE_mask_layer_shape_sort(masklay);
+#endif
}
}
@@ -3274,11 +3175,11 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- posttrans_fcurve_clean(ale->key_data, FALSE); /* only use handles in graph editor */
+ posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
- posttrans_fcurve_clean(ale->key_data, FALSE); /* only use handles in graph editor */
+ posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */
}
/* free temp data */
@@ -3659,7 +3560,7 @@ static void bezt_to_transdata(TransData *td, TransData2D *td2d, AnimData *adt, B
float mtx[3][3], float smtx[3][3])
{
float *loc = bezt->vec[bi];
- float *cent = bezt->vec[1];
+ const float *cent = bezt->vec[1];
/* New location from td gets dumped onto the old-location of td2d, which then
* gets copied to the actual data at td2d->loc2d (bezt->vec[n])
@@ -3859,7 +3760,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
float xscale, yscale;
/* apply scale factors to x and y axes of space-conversion matrices */
- UI_view2d_getscale(v2d, &xscale, &yscale);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
/* mtx is data to global (i.e. view) conversion */
mul_v3_fl(mtx[0], xscale);
@@ -4193,14 +4094,16 @@ void flushTransGraphData(TransInfo *t)
/* handle snapping for time values
* - we should still be in NLA-mapping timespace
* - only apply to keyframes (but never to handles)
+ * - don't do this when cancelling, or else these changes won't go away
*/
- if ((td->flag & TD_NOTIMESNAP) == 0) {
+ if ((t->state != TRANS_CANCEL) && (td->flag & TD_NOTIMESNAP) == 0) {
switch (sipo->autosnap) {
- case SACTSNAP_FRAME: /* snap to nearest frame (or second if drawing seconds) */
- if (sipo->flag & SIPO_DRAWTIME)
- td2d->loc[0] = floor(((double)td2d->loc[0] / secf) + 0.5) * secf;
- else
- td2d->loc[0] = floor((double)td2d->loc[0] + 0.5);
+ case SACTSNAP_FRAME: /* snap to nearest frame */
+ td2d->loc[0] = floor((double)td2d->loc[0] + 0.5);
+ break;
+
+ case SACTSNAP_SECOND: /* snap to nearest second */
+ td2d->loc[0] = floor(((double)td2d->loc[0] / secf) + 0.5) * secf;
break;
case SACTSNAP_MARKER: /* snap to nearest marker */
@@ -4214,6 +4117,31 @@ void flushTransGraphData(TransInfo *t)
td2d->loc2d[0] = BKE_nla_tweakedit_remap(adt, td2d->loc[0], NLATIME_CONVERT_UNMAP);
else
td2d->loc2d[0] = td2d->loc[0];
+
+ /* Time-stepping auto-snapping modes don't get applied for Graph Editor transforms,
+ * as these use the generic transform modes which don't account for this sort of thing.
+ * These ones aren't affected by NLA mapping, so we do this after the conversion...
+ *
+ * NOTE: We also have to apply to td->loc, as that's what the handle-adjustment step below looks
+ * to, otherwise we get "swimming handles"
+ * NOTE: We don't do this when cancelling transforms, or else these changes don't go away
+ */
+ if ((t->state != TRANS_CANCEL) && (td->flag & TD_NOTIMESNAP) == 0 &&
+ ELEM(sipo->autosnap, SACTSNAP_STEP, SACTSNAP_TSTEP))
+ {
+ switch (sipo->autosnap) {
+ case SACTSNAP_STEP: /* frame step */
+ td2d->loc2d[0] = floor((double)td2d->loc[0] + 0.5);
+ td->loc[0] = floor((double)td->loc[0] + 0.5);
+ break;
+
+ case SACTSNAP_TSTEP: /* second step */
+ /* XXX: the handle behaviour in this case is still not quite right... */
+ td2d->loc[0] = floor(((double)td2d->loc[0] / secf) + 0.5) * secf;
+ td->loc[0] = floor(((double)td->loc[0] / secf) + 0.5) * secf;
+ break;
+ }
+ }
/* if int-values only, truncate to integers */
if (td->flag & TD_INTVALUES)
@@ -4252,11 +4180,11 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
Scene *scene = t->scene;
int cfra = CFRA;
- int left = BKE_sequence_tx_get_final_left(seq, 1);
- int right = BKE_sequence_tx_get_final_right(seq, 1);
+ int left = BKE_sequence_tx_get_final_left(seq, true);
+ int right = BKE_sequence_tx_get_final_right(seq, true);
if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
- *recursive = FALSE;
+ *recursive = false;
*count = 0;
*flag = 0;
}
@@ -4264,16 +4192,16 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* for meta's we only ever need to extend their children, no matter what depth
* just check the meta's are in the bounds */
- if (t->frame_side == 'R' && right <= cfra) *recursive = FALSE;
- else if (t->frame_side == 'L' && left >= cfra) *recursive = FALSE;
- else *recursive = TRUE;
+ if (t->frame_side == 'R' && right <= cfra) *recursive = false;
+ else if (t->frame_side == 'L' && left >= cfra) *recursive = false;
+ else *recursive = true;
*count = 1;
*flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
}
else {
- *recursive = FALSE; /* not a meta, so no thinking here */
+ *recursive = false; /* not a meta, so no thinking here */
*count = 1; /* unless its set to 0, extend will never set 2 handles at once */
*flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
@@ -4301,7 +4229,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* Non nested strips (resect selection and handles) */
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
- *recursive = FALSE;
+ *recursive = false;
*count = 0;
*flag = 0;
}
@@ -4319,10 +4247,10 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
/* if any handles are selected, don't recurse */
- *recursive = TRUE;
+ *recursive = true;
}
else {
- *recursive = FALSE;
+ *recursive = false;
}
}
}
@@ -4341,12 +4269,12 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
* BKE_sequence_calc() will update its settings when run on the toplevel meta */
*flag = 0;
*count = 0;
- *recursive = TRUE;
+ *recursive = true;
}
else {
*flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
*count = 1; /* ignore the selection for nested */
- *recursive = FALSE;
+ *recursive = false;
}
#endif
}
@@ -4388,16 +4316,16 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq
/* Use seq_tx_get_final_left() and an offset here
* so transform has the left hand location of the strip.
* tdsq->start_offset is used when flushing the tx data back */
- start_left = BKE_sequence_tx_get_final_left(seq, 0);
+ start_left = BKE_sequence_tx_get_final_left(seq, false);
td2d->loc[0] = start_left;
tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
break;
case SEQ_LEFTSEL:
- start_left = BKE_sequence_tx_get_final_left(seq, 0);
+ start_left = BKE_sequence_tx_get_final_left(seq, false);
td2d->loc[0] = start_left;
break;
case SEQ_RIGHTSEL:
- td2d->loc[0] = BKE_sequence_tx_get_final_right(seq, 0);
+ td2d->loc[0] = BKE_sequence_tx_get_final_right(seq, false);
break;
}
@@ -4484,7 +4412,7 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
static void freeSeqData(TransInfo *t)
{
- Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(t->scene, false);
if (ed != NULL) {
ListBase *seqbasep = ed->seqbasep;
@@ -4659,7 +4587,7 @@ static void createTransSeqData(bContext *C, TransInfo *t)
View2D *v2d = UI_view2d_fromcontext(C);
Scene *scene = t->scene;
- Editing *ed = BKE_sequencer_editing_get(t->scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(t->scene, false);
TransData *td = NULL;
TransData2D *td2d = NULL;
TransDataSeq *tdsq = NULL;
@@ -4817,7 +4745,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
/* update object's loc/rot to get current rigid body transform */
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
- BKE_object_mat3_to_rot(ob, rot, FALSE);
+ BKE_object_mat3_to_rot(ob, rot, false);
}
}
@@ -4913,11 +4841,6 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
unit_m3(td->smtx);
unit_m3(td->mtx);
}
-
- /* set active flag */
- if (ob == OBACT) {
- td->flag |= TD_ACTIVE;
- }
}
@@ -5138,29 +5061,29 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
- do_loc = TRUE;
+ do_loc = true;
}
else if (tmode == TFM_ROTATION) {
if (v3d->around == V3D_ACTIVE) {
if (ob != OBACT)
- do_loc = TRUE;
+ do_loc = true;
}
else if (v3d->around == V3D_CURSOR)
- do_loc = TRUE;
+ do_loc = true;
if ((v3d->flag & V3D_ALIGN) == 0)
- do_rot = TRUE;
+ do_rot = true;
}
else if (tmode == TFM_RESIZE) {
if (v3d->around == V3D_ACTIVE) {
if (ob != OBACT)
- do_loc = TRUE;
+ do_loc = true;
}
else if (v3d->around == V3D_CURSOR)
- do_loc = TRUE;
+ do_loc = true;
if ((v3d->flag & V3D_ALIGN) == 0)
- do_scale = TRUE;
+ do_scale = true;
}
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
@@ -5271,28 +5194,28 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
}
/* only insert keyframe if needed? */
else if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED)) {
- short do_loc = FALSE, do_rot = FALSE, do_scale = FALSE;
+ bool do_loc = false, do_rot = false, do_scale = false;
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
if (targetless_ik)
- do_rot = TRUE;
+ do_rot = true;
else
- do_loc = TRUE;
+ do_loc = true;
}
else if (tmode == TFM_ROTATION) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
- do_loc = TRUE;
+ do_loc = true;
if ((v3d->flag & V3D_ALIGN) == 0)
- do_rot = TRUE;
+ do_rot = true;
}
else if (tmode == TFM_RESIZE) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
- do_loc = TRUE;
+ do_loc = true;
if ((v3d->flag & V3D_ALIGN) == 0)
- do_scale = TRUE;
+ do_scale = true;
}
if (do_loc) {
@@ -5354,7 +5277,11 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
{
bool do_update = false;
- do_update |= (plane_track->flag & SELECT) != 0;
+ if (plane_track->flag & PLANE_TRACK_HIDDEN) {
+ continue;
+ }
+
+ do_update |= PLANE_TRACK_VIEW_SELECTED(plane_track) != 0;
if (do_update == false) {
if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
int i;
@@ -5417,7 +5344,7 @@ static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
static void special_aftertrans_update__node(bContext *UNUSED(C), TransInfo *t)
{
- int canceled = (t->state == TRANS_CANCEL);
+ const bool canceled = (t->state == TRANS_CANCEL);
if (canceled && t->remove_on_cancel) {
/* remove selected nodes on cancel */
@@ -5477,8 +5404,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
{
Object *ob;
// short redrawipo=0, resetslowpar=1;
- int canceled = (t->state == TRANS_CANCEL);
- short duplicate = (t->mode == TFM_TIME_DUPLICATE);
+ const bool canceled = (t->state == TRANS_CANCEL);
+ const bool duplicate = (t->mode == TFM_TIME_DUPLICATE);
/* early out when nothing happened */
if (t->total == 0 || t->mode == TFM_DUMMY)
@@ -5494,7 +5421,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
/* handle multires re-projection, done
* on transform completion since it's
* really slow -joeedh */
- projectEdgeSlideData(t, TRUE);
+ projectEdgeSlideData(t, true);
/* free temporary faces to avoid automerging and deleting
* during cleanup - psy-fi */
@@ -5510,7 +5437,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
EdgeSlideData *sld = t->customData;
sld->perc = 0.0;
- projectEdgeSlideData(t, FALSE);
+ projectEdgeSlideData(t, false);
}
}
}
@@ -5596,11 +5523,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
{
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1);
- posttrans_fcurve_clean(fcu, FALSE); /* only use handles in graph editor */
+ posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */
ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1);
}
else
- posttrans_fcurve_clean(fcu, FALSE); /* only use handles in graph editor */
+ posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */
}
}
@@ -5784,7 +5711,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (t->obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
/* table needs to be created for each edit command, since vertices can move etc */
- mesh_octree_table(t->obedit, em, NULL, 'e');
+ ED_mesh_mirror_spatial_table(t->obedit, em, NULL, 'e');
}
}
else if ((t->flag & T_POSE) && (t->poseobj)) {
@@ -5920,6 +5847,8 @@ int special_transform_moving(TransInfo *t)
static void createTransObject(bContext *C, TransInfo *t)
{
+ Scene *scene = t->scene;
+
TransData *td = NULL;
TransDataExtension *tx;
int propmode = t->flag & T_PROP_EDIT;
@@ -5969,7 +5898,6 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_END;
if (propmode) {
- Scene *scene = t->scene;
View3D *v3d = t->view;
Base *base;
@@ -5996,14 +5924,25 @@ static void createTransObject(bContext *C, TransInfo *t)
/* transcribe given node into TransData2D for Transforming */
static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac)
{
+ float locx, locy;
+
+ /* account for parents (nested nodes) */
+ if (node->parent) {
+ nodeToView(node->parent, node->locx, node->locy, &locx, &locy);
+ }
+ else {
+ locx = node->locx;
+ locy = node->locy;
+ }
+
/* use top-left corner as the transform origin for nodes */
/* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
#ifdef USE_NODE_CENTER
- td2d->loc[0] = (node->locx * dpi_fac) + (BLI_rctf_size_x(&node->totr) * +0.5f);
- td2d->loc[1] = (node->locy * dpi_fac) + (BLI_rctf_size_y(&node->totr) * -0.5f);
+ td2d->loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node->totr) * +0.5f);
+ td2d->loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node->totr) * -0.5f);
#else
- td2d->loc[0] = node->locx * dpi_fac;
- td2d->loc[1] = node->locy * dpi_fac;
+ td2d->loc[0] = locx * dpi_fac;
+ td2d->loc[1] = locy * dpi_fac;
#endif
td2d->loc[2] = 0.0f;
td2d->loc2d = td2d->loc; /* current location */
@@ -6023,9 +5962,6 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const
td->ext = NULL; td->val = NULL;
td->flag |= TD_SELECTED;
- if (node->flag & NODE_HIDDEN) {
- td->flag |= TD_HIDDEN;
- }
td->dist = 0.0;
unit_m3(td->mtx);
@@ -6038,10 +5974,10 @@ static bool is_node_parent_select(bNode *node)
{
while ((node = node->parent)) {
if (node->flag & NODE_TRANSFORM) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
@@ -6060,12 +5996,10 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
/* nodes dont support PET and probably never will */
t->flag &= ~T_PROP_EDIT_ALL;
- /* initial: do not toggle hidden */
- t->flag &= ~T_TOGGLE_HIDDEN;
/* set transform flags on nodes */
for (node = snode->edittree->nodes.first; node; node = node->next) {
- if (node->flag & NODE_SELECT && is_node_parent_select(node) == FALSE) {
+ if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) {
node->flag |= NODE_TRANSFORM;
t->total++;
}
@@ -6099,7 +6033,7 @@ typedef struct TransDataTracking {
/* tracks transformation from main window */
int area;
- float *relative, *loc;
+ const float *relative, *loc;
float soffset[2], srelative[2];
float offset[2];
@@ -6311,7 +6245,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
plane_track;
plane_track = plane_track->next)
{
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
t->total += 4;
}
}
@@ -6364,7 +6298,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
plane_track;
plane_track = plane_track->next)
{
- if (plane_track->flag & SELECT) {
+ if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
planeTrackToTransData(framenr, td, td2d, tdt, plane_track, aspx, aspy);
td += 4;
td2d += 4;
@@ -6657,8 +6591,67 @@ typedef struct TransDataMasking {
MaskSplinePoint *point;
float parent_matrix[3][3];
float parent_inverse_matrix[3][3];
+ char orig_handle_type;
+
+ eMaskWhichHandle which_handle;
} TransDataMasking;
+static void MaskHandleToTransData(MaskSplinePoint *point, eMaskWhichHandle which_handle,
+ TransData *td, TransData2D *td2d, TransDataMasking *tdm,
+ const float asp[2],
+ /*const*/ float parent_matrix[3][3],
+ /*const*/ float parent_inverse_matrix[3][3])
+{
+ BezTriple *bezt = &point->bezt;
+ const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
+
+ tdm->point = point;
+ copy_m3_m3(tdm->vec, bezt->vec);
+
+ tdm->is_handle = true;
+ copy_m3_m3(tdm->parent_matrix, parent_matrix);
+ copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
+
+ BKE_mask_point_handle(point, which_handle, tdm->handle);
+ tdm->which_handle = which_handle;
+
+ copy_v2_v2(tdm->orig_handle, tdm->handle);
+
+ mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
+ td2d->loc[0] *= asp[0];
+ td2d->loc[1] *= asp[1];
+ td2d->loc[2] = 0.0f;
+
+ td2d->loc2d = tdm->handle;
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext = NULL;
+ td->val = NULL;
+
+ if (is_sel_any) {
+ td->flag |= TD_SELECTED;
+ }
+
+ td->dist = 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ tdm->orig_handle_type = bezt->h1;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ tdm->orig_handle_type = bezt->h2;
+ }
+}
+
static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
TransData *td, TransData2D *td2d, TransDataMasking *tdm,
const int propmode, const float asp[2])
@@ -6668,14 +6661,15 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
float parent_matrix[3][3], parent_inverse_matrix[3][3];
- tdm->point = point;
- copy_m3_m3(tdm->vec, bezt->vec);
-
BKE_mask_point_parent_matrix_get(point, CFRA, parent_matrix);
invert_m3_m3(parent_inverse_matrix, parent_matrix);
if (propmode || is_sel_point) {
int i;
+
+ tdm->point = point;
+ copy_m3_m3(tdm->vec, bezt->vec);
+
for (i = 0; i < 3; i++) {
copy_m3_m3(tdm->parent_matrix, parent_matrix);
copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
@@ -6693,7 +6687,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
td->flag = 0;
td->loc = td2d->loc;
- copy_v3_v3(td->center, bezt->vec[1]);
+ mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
copy_v3_v3(td->iloc, td->loc);
memset(td->axismtx, 0, sizeof(td->axismtx));
@@ -6718,49 +6712,64 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
unit_m3(td->mtx);
unit_m3(td->smtx);
+ if (i == 0) {
+ tdm->orig_handle_type = bezt->h1;
+ }
+ else if (i == 2) {
+ tdm->orig_handle_type = bezt->h2;
+ }
+
td++;
td2d++;
tdm++;
}
}
else {
- tdm->is_handle = TRUE;
- copy_m3_m3(tdm->parent_matrix, parent_matrix);
- copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
-
- BKE_mask_point_handle(point, tdm->handle);
-
- copy_v2_v2(tdm->orig_handle, tdm->handle);
-
- mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
- td2d->loc[0] *= asp[0];
- td2d->loc[1] *= asp[1];
- td2d->loc[2] = 0.0f;
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ MaskHandleToTransData(point, MASK_WHICH_HANDLE_STICK,
+ td, td2d, tdm, asp, parent_matrix,
+ parent_inverse_matrix);
- td2d->loc2d = tdm->handle;
+ td++;
+ td2d++;
+ tdm++;
+ }
+ else {
+ if (bezt->f1 & SELECT) {
+ MaskHandleToTransData(point, MASK_WHICH_HANDLE_LEFT,
+ td, td2d, tdm, asp, parent_matrix,
+ parent_inverse_matrix);
- td->flag = 0;
- td->loc = td2d->loc;
- copy_v3_v3(td->center, bezt->vec[1]);
- copy_v3_v3(td->iloc, td->loc);
+ if (bezt->h1 == HD_VECT) {
+ bezt->h1 = HD_FREE;
+ }
+ else if (bezt->h1 == HD_AUTO) {
+ bezt->h1 = HD_ALIGN_DOUBLESIDE;
+ bezt->h2 = HD_ALIGN_DOUBLESIDE;
+ }
- memset(td->axismtx, 0, sizeof(td->axismtx));
- td->axismtx[2][2] = 1.0f;
+ td++;
+ td2d++;
+ tdm++;
+ }
+ if (bezt->f3 & SELECT) {
+ MaskHandleToTransData(point, MASK_WHICH_HANDLE_RIGHT,
+ td, td2d, tdm, asp, parent_matrix,
+ parent_inverse_matrix);
- td->ext = NULL;
- td->val = NULL;
+ if (bezt->h2 == HD_VECT) {
+ bezt->h2 = HD_FREE;
+ }
+ else if (bezt->h2 == HD_AUTO) {
+ bezt->h1 = HD_ALIGN_DOUBLESIDE;
+ bezt->h2 = HD_ALIGN_DOUBLESIDE;
+ }
- if (is_sel_any) {
- td->flag |= TD_SELECTED;
+ td++;
+ td2d++;
+ tdm++;
+ }
}
-
- td->dist = 0.0;
-
- unit_m3(td->mtx);
- unit_m3(td->smtx);
-
- td++;
- td2d++;
}
}
@@ -6781,6 +6790,14 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
if (!mask)
return;
+ if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sc = t->sa->spacedata.first;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ if (!clip) {
+ return;
+ }
+ }
+
/* count */
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
MaskSpline *spline;
@@ -6796,10 +6813,23 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
MaskSplinePoint *point = &spline->points[i];
if (MASKPOINT_ISSEL_ANY(point)) {
- if (MASKPOINT_ISSEL_KNOT(point))
+ if (MASKPOINT_ISSEL_KNOT(point)) {
countsel += 3;
- else
- countsel += 1;
+ }
+ else {
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ countsel += 1;
+ }
+ else {
+ BezTriple *bezt = &point->bezt;
+ if (bezt->f1 & SELECT) {
+ countsel++;
+ }
+ if (bezt->f3 & SELECT) {
+ countsel++;
+ }
+ }
+ }
}
if (propmode)
@@ -6847,9 +6877,24 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
tdm += 3;
}
else {
- td++;
- td2d++;
- tdm++;
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ td++;
+ td2d++;
+ tdm++;
+ }
+ else {
+ BezTriple *bezt = &point->bezt;
+ if (bezt->f1 & SELECT) {
+ td++;
+ td2d++;
+ tdm++;
+ }
+ if (bezt->f3 & SELECT) {
+ td++;
+ td2d++;
+ tdm++;
+ }
+ }
}
}
}
@@ -6875,10 +6920,20 @@ void flushTransMasking(TransInfo *t)
mul_m3_v2(tdm->parent_inverse_matrix, td->loc2d);
if (tdm->is_handle) {
- BKE_mask_point_set_handle(tdm->point, td->loc2d,
+ BKE_mask_point_set_handle(tdm->point, tdm->which_handle,
+ td->loc2d,
(t->flag & T_ALT_TRANSFORM) != 0,
tdm->orig_handle, tdm->vec);
}
+
+ if (t->state == TRANS_CANCEL) {
+ if (tdm->which_handle == MASK_WHICH_HANDLE_LEFT) {
+ tdm->point->bezt.h1 = tdm->orig_handle_type;
+ }
+ else if (tdm->which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ tdm->point->bezt.h2 = tdm->orig_handle_type;
+ }
+ }
}
}
@@ -6910,7 +6965,7 @@ void createTransData(bContext *C, TransInfo *t)
if (t->data && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
- set_prop_dist(t, TRUE);
+ set_prop_dist(t, true);
sort_trans_data_dist(t);
}
}
@@ -6966,7 +7021,7 @@ void createTransData(bContext *C, TransInfo *t)
if (t->data && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
- set_prop_dist(t, TRUE);
+ set_prop_dist(t, true);
sort_trans_data_dist(t);
}
}
@@ -7062,11 +7117,15 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
+ /* Check if we're transforming the camera from the camera */
if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
View3D *v3d = t->view;
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp == RV3D_CAMOB) {
- t->flag |= T_CAMERA;
+ RegionView3D *rv3d = t->ar->regiondata;
+ if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
+ /* we could have a flag to easily check an object is being transformed */
+ if (v3d->camera->recalc) {
+ t->flag |= T_CAMERA;
+ }
}
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 99e39031fcd..776877f0350 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -45,11 +45,11 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_view3d_types.h"
#include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
+#include "DNA_meta_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -67,10 +67,8 @@
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_fcurve.h"
#include "BKE_lattice.h"
-#include "BKE_mesh.h"
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_sequencer.h"
@@ -401,7 +399,7 @@ static void recalcData_graphedit(TransInfo *t)
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
- /* ignore unselected fcurves */
+ /* ignore FC-Curves without any selected verts */
if (!fcu_test_selected(fcu))
continue;
@@ -526,23 +524,46 @@ static void recalcData_nla(TransInfo *t)
break;
}
- /* handle auto-snapping */
- switch (snla->autosnap) {
- case SACTSNAP_FRAME: /* snap to nearest frame/time */
- if (snla->flag & SNLA_DRAWTIME) {
- tdn->h1[0] = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
- tdn->h2[0] = (float)(floor(((double)tdn->h2[0] / secf) + 0.5) * secf);
- }
- else {
+ /* handle auto-snapping
+ * NOTE: only do this when transform is still running, or we can't restore
+ */
+ if (t->state != TRANS_CANCEL) {
+ switch (snla->autosnap) {
+ case SACTSNAP_FRAME: /* snap to nearest frame */
+ case SACTSNAP_STEP: /* frame step - this is basically the same, since we don't have any remapping going on */
+ {
tdn->h1[0] = floorf(tdn->h1[0] + 0.5f);
tdn->h2[0] = floorf(tdn->h2[0] + 0.5f);
+ break;
}
- break;
-
- case SACTSNAP_MARKER: /* snap to nearest marker */
- tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
- tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
- break;
+
+ case SACTSNAP_SECOND: /* snap to nearest second */
+ case SACTSNAP_TSTEP: /* second step - this is basically the same, since we don't have any remapping going on */
+ {
+ /* This case behaves differently from the rest, since lengths of strips
+ * may not be multiples of a second. If we just naively resize adjust
+ * the handles, things may not work correctly. Instead, we only snap
+ * the first handle, and move the other to fit.
+ *
+ * FIXME: we do run into problems here when user attempts to negatively
+ * scale the strip, as it then just compresses down and refuses
+ * to expand out the other end.
+ */
+ float h1_new = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
+ float delta = h1_new - tdn->h1[0];
+
+ tdn->h1[0] = h1_new;
+ tdn->h2[0] += delta;
+ break;
+ }
+
+ case SACTSNAP_MARKER: /* snap to nearest marker */
+ {
+ tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
+ tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
+ break;
+ }
+ }
}
/* Use RNA to write the values to ensure that constraints on these are obeyed
@@ -809,17 +830,12 @@ static void recalcData_objects(TransInfo *t)
}
else {
copy_v3_v3(up_axis, td->axismtx[2]);
-
- if (t->mode != TFM_ROTATION) {
- sub_v3_v3v3(vec, ebo->tail, ebo->head);
- normalize_v3(vec);
- rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
- mul_qt_v3(qrot, up_axis);
- }
- else {
- mul_m3_v3(t->mat, up_axis);
- }
-
+
+ sub_v3_v3v3(vec, ebo->tail, ebo->head);
+ normalize_v3(vec);
+ rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
+ mul_qt_v3(qrot, up_axis);
+
/* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
roll = ED_rollBoneToVector(ebo, up_axis, false);
ebo->roll = angle_compat_rad(roll, td->ival);
@@ -1462,31 +1478,29 @@ void calculateCenter2D(TransInfo *t)
}
}
-void calculateCenterCursor(TransInfo *t)
+void calculateCenterCursor(TransInfo *t, float r_center[3])
{
const float *cursor;
cursor = ED_view3d_cursor3d_get(t->scene, t->view);
- copy_v3_v3(t->center, cursor);
+ copy_v3_v3(r_center, cursor);
/* If edit or pose mode, move cursor in local space */
if (t->flag & (T_EDIT | T_POSE)) {
Object *ob = t->obedit ? t->obedit : t->poseobj;
float mat[3][3], imat[3][3];
- sub_v3_v3v3(t->center, t->center, ob->obmat[3]);
+ sub_v3_v3v3(r_center, r_center, ob->obmat[3]);
copy_m3_m4(mat, ob->obmat);
invert_m3_m3(imat, mat);
- mul_m3_v3(imat, t->center);
+ mul_m3_v3(imat, r_center);
}
-
- calculateCenter2D(t);
}
-void calculateCenterCursor2D(TransInfo *t)
+void calculateCenterCursor2D(TransInfo *t, float r_center[2])
{
float aspx = 1.0, aspy = 1.0;
- float *cursor = NULL;
+ const float *cursor = NULL;
if (t->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
@@ -1530,31 +1544,27 @@ void calculateCenterCursor2D(TransInfo *t)
BLI_assert(!"Shall not happen");
}
- t->center[0] = co[0] * aspx;
- t->center[1] = co[1] * aspy;
+ r_center[0] = co[0] * aspx;
+ r_center[1] = co[1] * aspy;
}
else {
- t->center[0] = cursor[0] * aspx;
- t->center[1] = cursor[1] * aspy;
+ r_center[0] = cursor[0] * aspx;
+ r_center[1] = cursor[1] * aspy;
}
}
-
- calculateCenter2D(t);
}
-static void calculateCenterCursorGraph2D(TransInfo *t)
+void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2])
{
SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first;
Scene *scene = t->scene;
/* cursor is combination of current frame, and graph-editor cursor value */
- t->center[0] = (float)(scene->r.cfra);
- t->center[1] = sipo->cursorVal;
-
- calculateCenter2D(t);
+ r_center[0] = (float)(scene->r.cfra);
+ r_center[1] = sipo->cursorVal;
}
-void calculateCenterMedian(TransInfo *t)
+void calculateCenterMedian(TransInfo *t, float r_center[3])
{
float partial[3] = {0.0f, 0.0f, 0.0f};
int total = 0;
@@ -1570,12 +1580,10 @@ void calculateCenterMedian(TransInfo *t)
}
if (i)
mul_v3_fl(partial, 1.0f / total);
- copy_v3_v3(t->center, partial);
-
- calculateCenter2D(t);
+ copy_v3_v3(r_center, partial);
}
-void calculateCenterBound(TransInfo *t)
+void calculateCenterBound(TransInfo *t, float r_center[3])
{
float max[3];
float min[3];
@@ -1592,83 +1600,137 @@ void calculateCenterBound(TransInfo *t)
copy_v3_v3(min, t->data[i].center);
}
}
- mid_v3_v3v3(t->center, min, max);
+ mid_v3_v3v3(r_center, min, max);
+}
- calculateCenter2D(t);
+/**
+ * \param select_only only get active center from data being transformed.
+ */
+bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
+{
+ bool ok = false;
+
+ if (t->obedit) {
+ switch (t->obedit->type) {
+ case OB_MESH:
+ {
+ BMEditSelection ese;
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+
+ if (BM_select_history_active_get(em->bm, &ese)) {
+ BM_editselection_center(&ese, r_center);
+ ok = true;
+ }
+ break;
+ }
+ case OB_ARMATURE:
+ {
+ bArmature *arm = t->obedit->data;
+ EditBone *ebo = arm->act_edbone;
+
+ if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) {
+ copy_v3_v3(r_center, ebo->head);
+ ok = true;
+ }
+
+ break;
+ }
+ case OB_CURVE:
+ case OB_SURF:
+ {
+ float center[3];
+ Curve *cu = (Curve *)t->obedit->data;
+
+ if (ED_curve_active_center(cu, center)) {
+ copy_v3_v3(r_center, center);
+ ok = true;
+ }
+ break;
+ }
+ case OB_MBALL:
+ {
+ MetaBall *mb = (MetaBall *)t->obedit->data;
+ MetaElem *ml_act = mb->lastelem;
+
+ if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
+ copy_v3_v3(r_center, &ml_act->x);
+ ok = true;
+ }
+ break;
+ }
+ case OB_LATTICE:
+ {
+ BPoint *actbp = BKE_lattice_active_point_get(t->obedit->data);
+
+ if (actbp) {
+ copy_v3_v3(r_center, actbp->vec);
+ ok = true;
+ }
+ break;
+ }
+ }
+ }
+ else if (t->flag & T_POSE) {
+ Scene *scene = t->scene;
+ Object *ob = OBACT;
+ if (ob) {
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+ if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
+ copy_v3_v3(r_center, pchan->pose_head);
+ ok = true;
+ }
+ }
+ }
+ else {
+ /* object mode */
+ Scene *scene = t->scene;
+ Object *ob = OBACT;
+ if (ob && (!select_only || (ob->flag & SELECT))) {
+ copy_v3_v3(r_center, ob->obmat[3]);
+ ok = true;
+ }
+ }
+
+ return ok;
}
+
void calculateCenter(TransInfo *t)
{
switch (t->around) {
case V3D_CENTER:
- calculateCenterBound(t);
+ calculateCenterBound(t, t->center);
break;
case V3D_CENTROID:
- calculateCenterMedian(t);
+ calculateCenterMedian(t, t->center);
break;
case V3D_CURSOR:
if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP))
- calculateCenterCursor2D(t);
+ calculateCenterCursor2D(t, t->center);
else if (t->spacetype == SPACE_IPO)
- calculateCenterCursorGraph2D(t);
+ calculateCenterCursorGraph2D(t, t->center);
else
- calculateCenterCursor(t);
+ calculateCenterCursor(t, t->center);
break;
case V3D_LOCAL:
/* Individual element center uses median center for helpline and such */
- calculateCenterMedian(t);
+ calculateCenterMedian(t, t->center);
break;
case V3D_ACTIVE:
{
- /* set median, and if if if... do object center */
-
- /* EDIT MODE ACTIVE EDITMODE ELEMENT */
-
- if (t->obedit) {
- if (t->obedit && t->obedit->type == OB_MESH) {
- BMEditSelection ese;
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
-
- if (BM_select_history_active_get(em->bm, &ese)) {
- BM_editselection_center(&ese, t->center);
- calculateCenter2D(t);
- break;
- }
- }
- else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
- float center[3];
- Curve *cu = (Curve *)t->obedit->data;
-
- if (ED_curve_active_center(cu, center)) {
- copy_v3_v3(t->center, center);
- calculateCenter2D(t);
- break;
- }
- }
- else if (t->obedit && t->obedit->type == OB_LATTICE) {
- BPoint *actbp = BKE_lattice_active_point_get(t->obedit->data);
-
- if (actbp) {
- copy_v3_v3(t->center, actbp->vec);
- calculateCenter2D(t);
- break;
- }
- }
- } /* END EDIT MODE ACTIVE ELEMENT */
-
- calculateCenterMedian(t);
- if ((t->flag & (T_EDIT | T_POSE)) == 0) {
- Scene *scene = t->scene;
- Object *ob = OBACT;
- if (ob) {
- copy_v3_v3(t->center, ob->obmat[3]);
- projectFloatView(t, t->center, t->center2d);
- }
+ if (calculateCenterActive(t, false, t->center)) {
+ /* pass */
+ }
+ else {
+ /* fallback */
+ calculateCenterMedian(t, t->center);
}
break;
}
}
-
+
+ calculateCenter2D(t);
+
/* setting constraint center */
copy_v3_v3(t->con.center, t->center);
if (t->flag & (T_EDIT | T_POSE)) {
@@ -1679,11 +1741,8 @@ void calculateCenter(TransInfo *t)
/* for panning from cameraview */
if (t->flag & T_OBJECT) {
if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
- View3D *v3d = t->view;
- Scene *scene = t->scene;
- RegionView3D *rv3d = t->ar->regiondata;
- if (v3d->camera == OBACT && rv3d->persp == RV3D_CAMOB) {
+ if (t->flag & T_CAMERA) {
float axis[3];
/* persinv is nasty, use viewinv instead, always right */
copy_v3_v3(axis, t->viewinv[2]);
@@ -1785,7 +1844,7 @@ void calculatePropRatio(TransInfo *t)
td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist;
break;
case PROP_ROOT:
- td->factor = (float)sqrt(dist);
+ td->factor = sqrtf(dist);
break;
case PROP_LIN:
td->factor = dist;
@@ -1794,7 +1853,7 @@ void calculatePropRatio(TransInfo *t)
td->factor = 1.0f;
break;
case PROP_SPHERE:
- td->factor = (float)sqrt(2 * dist - dist * dist);
+ td->factor = sqrtf(2 * dist - dist * dist);
break;
case PROP_RANDOM:
td->factor = BLI_frand() * dist;
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 39c7b4b5c1c..70b565859f3 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -68,7 +68,7 @@ static void InputSpring(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
dx = (float)(mi->center[0] - mval[0]);
dy = (float)(mi->center[1] - mval[1]);
- precise_ratio = (float)sqrt(dx * dx + dy * dy);
+ precise_ratio = sqrtf(dx * dx + dy * dy);
ratio = (ratio + (precise_ratio - ratio) / 10.0f) / mi->factor;
}
@@ -183,7 +183,7 @@ static void InputCustomRatioFlip(TransInfo *UNUSED(t), MouseInput *mi, const int
double length;
double distance;
double dx, dy;
- int *data = mi->data;
+ const int *data = mi->data;
if (data) {
dx = data[2] - data[0];
@@ -232,7 +232,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
double *angle = mi->data;
- /* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
+ /* use doubles here, to make sure a "1.0" (no rotation) doesn't become 9.999999e-01, which gives 0.02 for acos */
double deler = (((dx1 * dx1 + dy1 * dy1) +
(dx2 * dx2 + dy2 * dy2) -
(dx3 * dx3 + dy3 * dy3)) / (2.0 * ((A * B) ? (A * B) : 1.0)));
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 13ac0915766..fb4d8c2cf80 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -35,18 +35,9 @@
#include <math.h>
#include <float.h>
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-#include "MEM_guardedalloc.h"
-
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
@@ -61,7 +52,6 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_global.h"
-#include "BKE_mesh.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_editmesh.h"
@@ -79,7 +69,6 @@
#include "ED_armature.h"
#include "ED_curve.h"
-#include "ED_mesh.h"
#include "ED_particle.h"
#include "ED_view3d.h"
@@ -113,6 +102,10 @@
#define MAN_GHOST 1
#define MAN_MOVECOL 2
+/* threshold for testing view aligned manipulator axis */
+#define TW_AXIS_DOT_MIN 0.02f
+#define TW_AXIS_DOT_MAX 0.1f
+
/* transform widget center calc helper for below */
static void calc_tw_center(Scene *scene, const float co[3])
{
@@ -203,7 +196,7 @@ static int test_rotmode_euler(short rotmode)
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
-int gimbal_axis(Object *ob, float gmat[3][3])
+bool gimbal_axis(Object *ob, float gmat[3][3])
{
if (ob) {
if (ob->mode & OB_MODE_POSE) {
@@ -373,7 +366,7 @@ int calc_manipulator_stats(const bContext *C)
totsel++;
}
if ((ebo->flag & BONE_ROOTSEL) ||
- ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */
+ ((ebo->flag & BONE_TIPSEL) == false)) /* ensure we get at least one point */
{
calc_tw_center(scene, ebo->head);
totsel++;
@@ -462,16 +455,19 @@ int calc_manipulator_stats(const bContext *C)
}
else if (obedit->type == OB_MBALL) {
MetaBall *mb = (MetaBall *)obedit->data;
- MetaElem *ml /* , *ml_sel = NULL */ /* UNUSED */;
+ MetaElem *ml;
- ml = mb->editelems->first;
- while (ml) {
- if (ml->flag & SELECT) {
- calc_tw_center(scene, &ml->x);
- /* ml_sel = ml; */ /* UNUSED */
- totsel++;
+ if ((v3d->around == V3D_ACTIVE) && (ml = mb->lastelem)) {
+ calc_tw_center(scene, &ml->x);
+ totsel++;
+ }
+ else {
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ if (ml->flag & SELECT) {
+ calc_tw_center(scene, &ml->x);
+ totsel++;
+ }
}
- ml = ml->next;
}
}
else if (obedit->type == OB_LATTICE) {
@@ -506,7 +502,7 @@ int calc_manipulator_stats(const bContext *C)
else if (ob && (ob->mode & OB_MODE_POSE)) {
bPoseChannel *pchan;
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
- int ok = FALSE;
+ bool ok = false;
if ((ob->lay & v3d->lay) == 0) return 0;
@@ -516,7 +512,7 @@ int calc_manipulator_stats(const bContext *C)
if (bone) {
stats_pose(scene, rv3d, pchan);
totsel = 1;
- ok = TRUE;
+ ok = true;
}
}
else {
@@ -530,7 +526,7 @@ int calc_manipulator_stats(const bContext *C)
stats_pose(scene, rv3d, pchan);
}
}
- ok = TRUE;
+ ok = true;
}
}
@@ -663,36 +659,23 @@ int calc_manipulator_stats(const bContext *C)
static void test_manipulator_axis(const bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- float angle;
- float vec[3];
+ float view_vec[3], axis_vec[3];
+ float idot;
+ int i;
- ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], vec);
+ const int twdrawflag_axis[3] = {
+ (MAN_TRANS_X | MAN_SCALE_X),
+ (MAN_TRANS_Y | MAN_SCALE_Y),
+ (MAN_TRANS_Z | MAN_SCALE_Z)};
- angle = fabsf(angle_v3v3(rv3d->twmat[0], vec));
- if (angle > (float)M_PI / 2.0f) {
- angle = (float)M_PI - angle;
- }
- angle = rv3d->twangle[0] = RAD2DEGF(angle);
- if (angle < 5.0f) {
- rv3d->twdrawflag &= ~(MAN_TRANS_X | MAN_SCALE_X);
- }
+ ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
- angle = fabsf(angle_v3v3(rv3d->twmat[1], vec));
- if (angle > (float)M_PI / 2.0f) {
- angle = (float)M_PI - angle;
- }
- angle = rv3d->twangle[1] = RAD2DEGF(angle);
- if (angle < 5.0f) {
- rv3d->twdrawflag &= ~(MAN_TRANS_Y | MAN_SCALE_Y);
- }
-
- angle = fabsf(angle_v3v3(rv3d->twmat[2], vec));
- if (angle > (float)M_PI / 2.0f) {
- angle = (float)M_PI - angle;
- }
- angle = rv3d->twangle[2] = RAD2DEGF(angle);
- if (angle < 5.0f) {
- rv3d->twdrawflag &= ~(MAN_TRANS_Z | MAN_SCALE_Z);
+ for (i = 0; i < 3; i++) {
+ normalize_v3_v3(axis_vec, rv3d->twmat[i]);
+ rv3d->tw_idot[i] = idot = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
+ if (idot < TW_AXIS_DOT_MIN) {
+ rv3d->twdrawflag &= ~twdrawflag_axis[i];
+ }
}
}
@@ -723,9 +706,9 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
float cos_theta, sin_theta;
float cos_theta1, sin_theta1;
float ring_delta, side_delta;
- int i, j, do_caps = TRUE;
+ int i, j, do_caps = true;
- if (start == 0 && end == nrings) do_caps = FALSE;
+ if (start == 0 && end == nrings) do_caps = false;
ring_delta = 2.0f * (float)M_PI / (float)nrings;
side_delta = 2.0f * (float)M_PI / (float)nsides;
@@ -794,15 +777,17 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
}
}
-static char axisBlendAngle(float angle)
+static char axisBlendAngle(float idot)
{
- if (angle > 20)
+ if (idot > TW_AXIS_DOT_MAX) {
return 255;
-
- if (angle < 5)
+ }
+ else if (idot < TW_AXIS_DOT_MIN) {
return 0;
-
- return (char)(255.0f * (angle - 5) / 15.0f);
+ }
+ else {
+ return (char)(255.0f * (idot - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
+ }
}
/* three colors can be set:
@@ -879,21 +864,20 @@ static void manipulator_axis_order(RegionView3D *rv3d, int r_axis_order[3])
/* viewmatrix should have been set OK, also no shademode! */
static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int colcode,
- int flagx, int flagy, int flagz, int axis)
+ int flagx, int flagy, int flagz, int axis,
+ const bool is_picksel)
{
/* axes */
switch (axis) {
case 0:
if (flagx) {
- if (flagx & MAN_SCALE_X) {
- GPU_select_load(MAN_SCALE_X);
+ if (is_picksel) {
+ if (flagx & MAN_SCALE_X) GPU_select_load(MAN_SCALE_X);
+ else if (flagx & MAN_TRANS_X) GPU_select_load(MAN_TRANS_X);
}
- else if (flagx & MAN_TRANS_X) {
- GPU_select_load(MAN_TRANS_X);
+ else {
+ set_manipulator_color(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
}
-
- set_manipulator_color(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0]));
-
gpuBegin(GL_LINES);
gpuVertex3f(0.2f, 0.0f, 0.0f);
gpuVertex3f(1.0f, 0.0f, 0.0f);
@@ -901,36 +885,29 @@ static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int co
}
break;
case 1:
-
if (flagy) {
- if (flagy & MAN_SCALE_Y) {
- GPU_select_load(MAN_SCALE_Y);
+ if (is_picksel) {
+ if (flagy & MAN_SCALE_Y) GPU_select_load(MAN_SCALE_Y);
+ else if (flagy & MAN_TRANS_Y) GPU_select_load(MAN_TRANS_Y);
}
- else if (flagy & MAN_TRANS_Y) {
- GPU_select_load(MAN_TRANS_Y);
+ else {
+ set_manipulator_color(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
}
-
- set_manipulator_color(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1]));
-
gpuBegin(GL_LINES);
gpuVertex3f(0.0f, 0.2f, 0.0f);
gpuVertex3f(0.0f, 1.0f, 0.0f);
gpuEnd();
}
break;
-
-
case 2:
if (flagz) {
- if (flagz & MAN_SCALE_Z) {
- GPU_select_load(MAN_SCALE_Z);
+ if (is_picksel) {
+ if (flagz & MAN_SCALE_Z) GPU_select_load(MAN_SCALE_Z);
+ else if (flagz & MAN_TRANS_Z) GPU_select_load(MAN_TRANS_Z);
}
- else if (flagz & MAN_TRANS_Z) {
- GPU_select_load(MAN_TRANS_Z);
+ else {
+ set_manipulator_color(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
}
-
- set_manipulator_color(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2]));
-
gpuBegin(GL_LINES);
gpuVertex3f(0.0f, 0.0f, 0.2f);
gpuVertex3f(0.0f, 0.0f, 1.0f);
@@ -939,14 +916,13 @@ static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int co
break;
}
}
-
static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
int flagx, int flagy, int flagz,
- const int axis_order[3])
+ const int axis_order[3], const bool is_picksel)
{
int i;
for (i = 0; i < 3; i++) {
- draw_manipulator_axes_single(v3d, rv3d, colcode, flagx, flagy, flagz, axis_order[i]);
+ draw_manipulator_axes_single(v3d, rv3d, colcode, flagx, flagy, flagz, axis_order[i], is_picksel);
}
}
@@ -1012,21 +988,16 @@ static void draw_manipulator_rotate(
/* Screen aligned trackball rot circle */
if (drawflags & MAN_ROT_T) {
- if (is_picksel) {
- GPU_select_load(MAN_ROT_T);
- }
+ if (is_picksel) GPU_select_load(MAN_ROT_T);
+ else UI_ThemeColor(TH_TRANSFORM);
- UI_ThemeColor(TH_TRANSFORM);
gpuDrawFastCircleXY(0.2f*size);
}
/* Screen aligned view rot circle */
if (drawflags & MAN_ROT_V) {
- if (is_picksel) {
- GPU_select_load(MAN_ROT_V);
- }
-
- UI_ThemeColor(TH_TRANSFORM);
+ if (is_picksel) GPU_select_load(MAN_ROT_V);
+ else UI_ThemeColor(TH_TRANSFORM);
gpuDrawFastCircleXY(1.2f*size);
if (is_moving) {
@@ -1161,12 +1132,9 @@ static void draw_manipulator_rotate(
if (drawflags & MAN_ROT_Z) {
preOrthoFront(ortho, matt, 2);
- if (is_picksel) {
- GPU_select_load(MAN_ROT_Z);
- }
-
- set_manipulator_color(v3d, 'Z', colcode, 255);
- gpuDrawFastCircleXY(1);
+ if (is_picksel) GPU_select_load(MAN_ROT_Z);
+ else set_manipulator_color(v3d, 'Z', colcode, 255);
+
postOrtho(ortho);
}
@@ -1174,9 +1142,8 @@ static void draw_manipulator_rotate(
if (drawflags & MAN_ROT_X) {
preOrthoFront(ortho, matt, 0);
- if (is_picksel) {
- GPU_select_load(MAN_ROT_X);
- }
+ if (is_picksel) GPU_select_load(MAN_ROT_X);
+ else manipulator_setcolor(v3d, 'X', colcode, 255);
gpuPushMatrix();
gpuRotateRight('Y');
@@ -1189,10 +1156,9 @@ static void draw_manipulator_rotate(
/* Y circle */
if (drawflags & MAN_ROT_Y) {
preOrthoFront(ortho, matt, 1);
-
- if (is_picksel) {
- GPU_select_load(MAN_ROT_Y);
- }
+
+ if (is_picksel) GPU_select_load(MAN_ROT_Y);
+ else manipulator_setcolor(v3d, 'Y', colcode, 255);
gpuPushMatrix();
gpuRotateRight(-'X');
@@ -1210,30 +1176,27 @@ static void draw_manipulator_rotate(
/* Z handle on X axis */
if (drawflags & MAN_ROT_Z) {
preOrthoFront(ortho, rv3d->twmat, 2);
+ gpuPushMatrix();
+ if (is_picksel) GPU_select_load(MAN_ROT_Z);
+ else set_manipulator_color(v3d, 'Z', colcode, 255);
- if (is_picksel) {
- GPU_select_load(MAN_ROT_Z);
- }
-
- set_manipulator_color(v3d, 'Z', colcode, 255);
partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
+ gpuPopMatrix();
postOrtho(ortho);
}
/* Y handle on X axis */
if (drawflags & MAN_ROT_Y) {
preOrthoFront(ortho, rv3d->twmat, 1);
-
- if (is_picksel) {
- GPU_select_load(MAN_ROT_Y);
- }
+ gpuPushMatrix();
+ if (is_picksel) GPU_select_load(MAN_ROT_Y);
+ else set_manipulator_color(v3d, 'Y', colcode, 255);
gpuPushMatrix();
gpuRotateRight('X');
gpuRotateRight('Z');
- set_manipulator_color(v3d, 'Y', colcode, 255);
partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
gpuPopMatrix();
@@ -1243,16 +1206,15 @@ static void draw_manipulator_rotate(
/* X handle on Z axis */
if (drawflags & MAN_ROT_X) {
preOrthoFront(ortho, rv3d->twmat, 0);
-
- if (is_picksel) {
- GPU_select_load(MAN_ROT_X);
- }
+ glPushMatrix();
+
+ if (is_picksel) GPU_select_load(MAN_ROT_X);
+ else set_manipulator_color(v3d, 'X', colcode, 255);
gpuPushMatrix();
gpuRotateRight(-'Y');
gpuRotateRight('Z');
- set_manipulator_color(v3d, 'X', colcode, 255);
partial_doughnut(0.7f * cusize, 1.0f, 31, 33, 8, 64);
gpuPopMatrix();
@@ -1270,7 +1232,7 @@ static void draw_manipulator_rotate(
static void drawsolidcube(float size)
{
- static float cube[8][3] = {
+ const float cube[8][3] = {
{-1.0, -1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, 1.0, 1.0},
@@ -1353,8 +1315,8 @@ static void draw_manipulator_scale(
/* center circle, do not add to selection when shift is pressed (planar constraint) */
if (is_picksel && shift == 0) GPU_select_load(MAN_SCALE_C);
+ else set_manipulator_color(v3d, 'C', colcode, 255);
- set_manipulator_color(v3d, 'C', colcode, 255);
gpuPushMatrix();
size = screen_aligned(rv3d, rv3d->twmat);
unit_m4(unitmat);
@@ -1385,7 +1347,7 @@ static void draw_manipulator_scale(
/* in combo mode, this is always drawn as first type */
draw_manipulator_axes(v3d, rv3d, colcode,
drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z,
- axis_order);
+ axis_order, is_picksel);
for (i = 0; i < 3; i++) {
@@ -1394,7 +1356,7 @@ static void draw_manipulator_scale(
if (drawflags & MAN_SCALE_X) {
gpuTranslate(dz, 0.0, 0.0);
if (is_picksel) GPU_select_load(MAN_SCALE_X);
- set_manipulator_color(v3d, 'X', colcode, axisBlendAngle(rv3d->twangle[0]));
+ else set_manipulator_color(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
drawsolidcube(cusize);
gpuTranslate(-dz, 0.0, 0.0);
}
@@ -1404,7 +1366,7 @@ static void draw_manipulator_scale(
if (drawflags & MAN_SCALE_Y) {
gpuTranslate(0.0, dz, 0.0);
if (is_picksel) GPU_select_load(MAN_SCALE_Y);
- set_manipulator_color(v3d, 'Y', colcode, axisBlendAngle(rv3d->twangle[1]));
+ else set_manipulator_color(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
drawsolidcube(cusize);
gpuTranslate(0.0, -dz, 0.0);
}
@@ -1414,7 +1376,7 @@ static void draw_manipulator_scale(
if (drawflags & MAN_SCALE_Z) {
gpuTranslate(0.0, 0.0, dz);
if (is_picksel) GPU_select_load(MAN_SCALE_Z);
- set_manipulator_color(v3d, 'Z', colcode, axisBlendAngle(rv3d->twangle[2]));
+ else set_manipulator_color(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
drawsolidcube(cusize);
gpuTranslate(0.0, 0.0, -dz);
}
@@ -1465,10 +1427,9 @@ static void draw_manipulator_translate(
/* center circle, do not add to selection when shift is pressed (planar constraint) */
if (is_picksel && shift==0) {
- GPU_select_load(MAN_TRANS_C);
+ else set_manipulator_color(v3d, 'C', colcode, 255);
}
- set_manipulator_color(v3d, 'C', colcode, 255);
gpuPushMatrix();
size = screen_aligned(rv3d, rv3d->twmat);
@@ -1485,7 +1446,7 @@ static void draw_manipulator_translate(
if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) {
draw_manipulator_axes(v3d, rv3d, colcode,
drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z,
- axis_order);
+ axis_order, is_picksel);
}
/* offset in combo mode, for rotate a bit more */
@@ -1642,7 +1603,8 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
short hits;
const bool is_picksel = true;
- extern void setwinmatrixview3d(ARegion *, View3D *, rctf *); // XXX check a bit later on this... (ton)
+ /* XXX check a bit later on this... (ton) */
+ extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, rctf *rect);
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
@@ -1654,7 +1616,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
rect.ymin = mval[1] - hotspot;
rect.ymax = mval[1] + hotspot;
- setwinmatrixview3d(ar, v3d, &rect);
+ view3d_winmatrix_set(ar, v3d, &rect);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
GPU_aspect_end(); /* have to end current aspect before initializing selection mode */
@@ -1683,7 +1645,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
GPU_aspect_begin(GPU_ASPECT_BASIC, NULL); /* restarting in render mode (assuming was basic aspect before) */
- setwinmatrixview3d(ar, v3d, NULL);
+ view3d_winmatrix_set(ar, v3d, NULL);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
if (hits == 1) return buffer[3];
@@ -1786,7 +1748,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_translate", 0), event, op->ptr, NULL, FALSE);
+ //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_translate", 0), event, op->ptr, NULL, false);
}
else if (drawflags & MAN_SCALE_C) {
switch (drawflags) {
@@ -1817,7 +1779,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, FALSE);
+ //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, false);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
/* Do not pass op->ptr!!! trackball has no "constraint" properties!
@@ -1828,7 +1790,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
WM_operator_properties_create_ptr(&props_ptr, ot);
RNA_boolean_set(&props_ptr, "release_confirm", RNA_boolean_get(op->ptr, "release_confirm"));
WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, &props_ptr);
- //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, FALSE);
+ //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, false);
WM_operator_properties_free(&props_ptr);
}
else if (drawflags & MAN_ROT_C) {
@@ -1845,7 +1807,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_rotate", 0), event, op->ptr, NULL, FALSE);
+ //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_rotate", 0), event, op->ptr, NULL, false);
}
}
/* after transform, restore drawflags */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index f20fda27d37..f27ea4793fe 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -36,7 +36,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_armature.h"
#include "BKE_report.h"
#include "RNA_access.h"
@@ -50,12 +49,11 @@
#include "UI_resources.h"
#include "ED_screen.h"
-#include "ED_mesh.h"
#include "transform.h"
typedef struct TransformModeItem {
- char *idname;
+ const char *idname;
int mode;
void (*opfunc)(wmOperatorType *);
} TransformModeItem;
@@ -206,7 +204,7 @@ static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
BIF_removeTransformOrientationIndex(C, selected_index);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C));
return OPERATOR_FINISHED;
@@ -253,17 +251,18 @@ static int create_orientation_exec(bContext *C, wmOperator *op)
const bool use = RNA_boolean_get(op->ptr, "use");
const bool overwrite = RNA_boolean_get(op->ptr, "overwrite");
const bool use_view = RNA_boolean_get(op->ptr, "use_view");
+ View3D *v3d = CTX_wm_view3d(C);
RNA_string_get(op->ptr, "name", name);
- if (use && !CTX_wm_view3d(C)) {
+ if (use && !v3d) {
BKE_report(op->reports, RPT_ERROR, "Create Orientation's 'use' parameter only valid in a 3DView context");
return OPERATOR_CANCELLED;
}
BIF_createTransformOrientation(C, op->reports, name, use_view, use, overwrite);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C));
return OPERATOR_FINISHED;
@@ -282,10 +281,10 @@ static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot)
ot->poll = ED_operator_areaactive;
RNA_def_string(ot->srna, "name", NULL, MAX_NAME, "Name", "Name of the new custom orientation");
- RNA_def_boolean(ot->srna, "use_view", FALSE, "Use View",
+ RNA_def_boolean(ot->srna, "use_view", false, "Use View",
"Use the current view instead of the active object to create the new orientation");
- RNA_def_boolean(ot->srna, "use", FALSE, "Use after creation", "Select orientation after its creation");
- RNA_def_boolean(ot->srna, "overwrite", FALSE, "Overwrite previous",
+ RNA_def_boolean(ot->srna, "use", false, "Use after creation", "Select orientation after its creation");
+ RNA_def_boolean(ot->srna, "overwrite", false, "Overwrite previous",
"Overwrite previously created orientation with same name");
}
@@ -404,7 +403,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (mode_prev != t->mode) {
/* WARNING: this is not normal to switch operator types
* normally it would not be supported but transform happens
- * to share callbacks between differernt operators. */
+ * to share callbacks between different operators. */
wmOperatorType *ot_new = NULL;
TransformModeItem *item = transform_modes;
while (item->idname) {
@@ -990,7 +989,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "use", TRUE);
+ RNA_boolean_set(kmi->ptr, "use", true);
WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0);
@@ -1002,10 +1001,10 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
+ RNA_boolean_set(kmi->ptr, "texture_space", true);
kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
+ RNA_boolean_set(kmi->ptr, "texture_space", true);
WM_keymap_add_item(keymap, OP_SKIN_RESIZE, AKEY, KM_PRESS, KM_CTRL, 0);
@@ -1059,11 +1058,11 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
* in that case the secondary regular operators are called with same keymap.
*/
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(kmi->ptr, "release_confirm", true);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_A, KM_ANY, 0, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(kmi->ptr, "release_confirm", true);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
+ RNA_boolean_set(kmi->ptr, "release_confirm", true);
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 0182e7ac7a7..ba90926df3b 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -33,7 +33,6 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -47,7 +46,6 @@
#include "BLI_utildefines.h"
#include "BKE_action.h"
-#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
@@ -58,7 +56,6 @@
#include "BLF_translation.h"
#include "ED_armature.h"
-#include "ED_mesh.h"
#include "RNA_define.h"
@@ -229,7 +226,6 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports,
break;
default:
return NULL;
- break;
}
return addMatrixSpace(C, mat, name, overwrite);
@@ -245,7 +241,7 @@ bool createSpaceNormal(float mat[3][3], const float normal[3])
}
cross_v3_v3v3(mat[0], mat[2], tangent);
- if (dot_v3v3(mat[0], mat[0]) == 0.0f) {
+ if (is_zero_v3(mat[0])) {
tangent[0] = 1.0f;
tangent[1] = tangent[2] = 0.0f;
cross_v3_v3v3(mat[0], tangent, mat[2]);
@@ -799,18 +795,31 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
}
else if (obedit->type == OB_MBALL) {
MetaBall *mb = obedit->data;
+ MetaElem *ml;
+ bool ok = false;
+ float tmat[3][3];
- if (mb->lastelem) {
- float qmat[3][3];
-
- /* Rotation of MetaElem is stored in quat */
- quat_to_mat3(qmat, mb->lastelem->quat);
-
- copy_v3_v3(normal, qmat[2]);
+ if (activeOnly && (ml = mb->lastelem)) {
+ quat_to_mat3(tmat, ml->quat);
+ add_v3_v3(normal, tmat[2]);
+ add_v3_v3(plane, tmat[1]);
+ ok = true;
+ }
+ else {
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ if (ml->flag & SELECT) {
+ quat_to_mat3(tmat, ml->quat);
+ add_v3_v3(normal, tmat[2]);
+ add_v3_v3(plane, tmat[1]);
+ ok = true;
+ }
+ }
+ }
- copy_v3_v3(plane, qmat[1]);
-
- result = ORIENTATION_FACE;
+ if (ok) {
+ if (!is_zero_v3(plane)) {
+ result = ORIENTATION_FACE;
+ }
}
}
else if (obedit->type == OB_ARMATURE) {
@@ -859,12 +868,12 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
bArmature *arm = ob->data;
bPoseChannel *pchan;
float imat[3][3], mat[3][3];
- int ok = FALSE;
+ bool ok = false;
if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
add_v3_v3(normal, pchan->pose_mat[2]);
add_v3_v3(plane, pchan->pose_mat[1]);
- ok = TRUE;
+ ok = true;
}
else {
int totsel;
@@ -878,7 +887,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
add_v3_v3(plane, pchan->pose_mat[1]);
}
}
- ok = TRUE;
+ ok = true;
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index d9924ea8e0e..c94ba20ca47 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -40,7 +40,6 @@
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" /* Temporary, for snapping to other unselected meshes */
#include "DNA_node_types.h"
#include "DNA_space_types.h"
@@ -61,7 +60,6 @@
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_tracking.h"
#include "RNA_access.h"
@@ -70,7 +68,6 @@
#include "ED_armature.h"
#include "ED_image.h"
-#include "ED_mesh.h"
#include "ED_node.h"
#include "ED_uvedit.h"
#include "ED_view3d.h"
@@ -105,9 +102,9 @@ static void TargetSnapCenter(TransInfo *t);
static void TargetSnapClosest(TransInfo *t);
static void TargetSnapActive(TransInfo *t);
-static float RotationBetween(TransInfo *t, float p1[3], float p2[3]);
-static float TranslationBetween(TransInfo *t, float p1[3], float p2[3]);
-static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]);
+static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]);
+static float TranslationBetween(TransInfo *t, const float p1[3], const float p2[3]);
+static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]);
/****************** IMPLEMENTATIONS *********************/
@@ -338,7 +335,7 @@ bool usingSnappingNormal(TransInfo *t)
bool validSnappingNormal(TransInfo *t)
{
if (validSnap(t)) {
- if (dot_v3v3(t->tsnap.snapNormal, t->tsnap.snapNormal) > 0) {
+ if (!is_zero_v3(t->tsnap.snapNormal)) {
return true;
}
}
@@ -468,10 +465,10 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->modifiers |= MOD_SNAP;
}
- t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
- t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
- t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) == SCE_SNAP_NO_SELF);
- t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+ t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) != 0);
+ t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
+ t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0);
+ t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
}
}
@@ -670,12 +667,12 @@ static void ApplySnapResize(TransInfo *t, float vec[3])
/********************** DISTANCE **************************/
-static float TranslationBetween(TransInfo *UNUSED(t), float p1[3], float p2[3])
+static float TranslationBetween(TransInfo *UNUSED(t), const float p1[3], const float p2[3])
{
return len_v3v3(p1, p2);
}
-static float RotationBetween(TransInfo *t, float p1[3], float p2[3])
+static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
{
float angle, start[3], end[3], center[3];
@@ -731,7 +728,7 @@ static float RotationBetween(TransInfo *t, float p1[3], float p2[3])
return angle;
}
-static float ResizeBetween(TransInfo *t, float p1[3], float p2[3])
+static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
{
float d1[3], d2[3], center[3], len_d1;
@@ -776,7 +773,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
if (t->tsnap.mode == SCE_SNAP_MODE_VOLUME) {
ListBase depth_peels;
DepthPeel *p1, *p2;
- float *last_p = NULL;
+ const float *last_p = NULL;
float max_dist = FLT_MAX;
float p[3] = {0.0f, 0.0f, 0.0f};
@@ -862,10 +859,10 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
if (found == true) {
float tangent[3];
- sub_v3_v3v3(tangent, loc, t->tsnap.snapPoint);
- tangent[2] = 0;
+ sub_v2_v2v2(tangent, loc, t->tsnap.snapPoint);
+ tangent[2] = 0.0f;
- if (dot_v3v3(tangent, tangent) > 0) {
+ if (!is_zero_v3(tangent)) {
copy_v3_v3(t->tsnap.snapTangent, tangent);
}
@@ -883,7 +880,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
Image *ima = ED_space_image(t->sa->spacedata.first);
float aspx, aspy, co[2];
- UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co + 1);
+ UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], &co[0], &co[1]);
if (ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint)) {
ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
@@ -966,27 +963,14 @@ static void TargetSnapActive(TransInfo *t)
{
/* Only need to calculate once */
if ((t->tsnap.status & TARGET_INIT) == 0) {
- TransData *td = NULL;
- TransData *active_td = NULL;
- int i;
-
- for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) {
- if (td->flag & TD_ACTIVE) {
- active_td = td;
- break;
- }
- }
-
- if (active_td) {
- copy_v3_v3(t->tsnap.snapTarget, active_td->center);
-
+ if (calculateCenterActive(t, true, t->tsnap.snapTarget)) {
if (t->flag & (T_EDIT | T_POSE)) {
Object *ob = t->obedit ? t->obedit : t->poseobj;
mul_m4_v3(ob->obmat, t->tsnap.snapTarget);
}
-
- TargetSnapOffset(t, active_td);
-
+
+ TargetSnapOffset(t, NULL);
+
t->tsnap.status |= TARGET_INIT;
}
/* No active, default to median */
@@ -1283,8 +1267,8 @@ static bool snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *ar
bone = pchan->bone;
/* skip hidden bones */
if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
- float *head_vec = pchan->pose_head;
- float *tail_vec = pchan->pose_tail;
+ const float *head_vec = pchan->pose_head;
+ const float *tail_vec = pchan->pose_tail;
switch (snap_mode) {
case SCE_SNAP_MODE_VERTEX:
@@ -1468,7 +1452,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
case SCE_SNAP_MODE_VERTEX:
{
MVert *verts = dm->getVertArray(dm);
- int *index_array = NULL;
+ const int *index_array = NULL;
int index = 0;
int i;
@@ -1517,7 +1501,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
MVert *verts = dm->getVertArray(dm);
MEdge *edges = dm->getEdgeArray(dm);
int totedge = dm->getNumEdges(dm);
- int *index_array = NULL;
+ const int *index_array = NULL;
int index = 0;
int i;
@@ -2140,8 +2124,7 @@ static bool snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bN
rcti totr;
int new_dist;
- UI_view2d_to_region_no_clip(v2d, node->totr.xmin, node->totr.ymin, &totr.xmin, &totr.ymin);
- UI_view2d_to_region_no_clip(v2d, node->totr.xmax, node->totr.ymax, &totr.xmax, &totr.ymax);
+ UI_view2d_view_to_region_rcti(v2d, &node->totr, &totr);
if (border & NODE_LEFT) {
new_dist = abs(totr.xmin - mval[0]);
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 7253f584809..afce5ffdcf2 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -41,7 +41,6 @@ set(SRC
editmode_undo.c
numinput.c
undo.c
- crazyspace.c
util_intern.h
# general includes
@@ -53,7 +52,6 @@ set(SRC
../include/ED_curve.h
../include/ED_datafiles.h
../include/ED_fileselect.h
- ../include/ED_fluidsim.h
../include/ED_gpencil.h
../include/ED_image.h
../include/ED_info.h
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 4123132ad03..1fa1e5bdc49 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -43,6 +43,7 @@
#include "BKE_lattice.h"
#include "BKE_editmesh.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_context.h"
#include "ED_armature.h"
@@ -52,6 +53,7 @@
/* copied from editobject.c, now uses (almost) proper depgraph */
void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
{
+ const int mode = tvs->mode;
BLI_assert(ED_transverts_check_obedit(obedit) == true);
DAG_id_tag_update(obedit->data, 0);
@@ -67,32 +69,45 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
while (nu) {
/* keep handles' vectors unchanged */
- if (nu->bezt) {
+ if (nu->bezt && (mode & TM_SKIP_HANDLES)) {
int a = nu->pntsu;
TransVert *tv = tvs->transverts;
BezTriple *bezt = nu->bezt;
while (a--) {
- if (bezt->f1 & SELECT) tv++;
-
- if (bezt->f2 & SELECT) {
- float v[3];
+ if (bezt->hide == 0) {
+ bool skip_handle = false;
+ if (bezt->f2 & SELECT)
+ skip_handle = (mode & TM_SKIP_HANDLES) != 0;
- if (bezt->f1 & SELECT) {
- sub_v3_v3v3(v, (tv - 1)->oldloc, tv->oldloc);
- add_v3_v3v3(bezt->vec[0], bezt->vec[1], v);
+ if ((bezt->f1 & SELECT) && !skip_handle) {
+ BLI_assert(tv->loc == bezt->vec[0]);
+ tv++;
}
- if (bezt->f3 & SELECT) {
- sub_v3_v3v3(v, (tv + 1)->oldloc, tv->oldloc);
- add_v3_v3v3(bezt->vec[2], bezt->vec[1], v);
+ if (bezt->f2 & SELECT) {
+ float v[3];
+
+ if (((bezt->f1 & SELECT) && !skip_handle) == 0) {
+ sub_v3_v3v3(v, tv->loc, tv->oldloc);
+ add_v3_v3(bezt->vec[0], v);
+ }
+
+ if (((bezt->f3 & SELECT) && !skip_handle) == 0) {
+ sub_v3_v3v3(v, tv->loc, tv->oldloc);
+ add_v3_v3(bezt->vec[2], v);
+ }
+
+ BLI_assert(tv->loc == bezt->vec[1]);
+ tv++;
}
- tv++;
+ if ((bezt->f3 & SELECT) && !skip_handle) {
+ BLI_assert(tv->loc == bezt->vec[2]);
+ tv++;
+ }
}
- if (bezt->f3 & SELECT) tv++;
-
bezt++;
}
}
@@ -270,6 +285,12 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
copy_v3_v3(tv->oldloc, eve->co);
tv->loc = eve->co;
tv->flag = (BM_elem_index_get(eve) == TM_INDEX_ON) ? SELECT : 0;
+
+ if (mode & TM_CALC_NORMALS) {
+ tv->flag |= TX_VERT_USE_NORMAL;
+ copy_v3_v3(tv->normal, eve->no);
+ }
+
tv++;
a++;
}
@@ -352,23 +373,33 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
bezt = nu->bezt;
while (a--) {
if (bezt->hide == 0) {
- int skip_handle = 0;
+ bool skip_handle = false;
if (bezt->f2 & SELECT)
- skip_handle = mode & TM_SKIP_HANDLES;
+ skip_handle = (mode & TM_SKIP_HANDLES) != 0;
if ((bezt->f1 & SELECT) && !skip_handle) {
copy_v3_v3(tv->oldloc, bezt->vec[0]);
tv->loc = bezt->vec[0];
tv->flag = bezt->f1 & SELECT;
+
+ if (mode & TM_CALC_NORMALS) {
+ tv->flag |= TX_VERT_USE_NORMAL;
+ BKE_nurb_bezt_calc_plane(nu, bezt, tv->normal);
+ }
+
tv++;
tvs->transverts_tot++;
}
if (bezt->f2 & SELECT) {
copy_v3_v3(tv->oldloc, bezt->vec[1]);
tv->loc = bezt->vec[1];
- tv->val = &(bezt->alfa);
- tv->oldval = bezt->alfa;
tv->flag = bezt->f2 & SELECT;
+
+ if (mode & TM_CALC_NORMALS) {
+ tv->flag |= TX_VERT_USE_NORMAL;
+ BKE_nurb_bezt_calc_plane(nu, bezt, tv->normal);
+ }
+
tv++;
tvs->transverts_tot++;
}
@@ -376,6 +407,12 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
copy_v3_v3(tv->oldloc, bezt->vec[2]);
tv->loc = bezt->vec[2];
tv->flag = bezt->f3 & SELECT;
+
+ if (mode & TM_CALC_NORMALS) {
+ tv->flag |= TX_VERT_USE_NORMAL;
+ BKE_nurb_bezt_calc_plane(nu, bezt, tv->normal);
+ }
+
tv++;
tvs->transverts_tot++;
}
@@ -391,8 +428,6 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
if (bp->f1 & SELECT) {
copy_v3_v3(tv->oldloc, bp->vec);
tv->loc = bp->vec;
- tv->val = &(bp->alfa);
- tv->oldval = bp->alfa;
tv->flag = bp->f1 & SELECT;
tv++;
tvs->transverts_tot++;
@@ -415,8 +450,6 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
if (ml->flag & SELECT) {
tv->loc = &ml->x;
copy_v3_v3(tv->oldloc, tv->loc);
- tv->val = &(ml->rad);
- tv->oldval = ml->rad;
tv->flag = SELECT;
tv++;
tvs->transverts_tot++;
@@ -453,6 +486,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
MEM_freeN(tvs->transverts);
tvs->transverts = NULL;
}
+
+ tvs->mode = mode;
}
void ED_transverts_free(TransVertStore *tvs)
@@ -460,3 +495,14 @@ void ED_transverts_free(TransVertStore *tvs)
MEM_SAFE_FREE(tvs->transverts);
tvs->transverts_tot = 0;
}
+
+int ED_transverts_poll(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit) {
+ if (ED_transverts_check_obedit(obedit)) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 9d4fcc5ef8f..fca18e40d73 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -139,8 +139,8 @@ void ED_editors_exit(bContext *C)
}
/* global in meshtools... */
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, 'e');
}
/* flush any temp data from object editing to DNA before writing files,
@@ -160,12 +160,12 @@ void ED_editors_flush_edits(const bContext *C, bool for_render)
if (for_render) {
/* flush changes from dynamic topology sculpt */
- sculptsession_bm_to_me_for_render(obact);
+ BKE_sculptsession_bm_to_me_for_render(obact);
}
else {
/* Set reorder=false so that saving the file doesn't reorder
* the BMesh's elements */
- sculptsession_bm_to_me(obact, FALSE);
+ BKE_sculptsession_bm_to_me(obact, false);
}
}
}
@@ -292,7 +292,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
const int mval_dst[2] = {win->eventstate->x - ar->winrct.xmin,
win->eventstate->y - ar->winrct.ymin};
- UI_ThemeColor(TH_WIRE);
+ UI_ThemeColor(TH_VIEW_OVERLAY);
GPU_raster_begin();
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index caa5e7659f8..ef95e4cb3ff 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -36,10 +36,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BKE_blender.h"
@@ -212,9 +210,9 @@ static void undo_clean_stack(bContext *C)
if (uel->type == obedit->type) {
if (strcmp(uel->id.name, obedit->id.name) == 0) {
if (uel->validate_undo == NULL)
- is_valid = TRUE;
+ is_valid = true;
else if (uel->validate_undo(uel->undodata, editdata))
- is_valid = TRUE;
+ is_valid = true;
}
}
if (is_valid)
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 628492d459d..ee391af185d 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -48,6 +48,13 @@
#include "UI_interface.h"
+/* NumInput.flag */
+enum {
+ /* (1 << 8) and below are reserved for public flags! */
+ NUM_EDIT_FULL = (1 << 9), /* Enable full editing, with units and math operators support. */
+ NUM_FAKE_EDITED = (1 << 10), /* Fake edited state (temp, avoids issue with backspace). */
+};
+
/* NumInput.val_flag[] */
enum {
/* (1 << 8) and below are reserved for public flags! */
@@ -63,17 +70,20 @@ enum {
void initNumInput(NumInput *n)
{
- n->unit_sys = USER_UNIT_NONE;
- n->unit_type[0] = n->unit_type[1] = n->unit_type[2] = B_UNIT_NONE;
- n->idx = 0;
n->idx_max = 0;
+ n->unit_sys = USER_UNIT_NONE;
+ fill_vn_i(n->unit_type, NUM_MAX_ELEMENTS, B_UNIT_NONE);
+ n->unit_use_radians = false;
+
n->flag = 0;
- n->val_flag[0] = n->val_flag[1] = n->val_flag[2] = 0;
- zero_v3(n->val_org);
+ fill_vn_short(n->val_flag, NUM_MAX_ELEMENTS, 0);
zero_v3(n->val);
+ fill_vn_fl(n->val_org, NUM_MAX_ELEMENTS, 0.0f);
+ fill_vn_fl(n->val_inc, NUM_MAX_ELEMENTS, 1.0f);
+
+ n->idx = 0;
n->str[0] = '\0';
n->str_cur = 0;
- copy_v3_fl(n->val_inc, 1.0f);
}
/* str must be NUM_STR_REP_LEN * (idx_max + 1) length. */
@@ -142,6 +152,10 @@ bool hasNumInput(const NumInput *n)
{
short i;
+ if (n->flag & NUM_FAKE_EDITED) {
+ return true;
+ }
+
for (i = 0; i <= n->idx_max; i++) {
if (n->val_flag[i] & NUM_EDITED) {
return true;
@@ -154,31 +168,45 @@ bool hasNumInput(const NumInput *n)
/**
* \warning \a vec must be set beforehand otherwise we risk uninitialized vars.
*/
-void applyNumInput(NumInput *n, float *vec)
+bool applyNumInput(NumInput *n, float *vec)
{
short i, j;
float val;
if (hasNumInput(n)) {
for (j = 0; j <= n->idx_max; j++) {
- /* if AFFECTALL and no number typed and cursor not on number, use first number */
- i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
- val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i];
-
- if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) {
- val = 0.0f;
+ if (n->flag & NUM_FAKE_EDITED) {
+ val = n->val[j];
}
- if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
- val = 0.0001f;
- }
- if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) {
- val = floorf(val + 0.5f);
+ else {
+ /* if AFFECTALL and no number typed and cursor not on number, use first number */
+ i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
+ val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i];
+
+ if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) {
+ val = 0.0f;
+ }
if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
- val = 1.0f;
+ val = 0.0001f;
+ }
+ if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) {
+ val = floorf(val + 0.5f);
+ if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
+ val = 1.0f;
+ }
}
}
vec[j] = val;
}
+ n->flag &= ~NUM_FAKE_EDITED;
+ return true;
+ }
+ else {
+ /* Else, we set the 'org' values for numinput! */
+ for (j = 0; j <= n->idx_max; j++) {
+ n->val[j] = n->val_org[j] = vec[j];
+ }
+ return false;
}
}
@@ -207,6 +235,19 @@ static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf
return true;
}
+static bool editstr_is_simple_numinput(const char ascii)
+{
+ if (ascii >= '0' && ascii <= '9') {
+ return true;
+ }
+ else if (ascii == '.') {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
{
const char *utf8_buf = NULL;
@@ -238,6 +279,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[0] &= ~NUM_EDITED;
n->val_flag[1] &= ~NUM_EDITED;
n->val_flag[2] &= ~NUM_EDITED;
+ n->flag |= NUM_FAKE_EDITED;
updated = true;
break;
}
@@ -267,6 +309,9 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
memmove(&n->str[cur], &n->str[t_cur], strlen(&n->str[t_cur]) + 1); /* +1 for trailing '\0'. */
updated = true;
}
+ if (!n->str[0]) {
+ n->val[idx] = n->val_org[idx];
+ }
}
else {
return false;
@@ -299,13 +344,10 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
return false;
case TABKEY:
- n->val_org[idx] = n->val[idx];
n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE);
- idx += event->ctrl ? -1 : 1;
- idx %= idx_max + 1;
+ idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1);
n->idx = idx;
- n->val[idx] = n->val_org[idx];
if (n->val_flag[idx] & NUM_EDITED) {
value_to_editstr(n, idx);
}
@@ -315,34 +357,48 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
return true;
case PADPERIOD:
+ case PERIODKEY:
/* Force numdot, some OSs/countries generate a comma char in this case, sic... (T37992) */
ascii[0] = '.';
utf8_buf = ascii;
break;
+#if 0 /* Those keys are not directly accessible in all layouts, preventing to generate matching events.
+ * So we use a hack (ascii value) instead, see below.
+ */
+ case EQUALKEY:
+ case PADASTERKEY:
+ if (!(n->flag & NUM_EDIT_FULL)) {
+ n->flag |= NUM_EDIT_FULL;
+ n->val_flag[idx] |= NUM_EDITED;
+ return true;
+ }
+ else if (event->ctrl) {
+ n->flag &= ~NUM_EDIT_FULL;
+ return true;
+ }
+ break;
+#endif
case PADMINUS:
case MINUSKEY:
- if (event->ctrl) {
+ if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_NEGATE;
updated = true;
- break;
}
- /* fall-through */
+ break;
case PADSLASHKEY:
case SLASHKEY:
- if (event->ctrl) {
+ if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_INVERSE;
updated = true;
- break;
}
- /* fall-through */
+ break;
case CKEY:
if (event->ctrl) {
/* Copy current str to the copypaste buffer. */
WM_clipboard_text_set(n->str, 0);
updated = true;
- break;
}
- /* fall-through */
+ break;
case VKEY:
if (event->ctrl) {
/* extract the first line from the clipboard */
@@ -350,9 +406,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
if (pbuf) {
- bool success;
-
- success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
+ const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
MEM_freeN(pbuf);
if (!success) {
@@ -362,21 +416,44 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] |= NUM_EDITED;
}
updated = true;
- break;
}
- /* fall-through */
+ break;
default:
- utf8_buf = event->utf8_buf;
- ascii[0] = event->ascii;
break;
}
- if (utf8_buf && !utf8_buf[0] && ascii[0]) {
+ if (!updated && !utf8_buf && (event->utf8_buf[0] || event->ascii)) {
+ utf8_buf = event->utf8_buf;
+ ascii[0] = event->ascii;
+ }
+
+ /* XXX Hack around keyboards without direct access to '=' nor '*'... */
+ if (ELEM(ascii[0], '=', '*')) {
+ if (!(n->flag & NUM_EDIT_FULL)) {
+ n->flag |= NUM_EDIT_FULL;
+ n->val_flag[idx] |= NUM_EDITED;
+ return true;
+ }
+ else if (event->ctrl) {
+ n->flag &= ~NUM_EDIT_FULL;
+ return true;
+ }
+ }
+
+ if ((!utf8_buf || !utf8_buf[0]) && ascii[0]) {
/* Fallback to ascii. */
utf8_buf = ascii;
}
if (utf8_buf && utf8_buf[0]) {
+ if (!(n->flag & NUM_EDIT_FULL)) {
+ /* In simple edit mode, we only keep a few chars as valid! */
+ /* no need to decode unicode, ascii is first char only */
+ if (!editstr_is_simple_numinput(utf8_buf[0])) {
+ return false;
+ }
+ }
+
if (!editstr_insert_at_cursor(n, utf8_buf, BLI_str_utf8_size(utf8_buf))) {
return false;
}
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 6d3d33f1897..a4f2c36f250 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -37,12 +37,9 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -105,13 +102,13 @@ void ED_undo_push(bContext *C, const char *str)
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (U.undosteps == 0) return;
-
+
PE_undo_push(CTX_data_scene(C), str);
}
else {
BKE_write_undo(C, str);
}
-
+
if (wm->file_saved) {
wm->file_saved = 0;
/* notifier that data changed, for save-over warning or header */
@@ -121,14 +118,17 @@ void ED_undo_push(bContext *C, const char *str)
/* note: also check undo_history_exec() in bottom if you change notifiers */
static int ed_undo_step(bContext *C, int step, const char *undoname)
-{
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
ScrArea *sa = CTX_wm_area(C);
/* undo during jobs are running can easily lead to freeing data using by jobs,
* or they can just lead to freezing job in some other cases */
- if (WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_ANY)) {
+ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
return OPERATOR_CANCELLED;
}
@@ -182,9 +182,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (step == 1)
- PE_undo(CTX_data_scene(C));
+ PE_undo(scene);
else
- PE_redo(CTX_data_scene(C));
+ PE_redo(scene);
}
else if (U.uiflag & USER_GLOBALUNDO) {
// note python defines not valid here anymore.
@@ -202,12 +202,18 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
BKE_undo_name(C, undoname);
else
BKE_undo_step(C, step);
+
+ scene = CTX_data_scene(C);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
}
}
WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ if (win) {
+ win->addmousemove = true;
+ }
return OPERATOR_FINISHED;
}
@@ -424,13 +430,25 @@ void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int UNUSED(arg_ev
enum {
UNDOSYSTEM_GLOBAL = 1,
UNDOSYSTEM_EDITMODE = 2,
- UNDOSYSTEM_PARTICLE = 3
+ UNDOSYSTEM_PARTICLE = 3,
+ UNDOSYSTEM_IMAPAINT = 4
};
static int get_undo_system(bContext *C)
{
+ Object *obact = CTX_data_active_object(C);
Object *obedit = CTX_data_edit_object(C);
-
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* first check for editor undo */
+ if (sa && (sa->spacetype == SPACE_IMAGE)) {
+ SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
+
+ if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
+ if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE))
+ return UNDOSYSTEM_IMAPAINT;
+ }
+ }
/* find out which undo system */
if (obedit) {
if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) {
@@ -440,9 +458,15 @@ static int get_undo_system(bContext *C)
else {
Object *obact = CTX_data_active_object(C);
- if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
- return UNDOSYSTEM_PARTICLE;
- else if (U.uiflag & USER_GLOBALUNDO)
+ if (obact) {
+ if (obact->mode & OB_MODE_PARTICLE_EDIT)
+ return UNDOSYSTEM_PARTICLE;
+ else if (obact->mode & OB_MODE_TEXTURE_PAINT) {
+ if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE))
+ return UNDOSYSTEM_IMAPAINT;
+ }
+ }
+ if (U.uiflag & USER_GLOBALUNDO)
return UNDOSYSTEM_GLOBAL;
}
@@ -455,7 +479,7 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
EnumPropertyItem item_tmp = {0}, *item = NULL;
int active, i = 0;
- while (TRUE) {
+ while (true) {
const char *name = NULL;
if (undosys == UNDOSYSTEM_PARTICLE) {
@@ -464,6 +488,9 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
else if (undosys == UNDOSYSTEM_EDITMODE) {
name = undo_editmode_get_name(C, i, &active);
}
+ else if (undosys == UNDOSYSTEM_IMAPAINT) {
+ name = ED_undo_paint_get_name(UNDO_PAINT_IMAGE, i, &active);
+ }
else {
name = BKE_undo_get_name(i, &active);
}
@@ -501,16 +528,22 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
if (totitem > 0) {
uiPopupMenu *pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
- uiLayout *split = uiLayoutSplit(layout, 0.0f, FALSE);
+ uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
uiLayout *column = NULL;
+ const int col_size = 20 + totitem / 12;
int i, c;
+ bool add_col = true;
- for (c = 0, i = totitem - 1; i >= 0; i--, c++) {
- if ( (c % 20) == 0)
- column = uiLayoutColumn(split, FALSE);
- if (item[i].identifier)
+ for (c = 0, i = totitem; i--;) {
+ if (add_col && !(c % col_size)) {
+ column = uiLayoutColumn(split, false);
+ add_col = false;
+ }
+ if (item[i].identifier) {
uiItemIntO(column, item[i].name, item[i].icon, op->type->idname, "item", item[i].value);
-
+ ++c;
+ add_col = true;
+ }
}
MEM_freeN(item);
@@ -536,6 +569,9 @@ static int undo_history_exec(bContext *C, wmOperator *op)
undo_editmode_number(C, item + 1);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
+ else if (undosys == UNDOSYSTEM_IMAPAINT) {
+ ED_undo_paint_step_num(C, UNDO_PAINT_IMAGE, item );
+ }
else {
ED_viewport_render_kill_jobs(C, true);
BKE_undo_number(C, item);
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index e648caf51d2..78e3811a5fc 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -32,7 +32,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -47,7 +46,6 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_mesh.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index ffdf12a425e..08256ecd84b 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -32,10 +32,8 @@
/* my library */
-#include "ED_util.h"
#include "ED_image.h"
#include "ED_mesh.h"
-
#include "UI_resources.h"
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -48,7 +46,6 @@
#include "BIF_glutil.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_mesh.h"
#include "BKE_editmesh.h"
#include "BLI_math.h"
@@ -88,7 +85,7 @@ void draw_image_cursor(ARegion *ar, const float cursor[2])
{
float zoom[2], x_fac, y_fac;
- UI_view2d_getscale_inverse(&ar->v2d, &zoom[0], &zoom[1]);
+ UI_view2d_scale_get_inverse(&ar->v2d, &zoom[0], &zoom[1]);
mul_v2_fl(zoom, 256.0f * UI_DPI_FAC);
x_fac = zoom[0];
@@ -230,7 +227,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
totarea += BM_face_calc_area(efa);
- totuvarea += area_poly_v2(efa->len, tf_uv);
+ totuvarea += area_poly_v2((const float (*)[2])tf_uv, efa->len);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -273,7 +270,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
- uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea;
+ uvarea = area_poly_v2((const float (*)[2])tf_uv, efa->len) / totuvarea;
if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
areadiff = 1.0f;
@@ -494,11 +491,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ activetf = EDBM_mtexpoly_active_get(em, &efa_act, false, false); /* will be set to NULL if hidden */
+
gpuImmediateFormat_C4_V2();
- activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */
#ifndef USE_EDBM_LOOPTRIS
- activef = BM_mesh_active_face_get(bm, FALSE, FALSE);
+ activef = BM_mesh_active_face_get(bm, false, false);
#endif
ts = scene->toolsettings;
@@ -518,6 +516,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
/* 1. draw shadow mesh */
if (sima->flag & SI_DRAWSHADOW) {
+ DM_update_materials(em->derivedFinal, obedit);
/* first try existing derivedmesh */
if (!draw_uvs_dm_shadow(em->derivedFinal)) {
/* create one if it does not exist */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 8e980bdd4d2..5169cc73052 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -60,7 +60,6 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_node.h"
#include "BKE_report.h"
@@ -137,23 +136,24 @@ static bool is_image_texture_node(bNode *node)
return ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT);
}
-bool ED_object_get_active_image(Object *ob, int mat_nr, Image **ima, ImageUser **iuser, bNode **node_r)
+bool ED_object_get_active_image(Object *ob, int mat_nr,
+ Image **r_ima, ImageUser **r_iuser, bNode **r_node)
{
Material *ma = give_current_material(ob, mat_nr);
bNode *node = (ma && ma->use_nodes) ? nodeGetActiveTexture(ma->nodetree) : NULL;
if (node && is_image_texture_node(node)) {
- if (ima) *ima = (Image *)node->id;
- if (iuser) *iuser = NULL;
- if (node_r) *node_r = node;
- return TRUE;
+ if (r_ima) *r_ima = (Image *)node->id;
+ if (r_iuser) *r_iuser = NULL;
+ if (r_node) *r_node = node;
+ return true;
}
- if (ima) *ima = NULL;
- if (iuser) *iuser = NULL;
- if (node_r) *node_r = node;
+ if (r_ima) *r_ima = NULL;
+ if (r_iuser) *r_iuser = NULL;
+ if (r_node) *r_node = node;
- return FALSE;
+ return false;
}
void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *ima)
@@ -388,7 +388,7 @@ bool uvedit_face_select_enable(Scene *scene, BMEditMesh *em, BMFace *efa, const
ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- BM_face_select_set(em->bm, efa, TRUE);
+ BM_face_select_set(em->bm, efa, true);
if (do_history) {
BM_select_history_store(em->bm, (BMElem *)efa);
}
@@ -415,7 +415,7 @@ bool uvedit_face_select_disable(Scene *scene, BMEditMesh *em, BMFace *efa,
ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- BM_face_select_set(em->bm, efa, FALSE);
+ BM_face_select_set(em->bm, efa, false);
}
else {
BMLoop *l;
@@ -480,12 +480,12 @@ void uvedit_edge_select_enable(BMEditMesh *em, Scene *scene, BMLoop *l, const bo
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE)
- BM_face_select_set(em->bm, l->f, TRUE);
+ BM_face_select_set(em->bm, l->f, true);
else if (ts->selectmode & SCE_SELECT_EDGE)
- BM_edge_select_set(em->bm, l->e, TRUE);
+ BM_edge_select_set(em->bm, l->e, true);
else {
- BM_vert_select_set(em->bm, l->e->v1, TRUE);
- BM_vert_select_set(em->bm, l->e->v2, TRUE);
+ BM_vert_select_set(em->bm, l->e->v1, true);
+ BM_vert_select_set(em->bm, l->e->v2, true);
}
if (do_history) {
@@ -511,12 +511,12 @@ void uvedit_edge_select_disable(BMEditMesh *em, Scene *scene, BMLoop *l,
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE)
- BM_face_select_set(em->bm, l->f, FALSE);
+ BM_face_select_set(em->bm, l->f, false);
else if (ts->selectmode & SCE_SELECT_EDGE)
- BM_edge_select_set(em->bm, l->e, FALSE);
+ BM_edge_select_set(em->bm, l->e, false);
else {
- BM_vert_select_set(em->bm, l->e->v1, FALSE);
- BM_vert_select_set(em->bm, l->e->v2, FALSE);
+ BM_vert_select_set(em->bm, l->e->v1, false);
+ BM_vert_select_set(em->bm, l->e->v2, false);
}
}
else {
@@ -565,9 +565,9 @@ void uvedit_uv_select_enable(BMEditMesh *em, Scene *scene, BMLoop *l,
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE)
- BM_face_select_set(em->bm, l->f, TRUE);
+ BM_face_select_set(em->bm, l->f, true);
else
- BM_vert_select_set(em->bm, l->v, TRUE);
+ BM_vert_select_set(em->bm, l->v, true);
if (do_history) {
BM_select_history_remove(em->bm, (BMElem *)l->v);
@@ -586,9 +586,9 @@ void uvedit_uv_select_disable(BMEditMesh *em, Scene *scene, BMLoop *l,
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE)
- BM_face_select_set(em->bm, l->f, FALSE);
+ BM_face_select_set(em->bm, l->f, false);
else
- BM_vert_select_set(em->bm, l->v, FALSE);
+ BM_vert_select_set(em->bm, l->v, false);
}
else {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -990,7 +990,7 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
}
static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit,
- float limit[2], const bool extend)
+ const float limit[2], const bool extend)
{
BMFace *efa;
BMIter iter, liter;
@@ -1015,7 +1015,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
uv_select_all_perform(scene, ima, em, SEL_DESELECT);
}
- BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
/* set flags for first face and verts */
iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, hit->efa, hit->l);
@@ -1581,8 +1581,8 @@ static void uv_weld_align(bContext *C, int tool)
if (BLI_array_count(eve_line) > 2) {
/* we know the returns from these must be valid */
- float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]);
- float *uv_end = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
+ const float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]);
+ const float *uv_end = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]);
/* For t & u modes */
float a = 0.0f;
@@ -1683,7 +1683,7 @@ typedef struct UVvert {
static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
{
const float threshold = RNA_float_get(op->ptr, "threshold");
- const int use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
+ const bool use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
SpaceImage *sima;
Scene *scene;
@@ -1694,7 +1694,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
int uv_a_index;
int uv_b_index;
float *uv_a;
- float *uv_b;
+ const float *uv_b;
BMIter iter, liter;
BMFace *efa;
@@ -1707,7 +1707,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
scene = CTX_data_scene(C);
ima = CTX_data_edit_image(C);
- if (use_unselected == FALSE) {
+ if (use_unselected == false) {
UVvert *vert_arr = NULL;
BLI_array_declare(vert_arr);
MLoopUV **loop_arr = NULL;
@@ -2157,7 +2157,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* de-selecting an edge may deselect a face too - validate */
if (sync) {
- if (select == FALSE) {
+ if (select == false) {
BM_select_history_validate(em->bm);
}
}
@@ -2487,10 +2487,10 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_VERTSEL) {
- is_sel = TRUE;
+ is_sel = true;
}
else {
- is_unsel = TRUE;
+ is_unsel = true;
}
/* we have mixed selection, bail out */
@@ -2537,7 +2537,7 @@ static void uv_select_sync_flush(ToolSettings *ts, BMEditMesh *em, const short s
/* bmesh API handles flushing but not on de-select */
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode != SCE_SELECT_FACE) {
- if (select == FALSE) {
+ if (select == false) {
EDBM_deselect_flush(em);
}
else {
@@ -2545,7 +2545,7 @@ static void uv_select_sync_flush(ToolSettings *ts, BMEditMesh *em, const short s
}
}
- if (select == FALSE) {
+ if (select == false) {
BM_select_history_validate(em->bm);
}
}
@@ -2795,7 +2795,6 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
- rcti rect;
rctf rectf;
bool changed, pinned, select, extend;
const bool use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ?
@@ -2806,10 +2805,8 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* get rectangle from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+ WM_operator_properties_border_to_rctf(op, &rectf);
+ UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
/* figure out what to select/deselect */
select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT);
@@ -2905,7 +2902,7 @@ static void UV_OT_select_border(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "pinned", 0, "Pinned", "Border select pinned UVs only");
- WM_operator_properties_gesture_border(ot, TRUE);
+ WM_operator_properties_gesture_border(ot, true);
}
/* ******************** circle select operator **************** */
@@ -3070,8 +3067,9 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
float cent[2];
uv_poly_center(efa, cent, cd_loop_uv_offset);
- UI_view2d_view_to_region(&ar->v2d, cent[0], cent[1], &screen_uv[0], &screen_uv[1]);
- if (BLI_rcti_isect_pt_v(&rect, screen_uv) &&
+
+ if (UI_view2d_view_to_region_clip(&ar->v2d, cent[0], cent[1], &screen_uv[0], &screen_uv[1]) &&
+ BLI_rcti_isect_pt_v(&rect, screen_uv) &&
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
{
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -3092,8 +3090,10 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- UI_view2d_view_to_region(&ar->v2d, luv->uv[0], luv->uv[1], &screen_uv[0], &screen_uv[1]);
- if (BLI_rcti_isect_pt_v(&rect, screen_uv) &&
+ if (UI_view2d_view_to_region_clip(&ar->v2d,
+ luv->uv[0], luv->uv[1],
+ &screen_uv[0], &screen_uv[1]) &&
+ BLI_rcti_isect_pt_v(&rect, screen_uv) &&
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
{
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
@@ -3249,7 +3249,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2 (luv->uv, cursor);
+ copy_v2_v2(luv->uv, cursor);
changed = true;
}
}
@@ -3628,7 +3628,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
if (em->selectmode == SCE_SELECT_FACE) {
/* check that every UV is selected */
if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) {
- BM_face_select_set(em->bm, efa, FALSE);
+ BM_face_select_set(em->bm, efa, false);
}
uvedit_face_select_disable(scene, em, efa, cd_loop_uv_offset);
}
@@ -3637,7 +3637,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (UV_SEL_TEST(luv, !swap)) {
- BM_vert_select_set(em->bm, l->v, FALSE);
+ BM_vert_select_set(em->bm, l->v, false);
}
}
}
@@ -3647,7 +3647,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
else if (em->selectmode == SCE_SELECT_FACE) {
/* check if a UV is de-selected */
if (bm_face_is_all_uv_sel(efa, false, cd_loop_uv_offset) != !swap) {
- BM_face_select_set(em->bm, efa, FALSE);
+ BM_face_select_set(em->bm, efa, false);
uvedit_face_select_disable(scene, em, efa, cd_loop_uv_offset);
}
}
@@ -3655,7 +3655,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (UV_SEL_TEST(luv, !swap)) {
- BM_vert_select_set(em->bm, l->v, FALSE);
+ BM_vert_select_set(em->bm, l->v, false);
if (!swap) luv->flag &= ~MLOOPUV_VERTSEL;
}
}
@@ -3728,7 +3728,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
- /* BM_face_select_set(em->bm, efa, TRUE); */
+ /* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
}
@@ -3749,7 +3749,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
- /* BM_face_select_set(em->bm, efa, TRUE); */
+ /* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
}
@@ -3765,7 +3765,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
luv->flag |= MLOOPUV_VERTSEL;
}
}
- /* BM_face_select_set(em->bm, efa, TRUE); */
+ /* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
}
@@ -3780,7 +3780,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
- /* BM_face_select_set(em->bm, efa, TRUE); */
+ /* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
}
@@ -3795,14 +3795,14 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op))
luv->flag |= MLOOPUV_VERTSEL;
}
}
- /* BM_face_select_set(em->bm, efa, TRUE); */
+ /* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
}
}
/* re-select tagged faces */
- BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, TRUE, BM_ELEM_TAG);
+ BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -4094,7 +4094,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *UNUSED(op))
me->drawflag |= ME_DRAWSEAMS;
if (scene->toolsettings->edge_mode_live_unwrap)
- ED_unwrap_lscm(scene, ob, FALSE);
+ ED_unwrap_lscm(scene, ob, false);
DAG_id_tag_update(&me->id, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
@@ -4181,30 +4181,30 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0);
/* pick selection */
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "extend", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "extend", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "extend", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "extend", true);
WM_keymap_add_item(keymap, "UV_OT_select_split", YKEY, KM_PRESS, 0, 0);
/* border/circle selection */
kmi = WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "pinned", FALSE);
+ RNA_boolean_set(kmi->ptr, "pinned", false);
kmi = WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "pinned", TRUE);
+ RNA_boolean_set(kmi->ptr, "pinned", true);
WM_keymap_add_item(keymap, "UV_OT_circle_select", CKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "UV_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "UV_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
/* selection manipulation */
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0)->ptr, "extend", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0)->ptr, "extend", FALSE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "extend", TRUE);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0)->ptr, "extend", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0)->ptr, "extend", false);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "extend", true);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", true);
/* select more/less */
WM_keymap_add_item(keymap, "UV_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
@@ -4222,9 +4222,9 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
/* uv operations */
WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "clear", FALSE);
+ RNA_boolean_set(kmi->ptr, "clear", false);
kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "clear", TRUE);
+ RNA_boolean_set(kmi->ptr, "clear", true);
/* unwrap */
WM_keymap_add_item(keymap, "UV_OT_unwrap", EKEY, KM_PRESS, 0, 0);
@@ -4234,9 +4234,9 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
/* hide */
kmi = WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(kmi->ptr, "unselected", FALSE);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "UV_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", TRUE);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "UV_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
@@ -4249,7 +4249,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
- ED_keymap_proportional_editmode(keyconf, keymap, FALSE);
+ ED_keymap_proportional_editmode(keyconf, keymap, false);
transform_keymap_for_space(keyconf, keymap, SPACE_IMAGE);
}
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 40d2cc7dcd2..5f22a201600 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -200,7 +200,7 @@ typedef struct PChart {
} lscm;
struct PChartPack {
float rescale, area;
- float size[2], trans[2];
+ float size[2] /* , trans[2] */;
} pack;
} u;
@@ -1100,7 +1100,7 @@ static PFace *p_face_add(PHandle *handle)
}
static PFace *p_face_add_construct(PHandle *handle, ParamKey key, ParamKey *vkeys,
- float *co[3], float *uv[3], int i1, int i2, int i3,
+ float *co[4], float *uv[4], int i1, int i2, int i3,
ParamBool *pin, ParamBool *select)
{
PFace *f = p_face_add(handle);
@@ -1886,7 +1886,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
if (p_vert_interior(oldv)) {
/* hlscm criterion: angular defect smaller than threshold */
- if (fabs(angulardefect) > (M_PI * 30.0 / 180.0))
+ if (fabsf(angulardefect) > (float)(M_PI * 30.0 / 180.0))
return P_FALSE;
}
else {
@@ -1952,7 +1952,7 @@ static float p_collapse_cost(PEdge *edge, PEdge *pair)
sub_v3_v3v3(tetrav3, co2, oldv->co);
cross_v3_v3v3(c, tetrav2, tetrav3);
- volumecost += fabs(dot_v3v3(edgevec, c) / 6.0f);
+ volumecost += fabsf(dot_v3v3(edgevec, c) / 6.0f);
#if 0
shapecost += dot_v3v3(co1, keepv->co);
@@ -2821,9 +2821,9 @@ static void p_chart_pin_positions(PChart *chart, PVert **pin1, PVert **pin2)
float sub[3];
sub_v3_v3v3(sub, (*pin1)->co, (*pin2)->co);
- sub[0] = fabs(sub[0]);
- sub[1] = fabs(sub[1]);
- sub[2] = fabs(sub[2]);
+ sub[0] = fabsf(sub[0]);
+ sub[1] = fabsf(sub[1]);
+ sub[2] = fabsf(sub[2]);
if ((sub[0] > sub[1]) && (sub[0] > sub[2])) {
dirx = 0;
@@ -4148,7 +4148,7 @@ ParamHandle *param_construct_begin(void)
handle->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param construct arena");
handle->aspx = 1.0f;
handle->aspy = 1.0f;
- handle->do_aspect = FALSE;
+ handle->do_aspect = false;
handle->hash_verts = phash_new((PHashLink **)&handle->construction_chart->verts, 1);
handle->hash_edges = phash_new((PHashLink **)&handle->construction_chart->edges, 1);
@@ -4163,7 +4163,7 @@ void param_aspect_ratio(ParamHandle *handle, float aspx, float aspy)
phandle->aspx = aspx;
phandle->aspy = aspy;
- phandle->do_aspect = TRUE;
+ phandle->do_aspect = true;
}
void param_delete(ParamHandle *handle)
@@ -4250,7 +4250,7 @@ static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts,
}
void param_face_add(ParamHandle *handle, ParamKey key, int nverts,
- ParamKey *vkeys, float **co, float **uv,
+ ParamKey *vkeys, float *co[4], float *uv[4],
ParamBool *pin, ParamBool *select, float normal[3])
{
PHandle *phandle = (PHandle *)handle;
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 265577555a6..eaea781971d 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -59,8 +59,8 @@ void param_face_add(ParamHandle *handle,
ParamKey key,
int nverts,
ParamKey *vkeys,
- float **co,
- float **uv,
+ float *co[4],
+ float *uv[4],
ParamBool *pin,
ParamBool *select,
float face_normal[3]);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index b0462f86500..845b0c34bc4 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
@@ -50,7 +49,6 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_editmesh.h"
@@ -638,7 +636,7 @@ static void state_delete(StitchState *state)
static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
{
UvEdge *edges = state->edges;
- int *map = state->map;
+ const int *map = state->map;
UvElementMap *element_map = state->element_map;
UvElement *first_element = element_map->buf;
int i;
@@ -673,26 +671,30 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
if (iter2) {
int index1 = map[iter1 - first_element];
int index2 = map[iter2 - first_element];
+ UvEdge edgetmp;
+ UvEdge *edge2, *eiter;
+ bool valid = true;
- /* make certain we do not have the same edge! */
- if (state->uvs[index2] != element2 && state->uvs[index1] != element1) {
- UvEdge edgetmp;
- UvEdge *edge2;
+ /* make sure the indices are well behaved */
+ if (index1 > index2) {
+ SWAP(int, index1, index2);
+ }
+ edgetmp.uv1 = index1;
+ edgetmp.uv2 = index2;
- /* make sure the indices are well behaved */
- if (index1 < index2) {
- edgetmp.uv1 = index1;
- edgetmp.uv2 = index2;
- }
- else {
- edgetmp.uv1 = index2;
- edgetmp.uv2 = index1;
- }
+ /* get the edge from the hash */
+ edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
- /* get the edge from the hash */
- edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
+ /* more iteration to make sure non-manifold case is handled nicely */
+ for (eiter = edge; eiter; eiter = eiter->next) {
+ if (edge2 == eiter) {
+ valid = false;
+ break;
+ }
+ }
+ if (valid) {
/* here I am taking care of non manifold case, assuming more than two matching edges.
* I am not too sure we want this though */
last_set->next = edge2;
@@ -882,7 +884,7 @@ static void stitch_propagate_uv_final_position(Scene *scene,
}
/* end of calculations, keep only the selection flag */
- if ( (!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
+ if ((!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
element_iter->flag &= STITCH_SELECTED;
}
@@ -1257,7 +1259,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvEdge *edge = state->edges + i;
if ((edge->flag & STITCH_BOUNDARY) && (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
- island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
@@ -1305,7 +1307,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
if (edge->flag & STITCH_STITCHABLE) {
stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
- island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
@@ -1358,8 +1360,8 @@ static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
return
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+ BLI_ghashutil_uinthash(edge->uv2) +
+ BLI_ghashutil_uinthash(edge->uv1);
}
static int uv_edge_compare(const void *a, const void *b)
@@ -1456,7 +1458,7 @@ static void stitch_switch_selection_mode(StitchState *state)
UvElement *element2 = state->uvs[edge->uv2];
if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED))
- stitch_select_edge(edge, state, TRUE);
+ stitch_select_edge(edge, state, true);
}
/* unselect selected uvelements */
@@ -1477,8 +1479,8 @@ static void stitch_switch_selection_mode(StitchState *state)
UvElement *element1 = state->uvs[edge->uv1];
UvElement *element2 = state->uvs[edge->uv2];
- stitch_select_uv(element1, state, TRUE);
- stitch_select_uv(element2, state, TRUE);
+ stitch_select_uv(element1, state, true);
+ stitch_select_uv(element2, state, true);
edge->flag &= ~STITCH_SELECTED;
}
@@ -1878,7 +1880,7 @@ static int stitch_init(bContext *C, wmOperator *op)
edge = BLI_ghash_lookup(edge_hash, &tmp_edge);
- stitch_select_edge(edge, state, TRUE);
+ stitch_select_edge(edge, state, true);
}
RNA_END;
}
@@ -1914,11 +1916,11 @@ static int stitch_init(bContext *C, wmOperator *op)
if (!(ts->uv_flag & UV_SYNC_SELECTION) && ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT)))
continue;
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
UvEdge *edge = uv_edge_get(l, state);
if (edge) {
- stitch_select_edge(edge, state, TRUE);
+ stitch_select_edge(edge, state, true);
}
}
}
@@ -1942,7 +1944,7 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
state_delete(state);
return 0;
@@ -2064,7 +2066,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
/* This works due to setting of tmp in find nearest uv vert */
UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l);
- stitch_select_uv(element, state, FALSE);
+ stitch_select_uv(element, state, false);
}
}
@@ -2073,7 +2075,7 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
if (hit.efa) {
UvEdge *edge = uv_edge_get(hit.l, state);
- stitch_select_edge(edge, state, FALSE);
+ stitch_select_edge(edge, state, false);
}
}
}
@@ -2099,7 +2101,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
stitch_select(C, scene, event, state);
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2109,7 +2111,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
- if (stitch_process_data(state, scene, TRUE)) {
+ if (stitch_process_data(state, scene, true)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -2126,7 +2128,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case WHEELUPMOUSE:
if (event->val == KM_PRESS && event->alt) {
state->limit_dist += 0.01f;
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2141,7 +2143,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS && event->alt) {
state->limit_dist -= 0.01f;
state->limit_dist = MAX2(0.01f, state->limit_dist);
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2155,7 +2157,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LKEY:
if (event->val == KM_PRESS) {
state->use_limit = !state->use_limit;
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2168,7 +2170,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
state->static_island++;
state->static_island %= state->element_map->totalIslands;
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2179,7 +2181,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MKEY:
if (event->val == KM_PRESS) {
state->midpoints = !state->midpoints;
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2195,7 +2197,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
stitch_select(C, scene, event, state);
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2207,7 +2209,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case SKEY:
if (event->val == KM_PRESS) {
state->snap_islands = !state->snap_islands;
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2222,7 +2224,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
stitch_switch_selection_mode(state);
- if (!stitch_process_data(state, scene, FALSE)) {
+ if (!stitch_process_data(state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 75b124803ab..21e7bb00204 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -46,10 +46,8 @@
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
#include "BLI_uvproject.h"
#include "BLI_string.h"
-#include "BLI_scanfill.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_subsurf.h"
@@ -58,7 +56,6 @@
#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_editmesh.h"
@@ -91,9 +88,9 @@ static void modifier_unwrap_state(Object *obedit, Scene *scene, bool *r_use_subs
/* subsurf will take the modifier settings only if modifier is first or right after mirror */
if (subsurf) {
if (md && md->type == eModifierType_Subsurf)
- subsurf = TRUE;
+ subsurf = true;
else
- subsurf = FALSE;
+ subsurf = false;
}
*r_use_subsurf = subsurf;
@@ -195,8 +192,8 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
{
- int sloppy = TRUE;
- int selected = FALSE;
+ bool sloppy = true;
+ bool selected = false;
BMFace *efa;
Image *ima;
@@ -361,7 +358,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* Used to hold subsurfed Mesh */
DerivedMesh *derivedMesh, *initialDerived;
/* holds original indices for subsurfed mesh */
- int *origVertIndices, *origEdgeIndices, *origFaceIndices, *origPolyIndices;
+ const int *origVertIndices, *origEdgeIndices, *origFaceIndices, *origPolyIndices;
/* Holds vertices of subsurfed mesh */
MVert *subsurfedVerts;
MEdge *subsurfedEdges;
@@ -808,9 +805,9 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
}
if (use_subsurf)
- liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE);
+ liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true);
else
- liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE);
+ liveHandle = construct_param_handle(scene, obedit, em, false, fillholes, false, true);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
@@ -841,7 +838,7 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit)
if (scene->toolsettings->edge_mode_live_unwrap &&
CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV))
{
- ED_unwrap_lscm(scene, obedit, FALSE); /* unwrap all not just sel */
+ ED_unwrap_lscm(scene, obedit, false); /* unwrap all not just sel */
}
}
@@ -1139,7 +1136,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else
- handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect);
+ handle = construct_param_handle(scene, obedit, em, false, fill_holes, sel, correct_aspect);
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle);
@@ -1211,7 +1208,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap");
/* execute unwrap */
- ED_unwrap_lscm(scene, obedit, TRUE);
+ ED_unwrap_lscm(scene, obedit, true);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index 39267a6548c..c94a5ac9f92 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -38,8 +38,6 @@ set(SRC
intern/blender_interface/BlenderStrokeRenderer.cpp
intern/blender_interface/BlenderStrokeRenderer.h
intern/blender_interface/BlenderStyleModule.h
- intern/blender_interface/BlenderTextureManager.cpp
- intern/blender_interface/BlenderTextureManager.h
intern/blender_interface/FRS_freestyle.cpp
intern/geometry/BBox.h
intern/geometry/Bezier.cpp
@@ -185,6 +183,8 @@ set(SRC
intern/python/StrokeShader/BPy_BackboneStretcherShader.h
intern/python/StrokeShader/BPy_BezierCurveShader.cpp
intern/python/StrokeShader/BPy_BezierCurveShader.h
+ intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+ intern/python/StrokeShader/BPy_BlenderTextureShader.h
intern/python/StrokeShader/BPy_CalligraphicShader.cpp
intern/python/StrokeShader/BPy_CalligraphicShader.h
intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
@@ -213,6 +213,8 @@ set(SRC
intern/python/StrokeShader/BPy_SpatialNoiseShader.h
intern/python/StrokeShader/BPy_StrokeTextureShader.cpp
intern/python/StrokeShader/BPy_StrokeTextureShader.h
+ intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+ intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
intern/python/StrokeShader/BPy_TextureAssignerShader.cpp
intern/python/StrokeShader/BPy_TextureAssignerShader.h
intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
@@ -445,7 +447,9 @@ set(SRC
intern/stroke/Operators.h
intern/stroke/PSStrokeRenderer.cpp
intern/stroke/PSStrokeRenderer.h
+ intern/stroke/Predicates0D.cpp
intern/stroke/Predicates0D.h
+ intern/stroke/Predicates1D.cpp
intern/stroke/Predicates1D.h
intern/stroke/QInformationMap.h
intern/stroke/Stroke.cpp
@@ -460,6 +464,7 @@ set(SRC
intern/stroke/StrokeRenderer.h
intern/stroke/StrokeRep.cpp
intern/stroke/StrokeRep.h
+ intern/stroke/StrokeShader.cpp
intern/stroke/StrokeShader.h
intern/stroke/StrokeTesselator.cpp
intern/stroke/StrokeTesselator.h
@@ -509,7 +514,9 @@ set(SRC
intern/view_map/GridDensityProvider.h
intern/view_map/HeuristicGridDensityProviderFactory.cpp
intern/view_map/HeuristicGridDensityProviderFactory.h
+ intern/view_map/Interface0D.cpp
intern/view_map/Interface0D.h
+ intern/view_map/Interface1D.cpp
intern/view_map/Interface1D.h
intern/view_map/OccluderSource.cpp
intern/view_map/OccluderSource.h
diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp
index 967cb400241..cf7959ffaef 100644
--- a/source/blender/freestyle/intern/application/AppConfig.cpp
+++ b/source/blender/freestyle/intern/application/AppConfig.cpp
@@ -25,6 +25,7 @@
#include "AppConfig.h"
#include <iostream>
+#include "../system/FreestyleConfig.h"
#include "../system/StringUtils.h"
using namespace std;
diff --git a/source/blender/freestyle/intern/application/AppConfig.h b/source/blender/freestyle/intern/application/AppConfig.h
index 94ae0c3c348..ae1d96e06d8 100644
--- a/source/blender/freestyle/intern/application/AppConfig.h
+++ b/source/blender/freestyle/intern/application/AppConfig.h
@@ -30,7 +30,6 @@
#include <string>
#include <algorithm>
-#include "../system/FreestyleConfig.h"
#include "../system/Precision.h"
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/blender/freestyle/intern/application/AppView.h b/source/blender/freestyle/intern/application/AppView.h
index 3f6d0b8e93e..14101909ca1 100644
--- a/source/blender/freestyle/intern/application/AppView.h
+++ b/source/blender/freestyle/intern/application/AppView.h
@@ -31,6 +31,8 @@
#include "../scene_graph/NodeDrawingStyle.h"
#include "../system/Precision.h"
+#include "BLI_math.h"
+
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 81034c1502c..2bd31ea03a1 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -22,6 +22,10 @@
* \ingroup freestyle
*/
+extern "C" {
+#include <Python.h>
+}
+
#include <string>
#include <fstream>
#include <float.h>
@@ -62,6 +66,7 @@
#include "../blender_interface/BlenderStyleModule.h"
#include "BKE_global.h"
+#include "BLI_utildefines.h"
#include "DNA_freestyle_types.h"
@@ -190,14 +195,14 @@ void Controller::setRenderMonitor(RenderMonitor *iRenderMonitor)
void Controller::setPassDiffuse(float *buf, int width, int height)
{
AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
- assert(app_canvas != 0);
+ BLI_assert(app_canvas != 0);
app_canvas->setPassDiffuse(buf, width, height);
}
void Controller::setPassZ(float *buf, int width, int height)
{
AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
- assert(app_canvas != 0);
+ BLI_assert(app_canvas != 0);
app_canvas->setPassZ(buf, width, height);
}
@@ -850,6 +855,18 @@ Render *Controller::RenderStrokes(Render *re, bool render)
d = _Chrono.stop();
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Stroke rendering : " << d << endl;
+
+ uintptr_t mem_in_use = MEM_get_memory_in_use();
+ uintptr_t mmap_in_use = MEM_get_mapped_memory_in_use();
+ uintptr_t peak_memory = MEM_get_peak_memory();
+
+ float megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
+ float mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
+
+ printf("%d verts, %d faces, mem %.2fM (%.2fM, peak %.2fM)\n",
+ freestyle_render->i.totvert, freestyle_render->i.totface,
+ megs_used_memory, mmap_used_memory, megs_peak_memory);
}
delete blenderRenderer;
@@ -1024,7 +1041,6 @@ void Controller::init_options()
// Directories
ViewMapIO::Options::setModelsPath(cpath->getModelsPath());
- PythonInterpreter::Options::setPythonPath(cpath->getPythonPath());
TextureManager::Options::setPatternsPath(cpath->getPatternsPath());
TextureManager::Options::setBrushesPath(cpath->getModelsPath());
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index cd8ce14567e..a26bb0fa81e 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -573,7 +573,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
shape->setFrsMaterial(tmpMat);
}
else {
- // find if the material is aleady in the list
+ // find if the material is already in the list
unsigned int i = 0;
bool found = false;
@@ -761,7 +761,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
}
if (G.debug & G_DEBUG_FREESTYLE) {
printf("Warning: Object %s contains %lu degenerated triangle%s (strokes may be incorrect)\n",
- name, detriList.size(), (detriList.size() > 1) ? "s" : "");
+ name, (long unsigned int)detriList.size(), (detriList.size() > 1) ? "s" : "");
}
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index 17c0dd0c6db..d16a311991a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -74,7 +74,7 @@ struct LoaderState {
float maxBBox[3];
};
-class LIB_SCENE_GRAPH_EXPORT BlenderFileLoader
+class BlenderFileLoader
{
public:
/*! Builds a MaxFileLoader */
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index b25996031c0..6fff2feec95 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -23,18 +23,14 @@
*/
#include "BlenderStrokeRenderer.h"
-#include "BlenderTextureManager.h"
#include "../application/AppConfig.h"
#include "../stroke/Canvas.h"
-#include "BKE_global.h"
-
extern "C" {
#include "MEM_guardedalloc.h"
#include "DNA_camera_types.h"
-#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
@@ -51,19 +47,19 @@ extern "C" {
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BLI_utildefines.h"
+
#include "RE_pipeline.h"
}
+#include <limits.h>
+
namespace Freestyle {
BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
{
freestyle_bmain = &re->freestyle_bmain;
- // TEMPORARY - need a texture manager
- _textureManager = new BlenderTextureManager;
- _textureManager->load();
-
// for stroke mesh generation
_width = re->winx;
_height = re->winy;
@@ -135,24 +131,12 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
freestyle_scene->camera = object_camera;
- // Material
- material = BKE_material_add(freestyle_bmain, "stroke_material");
- material->mode |= MA_VERTEXCOLP;
- material->mode |= MA_TRANSP;
- material->mode |= MA_SHLESS;
- material->vcol_alpha = 1;
-
// Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
_mesh_id = 0xffffffff;
}
BlenderStrokeRenderer::~BlenderStrokeRenderer()
{
- if (0 != _textureManager) {
- delete _textureManager;
- _textureManager = NULL;
- }
-
// The freestyle_scene object is not released here. Instead,
// the scene is released in free_all_freestyle_renders() in
// source/blender/render/intern/source/pipeline.c, after the
@@ -184,8 +168,24 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
}
BLI_freelistN(&freestyle_scene->base);
- // release material
- BKE_libblock_free(freestyle_bmain, material);
+ // release materials
+ Link *lnk = (Link *)freestyle_bmain->mat.first;
+
+ while (lnk)
+ {
+ Material *ma = (Material*)lnk;
+ // We want to retain the linestyle mtexs, so let's detach them first
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a]) {
+ ma->mtex[a] = NULL;
+ }
+ else {
+ break; // Textures are ordered, no empty slots between two textures
+ }
+ }
+ lnk = lnk->next;
+ BKE_libblock_free(freestyle_bmain, ma);
+ }
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
@@ -208,132 +208,225 @@ unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
{
+ bool has_mat = false;
+ int a = 0;
+
+ // Look for a good existing material
+ for (Link *lnk = (Link *)freestyle_bmain->mat.first; lnk; lnk = lnk->next) {
+ Material *ma = (Material*) lnk;
+ bool texs_are_good = true;
+ // as soon as textures differ it's not the right one
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a] != iStrokeRep->getMTex(a)) {
+ texs_are_good = false;
+ break;
+ }
+ }
+
+ if (texs_are_good) {
+ iStrokeRep->setMaterial(ma);
+ has_mat = true;
+ break; // if textures are good, no need to search anymore
+ }
+ }
+
+ // If still no material, create one
+ if (!has_mat) {
+ Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
+
+ ma->mode |= MA_VERTEXCOLP;
+ ma->mode |= MA_TRANSP;
+ ma->mode |= MA_SHLESS;
+ ma->vcol_alpha = 1;
+
+ // Textures
+ //for (int a = 0; a < MAX_MTEX; a++) {
+ while (iStrokeRep->getMTex(a)) {
+ ma->mtex[a] = (MTex *) iStrokeRep->getMTex(a);
+
+ // We'll generate both with tips and without tips
+ // coordinates, on two different UV layers.
+ if (ma->mtex[a]->texflag & MTEX_TIPS) {
+ BLI_strncpy(ma->mtex[a]->uvname, "along_stroke_tips", sizeof(ma->mtex[a]->uvname));
+ }
+ else {
+ BLI_strncpy(ma->mtex[a]->uvname, "along_stroke", sizeof(ma->mtex[a]->uvname));
+ }
+ a++;
+ }
+ iStrokeRep->setMaterial(ma);
+ }
+
RenderStrokeRepBasic(iStrokeRep);
}
-void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
+// Check if the triangle is visible (i.e., within the render image boundary)
+bool BlenderStrokeRenderer::test_triangle_visibility(StrokeVertexRep *svRep[3]) const
{
- ////////////////////
- // Build up scene
- ////////////////////
+ int xl, xu, yl, yu;
+ Vec2r p;
+
+ xl = xu = yl = yu = 0;
+ for (int i = 0; i < 3; i++) {
+ p = svRep[i]->point2d();
+ if (p[0] < 0.0)
+ xl++;
+ else if (p[0] > _width)
+ xu++;
+ if (p[1] < 0.0)
+ yl++;
+ else if (p[1] > _height)
+ yu++;
+ }
+ return !(xl == 3 || xu == 3 || yl == 3 || yu == 3);
+}
+
+// Check the visibility of faces and strip segments.
+void BlenderStrokeRenderer::test_strip_visibility(Strip::vertex_container& strip_vertices,
+ int *visible_faces, int *visible_segments) const
+{
+ const int strip_vertex_count = strip_vertices.size();
+ Strip::vertex_container::iterator v[3];
+ StrokeVertexRep *svRep[3];
+ bool visible;
+
+ // iterate over all vertices and count visible faces and strip segments
+ // (note: a strip segment is a series of visible faces, while two strip
+ // segments are separated by one or more invisible faces)
+ v[0] = strip_vertices.begin();
+ v[1] = v[0] + 1;
+ v[2] = v[0] + 2;
+ *visible_faces = *visible_segments = 0;
+ visible = false;
+ for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
+ svRep[0] = *(v[0]);
+ svRep[1] = *(v[1]);
+ svRep[2] = *(v[2]);
+ if (test_triangle_visibility(svRep)) {
+ (*visible_faces)++;
+ if (!visible)
+ (*visible_segments)++;
+ visible = true;
+ }
+ else {
+ visible = false;
+ }
+ }
+}
+// Build a mesh object representing a stroke
+void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
+{
vector<Strip*>& strips = iStrokeRep->getStrips();
+ const bool hasTex = iStrokeRep->getMTex(0) != NULL;
Strip::vertex_container::iterator v[3];
StrokeVertexRep *svRep[3];
- /* Vec3r color[3]; */ /* UNUSED */
unsigned int vertex_index, edge_index, loop_index;
Vec2r p;
+ int totvert = 0, totedge = 0, totpoly = 0, totloop = 0;
+ int visible_faces, visible_segments;
+
+ bool visible;
for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
Strip::vertex_container& strip_vertices = (*s)->vertices();
- int strip_vertex_count = (*s)->sizeStrip();
- int xl, xu, yl, yu, n, visible_faces, visible_segments;
- bool visible;
- // iterate over all vertices and count visible faces and strip segments
- // (note: a strip segment is a series of visible faces, while two strip
- // segments are separated by one or more invisible faces)
- v[0] = strip_vertices.begin();
- v[1] = v[0] + 1;
- v[2] = v[0] + 2;
- visible_faces = visible_segments = 0;
- visible = false;
- for (n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
- svRep[0] = *(v[0]);
- svRep[1] = *(v[1]);
- svRep[2] = *(v[2]);
- xl = xu = yl = yu = 0;
- for (int j = 0; j < 3; j++) {
- p = svRep[j]->point2d();
- if (p[0] < 0.0)
- xl++;
- else if (p[0] > _width)
- xu++;
- if (p[1] < 0.0)
- yl++;
- else if (p[1] > _height)
- yu++;
- }
- if (xl == 3 || xu == 3 || yl == 3 || yu == 3) {
- visible = false;
- }
- else {
- visible_faces++;
- if (!visible)
- visible_segments++;
- visible = true;
- }
- }
+ // count visible faces and strip segments
+ test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
if (visible_faces == 0)
continue;
- //me = Mesh.New()
+ totvert += visible_faces + visible_segments * 2;
+ totedge += visible_faces * 2 + visible_segments;
+ totpoly += visible_faces;
+ totloop += visible_faces * 3;
+ }
+
#if 0
- Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, OB_MESH);
+ Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, OB_MESH);
#else
- Object *object_mesh = NewMesh();
+ Object *object_mesh = NewMesh();
#endif
- Mesh *mesh = (Mesh *)object_mesh->data;
- mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
- mesh->mat[0] = material;
- mesh->totcol = 1;
- test_object_materials(freestyle_bmain, (ID *)mesh);
+ Mesh *mesh = (Mesh *)object_mesh->data;
+ mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
+ mesh->mat[0] = iStrokeRep->getMaterial();
+ mesh->totcol = 1;
+ test_object_materials(freestyle_bmain, (ID *)mesh);
- // vertices allocation
- mesh->totvert = visible_faces + visible_segments * 2;
- mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+ // vertices allocation
+ mesh->totvert = totvert; // visible_faces + visible_segments * 2;
+ mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
- // edges allocation
- mesh->totedge = visible_faces * 2 + visible_segments;
- mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+ // edges allocation
+ mesh->totedge = totedge; // visible_faces * 2 + visible_segments;
+ mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
- // faces allocation
- mesh->totpoly = visible_faces;
- mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+ // faces allocation
+ mesh->totpoly = totpoly; // visible_faces;
+ mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
- // loops allocation
- mesh->totloop = visible_faces * 3;
- mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+ // loops allocation
+ mesh->totloop = totloop; // visible_faces * 3;
+ mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
- // colors allocation
- mesh->mloopcol = (MLoopCol *)CustomData_add_layer(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop);
+ // colors allocation
+ mesh->mloopcol = (MLoopCol *)CustomData_add_layer(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop);
- ////////////////////
- // Data copy
- ////////////////////
+ ////////////////////
+ // Data copy
+ ////////////////////
+
+ MVert *vertices = mesh->mvert;
+ MEdge *edges = mesh->medge;
+ MPoly *polys = mesh->mpoly;
+ MLoop *loops = mesh->mloop;
+ MLoopCol *colors = mesh->mloopcol;
+ MLoopUV *loopsuv[2] = {NULL};
+
+ if (hasTex) {
+ // First UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke");
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke");
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 0);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+
+ loopsuv[0] = mesh->mloopuv;
+
+ // Second UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke_tips");
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke_tips");
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 1);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+
+ loopsuv[1] = mesh->mloopuv;
+ }
+
+ vertex_index = edge_index = loop_index = 0;
+
+ for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
+ Strip::vertex_container& strip_vertices = (*s)->vertices();
+ int strip_vertex_count = strip_vertices.size();
- MVert *vertices = mesh->mvert;
- MEdge *edges = mesh->medge;
- MPoly *polys = mesh->mpoly;
- MLoop *loops = mesh->mloop;
- MLoopCol *colors = mesh->mloopcol;
+ // count visible faces and strip segments
+ test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
+ if (visible_faces == 0)
+ continue;
v[0] = strip_vertices.begin();
v[1] = v[0] + 1;
v[2] = v[0] + 2;
- vertex_index = edge_index = loop_index = 0;
visible = false;
// Note: Mesh generation in the following loop assumes stroke strips
// to be triangle strips.
- for (n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
+ for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
svRep[0] = *(v[0]);
svRep[1] = *(v[1]);
svRep[2] = *(v[2]);
- xl = xu = yl = yu = 0;
- for (int j = 0; j < 3; j++) {
- p = svRep[j]->point2d();
- if (p[0] < 0.0)
- xl++;
- else if (p[0] > _width)
- xu++;
- if (p[1] < 0.0)
- yl++;
- else if (p[1] > _height)
- yu++;
- }
- if (xl == 3 || xu == 3 || yl == 3 || yu == 3) {
+ if (!test_triangle_visibility(svRep)) {
visible = false;
}
else {
@@ -342,6 +435,9 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
vertices->co[0] = svRep[0]->point2d()[0];
vertices->co[1] = svRep[0]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
+ vertices->no[0] = 0;
+ vertices->no[1] = 0;
+ vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
@@ -349,6 +445,9 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
vertices->co[0] = svRep[1]->point2d()[0];
vertices->co[1] = svRep[1]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
+ vertices->no[0] = 0;
+ vertices->no[1] = 0;
+ vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
@@ -364,6 +463,9 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
vertices->co[0] = svRep[2]->point2d()[0];
vertices->co[1] = svRep[2]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
+ vertices->no[0] = 0;
+ vertices->no[1] = 0;
+ vertices->no[2] = SHRT_MAX;
++vertices;
++vertex_index;
@@ -383,48 +485,67 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
polys->totloop = 3;
++polys;
+ // Even and odd loops connect triangles vertices differently
+ bool is_odd = n % 2;
// loops
- if (n % 2 == 0) {
+ if (is_odd) {
loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 1;
+ loops[0].e = edge_index - 2;
- loops[1].v = vertex_index - 2;
+ loops[1].v = vertex_index - 3;
loops[1].e = edge_index - 3;
- loops[2].v = vertex_index - 3;
- loops[2].e = edge_index - 2;
+ loops[2].v = vertex_index - 2;
+ loops[2].e = edge_index - 1;
}
else {
loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 2;
+ loops[0].e = edge_index - 1;
- loops[1].v = vertex_index - 3;
+ loops[1].v = vertex_index - 2;
loops[1].e = edge_index - 3;
- loops[2].v = vertex_index - 2;
- loops[2].e = edge_index - 1;
+ loops[2].v = vertex_index - 3;
+ loops[2].e = edge_index - 2;
}
loops += 3;
loop_index += 3;
- // colors
- if (n % 2 == 0) {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[1]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[0]->alpha());
+ // UV
+ if (hasTex) {
+ // First UV layer (loopsuv[0]) has no tips (texCoord(0)).
+ // Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
+ for (int L = 0; L < 2; L++) {
+ if (is_odd) {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
+ }
+ else {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
+ }
+ /* freestyle tex-origin is upside-down */
+ for (int i = 0; i < 3; i++) {
+ loopsuv[L][i].uv[1] *= -1;
+ }
+ loopsuv[L] += 3;
+ }
}
- else {
+
+ // colors
+ if (is_odd) {
colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
@@ -439,14 +560,33 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
colors[2].a = (short)(255.0f * svRep[1]->alpha());
+ }
+ else {
+ colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
+ colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
+ colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
+ colors[0].a = (short)(255.0f * svRep[2]->alpha());
+
+ colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
+ colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
+ colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
+ colors[1].a = (short)(255.0f * svRep[1]->alpha());
+
+ colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
+ colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
+ colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
+ colors[2].a = (short)(255.0f * svRep[0]->alpha());
}
colors += 3;
}
} // loop over strip vertices
+ } // loop over strips
#if 0
- BKE_mesh_validate(mesh, TRUE);
+ BLI_assert(totvert == vertex_index);
+ BLI_assert(totedge == edge_index);
+ BLI_assert(totloop == loop_index);
+ BKE_mesh_validate(mesh, true);
#endif
- } // loop over strips
}
// A replacement of BKE_object_add() for better performance.
@@ -457,11 +597,9 @@ Object *BlenderStrokeRenderer::NewMesh() const
char name[MAX_ID_NAME];
unsigned int mesh_id = get_stroke_mesh_id();
- /* XXX this is for later review, for now we start names with 27 (DEL)
- to allow ignoring them in DAG_ids_check_recalc() */
- BLI_snprintf(name, MAX_ID_NAME, "%c0%08xOB", 27, mesh_id);
+ BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
ob = BKE_object_add_only_object(freestyle_bmain, OB_MESH, name);
- BLI_snprintf(name, MAX_ID_NAME, "%c0%08xME", 27, mesh_id);
+ BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
ob->data = BKE_mesh_add(freestyle_bmain, name);
ob->lay = 1;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
index 96ce8c1be7e..0025d48e77f 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
@@ -39,7 +39,7 @@ extern "C" {
namespace Freestyle {
-class LIB_STROKE_EXPORT BlenderStrokeRenderer : public StrokeRenderer
+class BlenderStrokeRenderer : public StrokeRenderer
{
public:
BlenderStrokeRenderer(Render *re, int render_count);
@@ -57,13 +57,15 @@ protected:
Main *freestyle_bmain;
Scene *old_scene;
Scene *freestyle_scene;
- Material *material;
float _width, _height;
float _z, _z_delta;
unsigned int _mesh_id;
float get_stroke_vertex_z(void) const;
unsigned int get_stroke_mesh_id(void) const;
+ bool test_triangle_visibility(StrokeVertexRep *svRep[3]) const;
+ void test_strip_visibility(Strip::vertex_container& strip_vertices,
+ int *visible_faces, int *visible_segments) const;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStrokeRenderer")
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
index 8a16a2b5c2a..a1fb9fade58 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
@@ -32,6 +32,7 @@ extern "C" {
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_text.h"
+#include "BLI_utildefines.h"
}
namespace Freestyle {
@@ -52,7 +53,7 @@ protected:
virtual int interpret()
{
PythonInterpreter *py_inter = dynamic_cast<PythonInterpreter*>(_inter);
- assert(py_inter != 0);
+ BLI_assert(py_inter != 0);
return py_inter->interpretText(_text, getFileName());
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp
deleted file mode 100644
index e58a219aede..00000000000
--- a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp
+++ /dev/null
@@ -1,101 +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.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp
- * \ingroup freestyle
- */
-
-#include "BlenderTextureManager.h"
-
-#include "BKE_global.h"
-
-namespace Freestyle {
-
-BlenderTextureManager::BlenderTextureManager()
-: TextureManager()
-{
- //_brushes_path = Config::getInstance()...
-}
-
-BlenderTextureManager::~BlenderTextureManager()
-{
-}
-
-void BlenderTextureManager::loadStandardBrushes()
-{
-#if 0
- getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM);
- _defaultTextureId = getBrushTextureIndex("smoothAlpha.bmp", Stroke::OPAQUE_MEDIUM);
-#endif
-}
-
-unsigned int BlenderTextureManager::loadBrush(string sname, Stroke::MediumType mediumType)
-{
-#if 0
- GLuint texId;
- glGenTextures(1, &texId);
- bool found = false;
- vector<string> pathnames;
- string path; //soc
- StringUtils::getPathName(TextureManager::Options::getBrushesPath(), sname, pathnames);
- for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) {
- path = j->c_str();
- //soc if (QFile::exists(path)) {
- if (BLI_exists( const_cast<char *>(path.c_str()))) {
- found = true;
- break;
- }
- }
- if (!found)
- return 0;
- // Brush texture
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Loading brush texture..." << endl;
- }
- switch (mediumType) {
- case Stroke::DRY_MEDIUM:
- //soc prepareTextureLuminance((const char*)path.toAscii(), texId);
- prepareTextureLuminance(path, texId);
- break;
- case Stroke::HUMID_MEDIUM:
- case Stroke::OPAQUE_MEDIUM:
- default:
- //soc prepareTextureAlpha((const char*)path.toAscii(), texId);
- prepareTextureAlpha(path, texId);
- break;
- }
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Done." << endl << endl;
- }
-
- return texId;
-#else
- return 0;
-#endif
-}
-
-} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index b592c1152b1..49c3fdce251 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -711,15 +711,7 @@ void FRS_delete_active_lineset(FreestyleConfig *config)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(config);
if (lineset) {
- if (lineset->group) {
- lineset->group->id.us--;
- }
- if (lineset->linestyle) {
- lineset->linestyle->id.us--;
- }
- BLI_remlink(&config->linesets, lineset);
- MEM_freeN(lineset);
- BKE_freestyle_lineset_set_active_index(config, 0);
+ BKE_freestyle_lineset_delete(config, lineset);
}
}
diff --git a/source/blender/freestyle/intern/geometry/Bezier.h b/source/blender/freestyle/intern/geometry/Bezier.h
index 34af31d0ba8..ed26803c2a2 100644
--- a/source/blender/freestyle/intern/geometry/Bezier.h
+++ b/source/blender/freestyle/intern/geometry/Bezier.h
@@ -42,7 +42,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_GEOMETRY_EXPORT BezierCurveSegment
+class BezierCurveSegment
{
private:
std::vector<Vec2d> _ControlPolygon;
@@ -70,7 +70,7 @@ public:
#endif
};
-class LIB_GEOMETRY_EXPORT BezierCurve
+class BezierCurve
{
private:
std::vector<Vec2d> _ControlPolygon;
diff --git a/source/blender/freestyle/intern/geometry/FastGrid.cpp b/source/blender/freestyle/intern/geometry/FastGrid.cpp
index 438cac3c209..2ce424483ea 100644
--- a/source/blender/freestyle/intern/geometry/FastGrid.cpp
+++ b/source/blender/freestyle/intern/geometry/FastGrid.cpp
@@ -25,9 +25,12 @@
* \date 30/07/2002
*/
+#include <cstdlib>
+
#include "FastGrid.h"
#include "BKE_global.h"
+#include "BLI_utildefines.h"
namespace Freestyle {
@@ -63,21 +66,21 @@ Cell *FastGrid::getCell(const Vec3u& p)
<< " " << _cells_size << endl;
}
#endif
- assert(_cells || ("_cells is a null pointer"));
- assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]) < _cells_size);
- assert(p[0] < _cells_nb[0]);
- assert(p[1] < _cells_nb[1]);
- assert(p[2] < _cells_nb[2]);
+ BLI_assert(_cells || ("_cells is a null pointer"));
+ BLI_assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]) < _cells_size);
+ BLI_assert(p[0] < _cells_nb[0]);
+ BLI_assert(p[1] < _cells_nb[1]);
+ BLI_assert(p[2] < _cells_nb[2]);
return _cells[_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]];
}
void FastGrid::fillCell(const Vec3u& p, Cell& cell)
{
- assert(_cells || ("_cells is a null pointer"));
- assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]) < _cells_size);
- assert(p[0] < _cells_nb[0]);
- assert(p[1] < _cells_nb[1]);
- assert(p[2] < _cells_nb[2]);
+ BLI_assert(_cells || ("_cells is a null pointer"));
+ BLI_assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]) < _cells_size);
+ BLI_assert(p[0] < _cells_nb[0]);
+ BLI_assert(p[1] < _cells_nb[1]);
+ BLI_assert(p[2] < _cells_nb[2]);
_cells[_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]] = &cell;
}
diff --git a/source/blender/freestyle/intern/geometry/FastGrid.h b/source/blender/freestyle/intern/geometry/FastGrid.h
index e292589b7cf..355a6e53399 100644
--- a/source/blender/freestyle/intern/geometry/FastGrid.h
+++ b/source/blender/freestyle/intern/geometry/FastGrid.h
@@ -28,8 +28,6 @@
* \date 30/07/2002
*/
-#include <cassert>
-
#include "Grid.h"
namespace Freestyle {
@@ -38,7 +36,7 @@ namespace Freestyle {
* We don't use a hashtable here. The grid is explicitly stored for faster computations.
* However, this might result in significant increase in memory usage (compared to the regular grid)
*/
-class LIB_GEOMETRY_EXPORT FastGrid : public Grid
+class FastGrid : public Grid
{
public:
FastGrid() : Grid()
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index e517bf4f196..fbfa5b331e6 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -557,17 +557,20 @@ void FitCurveWrapper::FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, V
if (maxError < iterationError) {
for (i = 0; i < maxIterations; i++) {
uPrime = Reparameterize(d, first, last, u, bezCurve);
- bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2);
- maxError = ComputeMaxError(d, first, last,
- bezCurve, uPrime, &splitPoint);
+
+ free((void *)u);
+ free((void *)bezCurve);
+ u = uPrime;
+
+ bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);
+ maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
+
if (maxError < error) {
DrawBezierCurve(3, bezCurve);
free((void *)u);
free((void *)bezCurve);
return;
}
- free((void *)u);
- u = uPrime;
}
}
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.h b/source/blender/freestyle/intern/geometry/FitCurve.h
index 809ef875c0a..2268f6be1b7 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.h
+++ b/source/blender/freestyle/intern/geometry/FitCurve.h
@@ -74,7 +74,7 @@ typedef struct Point2Struct
typedef Point2 Vector2;
-class LIB_GEOMETRY_EXPORT FitCurveWrapper
+class FitCurveWrapper
{
private:
std::vector<Vector2> _vertices;
diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.h b/source/blender/freestyle/intern/geometry/GeomCleaner.h
index 0b97614f6ea..d516c5623b9 100644
--- a/source/blender/freestyle/intern/geometry/GeomCleaner.h
+++ b/source/blender/freestyle/intern/geometry/GeomCleaner.h
@@ -40,7 +40,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_GEOMETRY_EXPORT GeomCleaner
+class GeomCleaner
{
public:
inline GeomCleaner() {}
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index abe13b85cd2..a750cf2f7cf 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -577,10 +577,10 @@ void transformVertex(const Vec3r& vert, const Matrix44r& matrix, Vec3r& res)
void transformVertices(const vector<Vec3r>& vertices, const Matrix44r& trans, vector<Vec3r>& res)
{
- for (vector<Vec3r>::const_iterator v = vertices.begin(); v != vertices.end(); v++) {
- Vec3r *res_tmp = new Vec3r;
- transformVertex(*v, trans, *res_tmp);
- res.push_back(*res_tmp);
+ size_t i;
+ res.resize(vertices.size());
+ for (i = 0; i < vertices.size(); i++) {
+ transformVertex(vertices[i], trans, res[i]);
}
}
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.h b/source/blender/freestyle/intern/geometry/GeomUtils.h
index dbb7a5d4e75..64aa6379e80 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.h
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.h
@@ -83,17 +83,14 @@ typedef enum {
COINCIDENT,
} intersection_test;
-LIB_GEOMETRY_EXPORT
intersection_test intersect2dSeg2dSeg(const Vec2r& p1, const Vec2r& p2, // first segment
const Vec2r& p3, const Vec2r& p4, // second segment
Vec2r& res); // found intersection point
-LIB_GEOMETRY_EXPORT
intersection_test intersect2dLine2dLine(const Vec2r& p1, const Vec2r& p2, // first segment
const Vec2r& p3, const Vec2r& p4, // second segment
Vec2r& res); // found intersection point
-LIB_GEOMETRY_EXPORT
intersection_test intersect2dSeg2dSegParametric(const Vec2r& p1, const Vec2r& p2, // first segment
const Vec2r& p3, const Vec2r& p4, // second segment
real& t, // I = P1 + t * P1P2)
@@ -101,26 +98,21 @@ intersection_test intersect2dSeg2dSegParametric(const Vec2r& p1, const Vec2r& p2
real epsilon = M_EPSILON);
/*! check whether a 2D segment intersect a 2D region or not */
-LIB_GEOMETRY_EXPORT
bool intersect2dSeg2dArea(const Vec2r& min, const Vec2r& max, const Vec2r& A, const Vec2r& B);
/*! check whether a 2D segment is included in a 2D region or not */
-LIB_GEOMETRY_EXPORT
bool include2dSeg2dArea(const Vec2r& min, const Vec2r& max, const Vec2r& A, const Vec2r& B);
/*! Box-triangle overlap test, adapted from Tomas Akenine-Möller code */
-LIB_GEOMETRY_EXPORT
bool overlapTriangleBox(Vec3r& boxcenter, Vec3r& boxhalfsize, Vec3r triverts[3]);
/*! Fast, Minimum Storage Ray-Triangle Intersection, adapted from Tomas Möller and Ben Trumbore code. */
-LIB_GEOMETRY_EXPORT
bool intersectRayTriangle(const Vec3r& orig, const Vec3r& dir, const Vec3r& v0, const Vec3r& v1, const Vec3r& v2,
real& t, // I = orig + t * dir
real& u, real& v, // I = (1 - u - v) * v0 + u * v1 + v * v2
const real epsilon = M_EPSILON); // the epsilon to use
/*! Intersection between plane and ray adapted from Graphics Gems, Didier Badouel */
-LIB_GEOMETRY_EXPORT
intersection_test intersectRayPlane(const Vec3r& orig, const Vec3r& dir, // ray origin and direction
// plane's normal and offset (plane = { P / P.N + d = 0 })
const Vec3r& norm, const real d,
@@ -130,7 +122,6 @@ intersection_test intersectRayPlane(const Vec3r& orig, const Vec3r& dir, // ray
/*! Intersection Ray-Bounding box (axis aligned).
* Adapted from Williams et al, "An Efficient Robust Ray-Box Intersection Algorithm", JGT 10:1 (2005), pp. 49-54.
*/
-LIB_GEOMETRY_EXPORT
bool intersectRayBBox(const Vec3r& orig, const Vec3r& dir, // ray origin and direction
const Vec3r& boxMin, const Vec3r& boxMax, // the bbox
// the interval in which at least on of the intersections must happen
@@ -140,16 +131,12 @@ bool intersectRayBBox(const Vec3r& orig, const Vec3r& dir, // ray origin an
real epsilon = M_EPSILON); // the epsilon to use
/*! Checks whether 3D point P lies inside or outside of the triangle ABC */
-LIB_GEOMETRY_EXPORT
bool includePointTriangle(const Vec3r& P, const Vec3r& A, const Vec3r& B, const Vec3r& C);
-LIB_GEOMETRY_EXPORT
void transformVertex(const Vec3r& vert, const Matrix44r& matrix, Vec3r& res);
-LIB_GEOMETRY_EXPORT
void transformVertices(const vector<Vec3r>& vertices, const Matrix44r& trans, vector<Vec3r>& res);
-LIB_GEOMETRY_EXPORT
Vec3r rotateVector(const Matrix44r& mat, const Vec3r& v);
//
@@ -171,7 +158,6 @@ Vec3r rotateVector(const Matrix44r& mat, const Vec3r& v);
* viewport
* The viewport: x,y coordinates followed by width and height (OpenGL like viewport)
*/
-LIB_GEOMETRY_EXPORT
void fromWorldToImage(const Vec3r& p, Vec3r& q, const real model_view_matrix[4][4], const real projection_matrix[4][4],
const int viewport[4]);
@@ -186,7 +172,6 @@ void fromWorldToImage(const Vec3r& p, Vec3r& q, const real model_view_matrix[4][
* viewport
* The viewport: x,y coordinates followed by width and height (OpenGL like viewport)
*/
-LIB_GEOMETRY_EXPORT
void fromWorldToImage(const Vec3r& p, Vec3r& q, const real transform[4][4], const int viewport[4]);
/*! Projects from world coordinates to camera coordinates
@@ -200,7 +185,6 @@ void fromWorldToImage(const Vec3r& p, Vec3r& q, const real transform[4][4], cons
* The model view matrix expressed in line major order (OpenGL
* matrices are column major ordered)
*/
-LIB_GEOMETRY_EXPORT
void fromWorldToCamera(const Vec3r& p, Vec3r& q, const real model_view_matrix[4][4]);
/*! Projects from World Coordinates to retina coordinates
@@ -213,7 +197,6 @@ void fromWorldToCamera(const Vec3r& p, Vec3r& q, const real model_view_matrix[4]
* The projection matrix expressed in line major order (OpenGL
* matrices are column major ordered)
*/
-LIB_GEOMETRY_EXPORT
void fromCameraToRetina(const Vec3r& p, Vec3r& q, const real projection_matrix[4][4]);
/*! From retina to image.
@@ -225,7 +208,6 @@ void fromCameraToRetina(const Vec3r& p, Vec3r& q, const real projection_matrix[4
* viewport
* The viewport: x,y coordinates followed by width and height (OpenGL like viewport).
*/
-LIB_GEOMETRY_EXPORT
void fromRetinaToImage(const Vec3r& p, Vec3r& q, const int viewport[4]);
/*! From image to retina
@@ -236,7 +218,6 @@ void fromRetinaToImage(const Vec3r& p, Vec3r& q, const int viewport[4]);
* viewport
* The viewport: x,y coordinates followed by width and height (OpenGL like viewport).
*/
-LIB_GEOMETRY_EXPORT
void fromImageToRetina(const Vec3r& p, Vec3r& q, const int viewport[4]);
/*! computes the coordinates of q in the camera coordinates system,
@@ -251,7 +232,6 @@ void fromImageToRetina(const Vec3r& p, Vec3r& q, const int viewport[4]);
* The projection matrix expressed in line major order (OpenGL
* matrices are column major ordered)
*/
-LIB_GEOMETRY_EXPORT
void fromRetinaToCamera(const Vec3r& p, Vec3r& q, real z, const real projection_matrix[4][4]);
/*! Projects from camera coordinates to world coordinates
@@ -265,7 +245,6 @@ void fromRetinaToCamera(const Vec3r& p, Vec3r& q, real z, const real projection_
* The model view matrix expressed in line major order (OpenGL
* matrices are column major ordered)
*/
-LIB_GEOMETRY_EXPORT
void fromCameraToWorld(const Vec3r& p, Vec3r& q, const real model_view_matrix[4][4]);
} // end of namespace GeomUtils
diff --git a/source/blender/freestyle/intern/geometry/Grid.cpp b/source/blender/freestyle/intern/geometry/Grid.cpp
index 49e115b4333..371c63318de 100644
--- a/source/blender/freestyle/intern/geometry/Grid.cpp
+++ b/source/blender/freestyle/intern/geometry/Grid.cpp
@@ -25,12 +25,13 @@
* \date 30/07/2002
*/
-#include <cassert>
#include <stdexcept>
#include "BBox.h"
#include "Grid.h"
+#include "BLI_utildefines.h"
+
namespace Freestyle {
// Grid Visitors
@@ -366,7 +367,7 @@ bool Grid::initInfiniteRay (const Vec3r &orig, const Vec3r& dir, unsigned timest
// is the ray intersecting the box?
real tmin(-1.0), tmax(-1.0);
if (GeomUtils::intersectRayBBox(orig, _ray_dir, boxMin, boxMax, 0, _t_end, tmin, tmax)) {
- assert(tmin != -1.0);
+ BLI_assert(tmin != -1.0);
Vec3r newOrig = orig + tmin * _ray_dir;
for (unsigned int i = 0; i < 3; i++) {
_current_cell[i] = (unsigned)floor((newOrig[i] - _orig[i]) / _cell_size[i]);
diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h
index 070bee047a9..c0cab2a05db 100644
--- a/source/blender/freestyle/intern/geometry/Grid.h
+++ b/source/blender/freestyle/intern/geometry/Grid.h
@@ -30,7 +30,7 @@
#include <cstring> // for memset
#include <float.h>
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
#include <stdint.h> // For SET_UINT_IN_POINTER, i.e. uintptr_t.
#endif
#include <vector>
@@ -62,7 +62,7 @@ typedef vector<Polygon3r*> OccludersSet;
//
///////////////////////////////////////////////////////////////////////////////
-class LIB_GEOMETRY_EXPORT Cell
+class Cell
{
public:
Cell(Vec3r& orig) {
@@ -175,7 +175,7 @@ public:
//
///////////////////////////////////////////////////////////////////////////////
-class LIB_GEOMETRY_EXPORT Grid
+class Grid
{
public:
/*! Builds a Grid. Must be followed by a call to configure() */
diff --git a/source/blender/freestyle/intern/geometry/GridHelpers.cpp b/source/blender/freestyle/intern/geometry/GridHelpers.cpp
index 2b809608edf..a0543e56a36 100644
--- a/source/blender/freestyle/intern/geometry/GridHelpers.cpp
+++ b/source/blender/freestyle/intern/geometry/GridHelpers.cpp
@@ -25,8 +25,6 @@
* \date 2010-12-21
*/
-#include <math.h>
-
#include "GridHelpers.h"
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/geometry/HashGrid.h b/source/blender/freestyle/intern/geometry/HashGrid.h
index 7013a969eb5..4ea7c7146a4 100644
--- a/source/blender/freestyle/intern/geometry/HashGrid.h
+++ b/source/blender/freestyle/intern/geometry/HashGrid.h
@@ -60,7 +60,7 @@ struct GridHasher
};
/*! Class to define a regular grid used for ray casting computations */
-class LIB_GEOMETRY_EXPORT HashGrid : public Grid
+class HashGrid : public Grid
{
public:
typedef map<Vec3u, Cell*> GridHashTable;
diff --git a/source/blender/freestyle/intern/geometry/Noise.h b/source/blender/freestyle/intern/geometry/Noise.h
index 8798bc45a93..88994fac0d1 100644
--- a/source/blender/freestyle/intern/geometry/Noise.h
+++ b/source/blender/freestyle/intern/geometry/Noise.h
@@ -45,7 +45,7 @@ namespace Freestyle {
using namespace Geometry;
/*! Class to provide Perlin Noise functionalities */
-class LIB_GEOMETRY_EXPORT Noise
+class Noise
{
public:
/*! Builds a Noise object */
diff --git a/source/blender/freestyle/intern/geometry/VecMat.h b/source/blender/freestyle/intern/geometry/VecMat.h
index c3aae0601fe..3c3d40875d0 100644
--- a/source/blender/freestyle/intern/geometry/VecMat.h
+++ b/source/blender/freestyle/intern/geometry/VecMat.h
@@ -704,7 +704,8 @@ public:
for (unsigned int j = 0; j < N; j++)
res(j, i) = this->_coord[i * N + j];
}
- return res;
+ *this = res;
+ return *this;
}
template <class U>
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.cpp b/source/blender/freestyle/intern/geometry/matrix_util.cpp
index 7905dda5843..5e585497516 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.cpp
+++ b/source/blender/freestyle/intern/geometry/matrix_util.cpp
@@ -36,10 +36,10 @@
* \author Bruno Levy
*/
-#include <math.h>
-
#include "matrix_util.h"
+#include "BLI_math.h"
+
namespace Freestyle {
namespace OGF {
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h
index 162e2f85d3c..d65b0ea803b 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.h
+++ b/source/blender/freestyle/intern/geometry/matrix_util.h
@@ -61,7 +61,6 @@ namespace MatrixUtil {
* @param eigen_values (return) are in decreasing order
* size = n, must be allocated by caller
*/
- LIB_GEOMETRY_EXPORT
void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec, double *eigen_val);
} // MatrixUtil namespace
diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h
index 7a63acdf52a..53bc23c6eb3 100644
--- a/source/blender/freestyle/intern/geometry/normal_cycle.h
+++ b/source/blender/freestyle/intern/geometry/normal_cycle.h
@@ -70,7 +70,7 @@ template <class T> inline void ogf_swap(T& x, T& y)
* D. Cohen-Steiner and J.M. Morvan,
* SOCG 2003
*/
-class LIB_GEOMETRY_EXPORT NormalCycle {
+class NormalCycle {
public:
NormalCycle();
void begin();
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h
index d3175e86382..7abd1bc18bc 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.h
+++ b/source/blender/freestyle/intern/image/GaussianFilter.h
@@ -43,7 +43,7 @@ extern "C" {
namespace Freestyle {
-class LIB_IMAGE_EXPORT GaussianFilter
+class GaussianFilter
{
protected:
/* The mask is a symetrical 2d array (with respect to the middle point).
diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h
index 5ce937ed9f8..9a24ac6e1c8 100644
--- a/source/blender/freestyle/intern/image/ImagePyramid.h
+++ b/source/blender/freestyle/intern/image/ImagePyramid.h
@@ -40,7 +40,7 @@ namespace Freestyle {
class GrayImage;
-class LIB_IMAGE_EXPORT ImagePyramid
+class ImagePyramid
{
protected:
std::vector<GrayImage*> _levels;
@@ -88,7 +88,7 @@ public:
#endif
};
-class LIB_IMAGE_EXPORT GaussianPyramid : public ImagePyramid
+class GaussianPyramid : public ImagePyramid
{
protected:
float _sigma;
diff --git a/source/blender/freestyle/intern/python/BPy_BBox.h b/source/blender/freestyle/intern/python/BPy_BBox.h
index 6f8a3d21c50..089c2167c69 100644
--- a/source/blender/freestyle/intern/python/BPy_BBox.h
+++ b/source/blender/freestyle/intern/python/BPy_BBox.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_BBOX_H__
#define __FREESTYLE_PYTHON_BBOX_H__
+extern "C" {
#include <Python.h>
+}
#include "../geometry/BBox.h"
#include "../geometry/Geom.h"
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
index 9622ca1eb98..a9a22970e4b 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_BINARYPREDICATE0D_H__
#define __FREESTYLE_PYTHON_BINARYPREDICATE0D_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Predicates0D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
index 07a3d2986ce..43511edc09c 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_BINARYPREDICATE1D_H__
#define __FREESTYLE_PYTHON_BINARYPREDICATE1D_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Predicates1D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.h b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
index 16e63be02f4..40652777c44 100644
--- a/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
+++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H__
#define __FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H__
+extern "C" {
#include <Python.h>
+}
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h
index 45fc05a0921..cf55ba335cd 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.h
+++ b/source/blender/freestyle/intern/python/BPy_Convert.h
@@ -25,7 +25,10 @@
#ifndef __FREESTYLE_PYTHON_CONVERT_H__
#define __FREESTYLE_PYTHON_CONVERT_H__
+extern "C" {
#include <Python.h>
+}
+
#include <typeinfo>
#include "../geometry/Geom.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index dee058e6844..f390e937aac 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -301,6 +301,7 @@ static char module_docstring[] =
"\n"
" - :class:`BackboneStretcherShader`\n"
" - :class:`BezierCurveShader`\n"
+" - :class:`BlenderTextureShader`\n"
" - :class:`CalligraphicShader`\n"
" - :class:`ColorNoiseShader`\n"
" - :class:`ColorVariationPatternShader`\n"
@@ -315,6 +316,7 @@ static char module_docstring[] =
" - :class:`SmoothingShader`\n"
" - :class:`SpatialNoiseShader`\n"
" - :class:`StrokeTextureShader`\n"
+" - :class:`StrokeTextureStepShader`\n"
" - :class:`TextureAssignerShader`\n"
" - :class:`ThicknessNoiseShader`\n"
" - :class:`ThicknessVariationPatternShader`\n"
@@ -485,6 +487,23 @@ PyObject *Freestyle_Init(void)
if (!module)
return NULL;
PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module);
+
+ // update 'sys.path' for Freestyle Python API modules
+ const char * const path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "freestyle");
+ if (path) {
+ char modpath[FILE_MAX];
+ BLI_join_dirfile(modpath, sizeof(modpath), path, "modules");
+ PyObject *sys_path = PySys_GetObject("path"); /* borrow */
+ PyObject *py_modpath = PyUnicode_FromString(modpath);
+ PyList_Append(sys_path, py_modpath);
+ Py_DECREF(py_modpath);
+#if 0
+ printf("Adding Python path: %s\n", modpath);
+#endif
+ }
+ else {
+ printf("Freestyle: couldn't find 'scripts/freestyle/modules', Freestyle won't work properly.\n");
+ }
// attach its classes (adding the object types to the module)
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.h b/source/blender/freestyle/intern/python/BPy_Freestyle.h
index c253a8181dd..0ed2e00d183 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.h
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.h
@@ -25,12 +25,12 @@
#ifndef __FREESTYLE_PYTHON_FREESTYLE_H__
#define __FREESTYLE_PYTHON_FREESTYLE_H__
-#include <Python.h>
-
#ifdef __cplusplus
extern "C" {
#endif
+#include <Python.h>
+
///////////////////////////////////////////////////////////////////////////////////////////
/*---------------------------Python BPy_Freestyle visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
index 62a9f2c9a78..7cbf5351745 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_FRSMATERIAL_H__
#define __FREESTYLE_PYTHON_FRSMATERIAL_H__
+extern "C" {
#include <Python.h>
+}
#include "../scene_graph/FrsMaterial.h"
diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.h b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
index 14d8696d0cb..19788e30a43 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsNoise.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_FRSNOISE_H__
#define __FREESTYLE_PYTHON_FRSNOISE_H__
+extern "C" {
#include <Python.h>
+}
#include "../geometry/Noise.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp
index 8cf20401dd0..7ef56f6baee 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Id.cpp
@@ -105,22 +105,16 @@ static PyObject *Id_RichCompare(BPy_Id *o1, BPy_Id *o2, int opid)
switch (opid) {
case Py_LT:
return PyBool_from_bool(o1->id->operator<(*(o2->id)));
- break;
case Py_LE:
return PyBool_from_bool(o1->id->operator<(*(o2->id)) || o1->id->operator==(*(o2->id)));
- break;
case Py_EQ:
return PyBool_from_bool(o1->id->operator==(*(o2->id)));
- break;
case Py_NE:
return PyBool_from_bool(o1->id->operator!=(*(o2->id)));
- break;
case Py_GT:
return PyBool_from_bool(!(o1->id->operator<(*(o2->id)) || o1->id->operator==(*(o2->id))));
- break;
case Py_GE:
return PyBool_from_bool(!(o1->id->operator<(*(o2->id))));
- break;
}
Py_RETURN_NONE;
}
diff --git a/source/blender/freestyle/intern/python/BPy_Id.h b/source/blender/freestyle/intern/python/BPy_Id.h
index d4b635a4ea5..62e480628e3 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.h
+++ b/source/blender/freestyle/intern/python/BPy_Id.h
@@ -25,7 +25,10 @@
#ifndef __FREESTYLE_PYTHON_ID_H__
#define __FREESTYLE_PYTHON_ID_H__
+extern "C" {
#include <Python.h>
+}
+
#include <iostream>
using namespace std;
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.h b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
index 36b925f1ee7..feabe307d56 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.h
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_INTEGRATIONTYPE_H__
#define __FREESTYLE_PYTHON_INTEGRATIONTYPE_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Interface1D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.h b/source/blender/freestyle/intern/python/BPy_Interface0D.h
index 02929bcdbc7..b8a4a6b21bd 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_INTERFACE0D_H__
#define __FREESTYLE_PYTHON_INTERFACE0D_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Interface0D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.h b/source/blender/freestyle/intern/python/BPy_Interface1D.h
index 9bc447725e9..17c0752b2e8 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface1D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface1D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_INTERFACE1D_H__
#define __FREESTYLE_PYTHON_INTERFACE1D_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Interface1D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.h b/source/blender/freestyle/intern/python/BPy_Iterator.h
index a739787aa85..dcb8191948e 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.h
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_ITERATOR_H__
#define __FREESTYLE_PYTHON_ITERATOR_H__
+extern "C" {
#include <Python.h>
+}
#include "../system/Iterator.h"
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.h b/source/blender/freestyle/intern/python/BPy_MediumType.h
index 120829e0b40..d99fb537bb3 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.h
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_MEDIUMTYPE_H__
#define __FREESTYLE_PYTHON_MEDIUMTYPE_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Stroke.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp
index da09de99590..deedbb93981 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp
@@ -35,7 +35,6 @@ extern "C" {
static PyObject *BPy_Nature_and(PyObject *a, PyObject *b);
static PyObject *BPy_Nature_xor(PyObject *a, PyObject *b);
static PyObject *BPy_Nature_or(PyObject *a, PyObject *b);
-static int BPy_Nature_bool(PyObject *v);
/*-----------------------BPy_Nature number method definitions --------------------*/
@@ -49,7 +48,7 @@ static PyNumberMethods nature_as_number = {
0, /* unaryfunc nb_negative */
0, /* unaryfunc nb_positive */
0, /* unaryfunc nb_absolute */
- (inquiry)BPy_Nature_bool, /* inquiry nb_bool */
+ 0, /* inquiry nb_bool */
0, /* unaryfunc nb_invert */
0, /* binaryfunc nb_lshift */
0, /* binaryfunc nb_rshift */
@@ -151,7 +150,7 @@ PyTypeObject Nature_Type = {
/*-----------------------BPy_Nature instance definitions ----------------------------------*/
static PyLongObject _Nature_POINT = {
- PyVarObject_HEAD_INIT(&Nature_Type, 1)
+ PyVarObject_HEAD_INIT(&Nature_Type, 0)
{ Nature::POINT }
};
static PyLongObject _Nature_S_VERTEX = {
@@ -175,7 +174,7 @@ static PyLongObject _Nature_CUSP = {
{ Nature::CUSP }
};
static PyLongObject _Nature_NO_FEATURE = {
- PyVarObject_HEAD_INIT(&Nature_Type, 1)
+ PyVarObject_HEAD_INIT(&Nature_Type, 0)
{ Nature::NO_FEATURE }
};
static PyLongObject _Nature_SILHOUETTE = {
@@ -263,35 +262,41 @@ int Nature_Init(PyObject *module)
static PyObject *BPy_Nature_bitwise(PyObject *a, int op, PyObject *b)
{
BPy_Nature *result;
- long op1, op2;
+ long op1, op2, v;
if (!BPy_Nature_Check(a) || !BPy_Nature_Check(b)) {
PyErr_SetString(PyExc_TypeError, "operands must be a Nature object");
return NULL;
}
- op1 = PyLong_AsLong(a);
- if (PyErr_Occurred()) {
+
+ if ((op1 = PyLong_AsLong(a)) == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_ValueError, "operand 1: unexpected Nature value");
return NULL;
}
- op2 = PyLong_AsLong(b);
- if (PyErr_Occurred()) {
+ if ((op2 = PyLong_AsLong(b)) == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_ValueError, "operand 2: unexpected Nature value");
return NULL;
}
- result = PyObject_NewVar(BPy_Nature, &Nature_Type, 1);
- if (!result)
- return NULL;
switch (op) {
- case '&':
- result->i.ob_digit[0] = op1 & op2;
- break;
- case '^':
- result->i.ob_digit[0] = op1 ^ op2;
- break;
- case '|':
- result->i.ob_digit[0] = op1 | op2;
- break;
+ case '&':
+ v = op1 & op2;
+ break;
+ case '^':
+ v = op1 ^ op2;
+ break;
+ case '|':
+ v = op1 | op2;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if (v == 0)
+ result = PyObject_NewVar(BPy_Nature, &Nature_Type, 0);
+ else {
+ result = PyObject_NewVar(BPy_Nature, &Nature_Type, 1);
+ if (result)
+ result->i.ob_digit[0] = v;
}
return (PyObject *)result;
}
@@ -311,11 +316,6 @@ static PyObject *BPy_Nature_or(PyObject *a, PyObject *b)
return BPy_Nature_bitwise(a, '|', b);
}
-static int BPy_Nature_bool(PyObject *v)
-{
- return ((PyLongObject *)v)->ob_digit[0] != 0;
-}
-
///////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.h b/source/blender/freestyle/intern/python/BPy_Nature.h
index 0b9901bbe06..ad6bc0fdbdd 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.h
+++ b/source/blender/freestyle/intern/python/BPy_Nature.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_NATURE_H__
#define __FREESTYLE_PYTHON_NATURE_H__
+extern "C" {
#include <Python.h>
+}
#include "../winged_edge/Nature.h"
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.h b/source/blender/freestyle/intern/python/BPy_Operators.h
index be9514f46d8..86d23c4917f 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.h
+++ b/source/blender/freestyle/intern/python/BPy_Operators.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_OPERATORS_H__
#define __FREESTYLE_PYTHON_OPERATORS_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Operators.h"
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.h b/source/blender/freestyle/intern/python/BPy_SShape.h
index 8e7d3b63582..4919a34bf6d 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.h
+++ b/source/blender/freestyle/intern/python/BPy_SShape.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_SSHAPE_H__
#define __FREESTYLE_PYTHON_SSHAPE_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Silhouette.h"
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
index 6d30b6b1421..ce2384ea7d6 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_STROKEATTRIBUTE_H__
#define __FREESTYLE_PYTHON_STROKEATTRIBUTE_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Stroke.h"
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
index e1d620cee1c..a6c7a40e780 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
@@ -29,6 +29,7 @@
#include "StrokeShader/BPy_BackboneStretcherShader.h"
#include "StrokeShader/BPy_BezierCurveShader.h"
+#include "StrokeShader/BPy_BlenderTextureShader.h"
#include "StrokeShader/BPy_CalligraphicShader.h"
#include "StrokeShader/BPy_ColorNoiseShader.h"
#include "StrokeShader/BPy_ColorVariationPatternShader.h"
@@ -45,6 +46,7 @@
#include "StrokeShader/BPy_SpatialNoiseShader.h"
#include "StrokeShader/BPy_streamShader.h"
#include "StrokeShader/BPy_StrokeTextureShader.h"
+#include "StrokeShader/BPy_StrokeTextureStepShader.h"
#include "StrokeShader/BPy_TextureAssignerShader.h"
#include "StrokeShader/BPy_ThicknessNoiseShader.h"
#include "StrokeShader/BPy_ThicknessVariationPatternShader.h"
@@ -77,6 +79,11 @@ int StrokeShader_Init(PyObject *module)
Py_INCREF(&BezierCurveShader_Type);
PyModule_AddObject(module, "BezierCurveShader", (PyObject *)&BezierCurveShader_Type);
+ if (PyType_Ready(&BlenderTextureShader_Type) < 0)
+ return -1;
+ Py_INCREF(&BlenderTextureShader_Type);
+ PyModule_AddObject(module, "BlenderTextureShader", (PyObject *)&BlenderTextureShader_Type);
+
if (PyType_Ready(&CalligraphicShader_Type) < 0)
return -1;
Py_INCREF(&CalligraphicShader_Type);
@@ -158,6 +165,11 @@ int StrokeShader_Init(PyObject *module)
Py_INCREF(&StrokeTextureShader_Type);
PyModule_AddObject(module, "StrokeTextureShader", (PyObject *)&StrokeTextureShader_Type);
+ if (PyType_Ready(&StrokeTextureStepShader_Type) < 0)
+ return -1;
+ Py_INCREF(&StrokeTextureStepShader_Type);
+ PyModule_AddObject(module, "StrokeTextureStepShader", (PyObject *)&StrokeTextureStepShader_Type);
+
if (PyType_Ready(&TextureAssignerShader_Type) < 0)
return -1;
Py_INCREF(&TextureAssignerShader_Type);
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.h b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
index 19af6006c10..91498581695 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_STROKESHADER_H__
#define __FREESTYLE_PYTHON_STROKESHADER_H__
+extern "C" {
#include <Python.h>
+}
#include "../system/FreestyleConfig.h"
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
index 3b6a2ab79e6..58126d5291a 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0D_H__
#define __FREESTYLE_PYTHON_UNARYFUNCTION0D_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Functions0D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
index 87c4430fd14..0b38b3d47ac 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1D_H__
#define __FREESTYLE_PYTHON_UNARYFUNCTION1D_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/Functions1D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
index 0101a5f508a..a40d4648444 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_UNARYPREDICATE0D_H__
#define __FREESTYLE_PYTHON_UNARYPREDICATE0D_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Predicates0D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
index fd37e1dc13a..bbbec57b2b3 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_UNARYPREDICATE1D_H__
#define __FREESTYLE_PYTHON_UNARYPREDICATE1D_H__
+extern "C" {
#include <Python.h>
+}
#include "../stroke/Predicates1D.h"
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.h b/source/blender/freestyle/intern/python/BPy_ViewMap.h
index 5150c6fbebd..cd42e9453ae 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_VIEWMAP_H__
#define __FREESTYLE_PYTHON_VIEWMAP_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/ViewMap.h"
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.h b/source/blender/freestyle/intern/python/BPy_ViewShape.h
index 7727b131e1b..3151ebe8cbd 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.h
@@ -25,7 +25,9 @@
#ifndef __FREESTYLE_PYTHON_VIEWSHAPE_H__
#define __FREESTYLE_PYTHON_VIEWSHAPE_H__
+extern "C" {
#include <Python.h>
+}
#include "../view_map/ViewMap.h"
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
index 214660b5a7c..add2a68214f 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FalseBP1D_Type;
#define BPy_FalseBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FalseBP1D_Type))
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
index e4b02fc97d5..e79e8118c5a 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Length2DBP1D_Type;
#define BPy_Length2DBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Length2DBP1D_Type))
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
index 097d68c4ce7..c78aab609a4 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SameShapeIdBP1D_Type;
#define BPy_SameShapeIdBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SameShapeIdBP1D_Type))
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
index 772de1ae3df..29cf57a2215 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TrueBP1D_Type;
#define BPy_TrueBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TrueBP1D_Type))
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
index 01bad10c71e..27182b852d1 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ViewMapGradientNormBP1D_Type;
#define BPy_ViewMapGradientNormBP1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp
index ed98bfee63f..f03aa0bcc97 100644
--- a/source/blender/freestyle/intern/python/Director.cpp
+++ b/source/blender/freestyle/intern/python/Director.cpp
@@ -74,7 +74,7 @@ int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D, Interface0D
Py_XDECREF(arg2);
return -1;
}
- PyObject *result = PyObject_CallMethod(bp0D->py_bp0D, (char *)"__call__", (char *)"OO", arg1, arg2);
+ PyObject *result = PyObject_CallMethod((PyObject *)bp0D->py_bp0D, (char *)"__call__", (char *)"OO", arg1, arg2);
Py_DECREF(arg1);
Py_DECREF(arg2);
if (!result)
@@ -101,7 +101,7 @@ int Director_BPy_BinaryPredicate1D___call__(BinaryPredicate1D *bp1D, Interface1D
Py_XDECREF(arg2);
return -1;
}
- PyObject *result = PyObject_CallMethod(bp1D->py_bp1D, (char *)"__call__", (char *)"OO", arg1, arg2);
+ PyObject *result = PyObject_CallMethod((PyObject *)bp1D->py_bp1D, (char *)"__call__", (char *)"OO", arg1, arg2);
Py_DECREF(arg1);
Py_DECREF(arg2);
if (!result)
@@ -124,7 +124,7 @@ int Director_BPy_UnaryPredicate0D___call__(UnaryPredicate0D *up0D, Interface0DIt
PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, 0);
if (!arg)
return -1;
- PyObject *result = PyObject_CallMethod(up0D->py_up0D, (char *)"__call__", (char *)"O", arg);
+ PyObject *result = PyObject_CallMethod((PyObject *)up0D->py_up0D, (char *)"__call__", (char *)"O", arg);
Py_DECREF(arg);
if (!result)
return -1;
@@ -146,7 +146,7 @@ int Director_BPy_UnaryPredicate1D___call__(UnaryPredicate1D *up1D, Interface1D&
PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D);
if (!arg)
return -1;
- PyObject *result = PyObject_CallMethod(up1D->py_up1D, (char *)"__call__", (char *)"O", arg);
+ PyObject *result = PyObject_CallMethod((PyObject *)up1D->py_up1D, (char *)"__call__", (char *)"O", arg);
Py_DECREF(arg);
if (!result)
return -1;
@@ -168,7 +168,7 @@ int Director_BPy_StrokeShader_shade(StrokeShader *ss, Stroke& s)
PyObject *arg = BPy_Stroke_from_Stroke(s);
if (!arg)
return -1;
- PyObject *result = PyObject_CallMethod(ss->py_ss, (char *)"shade", (char *)"O", arg);
+ PyObject *result = PyObject_CallMethod((PyObject *)ss->py_ss, (char *)"shade", (char *)"O", arg);
Py_DECREF(arg);
if (!result)
return -1;
@@ -183,7 +183,7 @@ int Director_BPy_ChainingIterator_init(ChainingIterator *c_it)
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_c_it) not initialized");
return -1;
}
- PyObject *result = PyObject_CallMethod(c_it->py_c_it, (char *)"init", NULL);
+ PyObject *result = PyObject_CallMethod((PyObject *)c_it->py_c_it, (char *)"init", NULL);
if (!result)
return -1;
Py_DECREF(result);
@@ -199,7 +199,7 @@ int Director_BPy_ChainingIterator_traverse(ChainingIterator *c_it, AdjacencyIter
PyObject *arg = BPy_AdjacencyIterator_from_AdjacencyIterator(a_it);
if (!arg)
return -1;
- PyObject *result = PyObject_CallMethod(c_it->py_c_it, (char *)"traverse", (char *)"O", arg);
+ PyObject *result = PyObject_CallMethod((PyObject *)c_it->py_c_it, (char *)"traverse", (char *)"O", arg);
Py_DECREF(arg);
if (!result)
return -1;
@@ -219,12 +219,13 @@ int Director_BPy_ChainingIterator_traverse(ChainingIterator *c_it, AdjacencyIter
}
// BPy_UnaryFunction{0D,1D}: __call__
-int Director_BPy_UnaryFunction0D___call__(void *uf0D, PyObject *obj, Interface0DIterator& if0D_it)
+int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0DIterator& if0D_it)
{
- if (!obj) { // internal error
+ if (!py_uf0D) { // internal error
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf0D) not initialized");
return -1;
}
+ PyObject *obj = (PyObject *)py_uf0D;
PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, 0);
if (!arg)
return -1;
@@ -277,12 +278,13 @@ int Director_BPy_UnaryFunction0D___call__(void *uf0D, PyObject *obj, Interface0D
return 0;
}
-int Director_BPy_UnaryFunction1D___call__(void *uf1D, PyObject *obj, Interface1D& if1D)
+int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D& if1D)
{
- if (!obj) { // internal error
+ if (!py_uf1D) { // internal error
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf1D) not initialized");
return -1;
}
+ PyObject *obj = (PyObject *)py_uf1D;
PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D);
if (!arg)
return -1;
diff --git a/source/blender/freestyle/intern/python/Director.h b/source/blender/freestyle/intern/python/Director.h
index d58a51b65b2..40576c0ec2c 100644
--- a/source/blender/freestyle/intern/python/Director.h
+++ b/source/blender/freestyle/intern/python/Director.h
@@ -41,16 +41,6 @@ class StrokeShader;
using namespace Freestyle;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <Python.h>
-
-#ifdef __cplusplus
-}
-#endif
-
// BinaryPredicate0D: __call__
int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D, Interface0D& i1, Interface0D& i2);
@@ -58,8 +48,8 @@ int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D, Interface0D
int Director_BPy_BinaryPredicate1D___call__(BinaryPredicate1D *bp1D, Interface1D& i1, Interface1D& i2);
// UnaryFunction{0D,1D}: __call__
-int Director_BPy_UnaryFunction0D___call__(void *uf0D, PyObject *obj, Interface0DIterator& if0D_it);
-int Director_BPy_UnaryFunction1D___call__(void *uf1D, PyObject *obj, Interface1D& if1D);
+int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0DIterator& if0D_it);
+int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D& if1D);
// UnaryPredicate0D: __call__
int Director_BPy_UnaryPredicate0D___call__(UnaryPredicate0D *up0D, Interface0DIterator& if0D_it);
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index 69d0adadc00..50c9d031d0d 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -199,26 +199,12 @@ static int CurvePoint_t2d_set(BPy_CurvePoint *self, PyObject *value, void *UNUSE
return 0;
}
-PyDoc_STRVAR(CurvePoint_curvature_fredo_doc,
-"The angle (Fredo's curvature) in radians.\n"
-"\n"
-":type: float");
-
-static PyObject *CurvePoint_curvature_fredo_get(BPy_CurvePoint *self, void *UNUSED(closure))
-{
- return PyFloat_FromDouble(self->cp->curvatureFredo());
-}
-
-// todo - CurvePoint.directionFredo()
-
static PyGetSetDef BPy_CurvePoint_getseters[] = {
{(char *)"first_svertex", (getter)CurvePoint_first_svertex_get, (setter)CurvePoint_first_svertex_set,
(char *)CurvePoint_first_svertex_doc, NULL},
{(char *)"second_svertex", (getter)CurvePoint_second_svertex_get, (setter)CurvePoint_second_svertex_set,
(char *)CurvePoint_second_svertex_doc, NULL},
{(char *)"t2d", (getter)CurvePoint_t2d_get, (setter)CurvePoint_t2d_set, (char *)CurvePoint_t2d_doc, NULL},
- {(char *)"curvature_fredo", (getter)CurvePoint_curvature_fredo_get, (setter)NULL,
- (char *)CurvePoint_curvature_fredo_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
index 9ab5bea9e8c..5d651ef1a56 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_CURVEPOINT_H__
#include "../BPy_Interface0D.h"
+
#include "../../stroke/Curve.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject CurvePoint_Type;
#define BPy_CurvePoint_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CurvePoint_Type))
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
index 84866fb5a4e..a154ac4e48e 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
@@ -25,9 +25,9 @@
#ifndef __FREESTYLE_PYTHON_SVERTEX_H__
#define __FREESTYLE_PYTHON_SVERTEX_H__
-#include "../../view_map/Silhouette.h"
#include "../BPy_Interface0D.h"
+#include "../../view_map/Silhouette.h"
#ifdef __cplusplus
extern "C" {
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SVertex_Type;
#define BPy_SVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SVertex_Type))
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
index 9589b939e57..21b45c987f2 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
@@ -25,17 +25,16 @@
#ifndef __FREESTYLE_PYTHON_VIEWVERTEX_H__
#define __FREESTYLE_PYTHON_VIEWVERTEX_H__
-#include "../../view_map/ViewMap.h"
#include "../BPy_Interface0D.h"
+#include "../../view_map/ViewMap.h"
+
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ViewVertex_Type;
#define BPy_ViewVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewVertex_Type))
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
index b4c52d6968e..8519fe98443 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_STROKEVERTEX_H__
#include "../BPy_CurvePoint.h"
+
#include "../../../stroke/Stroke.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject StrokeVertex_Type;
#define BPy_StrokeVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeVertex_Type))
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
index 7d5ffd2d410..7f8d5c175c7 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_NONTVERTEX_H__
#include "../BPy_ViewVertex.h"
+
#include "../../../view_map/ViewMap.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject NonTVertex_Type;
#define BPy_NonTVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&NonTVertex_Type))
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
index a3f8d0a57b0..4f14b5afdc0 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_TVERTEX_H__
#include "../BPy_ViewVertex.h"
+
#include "../../../view_map/ViewMap.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TVertex_Type;
#define BPy_TVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TVertex_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
index 3a0be48e4bf..7365ee8ac36 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
@@ -46,7 +46,7 @@ PyDoc_STRVAR(FEdge_doc,
"silhouettes, the FEdge is oriented so that the visible face lies on\n"
"the left of the edge. For borders, the FEdge is oriented so that the\n"
"face lies on the left of the edge. An FEdge can represent an initial\n"
-"edge of the mesh or runs accross a face of the initial mesh depending\n"
+"edge of the mesh or runs across a face of the initial mesh depending\n"
"on the smoothness or sharpness of the mesh. This class is specialized\n"
"into a smooth and a sharp version since their properties slightly vary\n"
"from one to the other.\n"
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
index 7e27e3e93ab..69e7fddd770 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_FEDGE_H__
#include "../BPy_Interface1D.h"
+
#include "../../view_map/Silhouette.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FEdge_Type;
#define BPy_FEdge_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdge_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
index e119fef5758..990d8fb5b24 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_FRSCURVE_H__
#include "../BPy_Interface1D.h"
+
#include "../../stroke/Curve.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FrsCurve_Type;
#define BPy_FrsCurve_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FrsCurve_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
index 0ceaf3ec9f5..a22e5c2d006 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_STROKE_H__
#include "../BPy_Interface1D.h"
+
#include "../../stroke/Stroke.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Stroke_Type;
#define BPy_Stroke_Check(v) (((PyObject *)v)->ob_type == &Stroke_Type)
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
index d47fed0fdc2..51af401f33b 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
@@ -25,18 +25,16 @@
#ifndef __FREESTYLE_PYTHON_VIEWEDGE_H__
#define __FREESTYLE_PYTHON_VIEWEDGE_H__
-#include "../../view_map/ViewMap.h"
-
#include "../BPy_Interface1D.h"
+#include "../../view_map/ViewMap.h"
+
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ViewEdge_Type;
#define BPy_ViewEdge_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewEdge_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
index 867b9b0387d..172dffff49b 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_CHAIN_H__
#include "../BPy_FrsCurve.h"
+
#include "../../../stroke/Chain.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Chain_Type;
#define BPy_Chain_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Chain_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
index 37f678ddd93..1c82453432b 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_FEDGESHARP_H__
#include "../BPy_FEdge.h"
+
#include "../../../view_map/Silhouette.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FEdgeSharp_Type;
#define BPy_FEdgeSharp_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdgeSharp_Type))
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
index a88afc24557..f3dfd796418 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
@@ -26,6 +26,7 @@
#define __FREESTYLE_PYTHON_FEDGESMOOTH_H__
#include "../BPy_FEdge.h"
+
#include "../../../view_map/Silhouette.h"
#ifdef __cplusplus
@@ -34,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FEdgeSmooth_Type;
#define BPy_FEdgeSmooth_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdgeSmooth_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
index 20deea25c10..51fb3e5ebdc 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
@@ -25,9 +25,9 @@
#ifndef __FREESTYLE_PYTHON_ADJACENCYITERATOR_H__
#define __FREESTYLE_PYTHON_ADJACENCYITERATOR_H__
-#include "../../stroke/ChainingIterators.h"
#include "../BPy_Iterator.h"
+#include "../../stroke/ChainingIterators.h"
#ifdef __cplusplus
extern "C" {
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject AdjacencyIterator_Type;
#define BPy_AdjacencyIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&AdjacencyIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
index 0a7d97813b5..733a16e3974 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
@@ -25,19 +25,16 @@
#ifndef __FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H__
#define __FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H__
+#include "BPy_ChainingIterator.h"
#include "../../stroke/ChainingIterators.h"
-#include "BPy_ChainingIterator.h"
-
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ChainPredicateIterator_Type;
#define BPy_ChainPredicateIterator_Check(v) \
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
index d58c3ffd294..e76c04a6640 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
@@ -25,19 +25,16 @@
#ifndef __FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H__
#define __FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H__
+#include "BPy_ChainingIterator.h"
#include "../../stroke/ChainingIterators.h"
-#include "BPy_ChainingIterator.h"
-
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ChainSilhouetteIterator_Type;
#define BPy_ChainSilhouetteIterator_Check(v) \
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
index 93526921ae3..72015e6a0d9 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
@@ -25,19 +25,16 @@
#ifndef __FREESTYLE_PYTHON_CHAININGITERATOR_H__
#define __FREESTYLE_PYTHON_CHAININGITERATOR_H__
+#include "BPy_ViewEdgeIterator.h"
#include "../../stroke/ChainingIterators.h"
-#include "BPy_ViewEdgeIterator.h"
-
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ChainingIterator_Type;
#define BPy_ChainingIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ChainingIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
index 104c8557754..8c93ac2c014 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
@@ -25,18 +25,16 @@
#ifndef __FREESTYLE_PYTHON_CURVEPOINTITERATOR_H__
#define __FREESTYLE_PYTHON_CURVEPOINTITERATOR_H__
-#include "../../stroke/CurveIterators.h"
-
#include "../BPy_Iterator.h"
+#include "../../stroke/CurveIterators.h"
+
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject CurvePointIterator_Type;
#define BPy_CurvePointIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CurvePointIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
index 224fe13c576..5b1b70f19e8 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
@@ -25,9 +25,9 @@
#ifndef __FREESTYLE_PYTHON_INTERFACE0DITERATOR_H__
#define __FREESTYLE_PYTHON_INTERFACE0DITERATOR_H__
-#include "../../view_map/Interface0D.h"
#include "../BPy_Iterator.h"
+#include "../../view_map/Interface0D.h"
#ifdef __cplusplus
extern "C" {
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Interface0DIterator_Type;
#define BPy_Interface0DIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Interface0DIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
index 858609efe47..a430e4e7876 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
@@ -25,10 +25,9 @@
#ifndef __FREESTYLE_PYTHON_SVERTEXITERATOR_H__
#define __FREESTYLE_PYTHON_SVERTEXITERATOR_H__
-#include "../../view_map/ViewMapIterators.h"
-
#include "../BPy_Iterator.h"
+#include "../../view_map/ViewMapIterators.h"
#ifdef __cplusplus
extern "C" {
@@ -36,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SVertexIterator_Type;
#define BPy_SVertexIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SVertexIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
index 4ce11191b1c..18bad65b00a 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
@@ -25,18 +25,16 @@
#ifndef __FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H__
#define __FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H__
-#include "../../stroke/StrokeIterators.h"
-
#include "../BPy_Iterator.h"
+#include "../../stroke/StrokeIterators.h"
+
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject StrokeVertexIterator_Type;
#define BPy_StrokeVertexIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeVertexIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
index eb11dd6cdea..47244dcb5f2 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
@@ -25,19 +25,16 @@
#ifndef __FREESTYLE_PYTHON_VIEWEDGEITERATOR_H__
#define __FREESTYLE_PYTHON_VIEWEDGEITERATOR_H__
+#include "../BPy_Iterator.h"
#include "../../view_map/ViewMapIterators.h"
-#include "../BPy_Iterator.h"
-
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ViewEdgeIterator_Type;
#define BPy_ViewEdgeIterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewEdgeIterator_Type))
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
index 999e0ecad5d..bb1207aa46b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
@@ -25,19 +25,16 @@
#ifndef __FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H__
#define __FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H__
-#include "../../stroke/Stroke.h"
-#include "../../view_map/ViewMapIterators.h"
-
#include "../BPy_Iterator.h"
+#include "../../view_map/ViewMapIterators.h"
+
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject orientedViewEdgeIterator_Type;
#define BPy_orientedViewEdgeIterator_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
index c9059eb96f2..82d39a853bd 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject BackboneStretcherShader_Type;
#define BPy_BackboneStretcherShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
index ad967a76fd3..6982661366f 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject BezierCurveShader_Type;
#define BPy_BezierCurveShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&BezierCurveShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
new file mode 100644
index 00000000000..c8b9d7098e4
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
@@ -0,0 +1,125 @@
+/*
+ * ***** 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 source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+ * \ingroup freestyle
+ */
+
+#include "BPy_BlenderTextureShader.h"
+
+#include "../../stroke/BasicStrokeShaders.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../../python/generic/py_capi_utils.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+//------------------------INSTANCE METHODS ----------------------------------
+
+static char BlenderTextureShader___doc__[] =
+"Class hierarchy: :class:`StrokeShader` > :class:`BlenderTextureShader`\n"
+"\n"
+"[Texture shader]\n"
+"\n"
+".. method:: __init__(LineStyleTextureSlot)\n"
+"\n"
+" Builds a BlenderTextureShader object.\n"
+"\n"
+" :arg mtex: texture slot to add to stroke shading.\n"
+" :type mtex: LineStyleTextureSlot\n"
+
+"\n"
+".. method:: shade(stroke)\n"
+"\n"
+" Assigns a blender texture slot to the stroke shading\n"
+" in order to simulate marks.\n"
+"\n"
+" :arg stroke: A Stroke object.\n"
+" :type stroke: :class:`Stroke`\n";
+
+static int BlenderTextureShader___init__(BPy_BlenderTextureShader *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"LineStyleTextureSlot", NULL};
+ PyObject *py_mtex;
+ MTex *_mtex;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &py_mtex))
+ return -1;
+
+ _mtex = (MTex*)PyC_RNA_AsPointer(py_mtex, "LineStyleTextureSlot");
+
+ if (_mtex) {
+ self->py_ss.ss = new StrokeShaders::BlenderTextureShader(_mtex);
+ }
+
+ return 0;
+}
+
+/*-----------------------BPy_BlenderTextureShader type definition ------------------------------*/
+
+PyTypeObject BlenderTextureShader_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "BlenderTextureShader", /* tp_name */
+ sizeof(BPy_BlenderTextureShader), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ BlenderTextureShader___doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &StrokeShader_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)BlenderTextureShader___init__, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
new file mode 100644
index 00000000000..46294c07b66
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
@@ -0,0 +1,57 @@
+/*
+ * ***** 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 source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
+ * \ingroup freestyle
+ */
+
+#ifndef __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
+#define __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
+
+#include "../BPy_StrokeShader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct MTex;
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#include <Python.h>
+
+extern PyTypeObject BlenderTextureShader_Type;
+
+#define BPy_BlenderTextureShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&BlenderTextureShader_Type))
+
+/*---------------------------Python BPy_BlenderTextureShader structure definition-----------*/
+typedef struct {
+ BPy_StrokeShader py_ss;
+} BPy_BlenderTextureShader;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
index bc94ad95442..6212a8f1d44 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject CalligraphicShader_Type;
#define BPy_CalligraphicShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CalligraphicShader_Type)
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
index 8be7f8b7b2d..5bce58f9f10 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ColorNoiseShader_Type;
#define BPy_ColorNoiseShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ColorNoiseShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h
index 4ec22d3e9f3..af5cf17caff 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ColorVariationPatternShader_Type;
#define BPy_ColorVariationPatternShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
index 5de697e62d8..a34db21a873 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ConstantColorShader_Type;
#define BPy_ConstantColorShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ConstantColorShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
index 6334283aff4..237b550b557 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ConstantThicknessShader_Type;
#define BPy_ConstantThicknessShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
index ccaf0708a74..124ce33aa8b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ConstrainedIncreasingThicknessShader_Type;
#define BPy_ConstrainedIncreasingThicknessShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
index 1d08aa5578e..0fc4ce822c3 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GuidingLinesShader_Type;
#define BPy_GuidingLinesShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GuidingLinesShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
index 729aef5e772..db51fac1bd6 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject IncreasingColorShader_Type;
#define BPy_IncreasingColorShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&IncreasingColorShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
index 8f44deb354f..809921ffe93 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject IncreasingThicknessShader_Type;
#define BPy_IncreasingThicknessShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
index 503e66d4b4c..023c8ff9fad 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject PolygonalizationShader_Type;
#define BPy_PolygonalizationShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
index 26e73b2721a..ece206a5be4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SamplingShader_Type;
#define BPy_SamplingShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SamplingShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
index c4ca83743a6..ca69561d8e0 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
@@ -68,7 +68,7 @@ static char SmoothingShader___doc__[] =
" Smoothes the stroke by moving the vertices to make the stroke\n"
" smoother. Uses curvature flow to converge towards a curve of\n"
" constant curvature. The diffusion method we use is anisotropic to\n"
-" prevent the diffusion accross corners.\n"
+" prevent the diffusion across corners.\n"
"\n"
" :arg stroke: A Stroke object.\n"
" :type stroke: :class:`Stroke`\n";
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
index fa7e924509b..5f45397c06a 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SmoothingShader_Type;
#define BPy_SmoothingShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SmoothingShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
index 03fc5727246..d7dfe6a6644 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject SpatialNoiseShader_Type;
#define BPy_SpatialNoiseShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SpatialNoiseShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h
index 9d106cac065..d025e8b7c2d 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject StrokeTextureShader_Type;
#define BPy_StrokeTextureShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeTextureShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
new file mode 100644
index 00000000000..5a7657f2dad
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
@@ -0,0 +1,114 @@
+/*
+ * ***** 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 source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+ * \ingroup freestyle
+ */
+
+#include "BPy_StrokeTextureStepShader.h"
+
+#include "../../stroke/BasicStrokeShaders.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+//------------------------INSTANCE METHODS ----------------------------------
+
+static char StrokeTextureStepShader___doc__[] =
+"Class hierarchy: :class:`StrokeShader` > :class:`StrokeTextureStepShader`\n"
+"\n"
+"[Texture shader]\n"
+"\n"
+".. method:: __init__(step)\n"
+"\n"
+" Builds a StrokeTextureStepShader object.\n"
+"\n"
+" :arg step: The spacing along the stroke.\n"
+" :type step: float\n"
+"\n"
+".. method:: shade(stroke)\n"
+"\n"
+" Assigns a spacing factor to the texture coordinates of the Stroke.\n"
+"\n"
+" :arg stroke: A Stroke object.\n"
+" :type stroke: :class:`Stroke`\n";
+
+static int StrokeTextureStepShader___init__(BPy_StrokeTextureStepShader *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"step", NULL};
+ float step = 0.1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist, &step))
+ return -1;
+ self->py_ss.ss = new StrokeShaders::StrokeTextureStepShader(step);
+ return 0;
+}
+
+/*-----------------------BPy_StrokeTextureStepShader type definition ------------------------------*/
+
+PyTypeObject StrokeTextureStepShader_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "StrokeTextureStepShader", /* tp_name */
+ sizeof(BPy_StrokeTextureStepShader), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ StrokeTextureStepShader___doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &StrokeShader_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)StrokeTextureStepShader___init__, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
new file mode 100644
index 00000000000..038d0022dec
--- /dev/null
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
@@ -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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
+ * \ingroup freestyle
+ */
+
+#ifndef __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
+#define __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
+
+#include "../BPy_StrokeShader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#include <Python.h>
+
+extern PyTypeObject StrokeTextureStepShader_Type;
+
+#define BPy_StrokeTextureStepShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeTextureStepShader_Type))
+
+/*---------------------------Python BPy_StrokeTextureStepShader structure definition----------*/
+typedef struct {
+ BPy_StrokeShader py_ss;
+} BPy_StrokeTextureStepShader;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h
index c3302a617b7..046f785dc57 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TextureAssignerShader_Type;
#define BPy_TextureAssignerShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TextureAssignerShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
index 6dc6d0df90f..3dd77c750f7 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ThicknessNoiseShader_Type;
#define BPy_ThicknessNoiseShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ThicknessNoiseShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h
index 160fba19983..604e875f815 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ThicknessVariationPatternShader_Type;
#define BPy_ThicknessVariationPatternShader_Check(v) \
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
index f8ef5aed6a3..c0c5b024153 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TipRemoverShader_Type;
#define BPy_TipRemoverShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TipRemoverShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h
index 65d77860352..9f2371a3756 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject fstreamShader_Type;
#define BPy_fstreamShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&fstreamShader_Type))
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h
index 281dab51f4a..047ff4b58b5 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject streamShader_Type;
#define BPy_streamShader_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&streamShader_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
index be2be0a9c5c..06ba12145c0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
@@ -38,8 +38,6 @@
#include "UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h"
#include "UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h"
-#include "../Director.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
index a8cd84312e6..bcf201e3b25 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DDouble_Type;
#define BPy_UnaryFunction0DDouble_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0DDouble_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
index 1fa50a1f0ca..ce335f8ad0f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DEdgeNature_Type;
#define BPy_UnaryFunction0DEdgeNature_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
index 093ebcee71a..ea0903701ec 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DFloat_Type;
#define BPy_UnaryFunction0DFloat_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0DFloat_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
index 6ba38a8fcbd..e736cbaf1f9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DId_Type;
#define BPy_UnaryFunction0DId_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0DId_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
index 697d226635a..8be2041158c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DMaterial_Type;
#define BPy_UnaryFunction0DMaterial_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
index 065deeef6ce..a0c9209da31 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DUnsigned_Type;
#define BPy_UnaryFunction0DUnsigned_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
index fc6dd3c6612..33b069e3bc3 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DVec2f_Type;
#define BPy_UnaryFunction0DVec2f_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0DVec2f_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
index 88863eae6df..da5f27ffb8c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DVec3f_Type;
#define BPy_UnaryFunction0DVec3f_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0DVec3f_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
index 4069db9b27f..c51942c78ac 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DVectorViewShape_Type;
#define BPy_UnaryFunction0DVectorViewShape_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
index 1a6a633c7ff..b7c67749d78 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction0DViewShape_Type;
#define BPy_UnaryFunction0DViewShape_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
index 8188fabfbe5..3c2a0112ca4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ShapeIdF0D_Type;
#define BPy_ShapeIdF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ShapeIdF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
index 3b70ae85374..d080976d7db 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject MaterialF0D_Type;
#define BPy_MaterialF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&MaterialF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
index fe296a20ff7..7a79c89f468 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject CurveNatureF0D_Type;
#define BPy_CurveNatureF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CurveNatureF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
index dc1c667a0a2..60f9fa87f47 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Normal2DF0D_Type;
#define BPy_Normal2DF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Normal2DF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
index 9aaafeec904..20014038704 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject VertexOrientation2DF0D_Type;
#define BPy_VertexOrientation2DF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
index eed6b93d481..e3a3a696ff5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject VertexOrientation3DF0D_Type;
#define BPy_VertexOrientation3DF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
index 56e3d416d30..02b6ee44e4e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetOccludeeF0D_Type;
#define BPy_GetOccludeeF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetOccludeeF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
index 12e93b71870..fa25061dd08 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetShapeF0D_Type;
#define BPy_GetShapeF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetShapeF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
index cd2d653af81..e9602363461 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Curvature2DAngleF0D_Type;
#define BPy_Curvature2DAngleF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Curvature2DAngleF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
index 458facca8c8..7f29affd131 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject DensityF0D_Type;
#define BPy_DensityF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&DensityF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
index 5cfedc93c6b..ff01bc0a296 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedXF0D_Type;
#define BPy_GetProjectedXF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedXF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
index cea48b0703a..d2b8798e237 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedYF0D_Type;
#define BPy_GetProjectedYF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedYF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
index c901e078b78..fa8a8c39d20 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedZF0D_Type;
#define BPy_GetProjectedZF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedZF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
index 31385434b77..27e1d17d007 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetXF0D_Type;
#define BPy_GetXF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetXF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
index 39c1b658324..91a24935472 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetYF0D_Type;
#define BPy_GetYF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetYF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
index 34f0ccdc02a..2c1cea52d91 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetZF0D_Type;
#define BPy_GetZF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetZF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
index dd5d4363cca..308aa0f381a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject LocalAverageDepthF0D_Type;
#define BPy_LocalAverageDepthF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&LocalAverageDepthF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
index 7f83636f586..1cf202cbed9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ZDiscontinuityF0D_Type;
#define BPy_ZDiscontinuityF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ZDiscontinuityF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
index 309b23972b0..83defbd21ca 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetCurvilinearAbscissaF0D_Type;
#define BPy_GetCurvilinearAbscissaF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
index c03eea65332..24fe5cdb6e8 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetParameterF0D_Type;
#define BPy_GetParameterF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetParameterF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
index 2999f94ab7b..200bbb67c52 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetViewMapGradientNormF0D_Type;
#define BPy_GetViewMapGradientNormF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
index 6686cc80170..e4e1707c5f7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ReadCompleteViewMapPixelF0D_Type;
#define BPy_ReadCompleteViewMapPixelF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
index 949fd66d2a9..c73a258b717 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ReadMapPixelF0D_Type;
#define BPy_ReadMapPixelF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ReadMapPixelF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
index c71ea3401a4..d2ba4990eb7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ReadSteerableViewMapPixelF0D_Type;
#define BPy_ReadSteerableViewMapPixelF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
index b5e19968617..142c5b7c04e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject QuantitativeInvisibilityF0D_Type;
#define BPy_QuantitativeInvisibilityF0D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
index e4ee0584860..d87ef720786 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetOccludersF0D_Type;
#define BPy_GetOccludersF0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetOccludersF0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
index 8f274cd80b7..5b56525f973 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DDouble_Type;
#define BPy_UnaryFunction1DDouble_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1DDouble_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
index ae4c5a864c1..6f38e774107 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
@@ -35,8 +35,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DEdgeNature_Type;
#define BPy_UnaryFunction1DEdgeNature_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
index f386a00c9ac..6d8a4d32ab8 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DFloat_Type;
#define BPy_UnaryFunction1DFloat_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1DFloat_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
index 36324fae6de..8a1f5ca4dff 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DUnsigned_Type;
#define BPy_UnaryFunction1DUnsigned_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
index 59e0983028c..eb7c2bb5cae 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DVec2f_Type;
#define BPy_UnaryFunction1DVec2f_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1DVec2f_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
index ccf323d97cd..4780c54da9d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DVec3f_Type;
#define BPy_UnaryFunction1DVec3f_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1DVec3f_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
index 7cf4fd50d11..974070198ab 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
@@ -36,8 +36,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DVectorViewShape_Type;
#define BPy_UnaryFunction1DVectorViewShape_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
index ae4a3b61520..03f8446fd45 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject UnaryFunction1DVoid_Type;
#define BPy_UnaryFunction1DVoid_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1DVoid_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
index 194941e6e70..c911155526b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject CurveNatureF1D_Type;
#define BPy_CurveNatureF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CurveNatureF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
index 6f653e629db..ac4efabc179 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Normal2DF1D_Type;
#define BPy_Normal2DF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Normal2DF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
index 14813b18d25..159e98e2fec 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Orientation2DF1D_Type;
#define BPy_Orientation2DF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Orientation2DF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
index 855f7363fa7..50d5427600f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Orientation3DF1D_Type;
#define BPy_Orientation3DF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Orientation3DF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
index 8f7dbfdbf57..457154e02c6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject Curvature2DAngleF1D_Type;
#define BPy_Curvature2DAngleF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Curvature2DAngleF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
index 3e4db290803..c1f0685a967 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject DensityF1D_Type;
#define BPy_DensityF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&DensityF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
index 4eabf52e986..b9706c2c7a9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetCompleteViewMapDensityF1D_Type;
#define BPy_GetCompleteViewMapDensityF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
index f6df23d9a2d..3168a72af5f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetDirectionalViewMapDensityF1D_Type;
#define BPy_GetDirectionalViewMapDensityF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
index 2c34b8720aa..556aedaaba7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedXF1D_Type;
#define BPy_GetProjectedXF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedXF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
index 2f4431eadbd..cd786bf0fa1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedYF1D_Type;
#define BPy_GetProjectedYF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedYF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
index fc59bb40805..fda8df45b2c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetProjectedZF1D_Type;
#define BPy_GetProjectedZF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetProjectedZF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
index dbfd9594302..60707ebf078 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetSteerableViewMapDensityF1D_Type;
#define BPy_GetSteerableViewMapDensityF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
index 129fb54b507..69dd7994bb5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetViewMapGradientNormF1D_Type;
#define BPy_GetViewMapGradientNormF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
index b43d867c38b..24d209b5439 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetXF1D_Type;
#define BPy_GetXF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetXF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
index 658be22817a..421ec0e393a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetYF1D_Type;
#define BPy_GetYF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetYF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
index e36de7c1125..844e18e1cab 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetZF1D_Type;
#define BPy_GetZF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetZF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
index d354076c984..f743dcb53cd 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject LocalAverageDepthF1D_Type;
#define BPy_LocalAverageDepthF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&LocalAverageDepthF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
index 6fe6ce5d0d7..31b0edf309b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ZDiscontinuityF1D_Type;
#define BPy_ZDiscontinuityF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ZDiscontinuityF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
index 8115c17aa1f..30439a35817 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject QuantitativeInvisibilityF1D_Type;
#define BPy_QuantitativeInvisibilityF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
index 4d2ab924f0d..0c7aed2eb46 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetOccludeeF1D_Type;
#define BPy_GetOccludeeF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetOccludeeF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
index 24c07e2a64c..1d0a8a79f2b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetOccludersF1D_Type;
#define BPy_GetOccludersF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetOccludersF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
index 0c498a5a9ba..72ce1dde537 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject GetShapeF1D_Type;
#define BPy_GetShapeF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&GetShapeF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
index 3c89e9b9ac0..968ab25da3b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ChainingTimeStampF1D_Type;
#define BPy_ChainingTimeStampF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ChainingTimeStampF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
index 92b990ac21c..e55e189d140 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject IncrementChainingTimeStampF1D_Type;
#define BPy_IncrementChainingTimeStampF1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
index 60becf26f48..0117231c4f1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TimeStampF1D_Type;
#define BPy_TimeStampF1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TimeStampF1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
index 19d38a1fb59..e083ba935cb 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FalseUP0D_Type;
#define BPy_FalseUP0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FalseUP0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
index dff2bdb269b..d13e8473d52 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TrueUP0D_Type;
#define BPy_TrueUP0D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TrueUP0D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
index aba39fb6557..154a268538c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ContourUP1D_Type;
#define BPy_ContourUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ContourUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
index 618d7f701f2..beed0ce0ed9 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject DensityLowerThanUP1D_Type;
#define BPy_DensityLowerThanUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&DensityLowerThanUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
index ef4e2ba6320..f4ca8a82a20 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject EqualToChainingTimeStampUP1D_Type;
#define BPy_EqualToChainingTimeStampUP1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
index 58266057911..8bd222c7430 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject EqualToTimeStampUP1D_Type;
#define BPy_EqualToTimeStampUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&EqualToTimeStampUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
index 6e789960bc9..cc346a8c814 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ExternalContourUP1D_Type;
#define BPy_ExternalContourUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ExternalContourUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
index 34eb70fa193..adce6ad68c9 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject FalseUP1D_Type;
#define BPy_FalseUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FalseUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
index f605e452ec2..8450e383277 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject QuantitativeInvisibilityUP1D_Type;
#define BPy_QuantitativeInvisibilityUP1D_Check(v) \
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
index 9e018d606d3..2cea311ce20 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject ShapeUP1D_Type;
#define BPy_ShapeUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ShapeUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
index 26c32da3db6..69467ee1733 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject TrueUP1D_Type;
#define BPy_TrueUP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TrueUP1D_Type))
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
index 430864c3966..696f5d3063c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
@@ -33,8 +33,6 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
-#include <Python.h>
-
extern PyTypeObject WithinImageBoundaryUP1D_Type;
#define BPy_WithinImageBoundaryUP1D_Check(v) \
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
index 1ffddc9b24d..d3a10aab4dd 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
@@ -38,7 +38,7 @@
namespace Freestyle {
-class LIB_SCENE_GRAPH_EXPORT IndexedFaceSet : public Rep
+class IndexedFaceSet : public Rep
{
public:
/*! Triangles description style:*/
diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h
index 6452e1260ad..6d1ac2825c0 100644
--- a/source/blender/freestyle/intern/scene_graph/LineRep.h
+++ b/source/blender/freestyle/intern/scene_graph/LineRep.h
@@ -40,7 +40,7 @@ using namespace std;
namespace Freestyle {
/*! Base class for all lines objects */
-class LIB_SCENE_GRAPH_EXPORT LineRep : public Rep
+class LineRep : public Rep
{
public:
/*! Line description style */
diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h
index ba8549f5128..546458bad48 100644
--- a/source/blender/freestyle/intern/scene_graph/Node.h
+++ b/source/blender/freestyle/intern/scene_graph/Node.h
@@ -43,7 +43,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_SCENE_GRAPH_EXPORT Node : public BaseObject
+class Node : public BaseObject
{
public:
inline Node() : BaseObject() {}
diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
index ee630e91884..5d84a624830 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
@@ -42,7 +42,7 @@ class NodeOrthographicCamera;
class NodePerspectiveCamera;
-class LIB_SCENE_GRAPH_EXPORT NodeCamera : public Node
+class NodeCamera : public Node
{
public:
typedef enum {
@@ -90,7 +90,7 @@ protected:
};
-class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera
+class NodeOrthographicCamera : public NodeCamera
{
public:
NodeOrthographicCamera();
@@ -157,7 +157,7 @@ private:
};
-class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera
+class NodePerspectiveCamera : public NodeCamera
{
public:
NodePerspectiveCamera();
diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
index 7e8c6635953..d053d67c6ba 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
@@ -35,7 +35,7 @@
namespace Freestyle {
-class LIB_SCENE_GRAPH_EXPORT NodeDrawingStyle : public NodeGroup
+class NodeDrawingStyle : public NodeGroup
{
public:
inline NodeDrawingStyle() : NodeGroup() {}
@@ -69,7 +69,7 @@ public:
_DrawingStyle.setPointSize(iPointSize);
}
- /*! Enables or disables the lighting. TRUE = enable */
+ /*! Enables or disables the lighting. true = enable */
inline void setLightingEnabled(const bool iEnableLighting)
{
_DrawingStyle.setLightingEnabled(iEnableLighting);
diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.h b/source/blender/freestyle/intern/scene_graph/NodeGroup.h
index 8123639e01f..69c8a2c8f3b 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeGroup.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.h
@@ -39,7 +39,7 @@ using namespace std;
namespace Freestyle {
-class LIB_SCENE_GRAPH_EXPORT NodeGroup : public Node
+class NodeGroup : public Node
{
public:
inline NodeGroup(): Node() {}
diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.h b/source/blender/freestyle/intern/scene_graph/NodeLight.h
index 25e13a768ec..c633a6bc7b8 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeLight.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeLight.h
@@ -38,7 +38,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_SCENE_GRAPH_EXPORT NodeLight : public Node
+class NodeLight : public Node
{
public:
NodeLight();
diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.h b/source/blender/freestyle/intern/scene_graph/NodeShape.h
index 3b4491f8b6d..351ccb8f743 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeShape.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeShape.h
@@ -45,7 +45,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_SCENE_GRAPH_EXPORT NodeShape : public Node
+class NodeShape : public Node
{
public:
inline NodeShape() : Node() {}
diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
index 5d26e85195f..8a25fe142d1 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
+++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp
@@ -28,7 +28,7 @@
#include "NodeTransform.h"
-#include "../system/FreestyleConfig.h"
+#include "BLI_math.h"
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.h b/source/blender/freestyle/intern/scene_graph/NodeTransform.h
index 544075998a4..c4de08ac4a7 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeTransform.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.h
@@ -39,7 +39,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_SCENE_GRAPH_EXPORT NodeTransform : public NodeGroup
+class NodeTransform : public NodeGroup
{
public:
inline NodeTransform() : NodeGroup()
diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
index 7272d47892a..8fafe72ac51 100644
--- a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
+++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
@@ -34,7 +34,7 @@
namespace Freestyle {
-class LIB_SCENE_GRAPH_EXPORT OrientedLineRep : public LineRep
+class OrientedLineRep : public LineRep
{
public:
OrientedLineRep() : LineRep() {}
diff --git a/source/blender/freestyle/intern/scene_graph/Rep.h b/source/blender/freestyle/intern/scene_graph/Rep.h
index 92624199c40..88ee0d2a801 100644
--- a/source/blender/freestyle/intern/scene_graph/Rep.h
+++ b/source/blender/freestyle/intern/scene_graph/Rep.h
@@ -42,7 +42,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_SCENE_GRAPH_EXPORT Rep : public BaseObject
+class Rep : public BaseObject
{
public:
inline Rep() : BaseObject()
diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
index d3870fe835d..c00f5124a31 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
+++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
@@ -66,7 +66,7 @@ class IndexedFaceSet;
class DrawingStyle;
class FrsMaterial;
-class LIB_SCENE_GRAPH_EXPORT SceneVisitor
+class SceneVisitor
{
public:
SceneVisitor() {}
diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.h b/source/blender/freestyle/intern/scene_graph/TriangleRep.h
index d204d128de4..d101cfd7988 100644
--- a/source/blender/freestyle/intern/scene_graph/TriangleRep.h
+++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.h
@@ -34,7 +34,7 @@
namespace Freestyle {
/*! Base class for all lines objects */
-class LIB_SCENE_GRAPH_EXPORT TriangleRep : public Rep
+class TriangleRep : public Rep
{
public:
/*! Line description style */
diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.h b/source/blender/freestyle/intern/scene_graph/VertexRep.h
index 1f1284fe163..87420429e00 100644
--- a/source/blender/freestyle/intern/scene_graph/VertexRep.h
+++ b/source/blender/freestyle/intern/scene_graph/VertexRep.h
@@ -32,7 +32,7 @@
namespace Freestyle {
-class LIB_SCENE_GRAPH_EXPORT VertexRep : public Rep
+class VertexRep : public Rep
{
public:
inline VertexRep() : Rep()
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
index f8204fb2c1c..48d5cd4803e 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
@@ -48,7 +48,7 @@ namespace Functions0D {
* This density is evaluated using a pixels square window around the evaluation point and integrating
* these values using a gaussian.
*/
-class LIB_STROKE_EXPORT DensityF0D : public UnaryFunction0D<double>
+class DensityF0D : public UnaryFunction0D<double>
{
public:
/*! Builds the functor from the gaussian sigma value.
@@ -78,7 +78,7 @@ private:
/*! Returns the average depth around a point.
* The result is obtained by querying the depth buffer on a window around that point.
*/
-class LIB_STROKE_EXPORT LocalAverageDepthF0D : public UnaryFunction0D<double>
+class LocalAverageDepthF0D : public UnaryFunction0D<double>
{
private:
GaussianFilter _filter;
@@ -102,7 +102,7 @@ public:
// ReadMapPixel
/*! Reads a pixel in a map. */
-class LIB_STROKE_EXPORT ReadMapPixelF0D : public UnaryFunction0D<float>
+class ReadMapPixelF0D : public UnaryFunction0D<float>
{
private:
const char * _mapName;
@@ -134,7 +134,7 @@ public:
// ReadSteerableViewMapPixel
/*! Reads a pixel in one of the level of one of the steerable viewmaps. */
-class LIB_STROKE_EXPORT ReadSteerableViewMapPixelF0D : public UnaryFunction0D<float>
+class ReadSteerableViewMapPixelF0D : public UnaryFunction0D<float>
{
private:
unsigned _orientation;
@@ -165,7 +165,7 @@ public:
// ReadCompleteViewMapPixel
/*! Reads a pixel in one of the level of the complete viewmap. */
-class LIB_STROKE_EXPORT ReadCompleteViewMapPixelF0D : public UnaryFunction0D<float>
+class ReadCompleteViewMapPixelF0D : public UnaryFunction0D<float>
{
private:
int _level;
@@ -192,7 +192,7 @@ public:
// GetViewMapGradientNormF0D
/*! Returns the norm of the gradient of the global viewmap density image. */
-class LIB_STROKE_EXPORT GetViewMapGradientNormF0D: public UnaryFunction0D< float>
+class GetViewMapGradientNormF0D: public UnaryFunction0D< float>
{
private:
int _level;
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
index 48534439217..cbdff4ed96c 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
@@ -130,7 +130,7 @@ private:
* The density is evaluated for a set of points along the Interface1D (using the ReadCompleteViewMapPixelF0D functor)
* and then integrated into a single value using a user-defined integration method.
*/
-class LIB_STROKE_EXPORT GetCompleteViewMapDensityF1D : public UnaryFunction1D<double>
+class GetCompleteViewMapDensityF1D : public UnaryFunction1D<double>
{
public:
/*! Builds the functor.
@@ -172,7 +172,7 @@ private:
* The density is evaluated for a set of points along the Interface1D (using the ReadSteerableViewMapPixelF0D functor)
* and then integrated into a single value using a user-defined integration method.
*/
-class LIB_STROKE_EXPORT GetDirectionalViewMapDensityF1D : public UnaryFunction1D<double>
+class GetDirectionalViewMapDensityF1D : public UnaryFunction1D<double>
{
public:
/*! Builds the functor.
@@ -212,7 +212,7 @@ private:
/*! Returns the density of the viewmap for a given Interface1D. The density of each FEdge is evaluated
* in the proper steerable ViewMap depending on its oorientation.
*/
-class LIB_STROKE_EXPORT GetSteerableViewMapDensityF1D : public UnaryFunction1D<real>
+class GetSteerableViewMapDensityF1D : public UnaryFunction1D<double>
{
private:
int _level;
@@ -230,7 +230,7 @@ public:
* by iType.
*/
GetSteerableViewMapDensityF1D(int level, IntegrationType iType = MEAN, float sampling = 2.0f)
- : UnaryFunction1D<real>(iType)
+ : UnaryFunction1D<double>(iType)
{
_level = level;
_sampling = sampling;
@@ -253,7 +253,7 @@ public:
/*! Returns the density of the viewmap for a given Interface1D. The density of each FEdge is evaluated in
* the proper steerable ViewMap depending on its oorientation.
*/
-class LIB_STROKE_EXPORT GetViewMapGradientNormF1D : public UnaryFunction1D<real>
+class GetViewMapGradientNormF1D : public UnaryFunction1D<double>
{
private:
int _level;
@@ -272,7 +272,7 @@ public:
* by iType.
*/
GetViewMapGradientNormF1D(int level, IntegrationType iType = MEAN, float sampling = 2.0f)
- : UnaryFunction1D<real>(iType), _func(level)
+ : UnaryFunction1D<double>(iType), _func(level)
{
_level = level;
_sampling = sampling;
diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
index d30a75d9e14..274e36a4c9b 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp
@@ -301,7 +301,7 @@ void Smoother::computeCurvature()
_curvature[i] = normalCurvature * _normal[i];
if (lba + lbc > M_EPSILON)
- _curvature[i] /= (0.5 * lba + lbc);
+ _curvature[i] /= (0.5 * lba + lbc);
}
_curvature[0] = _curvature[1];
_curvature[_nbVertices - 1] = _curvature[_nbVertices - 2];
@@ -325,7 +325,7 @@ void Smoother::computeCurvature()
_curvature[i] = normalCurvature * _normal[i];
if (lba + lbc > M_EPSILON)
- _curvature[i] /= (0.5 * lba + lbc);
+ _curvature[i] /= (0.5 * lba + lbc);
_normal[_nbVertices - 1] = _normal[0];
_curvature[_nbVertices - 1] = _curvature[0];
diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
index 18472ff2c2a..a9ef49aa802 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
@@ -37,7 +37,7 @@ namespace Freestyle {
* i.e. The stroke will be the thickest in a main direction, the thinest in the direction perpendicular to this one,
* and an interpolation inbetween.
*/
-class LIB_STROKE_EXPORT CalligraphicShader : public StrokeShader
+class CalligraphicShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -70,7 +70,7 @@ protected:
* Moves the vertices to make the stroke more noisy.
* @see \htmlonly <a href=noise/noise.html>noise/noise.html</a> \endhtmlonly
*/
-class LIB_STROKE_EXPORT SpatialNoiseShader : public StrokeShader
+class SpatialNoiseShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -108,7 +108,7 @@ protected:
* to prevent the diffusion accross corners.
* @see \htmlonly <a href=/smoothing/smoothing.html>smoothing/smoothing.html</a> \endhtmlonly
*/
-class LIB_STROKE_EXPORT SmoothingShader : public StrokeShader
+class SmoothingShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -149,7 +149,7 @@ protected:
real _carricatureFactor;
};
-class LIB_STROKE_EXPORT Smoother
+class Smoother
{
public:
Smoother(Stroke &ioStroke);
@@ -184,7 +184,7 @@ protected:
bool _safeTest;
};
-class LIB_STROKE_EXPORT Omitter : public Smoother
+class Omitter : public Smoother
{
public:
Omitter(Stroke &ioStroke);
@@ -203,7 +203,7 @@ protected:
};
/*! Omission shader */
-class LIB_STROKE_EXPORT OmissionShader : public StrokeShader
+class OmissionShader : public StrokeShader
{
public:
OmissionShader(real sizeWindow, real thrVari, real thrFlat, real lFlat);
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
index af3b7f09c31..e92913d097e 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
@@ -449,90 +449,27 @@ int ColorNoiseShader::shade(Stroke& stroke) const
//
///////////////////////////////////////////////////////////////////////////////
-int TextureAssignerShader::shade(Stroke& stroke) const
+int BlenderTextureShader::shade(Stroke& stroke) const
{
-#if 0
- getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM);
- getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM);
-#endif
+ return stroke.setMTex(_mtex);
+}
- TextureManager *instance = TextureManager::getInstance();
- if (!instance)
- return 0;
- string pathname;
- Stroke::MediumType mediumType;
- bool hasTips = false;
- switch (_textureId) {
- case 0:
- //pathname = TextureManager::Options::getBrushesPath() + "/charcoalAlpha.bmp";
- pathname = "/charcoalAlpha.bmp";
- mediumType = Stroke::HUMID_MEDIUM;
- hasTips = false;
- break;
- case 1:
- pathname = "/washbrushAlpha.bmp";
- mediumType = Stroke::HUMID_MEDIUM;
- hasTips = true;
- break;
- case 2:
- pathname = "/oil.bmp";
- mediumType = Stroke::HUMID_MEDIUM;
- hasTips = true;
- break;
- case 3:
- pathname = "/oilnoblend.bmp";
- mediumType = Stroke::HUMID_MEDIUM;
- hasTips = true;
- break;
- case 4:
- pathname = "/charcoalAlpha.bmp";
- mediumType = Stroke::DRY_MEDIUM;
- hasTips = false;
- break;
- case 5:
- mediumType = Stroke::DRY_MEDIUM;
- hasTips = true;
- break;
- case 6:
- pathname = "/opaqueDryBrushAlpha.bmp";
- mediumType = Stroke::OPAQUE_MEDIUM;
- hasTips = true;
- break;
- case 7:
- pathname = "/opaqueBrushAlpha.bmp";
- mediumType = Stroke::OPAQUE_MEDIUM;
- hasTips = true;
- break;
- default:
- pathname = "/smoothAlpha.bmp";
- mediumType = Stroke::OPAQUE_MEDIUM;
- hasTips = false;
- break;
- }
- unsigned int texId = instance->getBrushTextureIndex(pathname, mediumType);
- stroke.setMediumType(mediumType);
- stroke.setTips(hasTips);
- stroke.setTextureId(texId);
+int StrokeTextureStepShader::shade(Stroke& stroke) const
+{
+ stroke.setTextureStep(_step);
+ return 0;
+}
+
+// Legacy shaders from freestyle standalone texture system
+int TextureAssignerShader::shade(Stroke& stroke) const
+{
+ cout << "TextureAssignerShader is not supported in blender, please use the BlenderTextureShader" << endl;
return 0;
}
-// FIXME
int StrokeTextureShader::shade(Stroke& stroke) const
{
- TextureManager *instance = TextureManager::getInstance();
- if (!instance)
- return 0;
- string pathname = TextureManager::Options::getBrushesPath() + "/" + _texturePath;
- unsigned int texId = instance->getBrushTextureIndex(pathname, _mediumType);
- stroke.setMediumType(_mediumType);
- stroke.setTips(_tips);
- stroke.setTextureId(texId);
+ cout << "StrokeTextureShader is not supported in blender, please use the BlenderTextureShader" << endl;
return 0;
}
@@ -841,7 +778,7 @@ int BezierCurveShader::shade(Stroke& stroke) const
if (it.isEnd()) {
// XXX Shocking! :P Shouldn't we break in this case???
if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "fucked up" << endl;
+ cout << "messed up!" << endl;
}
}
}
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
index d55a689def4..9186d164e9b 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
@@ -36,6 +36,8 @@
#include "../geometry/Bezier.h"
#include "../geometry/Geom.h"
+struct MTex;
+
using namespace std;
namespace Freestyle {
@@ -52,7 +54,7 @@ namespace StrokeShaders {
/*! [ Thickness Shader ].
* Assigns an absolute constant thickness to every vertices of the Stroke.
*/
-class LIB_STROKE_EXPORT ConstantThicknessShader : public StrokeShader
+class ConstantThicknessShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -85,7 +87,7 @@ private:
* is its thickness from the point to the strip border in the direction pointing outside the object the
* Stroke delimitates.
*/
-class LIB_STROKE_EXPORT ConstantExternThicknessShader : public StrokeShader
+class ConstantExternThicknessShader : public StrokeShader
{
public:
ConstantExternThicknessShader(float thickness) : StrokeShader()
@@ -112,7 +114,7 @@ private:
* and the last vertex.
* The thickness is linearly interpolated from A to B.
*/
-class LIB_STROKE_EXPORT IncreasingThicknessShader : public StrokeShader
+class IncreasingThicknessShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -147,7 +149,7 @@ private:
* Same as previous but here we allow the user to control the ratio thickness/length so that we don't get
* fat short lines
*/
-class LIB_STROKE_EXPORT ConstrainedIncreasingThicknessShader : public StrokeShader
+class ConstrainedIncreasingThicknessShader : public StrokeShader
{
private:
float _ThicknessMin;
@@ -185,7 +187,7 @@ public:
/* [ Thickness Shader ].
* Modifys the thickness in a relative way depending on its length.
*/
-class LIB_STROKE_EXPORT LengthDependingThicknessShader : public StrokeShader
+class LengthDependingThicknessShader : public StrokeShader
{
private:
float _minThickness;
@@ -218,7 +220,7 @@ public:
* The new thicknesses are the result of the multiplication
* of the pattern and the original thickness
*/
-class LIB_STROKE_EXPORT ThicknessVariationPatternShader : public StrokeShader
+class ThicknessVariationPatternShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -263,7 +265,7 @@ private:
* Adds some noise to the stroke thickness.
* \see \htmlonly <a href=noise/noise.html>noise/noise.html</a>\endhtmlonly
*/
-class LIB_STROKE_EXPORT ThicknessNoiseShader : public StrokeShader
+class ThicknessNoiseShader : public StrokeShader
{
private:
float _amplitude;
@@ -297,7 +299,7 @@ public:
/*! [ Color Shader ].
* Assigns a constant color to every vertices of the Stroke.
*/
-class LIB_STROKE_EXPORT ConstantColorShader : public StrokeShader
+class ConstantColorShader : public StrokeShader
{
public:
/*! Builds the shader from a user-specified color.
@@ -335,7 +337,7 @@ private:
* The user specifies 2 colors A and B. The stroke color will change linearly from A to B between the
* first and the last vertex.
*/
-class LIB_STROKE_EXPORT IncreasingColorShader : public StrokeShader
+class IncreasingColorShader : public StrokeShader
{
private:
float _colorMin[4];
@@ -388,7 +390,7 @@ public:
* Applys a pattern to vary original color.
* The new color is the result of the multiplication of the pattern and the original color
*/
-class LIB_STROKE_EXPORT ColorVariationPatternShader : public StrokeShader
+class ColorVariationPatternShader : public StrokeShader
{
public:
/*! Builds the shader from the pattern texture file name.
@@ -425,7 +427,7 @@ private:
/* [ Color Shader ].
* Assigns a color to the stroke depending on the material of the shape to which ot belongs to. (Disney shader)
*/
-class LIB_STROKE_EXPORT MaterialColorShader : public StrokeShader
+class MaterialColorShader : public StrokeShader
{
private:
float _coefficient;
@@ -444,7 +446,7 @@ public:
virtual int shade(Stroke& stroke) const;
};
-class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader
+class CalligraphicColorShader : public StrokeShader
{
private:
/* UNUSED */
@@ -469,7 +471,7 @@ public:
/*! [ Color Shader ].
* Shader to add noise to the stroke colors.
*/
-class LIB_STROKE_EXPORT ColorNoiseShader : public StrokeShader
+class ColorNoiseShader : public StrokeShader
{
private:
float _amplitude;
@@ -516,7 +518,7 @@ public:
* Any other value will lead to the following preset:
* default) -> /brushes/smoothAlpha.bmp, OPAQUE_MEDIUM.
*/
-class LIB_STROKE_EXPORT TextureAssignerShader : public StrokeShader // FIXME
+class TextureAssignerShader : public StrokeShader // FIXME
{
private:
int _textureId;
@@ -544,7 +546,7 @@ public:
* Assigns a texture and a blending mode to the stroke
* in order to simulate its marks system.
*/
-class LIB_STROKE_EXPORT StrokeTextureShader : public StrokeShader
+class StrokeTextureShader : public StrokeShader
{
private:
string _texturePath;
@@ -601,7 +603,7 @@ public:
/*! [ Geometry Shader ].
* Stretches the stroke at its two extremities and following the respective directions: v(1)v(0) and v(n-1)v(n).
*/
-class LIB_STROKE_EXPORT BackboneStretcherShader : public StrokeShader
+class BackboneStretcherShader : public StrokeShader
{
private:
float _amount;
@@ -629,7 +631,7 @@ public:
* Resamples the stroke.
* @see Stroke::Resample(float).
*/
-class LIB_STROKE_EXPORT SamplingShader: public StrokeShader
+class SamplingShader: public StrokeShader
{
private:
float _sampling;
@@ -654,7 +656,7 @@ public:
};
-class LIB_STROKE_EXPORT ExternalContourStretcherShader : public StrokeShader
+class ExternalContourStretcherShader : public StrokeShader
{
private:
float _amount;
@@ -674,7 +676,7 @@ public:
};
// B-Spline stroke shader
-class LIB_STROKE_EXPORT BSplineShader: public StrokeShader
+class BSplineShader: public StrokeShader
{
public:
BSplineShader() : StrokeShader() {}
@@ -694,7 +696,7 @@ public:
* original backbone geometry.
* @see \htmlonly <a href=bezier/bezier.html>bezier/bezier.html</a> \endhtmlonly
*/
-class LIB_STROKE_EXPORT BezierCurveShader : public StrokeShader
+class BezierCurveShader : public StrokeShader
{
private:
float _error;
@@ -723,7 +725,7 @@ public:
* The displacement value is proportional to the 2d curvature at the considered point (the higher the curvature,
* the smaller the displacement) and to a value specified by the user.
*/
-class LIB_STROKE_EXPORT InflateShader : public StrokeShader
+class InflateShader : public StrokeShader
{
private:
float _amount;
@@ -756,7 +758,7 @@ public:
* The basic idea is to start from the minimal stroke approximation consisting in a line joining the first vertex
* to the last one and to subdivide using the original stroke vertices until a certain error is reached.
*/
-class LIB_STROKE_EXPORT PolygonalizationShader : public StrokeShader
+class PolygonalizationShader : public StrokeShader
{
private:
float _error;
@@ -789,7 +791,7 @@ public:
* Indeed, the precision of the approximation will depend on the size of the stroke's pieces.
* The bigger the pieces, the rougher the approximation.
*/
-class LIB_STROKE_EXPORT GuidingLinesShader : public StrokeShader
+class GuidingLinesShader : public StrokeShader
{
private:
float _offset;
@@ -817,7 +819,7 @@ public:
/*! [ Geometry Shader ].
* Removes the stroke's extremities.
*/
-class LIB_STROKE_EXPORT TipRemoverShader : public StrokeShader
+class TipRemoverShader : public StrokeShader
{
public:
/*! Builds the shader.
@@ -844,7 +846,7 @@ protected:
/*! [ output Shader ].
* streams the Stroke
*/
-class LIB_STROKE_EXPORT streamShader : public StrokeShader
+class streamShader : public StrokeShader
{
public:
/*! Destructor. */
@@ -863,7 +865,7 @@ public:
/*! [ output Shader ].
* streams the Stroke in a file
*/
-class LIB_STROKE_EXPORT fstreamShader : public StrokeShader
+class fstreamShader : public StrokeShader
{
protected:
mutable ofstream _stream;
@@ -894,6 +896,62 @@ public:
virtual int shade(Stroke& stroke) const;
};
+/*! [ Texture Shader ].
+ * Shader to assign texture to the Stroke material.
+ */
+
+class BlenderTextureShader : public StrokeShader
+{
+private:
+ MTex *_mtex;
+
+public:
+ /*! Builds the shader.
+ * \param mtex
+ * The blender texture to use.
+ */
+ BlenderTextureShader(MTex *mtex) : StrokeShader()
+ {
+ _mtex = mtex;
+ }
+
+ virtual string getName() const
+ {
+ return "BlenderTextureShader";
+ }
+
+ /*! The shading method */
+ virtual int shade(Stroke& stroke) const;
+};
+
+/*! [ Texture Shader ].
+ * Shader to assign texture to the Stroke material.
+ */
+
+class StrokeTextureStepShader : public StrokeShader
+{
+private:
+ float _step;
+
+public:
+ /*! Builds the shader.
+ * \param id
+ * The number of the preset to use.
+ */
+ StrokeTextureStepShader(float step) : StrokeShader()
+ {
+ _step = step;
+ }
+
+ virtual string getName() const
+ {
+ return "StrokeTextureStepShader";
+ }
+
+ /*! The shading method */
+ virtual int shade(Stroke& stroke) const;
+};
+
} // end of namespace StrokeShaders
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp
index 09c8d9ed74e..69d37f61df9 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.cpp
+++ b/source/blender/freestyle/intern/stroke/Canvas.cpp
@@ -56,10 +56,8 @@ using namespace std;
namespace Freestyle {
-LIB_STROKE_EXPORT
Canvas *Canvas::_pInstance = 0;
-LIB_STROKE_EXPORT
const char *Canvas::_MapsPath = 0;
Canvas::Canvas()
diff --git a/source/blender/freestyle/intern/stroke/Canvas.h b/source/blender/freestyle/intern/stroke/Canvas.h
index 038b4b3af0f..b56b5f92c14 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.h
+++ b/source/blender/freestyle/intern/stroke/Canvas.h
@@ -71,7 +71,7 @@ class StyleModule;
/*! Class to define the canvas on which strokes are drawn.
* It's used to store state information about the drawing.
*/
-class LIB_STROKE_EXPORT Canvas
+class Canvas
{
public:
/*! Returns a pointer on the Canvas instance */
diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp
index c09ccbd393a..7fd756472b0 100644
--- a/source/blender/freestyle/intern/stroke/Chain.cpp
+++ b/source/blender/freestyle/intern/stroke/Chain.cpp
@@ -27,8 +27,8 @@
#include "Chain.h"
-#include "../view_map/ViewMapAdvancedIterators.h"
#include "../view_map/ViewMapIterators.h"
+#include "../view_map/ViewMapAdvancedIterators.h"
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
index 66575fd8fc2..84d770a96cd 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp
@@ -25,6 +25,8 @@
* \date 01/07/2003
*/
+#include "../python/Director.h"
+
#include "ChainingIterators.h"
#include "../system/TimeStamp.h"
@@ -62,6 +64,16 @@ bool AdjacencyIterator::isValid(ViewEdge *edge)
return true;
}
+int ChainingIterator::init()
+{
+ return Director_BPy_ChainingIterator_init(this);
+}
+
+int ChainingIterator::traverse(const AdjacencyIterator &it)
+{
+ return Director_BPy_ChainingIterator_traverse(this, const_cast<AdjacencyIterator &>(it));
+}
+
int ChainingIterator::increment()
{
_increment = true;
@@ -152,7 +164,7 @@ int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait)
Nature::RIDGE
};
int numNatures = sizeof(natures) / sizeof(Nature::EdgeNature);
- for (unsigned int i = 0; i < numNatures; ++i) {
+ for (int i = 0; i < numNatures; ++i) {
if (getCurrentEdge()->getNature() & natures[i]) {
int n = 0;
while (!it.isEnd()) {
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h
index 8d01cea84e7..5d05ed2776d 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.h
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h
@@ -32,9 +32,7 @@
#include "Predicates1D.h"
-#include "../python/Director.h"
-
-#include "../system/Iterator.h" //soc
+#include "../system/Iterator.h"
#include "../view_map/ViewMap.h"
#include "../view_map/ViewMapIterators.h"
@@ -48,7 +46,7 @@ namespace Freestyle {
// Adjacency iterator used in the chaining process
//
///////////////////////////////////////////////////////////
-class LIB_STROKE_EXPORT AdjacencyIterator : public Iterator
+class AdjacencyIterator : public Iterator
{
protected:
ViewVertexInternal::orientedViewEdgeIterator _internalIterator;
@@ -152,7 +150,7 @@ protected:
* If you specify restriction rules (such as "Chain only ViewEdges of the selection"), they will be included
* in the adjacency iterator. (i.e, the adjacent iterator will only stop on "valid" edges).
*/
-class LIB_STROKE_EXPORT ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator
+class ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator
{
protected:
bool _restrictToSelection;
@@ -161,7 +159,7 @@ protected:
public:
ViewEdge *result;
- PyObject *py_c_it;
+ void *py_c_it;
/*! Builds a Chaining Iterator from the first ViewEdge used for iteration and its orientation.
* \param iRestrictToSelection
@@ -203,10 +201,7 @@ public:
* This method is called each time a new chain is started.
* It can be used to reset some history information that you might want to keep.
*/
- virtual int init()
- {
- return Director_BPy_ChainingIterator_init(this);
- }
+ virtual int init();
/*! This method iterates over the potential next ViewEdges and returns the one that will be followed next.
* returns the next ViewEdge to follow or 0 when the end of the chain is reached.
@@ -214,10 +209,7 @@ public:
* The iterator over the ViewEdges adjacent to the end vertex of the current ViewEdge.
* The Adjacency iterator reflects the restriction rules by only iterating over the valid ViewEdges.
*/
- virtual int traverse(const AdjacencyIterator &it)
- {
- return Director_BPy_ChainingIterator_traverse(this, const_cast<AdjacencyIterator &>(it));
- }
+ virtual int traverse(const AdjacencyIterator &it);
/* accessors */
/*! Returns true if the orientation of the current ViewEdge corresponds to its natural orientation */
@@ -266,7 +258,7 @@ public:
* In the case of an iteration over a set of ViewEdge that are both Silhouette and Crease, there will be a precedence
* of the silhouette over the crease criterion.
*/
-class LIB_STROKE_EXPORT ChainSilhouetteIterator : public ChainingIterator
+class ChainSilhouetteIterator : public ChainingIterator
{
public:
/*! Builds a ChainSilhouetteIterator from the first ViewEdge used for iteration and its orientation.
@@ -317,7 +309,7 @@ public:
* selection. The first ViewEdge respecting both the unary predicate and the binary predicate is kept as the next one.
* If none of the potential next ViewEdge respects these 2 predicates, 0 is returned.
*/
-class LIB_STROKE_EXPORT ChainPredicateIterator : public ChainingIterator
+class ChainPredicateIterator : public ChainingIterator
{
protected:
BinaryPredicate1D *_binary_predicate; // the caller is responsible for the deletion of this object
diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.h b/source/blender/freestyle/intern/stroke/ContextFunctions.h
index 28ce918e919..d8b780e77a0 100644
--- a/source/blender/freestyle/intern/stroke/ContextFunctions.h
+++ b/source/blender/freestyle/intern/stroke/ContextFunctions.h
@@ -45,27 +45,22 @@ namespace ContextFunctions {
// GetTimeStamp
/*! Returns the system time stamp */
-LIB_STROKE_EXPORT
unsigned GetTimeStampCF();
// GetCanvasWidth
/*! Returns the canvas width */
-LIB_STROKE_EXPORT
unsigned GetCanvasWidthCF();
// GetCanvasHeight
/*! Returns the canvas height */
-LIB_STROKE_EXPORT
unsigned GetCanvasHeightCF();
// GetBorder
/*! Returns the border */
-LIB_STROKE_EXPORT
BBox<Vec2i> GetBorderCF();
// Load map
/*! Loads an image map for further reading */
-LIB_STROKE_EXPORT
void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels = 4, float iSigma = 1.0f);
// ReadMapPixel
@@ -80,7 +75,6 @@ void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels =
* \param y
* The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner.
*/
-LIB_STROKE_EXPORT
float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y);
// ReadCompleteViewMapPixel
@@ -93,7 +87,6 @@ float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y);
* \param y
* The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner.
*/
-LIB_STROKE_EXPORT
float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y);
// ReadOrientedViewMapPixel
@@ -108,11 +101,9 @@ float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y);
* \param y
* The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner.
*/
-LIB_STROKE_EXPORT
float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y);
// DEBUG
-LIB_STROKE_EXPORT
FEdge *GetSelectedFEdgeCF();
} // end of namespace ContextFunctions
diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp
index af9c8c2869d..32cfac016d6 100644
--- a/source/blender/freestyle/intern/stroke/Curve.cpp
+++ b/source/blender/freestyle/intern/stroke/Curve.cpp
@@ -26,10 +26,11 @@
*/
#include "Curve.h"
-#include "CurveAdvancedIterators.h"
#include "CurveIterators.h"
+#include "CurveAdvancedIterators.h"
#include "BKE_global.h"
+#include "BLI_utildefines.h"
namespace Freestyle {
@@ -158,7 +159,7 @@ iA_B_eq_iB_A:
}
cerr << "Fatal error in CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3)" << endl;
}
- assert(__A != 0 && __B != 0);
+ BLI_assert(__A != 0 && __B != 0);
#if 0
_Point2d = __A->point2d() + _t2d * (__B->point2d() - __A->point2d());
@@ -475,7 +476,6 @@ real CurvePoint::curvature2d_as_angle() const
return __A->curvature2d_as_angle();
return ((1 - _t2d) * __A->curvature2d_as_angle() + _t2d * __B->curvature2d_as_angle());
}
-#endif
real CurvePoint::curvatureFredo() const
{
@@ -494,6 +494,7 @@ Vec2d CurvePoint::directionFredo () const
return __A->directionFredo();
return ((1 - _t2d) * __A->directionFredo() + _t2d * __B->directionFredo());
}
+#endif
/**********************************/
/* */
@@ -813,14 +814,12 @@ real Curve::local_average_density(float sigma, int iCombination ) const
return result;
#endif
}
-#endif
/* UNUSED */
// #define EPS_CURVA_DIR 0.01
void Curve::computeCurvatureAndOrientation ()
{
-#if 0
const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, prevV, v0;
Vec2d p0, p1, p2;
Vec3r p;
@@ -924,7 +923,7 @@ void Curve::computeCurvatureAndOrientation ()
p0 = p1;
p1 = p2;
}
-#endif
}
+#endif
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h
index 7e3b6732bff..17b9a5c0a1f 100644
--- a/source/blender/freestyle/intern/stroke/Curve.h
+++ b/source/blender/freestyle/intern/stroke/Curve.h
@@ -66,7 +66,7 @@ using namespace Geometry;
* Thus, a CurvePoint is built by lineraly interpolating two SVertex.
* CurvePoint can be used as virtual points while querying 0D information along a curve at a given resolution.
*/
-class LIB_STROKE_EXPORT CurvePoint : public Interface0D
+class CurvePoint : public Interface0D
{
public: // Implementation of Interface0D
/*! Returns the string "CurvePoint"*/
@@ -337,10 +337,10 @@ public:
Vec3r curvature2d_as_vector() const;
/*! angle in radians */
real curvature2d_as_angle() const;
-#endif
real curvatureFredo() const;
Vec2d directionFredo() const;
+#endif
};
@@ -365,7 +365,7 @@ class CurvePointIterator;
* SVertex is the type of the initial curve vertices.
* A Chain is a specialization of a Curve.
*/
-class LIB_STROKE_EXPORT Curve : public Interface1D
+class Curve : public Interface1D
{
public:
typedef CurvePoint Vertex;
@@ -422,8 +422,10 @@ public:
return "Curve";
}
+#if 0
/* fredo's curvature storage */
void computeCurvatureAndOrientation();
+#endif
/*! Adds a single vertex (CurvePoint) at the end of the Curve */
inline void push_vertex_back(Vertex *iVertex)
diff --git a/source/blender/freestyle/intern/stroke/CurveIterators.h b/source/blender/freestyle/intern/stroke/CurveIterators.h
index f2272f2f9a9..ff7b2d04385 100644
--- a/source/blender/freestyle/intern/stroke/CurveIterators.h
+++ b/source/blender/freestyle/intern/stroke/CurveIterators.h
@@ -43,15 +43,15 @@ namespace CurveInternal {
class CurvePointIterator : public Interface0DIteratorNested
{
public:
- friend class ::Curve;
+ friend class Freestyle::Curve;
public:
float _CurvilinearLength;
float _step;
- ::Curve::vertex_container::iterator __A;
- ::Curve::vertex_container::iterator __B;
- ::Curve::vertex_container::iterator _begin;
- ::Curve::vertex_container::iterator _end;
+ Curve::vertex_container::iterator __A;
+ Curve::vertex_container::iterator __B;
+ Curve::vertex_container::iterator _begin;
+ Curve::vertex_container::iterator _end;
int _n;
int _currentn;
float _t;
@@ -104,8 +104,8 @@ public:
virtual ~CurvePointIterator() {}
protected:
- inline CurvePointIterator(::Curve::vertex_container::iterator iA, ::Curve::vertex_container::iterator iB,
- ::Curve::vertex_container::iterator ibegin, ::Curve::vertex_container::iterator iend,
+ inline CurvePointIterator(Curve::vertex_container::iterator iA, Curve::vertex_container::iterator iB,
+ Curve::vertex_container::iterator ibegin, Curve::vertex_container::iterator iend,
int currentn, int n, float iCurveLength, float step, float t = 0.0f,
float iCurvilinearLength = 0.0f)
: Interface0DIteratorNested()
diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp
index 1ad8901fa7b..2e68aa0c1fa 100644
--- a/source/blender/freestyle/intern/stroke/Operators.cpp
+++ b/source/blender/freestyle/intern/stroke/Operators.cpp
@@ -38,10 +38,10 @@
namespace Freestyle {
-LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_view_edges_set;
-LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_chains_set;
-LIB_STROKE_EXPORT Operators::I1DContainer *Operators::_current_set = NULL;
-LIB_STROKE_EXPORT Operators::StrokesContainer Operators::_current_strokes_set;
+Operators::I1DContainer Operators::_current_view_edges_set;
+Operators::I1DContainer Operators::_current_chains_set;
+Operators::I1DContainer *Operators::_current_set = NULL;
+Operators::StrokesContainer Operators::_current_strokes_set;
int Operators::select(UnaryPredicate1D& pred)
{
@@ -106,7 +106,7 @@ int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& p
Chain *new_chain = new Chain(id);
++id;
- while (TRUE) {
+ while (true) {
new_chain->push_viewedge_back(*it, it.getOrientation());
if (modifier(**it) < 0) {
delete new_chain;
@@ -172,7 +172,7 @@ int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& p
Chain *new_chain = new Chain(id);
++id;
- while (TRUE) {
+ while (true) {
new_chain->push_viewedge_back(*it, it.getOrientation());
ts(**it);
++it;
@@ -349,7 +349,7 @@ int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred)
ViewEdgeIterator it_back(it);
--it_back;
#endif
- while (TRUE) {
+ while (true) {
new_chain->push_viewedge_back(*it, it.getOrientation());
ts(**it);
if (it.increment() < 0) {
diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h
index dcd61b8ce84..59ebec57246 100644
--- a/source/blender/freestyle/intern/stroke/Operators.h
+++ b/source/blender/freestyle/intern/stroke/Operators.h
@@ -53,7 +53,7 @@ namespace Freestyle {
* There are 4 classes of operators: Selection, Chaining, Splitting and Creating. All these operators are
* user controlled in the scripting language through Functors, Predicates and Shaders that are taken as arguments.
*/
-class LIB_STROKE_EXPORT Operators {
+class Operators {
public:
typedef vector<Interface1D*> I1DContainer;
diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
index 7958fbb311b..c802bf4291a 100644
--- a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
@@ -44,7 +44,7 @@ namespace Freestyle {
/* */
/**********************************/
-class LIB_STROKE_EXPORT PSStrokeRenderer : public StrokeRenderer
+class PSStrokeRenderer : public StrokeRenderer
{
public:
PSStrokeRenderer(const char *iFileName = NULL);
diff --git a/source/blender/render/intern/include/gammaCorrectionTables.h b/source/blender/freestyle/intern/stroke/Predicates0D.cpp
index 68bb15f7f4c..f189b2e38ea 100644
--- a/source/blender/render/intern/include/gammaCorrectionTables.h
+++ b/source/blender/freestyle/intern/stroke/Predicates0D.cpp
@@ -15,37 +15,27 @@
* 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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __GAMMACORRECTIONTABLES_H__
-#define __GAMMACORRECTIONTABLES_H__
-
-/** \file blender/render/intern/include/gammaCorrectionTables.h
- * \ingroup render
+/** \file blender/freestyle/intern/stroke/Predicates0D.cpp
+ * \ingroup freestyle
*/
-/**
- * Initialize the gamma lookup tables
- */
-void makeGammaTables(float gamma);
+#include "Predicates0D.h"
-/**
- * Apply gamma correction on col
- */
-float gammaCorrect(float col);
+#include "../python/Director.h"
-/**
- * Apply inverse gamma correction on col
- */
-float invGammaCorrect(float col);
+namespace Freestyle {
+
+int UnaryPredicate0D::operator()(Interface0DIterator& it)
+{
+ return Director_BPy_UnaryPredicate0D___call__(this, it);
+}
-#endif
+int BinaryPredicate0D::operator()(Interface0D& inter1, Interface0D& inter2)
+{
+ return Director_BPy_BinaryPredicate0D___call__(this, inter1, inter2);
+}
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h
index a6e7cbee042..6ce77649c31 100644
--- a/source/blender/freestyle/intern/stroke/Predicates0D.h
+++ b/source/blender/freestyle/intern/stroke/Predicates0D.h
@@ -29,8 +29,6 @@
* \date 01/07/2003
*/
-#include "../python/Director.h"
-
#include "../view_map/Functions0D.h"
#ifdef WITH_CXX_GUARDEDALLOC
@@ -54,7 +52,7 @@ class UnaryPredicate0D
{
public:
bool result;
- PyObject *py_up0D;
+ void *py_up0D;
/*! Default constructor. */
UnaryPredicate0D()
@@ -76,10 +74,7 @@ public:
* The Interface0DIterator pointing onto the Interface0D at which we wish to evaluate the predicate.
* \return true if the condition is satisfied, false otherwise.
*/
- virtual int operator()(Interface0DIterator& it)
- {
- return Director_BPy_UnaryPredicate0D___call__(this, it);
- }
+ virtual int operator()(Interface0DIterator& it);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryPredicate0D")
@@ -101,7 +96,7 @@ class BinaryPredicate0D
{
public:
bool result;
- PyObject *py_bp0D;
+ void *py_bp0D;
/*! Default constructor. */
BinaryPredicate0D()
@@ -126,10 +121,7 @@ public:
* The second Interface0D.
* \return true or false.
*/
- virtual int operator()(Interface0D& inter1, Interface0D& inter2)
- {
- return Director_BPy_BinaryPredicate0D___call__(this, inter1, inter2);
- }
+ virtual int operator()(Interface0D& inter1, Interface0D& inter2);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BinaryPredicate0D")
diff --git a/source/blender/compositor/nodes/COM_SeparateYCCANode.h b/source/blender/freestyle/intern/stroke/Predicates1D.cpp
index 542e1693932..7c5d777e57c 100644
--- a/source/blender/compositor/nodes/COM_SeparateYCCANode.h
+++ b/source/blender/freestyle/intern/stroke/Predicates1D.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Blender Foundation.
+ * ***** 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
@@ -15,24 +15,27 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor:
- * Dalai Felinto
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef _COM_SeparateYCCANode_h_
-#define _COM_SeparateYCCANode_h_
+/** \file blender/freestyle/intern/stroke/Predicates1D.cpp
+ * \ingroup freestyle
+ */
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-#include "COM_SeparateRGBANode.h"
+#include "Predicates1D.h"
-/**
- * @brief SeparateYCCANode
- * @ingroup Node
- */
-class SeparateYCCANode : public SeparateRGBANode {
-public:
- SeparateYCCANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
+#include "../python/Director.h"
+
+namespace Freestyle {
+
+int UnaryPredicate1D::operator()(Interface1D& inter)
+{
+ return Director_BPy_UnaryPredicate1D___call__(this, inter);
+}
+
+int BinaryPredicate1D::operator()(Interface1D& inter1, Interface1D& inter2)
+{
+ return Director_BPy_BinaryPredicate1D___call__(this, inter1, inter2);
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h
index 257f938bf30..46efeae9f12 100644
--- a/source/blender/freestyle/intern/stroke/Predicates1D.h
+++ b/source/blender/freestyle/intern/stroke/Predicates1D.h
@@ -33,8 +33,6 @@
#include "AdvancedFunctions1D.h"
-#include "../python/Director.h"
-
#include "../system/TimeStamp.h"
#include "../view_map/Interface1D.h"
@@ -61,7 +59,7 @@ class UnaryPredicate1D
{
public:
bool result;
- PyObject *py_up1D;
+ void *py_up1D;
/*! Default constructor. */
UnaryPredicate1D()
@@ -83,10 +81,7 @@ public:
* The Interface1D on which we wish to evaluate the predicate.
* \return true if the condition is satisfied, false otherwise.
*/
- virtual int operator()(Interface1D& inter)
- {
- return Director_BPy_UnaryPredicate1D___call__(this, inter);
- }
+ virtual int operator()(Interface1D& inter);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryPredicate1D")
@@ -108,7 +103,7 @@ class BinaryPredicate1D
{
public:
bool result;
- PyObject *py_bp1D;
+ void *py_bp1D;
/*! Default constructor. */
BinaryPredicate1D()
@@ -133,10 +128,7 @@ public:
* The second Interface1D.
* \return true or false.
*/
- virtual int operator()(Interface1D& inter1, Interface1D& inter2)
- {
- return Director_BPy_BinaryPredicate1D___call__(this, inter1, inter2);
- }
+ virtual int operator()(Interface1D& inter1, Interface1D& inter2);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BinaryPredicate1D")
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index 159e4a39849..6629de0fa04 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -26,8 +26,8 @@
*/
#include "Stroke.h"
-#include "StrokeAdvancedIterators.h"
#include "StrokeIterators.h"
+#include "StrokeAdvancedIterators.h"
#include "StrokeRenderer.h"
#include "BKE_global.h"
@@ -106,7 +106,7 @@ StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribut
for (int i = 0; i < 3; ++i)
_color[i] = (1 - t) * a1._color[i] + t * a2._color[i];
- _visible = true;
+ _visible = a1.isVisible();
// FIXME: to be checked (and enhanced)
if ((a1._userAttributesReal) && (a2._userAttributesReal)) {
@@ -393,6 +393,10 @@ Stroke::Stroke()
//_mediumType = DEFAULT_STROKE;
_mediumType = OPAQUE_MEDIUM;
_textureId = 0;
+ _textureStep = 1.0;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ _mtex[a] = NULL;
+ }
_tips = false;
_rep = NULL;
}
@@ -411,6 +415,15 @@ Stroke::Stroke(const Stroke& iBrother)
_sampling = iBrother._sampling;
_mediumType = iBrother._mediumType;
_textureId = iBrother._textureId;
+ _textureStep = iBrother._textureStep;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iBrother._mtex) {
+ _mtex[a] = iBrother._mtex[a];
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
_tips = iBrother._tips;
if (iBrother._rep)
_rep = new StrokeRep(*(iBrother._rep));
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index d116edc6ace..f6451d8e487 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -43,6 +43,14 @@
#include "MEM_guardedalloc.h"
#endif
+extern "C" {
+#include "DNA_material_types.h"
+}
+
+#ifndef MAX_MTEX
+#define MAX_MTEX 18
+#endif
+
namespace Freestyle {
//
@@ -53,7 +61,7 @@ namespace Freestyle {
/*! Class to define an attribute associated to a Stroke Vertex.
* This attribute stores the color, alpha and thickness values for a Stroke Vertex.
*/
-class LIB_STROKE_EXPORT StrokeAttribute
+class StrokeAttribute
{
public:
/*! default constructor */
@@ -314,7 +322,7 @@ private:
////////////////////////////////////////////////////////
/*! Class to define a stroke vertex. */
-class LIB_STROKE_EXPORT StrokeVertex : public CurvePoint
+class StrokeVertex : public CurvePoint
{
public: // Implementation of Interface0D
/*! Returns the string "StrokeVertex" */
@@ -489,7 +497,7 @@ class StrokeVertexIterator;
* This set of vertices defines the stroke's backbone geometry.
* Each of these stroke vertices defines the stroke's shape and appearance at this vertex position.
*/
-class LIB_STROKE_EXPORT Stroke : public Interface1D
+class Stroke : public Interface1D
{
public: // Implementation of Interface1D
/*! Returns the string "Stroke" */
@@ -528,9 +536,11 @@ private:
float _Length; // The stroke length
viewedge_container _ViewEdges;
float _sampling;
+ float _textureStep;
// StrokeRenderer *_renderer; // mark implementation OpenGL renderer
MediumType _mediumType;
unsigned int _textureId;
+ MTex *_mtex[MAX_MTEX];
bool _tips;
Vec2r _extremityOrientations[2]; // the orientations of the first and last extermity
StrokeRep *_rep;
@@ -635,6 +645,20 @@ public:
/*! Returns the id of the texture used to simulate th marks system for this Stroke */
inline unsigned int getTextureId() {return _textureId;}
+ /*! Returns the spacing of texture coordinates along the stroke lenght */
+ inline float getTextureStep() {return _textureStep;}
+
+ /*! Returns the texture used at given index to simulate the marks system for this Stroke */
+ inline MTex *getMTex(int idx) {
+ return _mtex[idx];
+ }
+
+ /*! Returns true if this Stroke has textures assigned, false otherwise. */
+ inline bool hasTex() const
+ {
+ return _mtex[0] != NULL;
+ }
+
/*! Returns true if this Stroke uses a texture with tips, false otherwise. */
inline bool hasTips() const
{
@@ -725,6 +749,24 @@ public:
_textureId = id;
}
+ /*! sets the spacing of texture coordinates along the stroke lenght. */
+ inline void setTextureStep(float step)
+ {
+ _textureStep = step;
+ }
+
+ /*! assigns a blender texture to the first available slot. */
+ inline int setMTex(MTex *mtex)
+ {
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (!_mtex[a]) {
+ _mtex[a] = mtex;
+ return 0;
+ }
+ }
+ return -1; /* no free slots */
+ }
+
/*! sets the flag telling whether this stroke is using a texture with tips or not. */
inline void setTips(bool iTips)
{
diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.h b/source/blender/freestyle/intern/stroke/StrokeIO.h
index daaf6239987..f3833e04143 100644
--- a/source/blender/freestyle/intern/stroke/StrokeIO.h
+++ b/source/blender/freestyle/intern/stroke/StrokeIO.h
@@ -36,13 +36,10 @@
namespace Freestyle {
-LIB_STROKE_EXPORT
ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute);
-LIB_STROKE_EXPORT
ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex);
-LIB_STROKE_EXPORT
ostream& operator<<(ostream& out, const Stroke& iStroke);
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/StrokeIterators.h b/source/blender/freestyle/intern/stroke/StrokeIterators.h
index 1082adfbf41..a8ec529fbfa 100644
--- a/source/blender/freestyle/intern/stroke/StrokeIterators.h
+++ b/source/blender/freestyle/intern/stroke/StrokeIterators.h
@@ -66,9 +66,9 @@ public:
_end = vi._end;
}
- StrokeVertexIterator(const ::Stroke::vertex_container::iterator& it,
- const ::Stroke::vertex_container::iterator& begin,
- const ::Stroke::vertex_container::iterator& end)
+ StrokeVertexIterator(const Stroke::vertex_container::iterator& it,
+ const Stroke::vertex_container::iterator& begin,
+ const Stroke::vertex_container::iterator& end)
{
_it = it;
_begin = begin;
@@ -208,15 +208,15 @@ public:
// Not exported in Python
//
//////////////////////////////////////////////////
- const ::Stroke::vertex_container::iterator& getIt()
+ const Stroke::vertex_container::iterator& getIt()
{
return _it;
}
private:
- ::Stroke::vertex_container::iterator _it;
- ::Stroke::vertex_container::iterator _begin;
- ::Stroke::vertex_container::iterator _end;
+ Stroke::vertex_container::iterator _it;
+ Stroke::vertex_container::iterator _begin;
+ Stroke::vertex_container::iterator _end;
};
} // end of namespace StrokeInternal
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
index f9d7413e2f9..d7b37d65a6d 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
@@ -41,7 +41,6 @@ namespace Freestyle {
/* */
/**********************************/
-LIB_STROKE_EXPORT
TextureManager *StrokeRenderer::_textureManager = 0;
StrokeRenderer::StrokeRenderer() {}
@@ -64,13 +63,10 @@ bool StrokeRenderer::loadTextures()
/**********************************/
-LIB_STROKE_EXPORT
TextureManager *TextureManager::_pInstance = 0;
-LIB_STROKE_EXPORT
string TextureManager::_patterns_path;
-LIB_STROKE_EXPORT
string TextureManager::_brushes_path;
TextureManager::TextureManager()
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
index 90f41a0d0ac..868f61224de 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
@@ -55,7 +55,7 @@ namespace Freestyle {
/*! Class to load textures */
-class LIB_STROKE_EXPORT TextureManager
+class TextureManager
{
public:
TextureManager ();
@@ -79,7 +79,7 @@ public:
return _defaultTextureId;
}
- struct LIB_STROKE_EXPORT Options
+ struct Options
{
static void setPatternsPath(const string& path);
static string getPatternsPath();
@@ -128,7 +128,7 @@ protected:
/**********************************/
/*! Class to render a stroke. Creates a triangle strip and stores it strip is lazily created at the first rendering */
-class LIB_STROKE_EXPORT StrokeRenderer
+class StrokeRenderer
{
public:
StrokeRenderer();
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index fb6da853e02..8e84228f37f 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -26,8 +26,8 @@
*/
#include "Stroke.h"
-#include "StrokeAdvancedIterators.h"
#include "StrokeIterators.h"
+#include "StrokeAdvancedIterators.h"
#include "StrokeRenderer.h"
#include "StrokeRep.h"
@@ -45,6 +45,7 @@ StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother)
{
_point2d = iBrother._point2d;
_texCoord = iBrother._texCoord;
+ _texCoord_w_tips = iBrother._texCoord_w_tips;
_color = iBrother._color;
_alpha = iBrother._alpha;
}
@@ -53,13 +54,17 @@ StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother)
// STRIP
/////////////////////////////////////
-Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip)
+Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTex, bool beginTip, bool endTip, float texStep)
{
createStrip(iStrokeVertices);
- if (!hasTips)
- computeTexCoord (iStrokeVertices);
- else
- computeTexCoordWithTips (iStrokeVertices, beginTip, endTip);
+
+ setVertexColor(iStrokeVertices);
+
+ if (hasTex) {
+ // We compute both kinds of coordinates to use different kinds of textures
+ computeTexCoord(iStrokeVertices, texStep);
+ computeTexCoordWithTips(iStrokeVertices, beginTip, endTip, texStep);
+ }
}
Strip::Strip(const Strip& iBrother)
@@ -482,24 +487,20 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
}
-// Texture coordinates
+// Vertex color (RGBA)
////////////////////////////////
-void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices)
+void Strip::setVertexColor (const vector<StrokeVertex *>& iStrokeVertices)
{
vector<StrokeVertex *>::const_iterator v, vend;
StrokeVertex *sv;
int i = 0;
for (v = iStrokeVertices.begin(), vend = iStrokeVertices.end(); v != vend; v++) {
sv = (*v);
- _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 0));
- _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
+ _vertices[i]->setColor(Vec3r(sv->attribute().getColorRGB()));
_vertices[i]->setAlpha(sv->attribute().getAlpha());
i++;
- _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 1));
- _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
+ _vertices[i]->setColor(Vec3r(sv->attribute().getColorRGB()));
_vertices[i]->setAlpha(sv->attribute().getAlpha());
i++;
#if 0
@@ -509,23 +510,41 @@ void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices)
}
}
-void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd)
+
+// Texture coordinates
+////////////////////////////////
+
+void Strip::computeTexCoord (const vector<StrokeVertex *>& iStrokeVertices, float texStep)
+{
+ vector<StrokeVertex *>::const_iterator v, vend;
+ StrokeVertex *sv;
+ int i = 0;
+ for (v = iStrokeVertices.begin(), vend = iStrokeVertices.end(); v != vend; v++) {
+ sv = (*v);
+ _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / (_averageThickness * texStep)), 0));
+ i++;
+ _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / (_averageThickness * texStep)), 1));
+ i++;
+ }
+}
+
+void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd, float texStep)
{
- //soc unused - unsigned int sizeStrip = _vertices.size() + 8; //for the transition between the tip and the body
vector<StrokeVertex*>::const_iterator v, vend;
StrokeVertex *sv = NULL;
+ StrokeVertexRep *tvRep[2] = {NULL};
+
+ float l, fact, t;
+ float u = 0, uPrev = 0;
+ int tiles;
+ int i = 0;
+ float spacedThickness = _averageThickness * texStep;
v = iStrokeVertices.begin();
vend = iStrokeVertices.end();
- float l = (*v)->strokeLength() / _averageThickness;
- int tiles = int(l);
- float fact = (float(tiles) + 0.5) / l;
- //soc unused - float uTip2 = float(tiles) + 0.25;
- float u = 0;
- float uPrev = 0;
- int i = 0;
- float t;
- StrokeVertexRep *tvRep1, *tvRep2;
+ l = (*v)->strokeLength() / spacedThickness;
+ tiles = int(l + 0.5); // round to the nearest
+ fact = (float(tiles) + 0.5) / l;
#if 0
cerr << "l=" << l << " tiles=" << tiles << " _averageThicnkess="
@@ -538,166 +557,122 @@ void Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertice
for (; v != vend; v++) {
sv = (*v);
svRep = *currentSV;
- u = sv->curvilinearAbscissa() / _averageThickness * fact;
+ u = sv->curvilinearAbscissa() / spacedThickness * fact;
if (u > 0.25)
break;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 1));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 1), true);
i++;
++currentSV;
uPrev = u;
}
- //first transition vertex
-
- if (fabs(u - uPrev) > ZERO)
- t = (0.25 - uPrev) / (u - uPrev);
- else
- t = 0;
-#if 0
- if (!tiles)
- t = 0.5;
-#endif
- tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep1->setTexCoord(Vec2r(0.25, 0.5));
- tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
- tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t *_vertices[i]->point2d()));
- tvRep2->setTexCoord(Vec2r(0.25, 1));
- tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
-
- // copy the vertices with different texture coordinates
- tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep1->setTexCoord(Vec2r(0.25, 0));
- tvRep1->setColor(_vertices[i - 2]->color());
- tvRep1->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep2->setTexCoord(Vec2r(0.25, 0.5));
- tvRep2->setColor(_vertices[i - 2]->color());
- tvRep2->setAlpha(_vertices[i - 2]->alpha());
- i++;
+ if (v != vend && i >= 2) {
+ // first transition vertex
+ if (fabs(u - uPrev) > ZERO)
+ t = (0.25 - uPrev) / (u - uPrev);
+ else
+ t = 0;
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d());
+ tvRep[k]->setTexCoord((1 - t) * _vertices[i - 2]->texCoord() + t * _vertices[i]->texCoord());
+ // v coord is 0.5 for tvRep[0], 1.0 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.25, 0.5 * (k + 1)), true);
+ tvRep[k]->setColor((1 - t) * _vertices[i - 2]->color() + t * Vec3r(sv->attribute().getColorRGB()));
+ tvRep[k]->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
+ // copy the vertices with different texture coordinates
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep(*(_vertices[i - 2]));
+ // v coord is 0.0 for tvRep[0], 0.5 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.0, 0.5 * k), true); // FIXED u coord
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
+ }
}
uPrev = 0;
- //body of the stroke
+ // body of the stroke
for (; v != vend; v++) {
sv = (*v);
svRep = *currentSV;
- u = sv->curvilinearAbscissa() / _averageThickness * fact - 0.25;
+ u = sv->curvilinearAbscissa() / spacedThickness * fact - 0.25;
if (u > tiles)
break;
- svRep->setTexCoord(Vec2r((real)u, 0));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
uPrev = u;
}
- if (tipEnd) {
- //second transition vertex
- if ((fabs(u - uPrev) > ZERO))
- t = (float(tiles) - uPrev) / (u - uPrev);
- else
- t = 0;
-
- tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep1->setTexCoord(Vec2r((real)tiles, 0));
- tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
- tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d()));
- tvRep2->setTexCoord(Vec2r((real)tiles, 0.5));
- tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() +
- t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2])));
- tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
- i++;
-
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
-
- //copy the vertices with different texture coordinates
- tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep1->setTexCoord(Vec2r(0.75, 0.5));
- tvRep1->setColor(_vertices[i - 2]->color());
- tvRep1->setAlpha(_vertices[i - 2]->alpha());
- i++;
-
- tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d());
- tvRep2->setTexCoord(Vec2r(0.75, 1));
- tvRep2->setColor(_vertices[i - 2]->color());
- tvRep2->setAlpha(_vertices[i - 2]->alpha());
- i++;
+ if (tipEnd) {
+ if (v != vend && i >= 2) {
+ // second transition vertex
+ if (fabs(u - uPrev) > ZERO)
+ t = (float(tiles) - uPrev) / (u - uPrev);
+ else
+ t = 0;
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d());
+ tvRep[k]->setTexCoord((1 - t) * _vertices[i - 2]->texCoord() + t * _vertices[i]->texCoord());
+ // v coord is 0.0 for tvRep[0], 0.5 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r((real)tiles, 0.5 * k), true); // FIXED u coord
+ tvRep[k]->setColor((1 - t) * _vertices[i - 2]->color() + t * Vec3r(sv->attribute().getColorRGB()));
+ tvRep[k]->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha());
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
- currentSV = _vertices.insert(currentSV, tvRep1);
- ++currentSV;
- currentSV = _vertices.insert(currentSV, tvRep2);
- ++currentSV;
+ // copy the vertices with different texture coordinates
+ for (int k = 0; k < 2; k++) {
+ tvRep[k] = new StrokeVertexRep(*(_vertices[i - 2]));
+ // v coord is 0.5 for tvRep[0], 1.0 for tvRep[1]
+ tvRep[k]->setTexCoord(Vec2r(0.75, 0.5 * (k + 1)), true);
+ i++;
+ }
+ for (int k = 0; k < 2; k++) {
+ currentSV = _vertices.insert(currentSV, tvRep[k]);
+ ++currentSV;
+ }
+ }
- //end tip
+ // end tip
for (; v != vend; v++) {
- sv = (*v);
+ sv = (*v);
svRep = *currentSV;
- u = 0.75 + sv->curvilinearAbscissa() / _averageThickness * fact - float(tiles) - 0.25;
+ u = 0.75 + sv->curvilinearAbscissa() / spacedThickness * fact - float(tiles) - 0.25;
- svRep->setTexCoord(Vec2r((real)u, 0.5));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 0.5), true);
i++;
++currentSV;
svRep = *currentSV;
- svRep->setTexCoord(Vec2r((real)u, 1));
- svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1],
- sv->attribute().getColor()[2]));
- svRep->setAlpha(sv->attribute().getAlpha());
+ svRep->setTexCoord(Vec2r((real)u, 1), true);
i++;
++currentSV;
}
@@ -729,6 +704,10 @@ StrokeRep::StrokeRep()
{
_stroke = 0;
_strokeType = Stroke::OPAQUE_MEDIUM;
+ _textureStep = 1.0;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ _mtex[a] = NULL;
+ }
TextureManager *ptm = TextureManager::getInstance();
if (ptm)
_textureId = ptm->getDefaultTextureId();
@@ -746,6 +725,15 @@ StrokeRep::StrokeRep(Stroke *iStroke)
_stroke = iStroke;
_strokeType = iStroke->getMediumType();
_textureId = iStroke->getTextureId();
+ _textureStep = iStroke->getTextureStep();
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iStroke->getMTex(a)) {
+ _mtex[a] = iStroke->getMTex(a);
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
if (_textureId == 0) {
TextureManager *ptm = TextureManager::getInstance();
if (ptm)
@@ -768,6 +756,15 @@ StrokeRep::StrokeRep(const StrokeRep& iBrother)
_stroke = iBrother._stroke;
_strokeType = iBrother._strokeType;
_textureId = iBrother._textureId;
+ _textureStep = iBrother._textureStep;
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (iBrother._mtex[a]) {
+ _mtex[a] = iBrother._mtex[a];
+ }
+ else {
+ _mtex[a] = NULL;
+ }
+ }
for (vector<Strip*>::const_iterator s = iBrother._strips.begin(), send = iBrother._strips.end();
s != send;
++s)
@@ -811,7 +808,7 @@ void StrokeRep::create()
end = true;
}
if ((!strip.empty()) && (strip.size() > 1)) {
- _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end));
+ _strips.push_back(new Strip(strip, _stroke->hasTex(), first, end, _textureStep));
strip.clear();
}
first = false;
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h
index d01b27215fe..61a456cdf42 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.h
@@ -36,6 +36,10 @@
#include "MEM_guardedalloc.h"
#endif
+extern "C" {
+#include "DNA_material_types.h"
+}
+
namespace Freestyle {
using namespace Geometry;
@@ -78,9 +82,13 @@ public:
return _point2d;
}
- inline Vec2r& texCoord()
+ inline Vec2r& texCoord(bool tips=false)
{
- return _texCoord;
+ if (tips) {
+ return _texCoord_w_tips;
+ }
+ else
+ return _texCoord;
}
inline Vec3r& color()
@@ -98,9 +106,14 @@ public:
_point2d = p;
}
- inline void setTexCoord(const Vec2r& p)
+ inline void setTexCoord(const Vec2r& p, bool tips=false)
{
- _texCoord = p;
+ if (tips) {
+ _texCoord_w_tips = p;
+ }
+ else {
+ _texCoord = p;
+ }
}
inline void setColor(const Vec3r& p)
@@ -116,6 +129,7 @@ public:
protected:
Vec2r _point2d;
Vec2r _texCoord;
+ Vec2r _texCoord_w_tips;
Vec3r _color;
float _alpha;
@@ -134,16 +148,17 @@ protected:
float _averageThickness;
public:
- Strip(const std::vector<StrokeVertex*>& iStrokeVertices, bool hasTips = false,
- bool tipBegin = false, bool tipEnd = false);
+ Strip(const std::vector<StrokeVertex*>& iStrokeVertices, bool hasTex = false,
+ bool tipBegin = false, bool tipEnd = false, float texStep = 1.0);
Strip(const Strip& iBrother);
virtual ~Strip();
protected:
void createStrip(const std::vector<StrokeVertex*>& iStrokeVertices);
void cleanUpSingularities(const std::vector<StrokeVertex*>& iStrokeVertices);
- void computeTexCoord (const std::vector<StrokeVertex*>& iStrokeVertices);
- void computeTexCoordWithTips (const std::vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd);
+ void setVertexColor (const std::vector<StrokeVertex*>& iStrokeVertices);
+ void computeTexCoord (const std::vector<StrokeVertex*>& iStrokeVertices, float texStep);
+ void computeTexCoordWithTips (const std::vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd, float texStep);
public:
inline int sizeStrip() const
@@ -168,6 +183,9 @@ protected:
vector<Strip*> _strips;
Stroke::MediumType _strokeType;
unsigned int _textureId;
+ float _textureStep;
+ MTex *_mtex[MAX_MTEX];
+ Material *_material;
// float _averageTextureAlpha;
@@ -194,6 +212,16 @@ public:
return _textureId;
}
+ inline MTex *getMTex(int idx) const
+ {
+ return _mtex[idx];
+ }
+
+ inline Material *getMaterial() const
+ {
+ return _material;
+ }
+
inline vector<Strip*>& getStrips()
{
return _strips;
@@ -220,6 +248,16 @@ public:
_textureId = textureId;
}
+ inline void setMaterial(Material *mat)
+ {
+ _material = mat;
+ }
+ /*
+ inline void setMTex(int idx, MTex *mtex_ptr)
+ {
+ _mtex[idx] = mtex_ptr;
+ }*/
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeRep")
#endif
diff --git a/source/blender/compositor/nodes/COM_SeparateRGBANode.h b/source/blender/freestyle/intern/stroke/StrokeShader.cpp
index 35321304d99..4b21910a894 100644
--- a/source/blender/compositor/nodes/COM_SeparateRGBANode.h
+++ b/source/blender/freestyle/intern/stroke/StrokeShader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Blender Foundation.
+ * ***** 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
@@ -15,23 +15,22 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef _COM_SeparateRGBANode_h_
-#define _COM_SeparateRGBANode_h_
-
-#include "COM_Node.h"
-#include "DNA_node_types.h"
-/**
- * @brief SeparateRGBANode
- * @ingroup Node
+/** \file blender/freestyle/intern/stroke/StrokeShader.cpp
+ * \ingroup freestyle
*/
-class SeparateRGBANode : public Node {
-public:
- SeparateRGBANode(bNode *editorNode);
- void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
-};
-#endif
+
+#include "StrokeShader.h"
+
+#include "../python/Director.h"
+
+namespace Freestyle {
+
+int StrokeShader::shade(Stroke& ioStroke) const
+{
+ return Director_BPy_StrokeShader_shade( const_cast<StrokeShader *>(this), ioStroke);
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/StrokeShader.h b/source/blender/freestyle/intern/stroke/StrokeShader.h
index 4657e98be61..e655b80d397 100644
--- a/source/blender/freestyle/intern/stroke/StrokeShader.h
+++ b/source/blender/freestyle/intern/stroke/StrokeShader.h
@@ -32,12 +32,12 @@
#include <iostream>
#include <vector>
-#include "../python/Director.h"
-
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
+using namespace std;
+
namespace Freestyle {
//
@@ -72,10 +72,10 @@ class Stroke;
* }
* \endcode
*/
-class LIB_STROKE_EXPORT StrokeShader
+class StrokeShader
{
public:
- PyObject *py_ss;
+ void *py_ss;
/*! Default constructor. */
StrokeShader()
@@ -97,10 +97,7 @@ public:
* The stroke we wish to shade. this Stroke is modified by the Shader (which typically
* modifies the Stroke's attribute's values such as Color, Thickness, Geometry...)
*/
- virtual int shade(Stroke& ioStroke) const
- {
- return Director_BPy_StrokeShader_shade( const_cast<StrokeShader *>(this), ioStroke);
- }
+ virtual int shade(Stroke& ioStroke) const;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeShader")
diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
index 443e14bd0f3..fb221735fb1 100644
--- a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp
@@ -56,7 +56,7 @@ LineRep *StrokeTesselator::Tesselate(Stroke *iStroke)
}
else {
if (_overloadFrsMaterial)
- line->setFrsMaterial(_FrsMaterial);
+ line->setFrsMaterial(_FrsMaterial);
line->setStyle(LineRep::LINE_STRIP);
diff --git a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h
index 8e89847ca3d..02f7177b95c 100644
--- a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h
@@ -52,7 +52,7 @@ namespace Freestyle {
/* */
/**********************************/
-class LIB_STROKE_EXPORT TextStrokeRenderer : public StrokeRenderer
+class TextStrokeRenderer : public StrokeRenderer
{
public:
TextStrokeRenderer(const char *iFileName = NULL);
diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h
index 56f52a5fb80..8cabd9130b4 100644
--- a/source/blender/freestyle/intern/system/BaseObject.h
+++ b/source/blender/freestyle/intern/system/BaseObject.h
@@ -29,15 +29,13 @@
* \date 06/02/2002
*/
-#include "FreestyleConfig.h"
-
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class LIB_SYSTEM_EXPORT BaseObject
+class BaseObject
{
public:
inline BaseObject()
diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h
index dedc4152ae9..f605735ec40 100644
--- a/source/blender/freestyle/intern/system/Exception.h
+++ b/source/blender/freestyle/intern/system/Exception.h
@@ -28,15 +28,13 @@
* \date 10/01/2003
*/
-#include "FreestyleConfig.h"
-
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class LIB_SYSTEM_EXPORT Exception
+class Exception
{
public:
typedef enum {
diff --git a/source/blender/freestyle/intern/system/FreestyleConfig.h b/source/blender/freestyle/intern/system/FreestyleConfig.h
index 42f9833836d..752940d83a5 100644
--- a/source/blender/freestyle/intern/system/FreestyleConfig.h
+++ b/source/blender/freestyle/intern/system/FreestyleConfig.h
@@ -30,8 +30,6 @@
#include <string>
-#include "BLI_math.h"
-
using namespace std;
namespace Freestyle {
@@ -48,44 +46,6 @@ namespace Config {
static const string PATH_SEP(":");
#endif // WIN32
-// DLL import/export macros for Win32
-
-#ifndef LIB_SYSTEM_EXPORT
-# define LIB_SYSTEM_EXPORT
-#endif // LIB_SYSTEM_EXPORT
-
-#ifndef LIB_IMAGE_EXPORT
-# define LIB_IMAGE_EXPORT
-#endif // LIB_IMAGE_EXPORT
-
-#ifndef LIB_GEOMETRY_EXPORT
-# define LIB_GEOMETRY_EXPORT
-#endif // LIB_GEOMETRY_EXPORT
-
-#ifndef LIB_SCENE_GRAPH_EXPORT
-# define LIB_SCENE_GRAPH_EXPORT
-#endif // LIB_SCENE_GRAPH_EXPORT
-
-#ifndef LIB_WINGED_EDGE_EXPORT
-# define LIB_WINGED_EDGE_EXPORT
-#endif // LIB_WINGED_EDGE_EXPORT
-
-#ifndef LIB_VIEW_MAP_EXPORT
-# define LIB_VIEW_MAP_EXPORT
-#endif // LIB_VIEW_MAP_EXPORT
-
-#ifndef LIB_STROKE_EXPORT
-# define LIB_STROKE_EXPORT
-#endif // LIB_STROKE_EXPORT
-
-#ifndef LIB_RENDERING_EXPORT
-# define LIB_RENDERING_EXPORT
-#endif // LIB_RENDERING_EXPORT
-
-#ifndef LIB_WRAPPER_EXPORT
-# define LIB_WRAPPER_EXPORT
-#endif // LIB_WRAPPER_EXPORT
-
} // end of namespace Config
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h
index e1269f40468..74af9f82b12 100644
--- a/source/blender/freestyle/intern/system/Interpreter.h
+++ b/source/blender/freestyle/intern/system/Interpreter.h
@@ -38,7 +38,7 @@ using namespace std;
namespace Freestyle {
-class LIB_SYSTEM_EXPORT Interpreter
+class Interpreter
{
public:
Interpreter()
@@ -46,7 +46,7 @@ public:
_language = "Unknown";
}
- virtual ~Interpreter() {}; //soc
+ virtual ~Interpreter() {}
virtual int interpretFile(const string& filename) = 0;
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp
index 6083a46d609..4949cb8c430 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.cpp
+++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp
@@ -26,6 +26,7 @@
*/
#include "BLI_math.h"
+#include "BLI_utildefines.h"
#include "PseudoNoise.h"
#include "RandGen.h"
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.h b/source/blender/freestyle/intern/system/PseudoNoise.h
index e53d8ed7a7a..602ad5293f0 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.h
+++ b/source/blender/freestyle/intern/system/PseudoNoise.h
@@ -28,7 +28,6 @@
* \date 16/06/2003
*/
-#include "FreestyleConfig.h"
#include "Precision.h"
#ifdef WITH_CXX_GUARDEDALLOC
@@ -37,7 +36,7 @@
namespace Freestyle {
-class LIB_SYSTEM_EXPORT PseudoNoise
+class PseudoNoise
{
public:
PseudoNoise();
diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.cpp b/source/blender/freestyle/intern/system/PythonInterpreter.cpp
index 9e7ef39a0e4..852030e365b 100644
--- a/source/blender/freestyle/intern/system/PythonInterpreter.cpp
+++ b/source/blender/freestyle/intern/system/PythonInterpreter.cpp
@@ -26,10 +26,3 @@
*/
#include "PythonInterpreter.h"
-
-namespace Freestyle {
-
-string PythonInterpreter::_path = "";
-bool PythonInterpreter::_initialized = false;
-
-} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h
index 30ee6d30163..60193590944 100644
--- a/source/blender/freestyle/intern/system/PythonInterpreter.h
+++ b/source/blender/freestyle/intern/system/PythonInterpreter.h
@@ -29,7 +29,10 @@
*/
#include <iostream>
+
+extern "C" {
#include <Python.h>
+}
#include "StringUtils.h"
#include "Interpreter.h"
@@ -52,7 +55,7 @@ extern "C" {
namespace Freestyle {
-class LIB_SYSTEM_EXPORT PythonInterpreter : public Interpreter
+class PythonInterpreter : public Interpreter
{
public:
PythonInterpreter()
@@ -60,12 +63,6 @@ public:
_language = "Python";
_context = 0;
memset(&_freestyle_bmain, 0, sizeof(Main));
- //Py_Initialize();
- }
-
- virtual ~PythonInterpreter()
- {
- //Py_Finalize();
}
void setContext(bContext *C)
@@ -75,8 +72,6 @@ public:
int interpretFile(const string& filename)
{
- initPath();
-
ReportList *reports = CTX_wm_reports(_context);
BKE_reports_clear(reports);
char *fn = const_cast<char*>(filename.c_str());
@@ -112,8 +107,6 @@ public:
int interpretText(struct Text *text, const string& name)
{
- initPath();
-
ReportList *reports = CTX_wm_reports(_context);
BKE_reports_clear(reports);
@@ -131,63 +124,14 @@ public:
return 0;
}
- struct Options
- {
- static void setPythonPath(const string& path)
- {
- _path = path;
- }
-
- static string getPythonPath()
- {
- return _path;
- }
- };
-
void reset()
{
- Py_Finalize();
- Py_Initialize();
- _initialized = false;
+ // nothing to do
}
private:
bContext *_context;
Main _freestyle_bmain;
-
- void initPath()
- {
- if (_initialized)
- return;
-
- vector<string> pathnames;
- StringUtils::getPathName(_path, "", pathnames);
-
- struct Text *text = BKE_text_add(&_freestyle_bmain, "tmp_freestyle_initpath.txt");
- string cmd = "import sys\n";
- txt_insert_buf(text, const_cast<char*>(cmd.c_str()));
-
- for (vector<string>::const_iterator it = pathnames.begin(); it != pathnames.end(); ++it) {
- if (!it->empty()) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Adding Python path: " << *it << endl;
- }
- cmd = "sys.path.append(r\"" + *it + "\")\n";
- txt_insert_buf(text, const_cast<char *>(cmd.c_str()));
- }
- }
-
- BPY_text_exec(_context, text, NULL, false);
-
- // cleaning up
- BKE_text_unlink(&_freestyle_bmain, text);
- BKE_libblock_free(&_freestyle_bmain, text);
-
- _initialized = true;
- }
-
- static bool _initialized;
- static string _path;
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h
index 3c8724bcbee..d39b4f95bbf 100644
--- a/source/blender/freestyle/intern/system/RandGen.h
+++ b/source/blender/freestyle/intern/system/RandGen.h
@@ -30,8 +30,6 @@
// TODO Check whether we could replace this with BLI rand stuff...
-#include "FreestyleConfig.h"
-
#include "../system/Precision.h"
#ifdef WITH_CXX_GUARDEDALLOC
@@ -40,7 +38,7 @@
namespace Freestyle {
-class LIB_SYSTEM_EXPORT RandGen
+class RandGen
{
public:
static real drand48();
diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h
index 92600eddc42..77b543c7886 100644
--- a/source/blender/freestyle/intern/system/StringUtils.h
+++ b/source/blender/freestyle/intern/system/StringUtils.h
@@ -34,15 +34,9 @@
#include <string>
#include <vector>
-#include "FreestyleConfig.h"
-
-//soc
extern "C" {
-
#include "BKE_utildefines.h"
-
#include "BLI_blenlib.h"
-
}
using namespace std;
@@ -51,7 +45,6 @@ namespace Freestyle {
namespace StringUtils {
-LIB_SYSTEM_EXPORT
void getPathName(const string& path, const string& base, vector<string>& pathnames);
// STL related
diff --git a/source/blender/freestyle/intern/system/TimeStamp.cpp b/source/blender/freestyle/intern/system/TimeStamp.cpp
index 7c02095ad51..0e387a5cc54 100644
--- a/source/blender/freestyle/intern/system/TimeStamp.cpp
+++ b/source/blender/freestyle/intern/system/TimeStamp.cpp
@@ -29,7 +29,6 @@
namespace Freestyle {
-LIB_SYSTEM_EXPORT
TimeStamp TimeStamp::_instance;
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h
index e809aa71575..ccf370ad228 100644
--- a/source/blender/freestyle/intern/system/TimeStamp.h
+++ b/source/blender/freestyle/intern/system/TimeStamp.h
@@ -28,15 +28,13 @@
* \date 12/12/2002
*/
-#include "FreestyleConfig.h"
-
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class LIB_SYSTEM_EXPORT TimeStamp
+class TimeStamp
{
public:
static inline TimeStamp *instance()
diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h
index 6fe8b0e7431..2d14adc5912 100644
--- a/source/blender/freestyle/intern/system/TimeUtils.h
+++ b/source/blender/freestyle/intern/system/TimeUtils.h
@@ -30,8 +30,6 @@
#include <time.h>
-#include "FreestyleConfig.h"
-
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h
index 92f886ef429..0ef4ce37b11 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.h
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.h
@@ -28,7 +28,7 @@
* \date 2011-1-29
*/
-#define BOX_GRID_LOGGING FALSE
+#define BOX_GRID_LOGGING 0
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector>
// separately results in redefinitions of identifiers. ViewMap.h already includes <vector>
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
index 2a1388c939b..d98a3238a25 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
@@ -27,8 +27,6 @@
#include "CulledOccluderSource.h"
-#include "FRS_freestyle.h"
-
#include "../geometry/GridHelpers.h"
#include "BKE_global.h"
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index 2da82f175ed..9c9cd88f188 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -26,7 +26,6 @@
*/
#include <float.h>
-#include <math.h>
#include "FEdgeXDetector.h"
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 2bc0cd13e88..8adf685a6eb 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -39,6 +39,8 @@
#include "../winged_edge/Curvature.h"
#include "../winged_edge/WXEdge.h"
+#include "BLI_math.h"
+
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
@@ -48,7 +50,7 @@ namespace Freestyle {
using namespace Geometry;
/*! This class takes as input a WXEdge structure and fills it */
-class LIB_VIEW_MAP_EXPORT FEdgeXDetector
+class FEdgeXDetector
{
public:
FEdgeXDetector()
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.cpp b/source/blender/freestyle/intern/view_map/Functions0D.cpp
index f95690e6ff6..f47e5ff16d5 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions0D.cpp
@@ -182,9 +182,9 @@ int VertexOrientation3DF0D::operator()(Interface0DIterator& iter)
A = Vec3r(iter->getX(), iter->getY(), iter->getZ());
}
else {
- Interface0DIterator previous = iter;
- --previous ;
- A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
+ Interface0DIterator previous = iter;
+ --previous ;
+ A = Vec3r(previous->getX(), previous->getY(), previous->getZ());
}
Interface0DIterator next = iter;
++next ;
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.h b/source/blender/freestyle/intern/view_map/Functions0D.h
index e9474191319..045ad317db2 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.h
+++ b/source/blender/freestyle/intern/view_map/Functions0D.h
@@ -74,11 +74,11 @@ using namespace Geometry;
* - UnaryFunction0DVec3f
*/
template <class T>
-class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D
+class UnaryFunction0D
{
public:
T result;
- PyObject *py_uf0D;
+ void *py_uf0D;
/*! The type of the value returned by the functor. */
typedef T ReturnedValueType;
@@ -103,6 +103,7 @@ public:
* An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
* \return the result of the function of type T.
*/
+ /* FIXME move the implementation to Functions0D.cpp */
virtual int operator()(Interface0DIterator& iter)
{
return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
@@ -143,7 +144,7 @@ namespace Functions0D {
// GetXF0D
/*! Returns the X 3D coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real>
+class GetXF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetXF0D" */
@@ -162,7 +163,7 @@ public:
// GetYF0D
/*! Returns the Y 3D coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real>
+class GetYF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetYF0D" */
@@ -181,7 +182,7 @@ public:
// GetZF0D
/*! Returns the Z 3D coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real>
+class GetZF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetZF0D" */
@@ -200,7 +201,7 @@ public:
// GetProjectedXF0D
/*! Returns the X 3D projected coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real>
+class GetProjectedXF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetProjectedXF0D" */
@@ -219,7 +220,7 @@ public:
// GetProjectedYF0D
/*! Returns the Y projected 3D coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real>
+class GetProjectedYF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetProjectedYF0D" */
@@ -238,7 +239,7 @@ public:
// GetProjectedZF0D
/*! Returns the Z projected 3D coordinate of an Interface0D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real>
+class GetProjectedZF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "GetProjectedZF0D" */
@@ -257,7 +258,7 @@ public:
// GetCurvilinearAbscissaF0D
/*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
-class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
+class GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
@@ -276,7 +277,7 @@ public:
// GetParameterF0D
/*! Returns the parameter of an Interface0D in the context of its 1D element. */
-class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float>
+class GetParameterF0D : public UnaryFunction0D<float>
{
public:
/*! Returns the string "GetCurvilinearAbscissaF0D" */
@@ -297,7 +298,7 @@ public:
/*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
+class VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "VertexOrientation2DF0D" */
@@ -314,7 +315,7 @@ public:
/*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
+class VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
{
public:
/*! Returns the string "VertexOrientation3DF0D" */
@@ -331,7 +332,7 @@ public:
/*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
* belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real>
+class Curvature2DAngleF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "Curvature2DAngleF0D" */
@@ -349,7 +350,7 @@ public:
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no object is occluded
* by the shape to which the Interface0D belongs to, 1 is returned.
*/
-class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real>
+class ZDiscontinuityF0D : public UnaryFunction0D<double>
{
public:
/*! Returns the string "ZDiscontinuityF0D" */
@@ -366,7 +367,7 @@ public:
/*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
* evaluated at the Interface0D pointed by this Interface0DIterator&.
*/
-class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f>
+class Normal2DF0D : public UnaryFunction0D<Vec2f>
{
public:
/*! Returns the string "Normal2DF0D" */
@@ -388,7 +389,7 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getMaterial functor.
*/
-class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial>
+class MaterialF0D : public UnaryFunction0D<FrsMaterial>
{
public:
/*! Returns the string "MaterialF0D" */
@@ -409,7 +410,7 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getShapeIdF0D functor.
*/
-class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id>
+class ShapeIdF0D : public UnaryFunction0D<Id>
{
public:
/*! Returns the string "ShapeIdF0D" */
@@ -430,7 +431,7 @@ public:
* However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
* should implement its own getQIF0D functor.
*/
-class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
+class QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
@@ -445,7 +446,7 @@ public:
// CurveNatureF0D
/*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
-class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
+class CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
{
public:
/*! Returns the string "QuantitativeInvisibilityF0D" */
@@ -460,7 +461,7 @@ public:
// GetShapeF0D
/*! Returns the ViewShape* containing the Interface0D */
-class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*>
+class GetShapeF0D : public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetShapeF0D" */
@@ -475,7 +476,7 @@ public:
// GetOccludersF0D
/*! Returns a vector containing the ViewShape* occluding the Interface0D */
-class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
+class GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
{
public:
/*! Returns the string "GetOccludersF0D" */
@@ -490,7 +491,7 @@ public:
// GetOccludeeF0D
/*! Returns the ViewShape* "occluded" by the Interface0D */
-class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
+class GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
{
public:
/*! Returns the string "GetOccludeeF0D" */
@@ -507,27 +508,21 @@ public:
/////////////////////////// Internal ////////////////////////////
// getFEdge
-LIB_VIEW_MAP_EXPORT
FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
// getFEdges
-LIB_VIEW_MAP_EXPORT
void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
// getViewEdges
-LIB_VIEW_MAP_EXPORT
void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
// getShapeF0D
-LIB_VIEW_MAP_EXPORT
ViewShape *getShapeF0D(Interface0DIterator& it);
// getOccludersF0D
-LIB_VIEW_MAP_EXPORT
void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
// getOccludeeF0D
-LIB_VIEW_MAP_EXPORT
ViewShape *getOccludeeF0D(Interface0DIterator& it);
} // end of namespace Functions0D
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.cpp b/source/blender/freestyle/intern/view_map/Functions1D.cpp
index c66d8b8bfe7..f29da6680bf 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.cpp
+++ b/source/blender/freestyle/intern/view_map/Functions1D.cpp
@@ -26,7 +26,7 @@
* \date 01/07/2003
*/
-# include "Functions1D.h"
+#include "Functions1D.h"
using namespace std;
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h
index 7b10d1b5185..0821475ca9c 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.h
+++ b/source/blender/freestyle/intern/view_map/Functions1D.h
@@ -64,11 +64,11 @@ namespace Freestyle {
* - UnaryFunction1DVec3f
*/
template <class T>
-class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D
+class UnaryFunction1D
{
public:
T result;
- PyObject *py_uf1D;
+ void *py_uf1D;
/*! The type of the value returned by the functor. */
typedef T ReturnedValueType;
@@ -104,6 +104,7 @@ public:
* The Interface1D on which we wish to evaluate the function.
* \return the result of the function of type T.
*/
+ /* FIXME move the implementation to Functions1D.cpp */
virtual int operator()(Interface1D& inter)
{
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
@@ -133,7 +134,7 @@ protected:
class UnaryFunction1D_void
{
public:
- PyObject *py_uf1D;
+ void *py_uf1D;
UnaryFunction1D_void()
{
@@ -152,6 +153,7 @@ public:
return "UnaryFunction1D_void";
}
+ /* FIXME move the implementation to Functions1D.cpp */
int operator()(Interface1D& inter)
{
return Director_BPy_UnaryFunction1D___call__(this, py_uf1D, inter);
@@ -185,7 +187,7 @@ namespace Functions1D {
// GetXF1D
/*! Returns the X 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real>
+class GetXF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetXF0D _func;
@@ -195,7 +197,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType) {}
+ GetXF1D(IntegrationType iType) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetXF1D" */
string getName() const
@@ -209,7 +211,7 @@ public:
// GetYF1D
/*! Returns the Y 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real>
+class GetYF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetYF0D _func;
@@ -219,7 +221,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetYF1D" */
string getName() const
@@ -233,7 +235,7 @@ public:
// GetZF1D
/*! Returns the Z 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real>
+class GetZF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetZF0D _func;
@@ -243,7 +245,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetZF1D" */
string getName() const
@@ -257,7 +259,7 @@ public:
// GetProjectedXF1D
/*! Returns the projected X 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real>
+class GetProjectedXF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetProjectedXF0D _func;
@@ -267,7 +269,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetProjectedXF1D" */
string getName() const
@@ -281,7 +283,7 @@ public:
// GetProjectedYF1D
/*! Returns the projected Y 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real>
+class GetProjectedYF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetProjectedYF0D _func;
@@ -291,7 +293,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetProjectedYF1D" */
string getName() const
@@ -305,7 +307,7 @@ public:
// GetProjectedZF1D
/*! Returns the projected Z 3D coordinate of an Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real>
+class GetProjectedZF1D : public UnaryFunction1D<double>
{
private:
Functions0D::GetProjectedZF0D _func;
@@ -315,7 +317,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "GetProjectedZF1D" */
string getName() const
@@ -329,7 +331,7 @@ public:
// Orientation2DF1D
/*! Returns the 2D orientation as a Vec2f*/
-class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f>
+class Orientation2DF1D : public UnaryFunction1D<Vec2f>
{
private:
Functions0D::VertexOrientation2DF0D _func;
@@ -353,7 +355,7 @@ public:
// Orientation3DF1D
/*! Returns the 3D orientation as a Vec3f. */
-class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f>
+class Orientation3DF1D : public UnaryFunction1D<Vec3f>
{
private:
Functions0D::VertexOrientation3DF0D _func;
@@ -380,7 +382,7 @@ public:
* This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no object is occluded
* by the shape to which the Interface1D belongs to, 1 is returned.
*/
-class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real>
+class ZDiscontinuityF1D : public UnaryFunction1D<double>
{
private:
Functions0D::ZDiscontinuityF0D _func;
@@ -390,7 +392,7 @@ public:
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "ZDiscontinuityF1D" */
string getName() const
@@ -408,7 +410,7 @@ public:
* results of a chaining (chain, stroke), then it might be made of several 1D elements of different
* Quantitative Invisibilities.
*/
-class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
+class QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned>
{
private:
Functions0D::QuantitativeInvisibilityF0D _func;
@@ -436,7 +438,7 @@ public:
* Indeed, the Interface1D might result from the gathering of several 1D elements, each one being of a different
* nature. An integration method, such as the MEAN, might give, in this case, irrelevant results.
*/
-class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
+class CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature>
{
private:
Functions0D::CurveNatureF0D _func;
@@ -460,7 +462,7 @@ public:
// TimeStampF1D
/*! Returns the time stamp of the Interface1D. */
-class LIB_VIEW_MAP_EXPORT TimeStampF1D : public UnaryFunction1D_void
+class TimeStampF1D : public UnaryFunction1D_void
{
public:
/*! Returns the string "TimeStampF1D" */
@@ -475,7 +477,7 @@ public:
// IncrementChainingTimeStampF1D
/*! Increments the chaining time stamp of the Interface1D. */
-class LIB_VIEW_MAP_EXPORT IncrementChainingTimeStampF1D : public UnaryFunction1D_void
+class IncrementChainingTimeStampF1D : public UnaryFunction1D_void
{
public:
/*! Returns the string "IncrementChainingTimeStampF1D" */
@@ -490,7 +492,7 @@ public:
// ChainingTimeStampF1D
/*! Sets the chaining time stamp of the Interface1D. */
-class LIB_VIEW_MAP_EXPORT ChainingTimeStampF1D : public UnaryFunction1D_void
+class ChainingTimeStampF1D : public UnaryFunction1D_void
{
public:
/*! Returns the string "ChainingTimeStampF1D" */
@@ -506,14 +508,14 @@ public:
// Curvature2DAngleF1D
/*! Returns the 2D curvature as an angle for an Interface1D. */
-class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real>
+class Curvature2DAngleF1D : public UnaryFunction1D<double>
{
public:
/*! Builds the functor.
* \param iType
* The integration method used to compute a single value from a set of values.
*/
- Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {}
+ Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<double>(iType) {}
/*! Returns the string "Curvature2DAngleF1D" */
string getName() const
@@ -534,7 +536,7 @@ private:
// Normal2DF1D
/*! Returns the 2D normal for an interface 1D. */
-class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f>
+class Normal2DF1D : public UnaryFunction1D<Vec2f>
{
public:
/*! Builds the functor.
@@ -562,7 +564,7 @@ private:
// GetShapeF1D
/*! Returns list of shapes covered by this Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
+class GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{
public:
/*! Builds the functor. */
@@ -580,7 +582,7 @@ public:
// GetOccludersF1D
/*! Returns list of occluding shapes covered by this Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
+class GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{
public:
/*! Builds the functor. */
@@ -598,7 +600,7 @@ public:
// GetOccludeeF1D
/*! Returns list of occluded shapes covered by this Interface1D. */
-class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
+class GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> >
{
public:
/*! Builds the functor. */
@@ -618,15 +620,12 @@ public:
////////////
// getOccludeeF1D
-LIB_VIEW_MAP_EXPORT
void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
// getOccludersF1D
-LIB_VIEW_MAP_EXPORT
void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes);
// getShapeF1D
-LIB_VIEW_MAP_EXPORT
void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes);
} // end of namespace Functions1D
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.cpp b/source/blender/freestyle/intern/view_map/Interface0D.cpp
new file mode 100644
index 00000000000..135a935d2fe
--- /dev/null
+++ b/source/blender/freestyle/intern/view_map/Interface0D.cpp
@@ -0,0 +1,123 @@
+/*
+ * ***** 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/view_map/Interface0D.cpp
+ * \ingroup freestyle
+ */
+
+extern "C" {
+#include <Python.h>
+}
+
+#include "Interface0D.h"
+
+namespace Freestyle {
+
+real Interface0D::getX() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
+ return 0;
+}
+
+real Interface0D::getY() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
+ return 0;
+}
+
+real Interface0D::getZ() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
+ return 0;
+}
+
+Geometry::Vec3f Interface0D::getPoint3D() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
+ return 0;
+}
+
+real Interface0D::getProjectedX() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
+ return 0;
+}
+
+real Interface0D::getProjectedY() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
+ return 0;
+}
+
+real Interface0D::getProjectedZ() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
+ return 0;
+}
+
+Geometry::Vec2f Interface0D::getPoint2D() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
+ return 0;
+}
+
+FEdge * Interface0D::getFEdge(Interface0D&)
+{
+ PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
+ return 0;
+}
+
+Id Interface0D::getId() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return 0;
+}
+
+Nature::VertexNature Interface0D::getNature() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::POINT;
+}
+
+SVertex * Interface0D::castToSVertex()
+{
+ PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
+ return 0;
+}
+
+ViewVertex * Interface0D::castToViewVertex()
+{
+ PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
+ return 0;
+}
+
+NonTVertex * Interface0D::castToNonTVertex()
+{
+ PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
+ return 0;
+}
+
+TVertex * Interface0D::castToTVertex()
+{
+ PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
+ return 0;
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h
index c9776bb77fa..e59ed4c96c8 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.h
+++ b/source/blender/freestyle/intern/view_map/Interface0D.h
@@ -29,13 +29,12 @@
*/
#include <iostream>
-#include <Python.h>
#include <string>
#include "../geometry/Geom.h"
#include "../system/Id.h"
-#include "../system/Iterator.h" //soc
+#include "../system/Iterator.h"
#include "../system/Precision.h"
#include "../winged_edge/Nature.h"
@@ -65,7 +64,9 @@ class Interface0D
public:
/*! Default constructor */
Interface0D() {}
- virtual ~Interface0D() {}; //soc
+
+ /*! Destructor */
+ virtual ~Interface0D() {};
/*! Returns the string "Interface0D". */
virtual string getExactTypeName() const
@@ -76,110 +77,49 @@ public:
// Data access methods
/*! Returns the 3D x coordinate of the point. */
- virtual real getX() const
- {
- PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden");
- return 0;
- }
+ virtual real getX() const;
/*! Returns the 3D y coordinate of the point. */
- virtual real getY() const
- {
- PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden");
- return 0;
- }
+ virtual real getY() const;
- /*! Returns the 3D z coordinate of the point. */
- virtual real getZ() const
- {
- PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden");
- return 0;
- }
+ /*! Returns the 3D z coordinate of the point. */
+ virtual real getZ() const;
- /*! Returns the 3D point. */
- virtual Geometry::Vec3f getPoint3D() const
- {
- PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden");
- return 0;
- }
+ /*! Returns the 3D point. */
+ virtual Geometry::Vec3f getPoint3D() const;
/*! Returns the 2D x coordinate of the point. */
- virtual real getProjectedX() const
- {
- PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden");
- return 0;
- }
+ virtual real getProjectedX() const;
/*! Returns the 2D y coordinate of the point. */
- virtual real getProjectedY() const
- {
- PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden");
- return 0;
- }
+ virtual real getProjectedY() const;
/*! Returns the 2D z coordinate of the point. */
- virtual real getProjectedZ() const
- {
- PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden");
- return 0;
- }
+ virtual real getProjectedZ() const;
- /*! Returns the 2D point. */
- virtual Geometry::Vec2f getPoint2D() const
- {
- PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden");
- return 0;
- }
+ /*! Returns the 2D point. */
+ virtual Geometry::Vec2f getPoint2D() const;
/*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */
- virtual FEdge *getFEdge(Interface0D&)
- {
- PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
- return 0;
- }
+ virtual FEdge *getFEdge(Interface0D&);
/*! Returns the Id of the point. */
- virtual Id getId() const
- {
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return 0;
- }
+ virtual Id getId() const;
/*! Returns the nature of the point. */
- virtual Nature::VertexNature getNature() const
- {
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::POINT;
- }
-
+ virtual Nature::VertexNature getNature() const;
/*! Cast the Interface0D in SVertex if it can be. */
- virtual SVertex *castToSVertex()
- {
- PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden");
- return 0;
- }
+ virtual SVertex *castToSVertex();
/*! Cast the Interface0D in ViewVertex if it can be. */
- virtual ViewVertex *castToViewVertex()
- {
- PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden");
- return 0;
- }
+ virtual ViewVertex *castToViewVertex();
/*! Cast the Interface0D in NonTVertex if it can be. */
- virtual NonTVertex *castToNonTVertex()
- {
- PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden");
- return 0;
- }
+ virtual NonTVertex *castToNonTVertex();
/*! Cast the Interface0D in TVertex if it can be. */
- virtual TVertex *castToTVertex()
- {
- PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden");
- return 0;
- }
+ virtual TVertex *castToTVertex();
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface0D")
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.cpp b/source/blender/freestyle/intern/view_map/Interface1D.cpp
new file mode 100644
index 00000000000..985310e52b5
--- /dev/null
+++ b/source/blender/freestyle/intern/view_map/Interface1D.cpp
@@ -0,0 +1,75 @@
+/*
+ * ***** 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/view_map/Interface1D.cpp
+ * \ingroup freestyle
+ */
+
+extern "C" {
+#include <Python.h>
+}
+
+#include "Interface1D.h"
+
+namespace Freestyle {
+
+Interface0DIterator Interface1D::verticesBegin()
+{
+ PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
+ return Interface0DIterator();
+}
+
+Interface0DIterator Interface1D::verticesEnd()
+{
+ PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
+ return Interface0DIterator();
+}
+
+Interface0DIterator Interface1D::pointsBegin(float t)
+{
+ PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
+ return Interface0DIterator();
+}
+
+Interface0DIterator Interface1D::pointsEnd(float t)
+{
+ PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
+ return Interface0DIterator();
+}
+
+real Interface1D::getLength2D() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
+ return 0;
+}
+
+Id Interface1D::getId() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
+ return Id(0, 0);
+}
+
+Nature::EdgeNature Interface1D::getNature() const
+{
+ PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
+ return Nature::NO_FEATURE;
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h
index c7beafaf14d..7afa61ff496 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.h
+++ b/source/blender/freestyle/intern/view_map/Interface1D.h
@@ -30,7 +30,6 @@
#include <float.h>
#include <iostream>
-#include <Python.h>
#include <string>
#include "Functions0D.h"
@@ -137,7 +136,8 @@ public:
_timeStamp = 0;
}
- virtual ~Interface1D() {}; //soc
+ /*! Destructor */
+ virtual ~Interface1D() {};
/*! Returns the string "Interface1D". */
virtual string getExactTypeName() const
@@ -148,18 +148,10 @@ public:
// Iterator access
/*! Returns an iterator over the Interface1D vertices, pointing to the first vertex. */
- virtual Interface0DIterator verticesBegin()
- {
- PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden");
- return Interface0DIterator();
- }
+ virtual Interface0DIterator verticesBegin();
/*! Returns an iterator over the Interface1D vertices, pointing after the last vertex. */
- virtual Interface0DIterator verticesEnd()
- {
- PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden");
- return Interface0DIterator();
- }
+ virtual Interface0DIterator verticesEnd();
/*! Returns an iterator over the Interface1D points, pointing to the first point. The difference with
* verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling.
@@ -167,11 +159,7 @@ public:
* \param t
* The sampling with which we want to iterate over points of this 1D element.
*/
- virtual Interface0DIterator pointsBegin(float t = 0.0f)
- {
- PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden");
- return Interface0DIterator();
- }
+ virtual Interface0DIterator pointsBegin(float t = 0.0f);
/*! Returns an iterator over the Interface1D points, pointing after the last point. The difference with
* verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling.
@@ -179,36 +167,19 @@ public:
* \param t
* The sampling with which we want to iterate over points of this 1D element.
*/
- virtual Interface0DIterator pointsEnd(float t = 0.0f)
- {
- PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden");
- return Interface0DIterator();
- }
+ virtual Interface0DIterator pointsEnd(float t = 0.0f);
// Data access methods
/*! Returns the 2D length of the 1D element. */
- virtual real getLength2D() const
- {
- PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden");
- return 0;
- }
+ virtual real getLength2D() const;
/*! Returns the Id of the 1D element. */
- virtual Id getId() const
- {
- PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden");
- return Id(0, 0);
- }
-
+ virtual Id getId() const;
// FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D)
/*! Returns the nature of the 1D element. */
- virtual Nature::EdgeNature getNature() const
- {
- PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden");
- return Nature::NO_FEATURE;
- }
+ virtual Nature::EdgeNature getNature() const;
/*! Returns the time stamp of the 1D element. Mainly used for selection. */
virtual unsigned getTimeStamp() const
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h
index 02d3698c914..e747f9c3e68 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.h
+++ b/source/blender/freestyle/intern/view_map/Silhouette.h
@@ -74,7 +74,7 @@ class ViewVertex;
class SShape;
/*! Class to define a vertex of the embedding. */
-class LIB_VIEW_MAP_EXPORT SVertex : public Interface0D
+class SVertex : public Interface0D
{
public: // Implementation of Interface0D
/*! Returns the string "SVertex" .*/
@@ -167,8 +167,10 @@ private:
vector<FEdge*> _FEdges; // the edges containing this vertex
SShape *_Shape; // the shape to which belongs the vertex
ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
+#if 0
real _curvatureFredo;
Vec2r _directionFredo;
+#endif
CurvatureInfo *_curvature_info;
public:
@@ -326,6 +328,7 @@ public:
return _curvature_info;
}
+#if 0
/* Fredo's normal and curvature*/
void setCurvatureFredo(real c)
{
@@ -346,6 +349,7 @@ public:
{
return _directionFredo;
}
+#endif
/*! Sets the Id */
inline void setId(const Id& id)
@@ -458,7 +462,7 @@ class ViewEdge;
* This class is specialized into a smooth and a sharp version since their properties slightly vary from
* one to the other.
*/
-class LIB_VIEW_MAP_EXPORT FEdge : public Interface1D
+class FEdge : public Interface1D
{
public: // Implementation of Interface0D
/*! Returns the string "FEdge". */
@@ -1099,7 +1103,7 @@ Interface0DIterator FEdge::pointsEnd(float t)
* by two faces of the mesh. Face a lies on its right whereas Face b lies on its left.
* If it is a border edge, then it doesn't have any face on its right, and thus Face a = 0.
*/
-class LIB_VIEW_MAP_EXPORT FEdgeSharp : public FEdge
+class FEdgeSharp : public FEdge
{
protected:
Vec3r _aNormal; // When following the edge, normal of the right face
@@ -1242,7 +1246,7 @@ public:
/*! Class defining a smooth edge. This kind of edge typically runs across a face of the input mesh. It can be
* a silhouette, a ridge or valley, a suggestive contour.
*/
-class LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge
+class FEdgeSmooth : public FEdge
{
protected:
Vec3r _Normal;
@@ -1362,7 +1366,7 @@ public:
/*! Class to define a feature shape. It is the gathering of feature elements from an identified input shape */
-class LIB_VIEW_MAP_EXPORT SShape
+class SShape
{
private:
vector<FEdge*> _chains; // list of fedges that are chains starting points.
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
index 8b8f42f3922..ee885f29211 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
@@ -26,6 +26,9 @@
* \date 03/09/2002
*/
+#include <cstring>
+#include <cstdio>
+
#include "Silhouette.h"
#include "SilhouetteGeomEngine.h"
@@ -295,11 +298,11 @@ iter:
}
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
- printf("SilhouetteGeomEngine::ImageToWorldParameter(): #iters = %d, dist = %e\n", i, dist);
+ cout << "SilhouetteGeomEngine::ImageToWorldParameter(): #iters = " << i << ", dist = " << dist << "\n";
}
#endif
if (i == max_iters && G.debug & G_DEBUG_FREESTYLE) {
- printf("SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = %e)\n", dist);
+ cout << "SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = " << dist << ")\n";
}
}
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
index 4002385a823..1234c028ca1 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
@@ -46,7 +46,7 @@ using namespace Geometry;
class SVertex;
class FEdge;
-class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine
+class SilhouetteGeomEngine
{
private:
// The viewpoint under which the silhouette has to be computed
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index 050dcc4c882..5a94a84705d 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -28,7 +28,7 @@
* \date 2010-12-19
*/
-#define SPHERICAL_GRID_LOGGING FALSE
+#define SPHERICAL_GRID_LOGGING 0
// I would like to avoid using deque because including ViewMap.h and <deque> or <vector> separately results in
// redefinitions of identifiers. ViewMap.h already includes <vector> so it should be a safe fall-back.
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
index c777db6249f..fe6f3f1892d 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -25,9 +25,6 @@
* \date 01/07/2003
*/
-#include <math.h>
-//soc #include <qimage.h>
-//soc #include <qstring.h>
#include <sstream>
#include "Silhouette.h"
@@ -39,6 +36,7 @@
#include "../image/Image.h"
#include "BKE_global.h"
+#include "BLI_math.h"
extern "C" {
#include "IMB_imbuf.h"
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
index d6af7384fb8..0cd5d222621 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
@@ -51,7 +51,7 @@ class GrayImage;
/*! This class checks for every FEdge in which steerable it belongs and stores the mapping allowing to retrieve
* this information from the FEdge Id.
*/
-class LIB_VIEW_MAP_EXPORT SteerableViewMap
+class SteerableViewMap
{
protected:
// for each vector the list of nbOrientations weigths corresponding to its contributions
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
index 6efc81efbaf..7f214919114 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
@@ -183,7 +183,7 @@ class ViewVertex;
class ViewEdge;
class ViewShape;
-class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder
+class ViewEdgeXBuilder
{
protected:
int _currentViewId; // Id for view edges
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index 246c4caef82..fd5ebb99f72 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -28,8 +28,8 @@
#include <float.h>
#include "ViewMap.h"
-#include "ViewMapAdvancedIterators.h"
#include "ViewMapIterators.h"
+#include "ViewMapAdvancedIterators.h"
#include "../geometry/GeomUtils.h"
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index 2c9672be53b..eeaeada5dc6 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -65,7 +65,7 @@ class ViewShape;
class TVertex;
/*! Class defining the ViewMap.*/
-class LIB_VIEW_MAP_EXPORT ViewMap
+class ViewMap
{
public:
typedef vector<ViewEdge*> viewedges_container;
@@ -268,7 +268,7 @@ class orientedViewEdgeIterator;
* NonTVertex when it corresponds to a vertex of the initial input mesh (it is the case for vertices such as corners
* for example). Thus, this class can be specialized into two classes, the TVertex class and the NonTVertex class.
*/
-class LIB_VIEW_MAP_EXPORT ViewVertex : public Interface0D
+class ViewVertex : public Interface0D
{
public: // Implementation of Interface0D
/*! Returns the string "ViewVertex". */
@@ -386,7 +386,7 @@ public:
* Basically the front edge hides part of the back edge.
* So, among the back edges, 1 is of invisibility n and the other of visibility n+1
*/
-class LIB_VIEW_MAP_EXPORT TVertex : public ViewVertex
+class TVertex : public ViewVertex
{
public:
typedef vector<directedViewEdge*> edge_pointers_container;
@@ -660,7 +660,7 @@ public:
* Associated to a single SVertex.
* Can be associated to 2 or several view edges
*/
-class LIB_VIEW_MAP_EXPORT NonTVertex : public ViewVertex
+class NonTVertex : public ViewVertex
{
public:
typedef vector<directedViewEdge> edges_container;
@@ -891,7 +891,7 @@ template<class Traits> class vertex_iterator_base;
/*! Class defining a ViewEdge. A ViewEdge in an edge of the image graph. it connects two ViewVertex.
* It is made by connecting a set of FEdges.
*/
-class LIB_VIEW_MAP_EXPORT ViewEdge : public Interface1D
+class ViewEdge : public Interface1D
{
public: // Implementation of Interface0D
/*! Returns the string "ViewEdge". */
@@ -1392,7 +1392,7 @@ public:
/**********************************/
/*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) that are issued from the same input shape. */
-class LIB_VIEW_MAP_EXPORT ViewShape
+class ViewShape
{
private:
vector<ViewVertex*> _Vertices;
diff --git a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
index a8c046c4dc1..8e98cabd75b 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
@@ -53,21 +53,21 @@ namespace Freestyle {
namespace ViewVertexInternal {
-class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge>
+class edge_const_traits : public Const_traits<ViewVertex::directedViewEdge>
{
public:
- typedef vector< ::ViewVertex::directedViewEdge> edges_container;
+ typedef vector<ViewVertex::directedViewEdge> edges_container;
typedef edges_container::const_iterator edges_container_iterator;
- typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container;
+ typedef vector<ViewVertex::directedViewEdge*> edge_pointers_container;
typedef edge_pointers_container::const_iterator edge_pointers_container_iterator;
};
-class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge>
+class edge_nonconst_traits : public Nonconst_traits<ViewVertex::directedViewEdge>
{
public:
- typedef vector< ::ViewVertex::directedViewEdge> edges_container;
+ typedef vector<ViewVertex::directedViewEdge> edges_container;
typedef edges_container::iterator edges_container_iterator;
- typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container;
+ typedef vector<ViewVertex::directedViewEdge*> edge_pointers_container;
typedef edge_pointers_container::iterator edge_pointers_container_iterator;
};
@@ -377,14 +377,14 @@ public:
_first = 0;
}
- inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother) : parent_class()
+ inline edge_iterator_base(const edge_iterator_base<Nonconst_traits<ViewEdge*> >& iBrother) : parent_class()
{
_ViewEdge = iBrother._ViewEdge;
_first = iBrother._first;
_orientation = iBrother._orientation;
}
- inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother) : parent_class()
+ inline edge_iterator_base(const edge_iterator_base<Const_traits<ViewEdge*> >& iBrother) : parent_class()
{
_ViewEdge = iBrother._ViewEdge;
_first = iBrother._first;
@@ -521,7 +521,7 @@ public:
value_type _FEdgeB; // last fedge of the view edge
public:
- friend class ::ViewEdge;
+ friend class ViewEdge;
friend class fedge_iterator;
inline fedge_iterator_base() : parent_class() {}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index 702ee9bfea2..a0a1282219c 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -51,7 +51,7 @@ namespace Freestyle {
// XXX Grmll... G is used as template's typename parameter :/
static const Global &_global = G;
-#define LOGGING FALSE
+#define LOGGING 0
using namespace std;
@@ -138,28 +138,28 @@ static void findOccludee(FEdge *fe, G& grid, I& occluders, real epsilon, WFace *
if (p->rayIntersect(A, v, t, t_u, t_v)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRay " << A << " * " << v << " intersects at time " << t << endl;
- cout << "\t\t(v * normal) == " << (v * p->getNormal()) << " for normal " << p->getNormal() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRay " << A << " * " << v << " intersects at time " << t << endl;
+ cout << "\t\t(v * normal) == " << (v * p->getNormal()) << " for normal " << p->getNormal() << endl;
+ }
#endif
- if (fabs(v * p->getNormal()) > 0.0001) {
- if ((t > 0.0)) { // && (t<1.0))
- if (t < mint) {
- *oaWFace = oface;
- mint = t;
- noIntersection = false;
- fe->setOccludeeIntersection(Vec3r(A + t * v));
+ if (fabs(v * p->getNormal()) > 0.0001) {
+ if ((t > 0.0)) { // && (t<1.0))
+ if (t < mint) {
+ *oaWFace = oface;
+ mint = t;
+ noIntersection = false;
+ fe->setOccludeeIntersection(Vec3r(A + t * v));
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tIs occludee" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tIs occludee" << endl;
+ }
#endif
+ }
}
}
- }
- occluders.reportDepth(A, v, t);
+ occluders.reportDepth(A, v, t);
}
}
@@ -246,146 +246,146 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
I occluders(grid, center, epsilon);
for (occluders.initBeforeTarget(); occluders.validBeforeTarget(); occluders.nextOccluder()) {
- // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
- // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
- //-----------
- oface = occluders.getWFace();
- Polygon3r *p = occluders.getCameraSpacePolygon();
- real t, t_u, t_v;
-#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tEvaluating intersection for occluder " << (p->getVertices())[0] << (p->getVertices())[1] <<
- (p->getVertices())[2] << endl << "\t\t\tand ray " << vp << " * " << u << " (center " << center <<
- ")" << endl;
- }
-#endif
-
+ // If we're dealing with an exact silhouette, check whether we must take care of this occluder of not.
+ // (Indeed, we don't consider the occluders that share at least one vertex with the face containing this edge).
+ //-----------
+ oface = occluders.getWFace();
+ Polygon3r *p = occluders.getCameraSpacePolygon();
+ real t, t_u, t_v;
#if LOGGING
- Vec3r v(vp - center);
- real rl = v.norm();
- v.normalize();
- vector<Vec3r> points;
- // Iterate over vertices, storing projections in points
- for (vector<WOEdge*>::const_iterator woe = oface->getEdgeList().begin(), woend = oface->getEdgeList().end();
- woe != woend;
- woe++)
- {
- points.push_back(Vec3r((*woe)->GetaVertex()->GetVertex()));
- }
- Polygon3r p1(points, oface->GetNormal());
- Vec3r v1((p1.getVertices())[0]);
- real d = -(v1 * p->getNormal());
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tp: " << (p->getVertices())[0] << (p->getVertices())[1] << (p->getVertices())[2] << ", norm: " <<
- p->getNormal() << endl;
- cout << "\t\tp1: " << (p1.getVertices())[0] << (p1.getVertices())[1] << (p1.getVertices())[2] << ", norm: " <<
- p1.getNormal() << endl;
- }
-#else
- real d = -((p->getVertices())[0] * p->getNormal());
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tEvaluating intersection for occluder " << (p->getVertices())[0] << (p->getVertices())[1] <<
+ (p->getVertices())[2] << endl << "\t\t\tand ray " << vp << " * " << u << " (center " << center <<
+ ")" << endl;
+ }
#endif
- if (face) {
#if LOGGING
+ Vec3r v(vp - center);
+ real rl = v.norm();
+ v.normalize();
+ vector<Vec3r> points;
+ // Iterate over vertices, storing projections in points
+ for (vector<WOEdge*>::const_iterator woe = oface->getEdgeList().begin(), woend = oface->getEdgeList().end();
+ woe != woend;
+ woe++)
+ {
+ points.push_back(Vec3r((*woe)->GetaVertex()->GetVertex()));
+ }
+ Polygon3r p1(points, oface->GetNormal());
+ Vec3r v1((p1.getVertices())[0]);
+ real d = -(v1 * p->getNormal());
if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tDetermining face adjacency...";
+ cout << "\t\tp: " << (p->getVertices())[0] << (p->getVertices())[1] << (p->getVertices())[2] << ", norm: " <<
+ p->getNormal() << endl;
+ cout << "\t\tp1: " << (p1.getVertices())[0] << (p1.getVertices())[1] << (p1.getVertices())[2] << ", norm: " <<
+ p1.getNormal() << endl;
}
+#else
+ real d = -((p->getVertices())[0] * p->getNormal());
#endif
- skipFace = false;
- if (face == oface) {
+ if (face) {
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face concurrency." << endl;
+ cout << "\t\tDetermining face adjacency...";
}
#endif
- continue;
- }
-
+ skipFace = false;
- for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end(); fv != fvend; ++fv) {
- if ((*fv)->isBoundary())
+ if (face == oface) {
+#if LOGGING
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face concurrency." << endl;
+ }
+#endif
continue;
+ }
- WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
- WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
- for (ie = iebegin; ie != ieend; ++ie) {
- if ((*ie) == 0)
+
+ for (vector<WVertex*>::iterator fv = faceVertices.begin(), fvend = faceVertices.end(); fv != fvend; ++fv) {
+ if ((*fv)->isBoundary())
continue;
- WFace *sface = (*ie)->GetbFace();
- //WFace *sfacea = (*ie)->GetaFace();
- //if ((sface == oface) || (sfacea == oface))
- if (sface == oface) {
- skipFace = true;
- break;
+ WVertex::incoming_edge_iterator iebegin = (*fv)->incoming_edges_begin();
+ WVertex::incoming_edge_iterator ieend = (*fv)->incoming_edges_end();
+ for (ie = iebegin; ie != ieend; ++ie) {
+ if ((*ie) == 0)
+ continue;
+
+ WFace *sface = (*ie)->GetbFace();
+ //WFace *sfacea = (*ie)->GetaFace();
+ //if ((sface == oface) || (sfacea == oface))
+ if (sface == oface) {
+ skipFace = true;
+ break;
+ }
}
+ if (skipFace)
+ break;
}
- if (skipFace)
- break;
- }
- if (skipFace) {
+ if (skipFace) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << " Rejecting occluder for face adjacency." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << " Rejecting occluder for face adjacency." << endl;
+ }
#endif
- continue;
+ continue;
+ }
}
- }
- else {
- // check whether the edge and the polygon plane are coincident:
- //-------------------------------------------------------------
- //first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon)) {
+ else {
+ // check whether the edge and the polygon plane are coincident:
+ //-------------------------------------------------------------
+ //first let us compute the plane equation.
+ if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRejecting occluder for target coincidence." << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRejecting occluder for target coincidence." << endl;
+ }
#endif
- continue;
+ continue;
+ }
}
- }
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- real x;
- if (p1.rayIntersect(center, v, x, t_u, t_v)) {
- cout << "\t\tRay should intersect at time " << (rl - x) << ". Center: " << center << ", V: " << v <<
- ", RL: " << rl << ", T:" << x << endl;
- }
- else {
- cout << "\t\tRay should not intersect. Center: " << center << ", V: " << v << ", RL: " << rl << endl;
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ real x;
+ if (p1.rayIntersect(center, v, x, t_u, t_v)) {
+ cout << "\t\tRay should intersect at time " << (rl - x) << ". Center: " << center << ", V: " << v <<
+ ", RL: " << rl << ", T:" << x << endl;
+ }
+ else {
+ cout << "\t\tRay should not intersect. Center: " << center << ", V: " << v << ", RL: " << rl << endl;
+ }
}
- }
#endif
- if (p->rayIntersect(center, u, t, t_u, t_v)) {
+ if (p->rayIntersect(center, u, t, t_u, t_v)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tRay " << center << " * " << u << " intersects at time " << t << " (raylength is " <<
- raylength << ")" << endl;
- cout << "\t\t(u * normal) == " << (u * p->getNormal()) << " for normal " << p->getNormal() << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tRay " << center << " * " << u << " intersects at time " << t << " (raylength is " <<
+ raylength << ")" << endl;
+ cout << "\t\t(u * normal) == " << (u * p->getNormal()) << " for normal " << p->getNormal() << endl;
+ }
#endif
- if (fabs(u * p->getNormal()) > 0.0001) {
- if ((t > 0.0) && (t < raylength)) {
+ if (fabs(u * p->getNormal()) > 0.0001) {
+ if ((t > 0.0) && (t < raylength)) {
#if LOGGING
- if (_global.debug & G_DEBUG_FREESTYLE) {
- cout << "\t\tIs occluder" << endl;
- }
+ if (_global.debug & G_DEBUG_FREESTYLE) {
+ cout << "\t\tIs occluder" << endl;
+ }
#endif
- if ( foundOccluders != NULL ) {
- ViewShape *vshape = viewMap->viewShape(oface->GetVertex(0)->shape()->GetId());
- foundOccluders->insert(vshape);
- }
- ++qi;
+ if ( foundOccluders != NULL ) {
+ ViewShape *vshape = viewMap->viewShape(oface->GetVertex(0)->shape()->GetId());
+ foundOccluders->insert(vshape);
+ }
+ ++qi;
- if (! grid.enableQI())
- break;
- }
+ if (! grid.enableQI())
+ break;
+ }
- occluders.reportDepth(center, u, t);
+ occluders.reportDepth(center, u, t);
}
}
}
@@ -2332,14 +2332,16 @@ void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsi
if ((Ta < -epsilon) || (Ta > 1 + epsilon) || (Tb < -epsilon) || (Tb > 1 + epsilon)) {
printf("ta %.12e\n", ta);
printf("tb %.12e\n", tb);
- printf("a1 %e, %e -- b1 %e, %e\n", a1[0], a1[1], b1[0], b1[1]);
- printf("a2 %e, %e -- b2 %e, %e\n", a2[0], a2[1], b2[0], b2[1]);
+ printf("a1 %e, %e -- a2 %e, %e\n", a1[0], a1[1], a2[0], a2[1]);
+ printf("b1 %e, %e -- b2 %e, %e\n", b1[0], b1[1], b2[0], b2[1]);
+ //printf("line([%e, %e], [%e, %e]);\n", a1[0], a2[0], a1[1], a2[1]);
+ //printf("line([%e, %e], [%e, %e]);\n", b1[0], b2[0], b1[1], b2[1]);
if ((Ta < -epsilon) || (Ta > 1 + epsilon))
- printf("Ta %.12e\n", Ta);
+ printf("Ta %.12e\n", Ta);
if ((Tb < -epsilon) || (Tb > 1 + epsilon))
- printf("Tb %.12e\n", Tb);
- printf("A1 %e, %e, %e -- B1 %e, %e, %e\n", A1[0], A1[1], A1[2], B1[0], B1[1], B1[2]);
- printf("A2 %e, %e, %e -- B2 %e, %e, %e\n", A2[0], A2[1], A2[2], B2[0], B2[1], B2[2]);
+ printf("Tb %.12e\n", Tb);
+ printf("A1 %e, %e, %e -- A2 %e, %e, %e\n", A1[0], A1[1], A1[2], A2[0], A2[1], A2[2]);
+ printf("B1 %e, %e, %e -- B2 %e, %e, %e\n", B1[0], B1[1], B1[2], B2[0], B2[1], B2[2]);
}
}
#endif
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index 29e393052a3..08b2fde8f31 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -60,7 +60,7 @@ namespace Freestyle {
using namespace Geometry;
-class LIB_VIEW_MAP_EXPORT ViewMapBuilder
+class ViewMapBuilder
{
private:
ViewMap *_ViewMap; // result
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
index e78fb894be0..71ae68c06bc 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
@@ -25,6 +25,8 @@
* \date 09/01/2003
*/
+#include <limits.h>
+
#include "ViewMapIO.h"
#ifdef IRIX
@@ -674,14 +676,16 @@ static int save(ostream& out, ViewShape *vs)
// ViewEdges (List)
tmp = vs->edges().size();
WRITE(tmp);
- for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++)
+ for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++) {
WRITE_IF_NON_NULL(*i4);
+ }
// ViewVertices (List)
tmp = vs->vertices().size();
WRITE(tmp);
- for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); i5 != vs->vertices().end(); i5++)
+ for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); i5 != vs->vertices().end(); i5++) {
WRITE_IF_NON_NULL(*i5);
+ }
return 0;
}
@@ -816,8 +820,9 @@ static int save(ostream& out, SVertex *sv)
// FEdges (List)
tmp = sv->fedges().size();
WRITE(tmp);
- for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++)
+ for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++) {
WRITE_IF_NON_NULL(*j);
+ }
return 0;
}
@@ -868,8 +873,9 @@ static int save(ostream& out, ViewEdge *ve)
if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
tmp = ve->occluders().size();
WRITE(tmp);
- for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); i != ve->occluders().end(); i++)
+ for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); i != ve->occluders().end(); i++) {
WRITE_IF_NON_NULL((*i));
+ }
}
return 0;
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.h b/source/blender/freestyle/intern/view_map/ViewMapIO.h
index e2223cd5734..eb26e8adab0 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.h
@@ -42,10 +42,8 @@ namespace ViewMapIO {
static const unsigned ZERO = UINT_MAX;
-LIB_VIEW_MAP_EXPORT
int load(istream& in, ViewMap *vm, ProgressBar *pb = NULL);
-LIB_VIEW_MAP_EXPORT
int save(ostream& out, ViewMap *vm, ProgressBar *pb = NULL);
namespace Options {
@@ -53,22 +51,16 @@ namespace Options {
static const unsigned char FLOAT_VECTORS = 1;
static const unsigned char NO_OCCLUDERS = 2;
-LIB_VIEW_MAP_EXPORT
void setFlags(const unsigned char flags);
-LIB_VIEW_MAP_EXPORT
void addFlags(const unsigned char flags);
-LIB_VIEW_MAP_EXPORT
void rmFlags(const unsigned char flags);
-LIB_VIEW_MAP_EXPORT
unsigned char getFlags();
-LIB_VIEW_MAP_EXPORT
void setModelsPath(const string& path);
-LIB_VIEW_MAP_EXPORT
string getModelsPath();
}; // End of namepace Options
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
index 2794d9028d2..469c2c3b29c 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
@@ -66,8 +66,8 @@ public:
friend class ViewEdge;
// FIXME
- typedef ::TVertex::edge_pointers_container edge_pointers_container;
- typedef ::NonTVertex::edges_container edges_container;
+ typedef TVertex::edge_pointers_container edge_pointers_container;
+ typedef NonTVertex::edges_container edges_container;
protected:
Nature::VertexNature _Nature; // the nature of the underlying vertex
@@ -184,7 +184,7 @@ public:
/*! Returns a reference to the pointed orientedViewEdge.
* In the scripting language, you must call "getObject()" instead.
*/
- virtual ::ViewVertex::directedViewEdge& operator*() const
+ virtual ViewVertex::directedViewEdge& operator*() const
{
if (_Nature & Nature::T_VERTEX)
//return _tvertex_iter;
@@ -195,7 +195,7 @@ public:
/*! Returns a pointer to the pointed orientedViewEdge.
* Can't be called in the scripting language.
*/
- virtual ::ViewVertex::directedViewEdge *operator->() const
+ virtual ViewVertex::directedViewEdge *operator->() const
{
return &(operator*());
}
@@ -205,11 +205,11 @@ public:
virtual inline int increment()
{
if (_Nature & Nature::T_VERTEX) {
- ::ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
+ ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
++_tvertex_iter;
if (_tvertex_iter != _tend) {
// FIXME : pquoi deja ?
- ::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
+ ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
if (tmp2.first == tmp.first)
++_tvertex_iter;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index 9c4d214d931..cb19875b6c7 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -50,7 +50,7 @@ class NodeGroup;
class SShape;
class WShape;
-class LIB_VIEW_MAP_EXPORT ViewMapTesselator
+class ViewMapTesselator
{
public:
inline ViewMapTesselator()
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 3d1cb907ed0..4a910099bff 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -45,7 +45,6 @@
#include <assert.h>
#include <cstdlib> // for malloc and free
-#include <math.h>
#include <set>
#include <stack>
@@ -54,7 +53,7 @@
#include "../geometry/normal_cycle.h"
-#include "../system/FreestyleConfig.h"
+#include "BLI_math.h"
namespace Freestyle {
@@ -130,7 +129,7 @@ static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
* VisMath '02, Berlin (Germany)
* http://www-grail.usc.edu/pubs.html
*
- * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
+ * Returns: %true if the operator could be evaluated, %false if the evaluation failed for some reason (@v is
* boundary or is the endpoint of a non-manifold edge.)
*/
bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
@@ -192,7 +191,7 @@ bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
* VisMath '02, Berlin (Germany)
* http://www-grail.usc.edu/pubs.html
*
- * Returns: %TRUE if the operator could be evaluated, %FALSE if the evaluation failed for some reason (@v is
+ * Returns: %true if the operator could be evaluated, %false if the evaluation failed for some reason (@v is
* boundary or is the endpoint of a non-manifold edge.)
*/
bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h
index 5977f12d870..dbcecf5bc4b 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.h
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.h
@@ -61,7 +61,7 @@ using namespace Geometry;
class WVertex;
-class LIB_WINGED_EDGE_EXPORT CurvatureInfo
+class CurvatureInfo
{
public:
CurvatureInfo()
@@ -133,21 +133,21 @@ public:
#endif
};
-bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
+bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &n);
-bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
+bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg);
-void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
+void gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2);
-void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
+void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2);
namespace OGF {
class NormalCycle ;
-void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
+void compute_curvature_tensor( WVertex *start, double radius, NormalCycle& nc);
-void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
+void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle& nc);
} // OGF namespace
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
index 03d3cf65142..97248669822 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
@@ -470,7 +470,6 @@ WShape *WFace::getShape()
* *
**********************************/
-LIB_WINGED_EDGE_EXPORT
unsigned WShape::_SceneCurrentId = 0;
WShape *WShape::duplicate()
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h
index f0692aecd5b..5dda41ad279 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.h
@@ -29,7 +29,6 @@
*/
#include <iterator>
-#include <math.h>
#include <vector>
#include "../geometry/Geom.h"
@@ -38,6 +37,8 @@
#include "../system/FreestyleConfig.h"
+#include "BLI_math.h"
+
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
@@ -63,7 +64,7 @@ class WEdge;
class WShape;
class WFace;
-class LIB_WINGED_EDGE_EXPORT WVertex
+class WVertex
{
protected:
int _Id; // an identificator
@@ -165,7 +166,7 @@ public:
#if defined(__GNUC__) && (__GNUC__ < 3)
class incoming_edge_iterator : public input_iterator<WOEdge *, ptrdiff_t>
#else
- class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator
+ class incoming_edge_iterator
: public iterator<input_iterator_tag, WOEdge *, ptrdiff_t>
#endif
{
@@ -253,7 +254,7 @@ public:
#if defined(__GNUC__) && (__GNUC__ < 3)
class face_iterator : public input_iterator<WFace *, ptrdiff_t>
#else
- class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace *, ptrdiff_t>
+ class face_iterator : public iterator<input_iterator_tag, WFace *, ptrdiff_t>
#endif
{
private:
@@ -365,7 +366,7 @@ public:
class WFace;
class WEdge;
-class LIB_WINGED_EDGE_EXPORT WOEdge
+class WOEdge
{
protected:
#if 0
@@ -548,7 +549,7 @@ public:
* *
**********************************/
-class LIB_WINGED_EDGE_EXPORT WEdge
+class WEdge
{
protected:
WOEdge *_paOEdge; // first oriented edge
@@ -736,7 +737,7 @@ public:
**********************************/
-class LIB_WINGED_EDGE_EXPORT WFace
+class WFace
{
protected:
vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face
@@ -1019,7 +1020,7 @@ public:
**********************************/
-class LIB_WINGED_EDGE_EXPORT WShape
+class WShape
{
protected:
vector<WVertex *> _VertexList;
diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
index 819bb24ffc2..1b83b81274a 100644
--- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
@@ -40,7 +40,7 @@
namespace Freestyle {
-class LIB_WINGED_EDGE_EXPORT WFillGrid
+class WFillGrid
{
public:
inline WFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
index 5b33df906a6..247999bfcbf 100644
--- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
@@ -35,7 +35,7 @@
namespace Freestyle {
-class LIB_WINGED_EDGE_EXPORT WSFillGrid
+class WSFillGrid
{
public:
inline WSFillGrid(Grid *grid = NULL, WingedEdge *winged_edge = NULL)
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
index 88da9cf9f80..84dbd5fbef8 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp
@@ -197,43 +197,43 @@ WXSmoothEdge *WXFaceLayer::BuildSmoothEdge()
WSFace *bface = (WSFace *)GetBordingFace(i);
if (bface) {
if ((front()) ^ (bface->front())) { // fA->front XOR fB->front (true if one is 0 and the other is 1)
- // that means that the edge i of the face is a silhouette edge
- // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
- if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
- // that means that this silhouette edge has already been built
- return ((WSExactFace *)bface)->exactSilhouetteEdge();
- }
- // Else we must build it
- WOEdge *woea, *woeb;
- real ta, tb;
- if (!front()) { // is it in the right order ?
- // the order of the WOEdge index is wrong
- woea = _OEdgeList[(i + 1) % numberOfEdges()];
- if (0 == i)
- woeb = _OEdgeList[numberOfEdges() - 1];
- else
- woeb = _OEdgeList[(i - 1)];
- ta = 0;
- tb = 1;
- }
- else {
- // the order of the WOEdge index is good
- if (0 == i)
- woea = _OEdgeList[numberOfEdges() - 1];
- else
- woea = _OEdgeList[(i - 1)];
- woeb = _OEdgeList[(i + 1) % numberOfEdges()];
- ta = 1;
- tb = 0;
- }
+ // that means that the edge i of the face is a silhouette edge
+ // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
+ if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
+ // that means that this silhouette edge has already been built
+ return ((WSExactFace *)bface)->exactSilhouetteEdge();
+ }
+ // Else we must build it
+ WOEdge *woea, *woeb;
+ real ta, tb;
+ if (!front()) { // is it in the right order ?
+ // the order of the WOEdge index is wrong
+ woea = _OEdgeList[(i + 1) % numberOfEdges()];
+ if (0 == i)
+ woeb = _OEdgeList[numberOfEdges() - 1];
+ else
+ woeb = _OEdgeList[(i - 1)];
+ ta = 0;
+ tb = 1;
+ }
+ else {
+ // the order of the WOEdge index is good
+ if (0 == i)
+ woea = _OEdgeList[numberOfEdges() - 1];
+ else
+ woea = _OEdgeList[(i - 1)];
+ woeb = _OEdgeList[(i + 1) % numberOfEdges()];
+ ta = 1;
+ tb = 0;
+ }
- _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
- _pSmoothEdge->setWOeA(woea);
- _pSmoothEdge->setWOeA(woeb);
- _pSmoothEdge->setTa(ta);
- _pSmoothEdge->setTb(tb);
+ _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
+ _pSmoothEdge->setWOeA(woea);
+ _pSmoothEdge->setWOeA(woeb);
+ _pSmoothEdge->setTa(ta);
+ _pSmoothEdge->setTb(tb);
- return _pSmoothEdge;
+ return _pSmoothEdge;
}
}
}
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h
index 364183bbc84..ce9749369fc 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h
@@ -327,7 +327,7 @@ public:
*/
class WXFace;
-class LIB_WINGED_EDGE_EXPORT WXFaceLayer
+class WXFaceLayer
{
public:
void *userdata;
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
index 5579989072a..143c2e33608 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
@@ -35,7 +35,7 @@
namespace Freestyle {
-class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder
+class WXEdgeBuilder : public WingedEdgeBuilder
{
public:
WXEdgeBuilder() : WingedEdgeBuilder() {}
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
index d68acaf29c1..7fd5cd8443a 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
@@ -40,7 +40,7 @@
namespace Freestyle {
-class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor
+class WingedEdgeBuilder : public SceneVisitor
{
public:
inline WingedEdgeBuilder() : SceneVisitor()
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 91413057dae..d4381febfe0 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -164,6 +164,10 @@ source_group("Internal Header Files" FILES ${INTERN_INC})
source_group("Generated Files" FILES ${GEN_SRC})
source_group("Shader Files" FILES ${GLSL_SRC})
+if(WITH_GAMEENGINE)
+ add_definitions(-DWITH_GAMEENGINE)
+endif()
+
if(WITH_MOD_SMOKE)
add_definitions(-DWITH_SMOKE)
endif()
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index b8139ad01c6..46010b4786a 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -93,9 +93,13 @@ typedef struct GPUDrawObject {
/* for each original vertex, the list of related points */
struct GPUVertPointLink *vert_points;
+
+ /* see: USE_GPU_POINT_LINK define */
+#if 0
/* storage for the vert_points lists */
struct GPUVertPointLink *vert_points_mem;
int vert_points_usage;
+#endif
int colType;
@@ -111,7 +115,7 @@ typedef struct GPUDrawObject {
/* if there was a failure allocating some buffer, use old
* rendering code */
- int legacy;
+ bool legacy;
} GPUDrawObject;
/* used for GLSL materials */
@@ -156,39 +160,49 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start,
void GPU_buffer_unbind(void);
/* used to check whether to use the old (without buffers) code */
-int GPU_buffer_legacy(struct DerivedMesh *dm);
+bool GPU_buffer_legacy(struct DerivedMesh *dm);
/* Buffers for non-DerivedMesh drawing */
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
-GPU_PBVH_Buffers *GPU_build_pbvh_mesh_buffers(int (*face_vert_indices)[4],
+/* build */
+GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
struct MFace *mface, struct MVert *mvert,
int *face_indices, int totface);
-void GPU_update_mesh_pbvh_buffers(struct GPU_PBVH_Buffers *buffers, struct MVert *mvert,
- int *vert_indices, int totvert, const float *vmask,
- int (*face_vert_indices)[4], int show_diffuse_color);
-
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
unsigned int **grid_hidden, int gridsize);
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading);
+/* update */
+
+void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
+ int *vert_indices, int totvert, const float *vmask,
+ int (*face_vert_indices)[4], bool show_diffuse_color);
+
void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
struct BMesh *bm,
- struct GHash *bm_faces,
+ struct GSet *bm_faces,
struct GSet *bm_unique_verts,
- struct GSet *bm_other_verts);
+ struct GSet *bm_other_verts,
+ bool show_diffuse_color);
void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, struct CCGElem **grids,
const struct DMFlagMat *grid_flag_mats,
int *grid_indices, int totgrid, const struct CCGKey *key,
- int show_diffuse_color);
+ bool show_diffuse_color);
+/* draw */
void GPU_draw_pbvh_buffers(struct GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
bool wireframe);
-int GPU_pbvh_buffers_diffuse_changed(struct GPU_PBVH_Buffers *buffers, int show_diffuse_color);
+/* debug PBVH draw*/
+void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf);
+void GPU_end_draw_pbvh_BB(void);
+void GPU_init_draw_pbvh_BB(void);
+
+bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color);
void GPU_free_pbvh_buffers(struct GPU_PBVH_Buffers *buffers);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index b6aefb0f73c..cde4fdca710 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -87,6 +87,7 @@ int GPU_enable_material(int nr, void *attribs);
void GPU_disable_material(void);
void GPU_material_diffuse_get(int nr, float diff[4]);
+bool GPU_material_use_matcaps_get(void);
void GPU_set_material_alpha_blend(int alphablend);
int GPU_get_material_alpha_blend(void);
@@ -138,10 +139,11 @@ GLenum GPU_mipmap_2D(GLboolean genmip, GLenum internalFormat, int w, int h, GLen
void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h);
void GPU_update_images_framechange(void);
int GPU_update_image_time(struct Image *ima, double time);
-int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, int compare, int mipmap, bool is_data);
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int use_hight_bit_depth, struct Image *ima);
+int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, bool compare, bool mipmap, bool is_data);
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth,
+ bool mipmap, bool use_hight_bit_depth, struct Image *ima);
void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, struct Image *ima, struct ImBuf *ibuf);
-int GPU_upload_dxt_texture(struct ImBuf *ibuf);
+bool GPU_upload_dxt_texture(struct ImBuf *ibuf);
void GPU_free_image(struct Image *ima);
void GPU_free_images(void);
void GPU_free_images_anim(void);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index ce766ac36f4..b4078bf234e 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -125,7 +125,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
GPUTexture *GPU_texture_from_blender(struct Image *ima,
- struct ImageUser *iuser, int isdata, double time, int mipmap);
+ struct ImageUser *iuser, bool is_data, double time, int mipmap);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
void GPU_texture_free(GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index d16bcce7b5a..73c377bb570 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -51,6 +51,7 @@ struct Image;
struct bNode;
struct LinkNode;
struct Scene;
+struct SceneRenderLayer;
struct GPUVertexAttribs;
struct GPUNode;
struct GPUNodeLink;
@@ -88,9 +89,14 @@ typedef enum GPUBuiltin {
GPU_VIEW_POSITION = 16,
GPU_VIEW_NORMAL = 32,
GPU_OBCOLOR = 64,
- GPU_AUTO_BUMPSCALE = 128
+ GPU_AUTO_BUMPSCALE = 128,
} GPUBuiltin;
+typedef enum GPUOpenGLBuiltin {
+ GPU_MATCAP_NORMAL = 1,
+ GPU_COLOR = 2,
+} GPUOpenGLBuiltin;
+
typedef enum GPUBlendMode {
GPU_BLEND_SOLID = 0,
GPU_BLEND_ADD = 1,
@@ -104,19 +110,20 @@ typedef struct GPUNodeStack {
const char *name;
float vec[4];
struct GPUNodeLink *link;
- short hasinput;
- short hasoutput;
+ bool hasinput;
+ bool hasoutput;
short sockettype;
} GPUNodeStack;
GPUNodeLink *GPU_attribute(int type, const char *name);
GPUNodeLink *GPU_uniform(float *num);
GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int isdata);
+GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
GPUNodeLink *GPU_texture(int size, float *pixels);
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
+GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin);
bool GPU_link(GPUMaterial *mat, const char *name, ...);
bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
@@ -133,6 +140,7 @@ void GPU_material_free(struct Material *ma);
void GPU_materials_free(void);
+bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4]);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
@@ -142,7 +150,7 @@ struct Scene *GPU_material_scene(GPUMaterial *material);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
-int GPU_material_do_color_management(GPUMaterial *mat);
+bool GPU_material_do_color_management(GPUMaterial *mat);
/* Exported shading */
diff --git a/source/blender/gpu/GPU_raster.h b/source/blender/gpu/GPU_raster.h
index 1c1fc50638f..76e724cb2a1 100644
--- a/source/blender/gpu/GPU_raster.h
+++ b/source/blender/gpu/GPU_raster.h
@@ -47,6 +47,7 @@ extern const GLubyte GPU_stipple_halftone [128];
extern const GLubyte GPU_stipple_quarttone [128];
extern const GLubyte GPU_stipple_diag_stripes_pos[128];
extern const GLubyte GPU_stipple_diag_stripes_neg[128];
+extern const GLubyte stipple_checker_8px [128];
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index c1c3fa92cb1..e9320f08eff 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -49,6 +49,8 @@ incs = [
env['BF_OPENGL_INC'],
]
+if env['WITH_BF_GAMEENGINE']:
+ defs.append('WITH_GAMEENGINE')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs.append(env['BF_PTHREADS_INC'])
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index a6234685072..9bd5a95e489 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -50,7 +50,7 @@
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
#include "BKE_paint.h"
-#include "BKE_subsurf.h"
+#include "BKE_pbvh.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
@@ -61,7 +61,6 @@
#include "bmesh.h"
#include "DNA_meshdata_types.h"
-#include "DNA_material_types.h"
#include "DNA_userdef_types.h"
#include "MEM_guardedalloc.h"
@@ -83,9 +82,6 @@ typedef enum {
#define MAX_GPU_ATTRIB_DATA 32
-/* material number is an 16-bit signed short and the range (assume material number is non-negative) */
-#define MAX_MATERIALS MAXMAT
-
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
static int useVBOs = -1;
static GPUBufferState GLStates = 0;
@@ -130,10 +126,10 @@ static GPUBufferPool *gpu_buffer_pool_new(void)
pool->maxsize = MAX_FREE_GPU_BUFFERS;
pool->maxpbvhsize = MAX_FREE_GPU_BUFF_IDS;
- pool->buffers = MEM_callocN(sizeof(*pool->buffers) * pool->maxsize,
- "GPUBufferPool.buffers");
- pool->pbvhbufids = MEM_callocN(sizeof(*pool->pbvhbufids) * pool->maxpbvhsize,
- "GPUBufferPool.pbvhbuffers");
+ pool->buffers = MEM_mallocN(sizeof(*pool->buffers) * pool->maxsize,
+ "GPUBufferPool.buffers");
+ pool->pbvhbufids = MEM_mallocN(sizeof(*pool->pbvhbufids) * pool->maxpbvhsize,
+ "GPUBufferPool.pbvhbuffers");
return pool;
}
@@ -391,14 +387,22 @@ void GPU_buffer_free(GPUBuffer *buffer)
BLI_mutex_unlock(&buffer_mutex);
}
+/* currently unused */
+// #define USE_GPU_POINT_LINK
+
typedef struct GPUVertPointLink {
+#ifdef USE_GPU_POINT_LINK
struct GPUVertPointLink *next;
+#endif
/* -1 means uninitialized */
int point_index;
} GPUVertPointLink;
+
/* add a new point to the list of points related to a particular
* vertex */
+#ifdef USE_GPU_POINT_LINK
+
static void gpu_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
{
GPUVertPointLink *lnk;
@@ -418,6 +422,19 @@ static void gpu_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, in
lnk->point_index = point_index;
}
+#else
+
+static void gpu_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
+{
+ GPUVertPointLink *lnk;
+ lnk = &gdo->vert_points[vert_index];
+ if (lnk->point_index == -1) {
+ lnk->point_index = point_index;
+ }
+}
+
+#endif /* USE_GPU_POINT_LINK */
+
/* update the vert_points and triangle_to_mface fields with a new
* triangle */
static void gpu_drawobject_add_triangle(GPUDrawObject *gdo,
@@ -433,17 +450,21 @@ static void gpu_drawobject_add_triangle(GPUDrawObject *gdo,
/* for each vertex, build a list of points related to it; these lists
* are stored in an array sized to the number of vertices */
-static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface)
+static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface, int totmat)
{
GPUBufferMaterial *mat;
- int i, mat_orig_to_new[MAX_MATERIALS];
+ int i, *mat_orig_to_new;
+ mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat,
+ "GPUDrawObject.mat_orig_to_new");
/* allocate the array and space for links */
- gdo->vert_points = MEM_callocN(sizeof(GPUVertPointLink) * gdo->totvert,
+ gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert,
"GPUDrawObject.vert_points");
+#ifdef USE_GPU_POINT_LINK
gdo->vert_points_mem = MEM_callocN(sizeof(GPUVertPointLink) * gdo->tot_triangle_point,
"GPUDrawObject.vert_points_mem");
gdo->vert_points_usage = 0;
+#endif
/* build a map from the original material indices to the new
* GPUBufferMaterial indices */
@@ -451,8 +472,12 @@ static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int to
mat_orig_to_new[gdo->materials[i].mat_nr] = i;
/* -1 indicates the link is not yet used */
- for (i = 0; i < gdo->totvert; i++)
+ for (i = 0; i < gdo->totvert; i++) {
+#ifdef USE_GPU_POINT_LINK
+ gdo->vert_points[i].link = NULL;
+#endif
gdo->vert_points[i].point_index = -1;
+ }
for (i = 0; i < totface; i++, f++) {
mat = &gdo->materials[mat_orig_to_new[f->mat_nr]];
@@ -477,6 +502,8 @@ static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int to
gdo->tot_loose_point++;
}
}
+
+ MEM_freeN(mat_orig_to_new);
}
/* see GPUDrawObject's structure definition for a description of the
@@ -485,15 +512,19 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
{
GPUDrawObject *gdo;
MFace *mface;
- int points_per_mat[MAX_MATERIALS];
+ int totmat = dm->totmat;
+ int *points_per_mat;
int i, curmat, curpoint, totface;
+ /* object contains at least one material (default included) so zero means uninitialized dm */
+ BLI_assert(totmat != 0);
+
mface = dm->getTessFaceArray(dm);
totface = dm->getNumTessFaces(dm);
/* get the number of points used by each material, treating
* each quad as two triangles */
- memset(points_per_mat, 0, sizeof(int) * MAX_MATERIALS);
+ points_per_mat = MEM_callocN(sizeof(*points_per_mat) * totmat, "GPU_drawobject_new.mat_orig_to_new");
for (i = 0; i < totface; i++)
points_per_mat[mface[i].mat_nr] += mface[i].v4 ? 6 : 3;
@@ -503,7 +534,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
gdo->totedge = dm->getNumEdges(dm);
/* count the number of materials used by this DerivedMesh */
- for (i = 0; i < MAX_MATERIALS; i++) {
+ for (i = 0; i < totmat; i++) {
if (points_per_mat[i] > 0)
gdo->totmaterial++;
}
@@ -513,7 +544,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
"GPUDrawObject.materials");
/* initialize the materials array */
- for (i = 0, curmat = 0, curpoint = 0; i < MAX_MATERIALS; i++) {
+ for (i = 0, curmat = 0, curpoint = 0; i < totmat; i++) {
if (points_per_mat[i] > 0) {
gdo->materials[curmat].start = curpoint;
gdo->materials[curmat].totpoint = 0;
@@ -530,7 +561,8 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
gdo->triangle_to_mface = MEM_mallocN(sizeof(int) * (gdo->tot_triangle_point / 3),
"GPUDrawObject.triangle_to_mface");
- gpu_drawobject_init_vert_points(gdo, mface, totface);
+ gpu_drawobject_init_vert_points(gdo, mface, totface, totmat);
+ MEM_freeN(points_per_mat);
return gdo;
}
@@ -545,7 +577,9 @@ void GPU_drawobject_free(DerivedMesh *dm)
MEM_freeN(gdo->materials);
MEM_freeN(gdo->triangle_to_mface);
MEM_freeN(gdo->vert_points);
+#ifdef USE_GPU_POINT_LINK
MEM_freeN(gdo->vert_points_mem);
+#endif
GPU_buffer_free(gdo->points);
GPU_buffer_free(gdo->normals);
GPU_buffer_free(gdo->uv);
@@ -567,10 +601,10 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
GPUBufferPool *pool;
GPUBuffer *buffer;
float *varray;
- int mat_orig_to_new[MAX_MATERIALS];
+ int *mat_orig_to_new;
int *cur_index_per_mat;
int i;
- int success;
+ bool success;
GLboolean uploaded;
pool = gpu_get_global_buffer_pool();
@@ -587,6 +621,8 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
return NULL;
}
+ mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
+ "GPU_buffer_setup.mat_orig_to_new");
cur_index_per_mat = MEM_mallocN(sizeof(int) * object->totmaterial,
"GPU_buffer_setup.cur_index_per_mat");
for (i = 0; i < object->totmaterial; i++) {
@@ -659,6 +695,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
}
MEM_freeN(cur_index_per_mat);
+ MEM_freeN(mat_orig_to_new);
BLI_mutex_unlock(&buffer_mutex);
@@ -709,7 +746,8 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i
int start;
float f_no[3];
- float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MVert *mvert = dm->getVertArray(dm);
MFace *f = dm->getTessFaceArray(dm);
@@ -720,7 +758,20 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i
start = index[mat_orig_to_new[f->mat_nr]];
index[mat_orig_to_new[f->mat_nr]] += f->v4 ? 18 : 9;
- if (smoothnormal) {
+ if (tlnors) {
+ short (*tlnor)[3] = tlnors[i];
+ /* Copy loop normals */
+ normal_short_to_float_v3(&varray[start], tlnor[0]);
+ normal_short_to_float_v3(&varray[start + 3], tlnor[1]);
+ normal_short_to_float_v3(&varray[start + 6], tlnor[2]);
+
+ if (f->v4) {
+ normal_short_to_float_v3(&varray[start + 9], tlnor[2]);
+ normal_short_to_float_v3(&varray[start + 12], tlnor[3]);
+ normal_short_to_float_v3(&varray[start + 15], tlnor[0]);
+ }
+ }
+ else if (smoothnormal) {
/* copy vertex normal */
normal_short_to_float_v3(&varray[start], mvert[f->v1].no);
normal_short_to_float_v3(&varray[start + 3], mvert[f->v2].no);
@@ -836,7 +887,7 @@ static void GPU_buffer_copy_edge(DerivedMesh *dm, float *varray_, int *UNUSED(in
MEdge *medge;
unsigned int *varray = (unsigned int *)varray_;
int i, totedge;
-
+
medge = dm->getEdgeArray(dm);
totedge = dm->getNumEdges(dm);
@@ -1256,13 +1307,13 @@ void GPU_color_switch(int mode)
/* return 1 if drawing should be done using old immediate-mode
* code, 0 otherwise */
-int GPU_buffer_legacy(DerivedMesh *dm)
+bool GPU_buffer_legacy(DerivedMesh *dm)
{
int test = (U.gameflags & USER_DISABLE_VBO);
if (test)
return 1;
- if (dm->drawObject == 0)
+ if (dm->drawObject == NULL)
dm->drawObject = GPU_drawobject_new(dm);
return dm->drawObject->legacy;
}
@@ -1359,7 +1410,7 @@ struct GPU_PBVH_Buffers {
/* mesh pointers in case buffer allocation fails */
MFace *mface;
MVert *mvert;
- int *face_indices;
+ const int *face_indices;
int totface;
const float *vmask;
@@ -1368,7 +1419,7 @@ struct GPU_PBVH_Buffers {
CCGElem **grids;
const DMFlagMat *grid_flag_mats;
BLI_bitmap * const *grid_hidden;
- int *grid_indices;
+ const int *grid_indices;
int totgrid;
int has_hidden;
@@ -1380,7 +1431,8 @@ struct GPU_PBVH_Buffers {
* smooth-shaded or all faces are flat-shaded */
int smooth;
- int show_diffuse_color;
+ bool show_diffuse_color;
+ bool use_matcaps;
float diffuse_color[4];
};
typedef enum {
@@ -1458,7 +1510,7 @@ static void gpu_color_from_mask_quad_copy(const CCGKey *key,
static void gpu_color_from_mask_quad_set(const CCGKey *key,
CCGElem *a, CCGElem *b,
CCGElem *c, CCGElem *d,
- float diffuse_color[4])
+ const float diffuse_color[4])
{
float color = gpu_color_from_mask_quad(key, a, b, c, d);
// XXX jwilkins: this probably needs a VertexAttrib as well
@@ -1467,19 +1519,22 @@ static void gpu_color_from_mask_quad_set(const CCGKey *key,
void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
int *vert_indices, int totvert, const float *vmask,
- int (*face_vert_indices)[4], int show_diffuse_color)
+ int (*face_vert_indices)[4], bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j, k;
buffers->vmask = vmask;
buffers->show_diffuse_color = show_diffuse_color;
+ buffers->use_matcaps = GPU_material_use_matcaps_get();
if (buffers->vert_buf) {
int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
- float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f};
- if (buffers->show_diffuse_color) {
+ if (buffers->use_matcaps)
+ diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ else if (show_diffuse_color) {
MFace *f = buffers->mface + buffers->face_indices[0];
GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
@@ -1600,7 +1655,7 @@ void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
buffers->mvert = mvert;
}
-GPU_PBVH_Buffers *GPU_build_pbvh_mesh_buffers(int (*face_vert_indices)[4],
+GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
MFace *mface, MVert *mvert,
int *face_indices,
int totface)
@@ -1613,7 +1668,8 @@ GPU_PBVH_Buffers *GPU_build_pbvh_mesh_buffers(int (*face_vert_indices)[4],
buffers->index_type = GL_UNSIGNED_SHORT;
buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH;
- buffers->show_diffuse_color = FALSE;
+ buffers->show_diffuse_color = false;
+ buffers->use_matcaps = false;
/* Count the number of visible triangles */
for (i = 0, tottri = 0; i < totface; ++i) {
@@ -1622,6 +1678,16 @@ GPU_PBVH_Buffers *GPU_build_pbvh_mesh_buffers(int (*face_vert_indices)[4],
tottri += f->v4 ? 2 : 1;
}
+ if (tottri == 0) {
+ buffers->tot_tri = 0;
+
+ buffers->mface = mface;
+ buffers->face_indices = face_indices;
+ buffers->totface = 0;
+
+ return buffers;
+ }
+
/* An element index buffer is used for smooth shading, but flat
* shading requires separate vertex normals so an index buffer is
* can't be used there. */
@@ -1683,12 +1749,13 @@ GPU_PBVH_Buffers *GPU_build_pbvh_mesh_buffers(int (*face_vert_indices)[4],
void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
const DMFlagMat *grid_flag_mats, int *grid_indices,
- int totgrid, const CCGKey *key, int show_diffuse_color)
+ int totgrid, const CCGKey *key, bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j, k, x, y;
buffers->show_diffuse_color = show_diffuse_color;
+ buffers->use_matcaps = GPU_material_use_matcaps_get();
/* Build VBO */
if (buffers->vert_buf) {
@@ -1697,7 +1764,9 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
const int has_mask = key->has_mask;
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
- if (buffers->show_diffuse_color) {
+ if (buffers->use_matcaps)
+ diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ else if (show_diffuse_color) {
const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
@@ -1734,7 +1803,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
if (!smooth) {
/* for flat shading, recalc normals and set the last vertex of
- * each quad in the index buffer to have the flat normal as
+ * each triangle in the index buffer to have the flat normal as
* that is what opengl will use */
for (j = 0; j < key->grid_size - 1; j++) {
for (k = 0; k < key->grid_size - 1; k++) {
@@ -1752,7 +1821,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
CCG_elem_co(key, elems[2]),
CCG_elem_co(key, elems[3]));
- vd = vert_data + (j + 1) * key->grid_size + (k + 1);
+ vd = vert_data + (j + 1) * key->grid_size + k;
normal_float_to_short_v3(vd->no, fno);
if (has_mask) {
@@ -1790,52 +1859,22 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
//printf("node updated %p\n", buffers);
}
-/* Returns the number of visible quads in the nodes' grids. */
-static int gpu_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices, int totgrid,
- int gridsize)
-{
- int gridarea = (gridsize - 1) * (gridsize - 1);
- int i, x, y, totquad;
-
- /* grid hidden layer is present, so have to check each grid for
- * visibility */
-
- for (i = 0, totquad = 0; i < totgrid; i++) {
- const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
-
- if (gh) {
- /* grid hidden are present, have to check each element */
- for (y = 0; y < gridsize - 1; y++) {
- for (x = 0; x < gridsize - 1; x++) {
- if (!paint_is_grid_face_hidden(gh, gridsize, x, y))
- totquad++;
- }
- }
- }
- else
- totquad += gridarea;
- }
-
- return totquad;
-}
-
/* Build the element array buffer of grid indices using either
* unsigned shorts or unsigned ints. */
#define FILL_QUAD_BUFFER(type_, tot_quad_, buffer_) \
{ \
- type_ *quad_data; \
+ type_ *tri_data; \
int offset = 0; \
int i, j, k; \
\
gpu_glBufferData(GL_ELEMENT_ARRAY_BUFFER, \
- sizeof(type_) * (tot_quad_) * 4, NULL, \
+ sizeof(type_) * (tot_quad_) * 6, NULL, \
GL_STATIC_DRAW); \
\
- /* Fill the quad buffer */ \
- quad_data = gpu_glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, \
+ /* Fill the buffer */ \
+ tri_data = gpu_glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, \
GL_WRITE_ONLY); \
- if (quad_data) { \
+ if (tri_data) { \
for (i = 0; i < totgrid; ++i) { \
BLI_bitmap *gh = NULL; \
if (grid_hidden) \
@@ -1849,10 +1888,13 @@ static int gpu_count_grid_quads(BLI_bitmap **grid_hidden,
gridsize, k, j)) \
continue; \
\
- *(quad_data++) = offset + j * gridsize + k + 1; \
- *(quad_data++) = offset + j * gridsize + k; \
- *(quad_data++) = offset + (j + 1) * gridsize + k; \
- *(quad_data++) = offset + (j + 1) * gridsize + k + 1; \
+ *(tri_data++) = offset + j * gridsize + k + 1; \
+ *(tri_data++) = offset + j * gridsize + k; \
+ *(tri_data++) = offset + (j + 1) * gridsize + k; \
+ \
+ *(tri_data++) = offset + (j + 1) * gridsize + k + 1; \
+ *(tri_data++) = offset + j * gridsize + k + 1; \
+ *(tri_data++) = offset + (j + 1) * gridsize + k; \
} \
} \
\
@@ -1876,7 +1918,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
/* used in the FILL_QUAD_BUFFER macro */
BLI_bitmap * const *grid_hidden = NULL;
- int *grid_indices = NULL;
+ const int *grid_indices = NULL;
int totgrid = 1;
/* VBO is disabled; delete the previous buffer (if it exists) and
@@ -1920,7 +1962,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
}
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
- BLI_bitmap **grid_hidden, int gridsize)
+ BLI_bitmap **grid_hidden, int gridsize)
{
GPU_PBVH_Buffers *buffers;
int totquad;
@@ -1930,10 +1972,15 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
buffers->grid_hidden = grid_hidden;
buffers->totgrid = totgrid;
- buffers->show_diffuse_color = FALSE;
+ buffers->show_diffuse_color = false;
+ buffers->use_matcaps = false;
/* Count the number of quads */
- totquad = gpu_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
+ totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
+
+ /* totally hidden node, return here to avoid BufferData with zero below. */
+ if (totquad == 0)
+ return buffers;
if (totquad == fully_visible_totquad) {
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
@@ -1982,14 +2029,12 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
int *v_index,
const float fno[3],
const float *fmask,
- const int cd_vert_mask_offset)
+ const int cd_vert_mask_offset,
+ const float diffuse_color[4])
{
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
VertexBufferFormat *vd = &vert_data[*v_index];
- /* TODO: should use material color */
- float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
-
/* Set coord, normal, and mask */
copy_v3_v3(vd->co, v->co);
normal_float_to_short_v3(vd->no, fno ? fno : v->no);
@@ -2031,15 +2076,15 @@ static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts,
}
/* Return the total number of visible faces */
-static int gpu_bmesh_face_visible_count(GHash *bm_faces)
+static int gpu_bmesh_face_visible_count(GSet *bm_faces)
{
- GHashIterator gh_iter;
+ GSetIterator gh_iter;
int totface = 0;
- GHASH_ITER (gh_iter, bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
- if (!paint_is_bmesh_face_hidden(f))
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
totface++;
}
@@ -2050,17 +2095,22 @@ static int gpu_bmesh_face_visible_count(GHash *bm_faces)
* shading, an element index buffer. */
void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
BMesh *bm,
- GHash *bm_faces,
+ GSet *bm_faces,
GSet *bm_unique_verts,
- GSet *bm_other_verts)
+ GSet *bm_other_verts,
+ bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
void *tri_data;
int tottri, totvert, maxvert = 0;
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
/* TODO, make mask layer optional for bmesh buffer */
const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+ buffers->show_diffuse_color = show_diffuse_color;
+ buffers->use_matcaps = GPU_material_use_matcaps_get();
+
if (!buffers->vert_buf || (buffers->smooth && !buffers->index_buf))
return;
@@ -2074,6 +2124,24 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
else
totvert = tottri * 3;
+ if (!tottri) {
+ buffers->tot_tri = 0;
+ return;
+ }
+
+ if (buffers->use_matcaps)
+ diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ else if (show_diffuse_color) {
+ /* due to dynamic nature of dyntopo, only get first material */
+ GSetIterator gs_iter;
+ BMFace *f;
+ BLI_gsetIterator_init(&gs_iter, bm_faces);
+ f = BLI_gsetIterator_getKey(&gs_iter);
+ GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ }
+
+ copy_v4_v4(buffers->diffuse_color, diffuse_color);
+
/* Initialize vertex buffer */
gpu_glBindBuffer(GL_ARRAY_BUFFER, buffers->vert_buf);
gpu_glBufferData(GL_ARRAY_BUFFER,
@@ -2095,26 +2163,26 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
GSET_ITER (gs_iter, bm_unique_verts) {
gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
vert_data, &v_index, NULL, NULL,
- cd_vert_mask_offset);
+ cd_vert_mask_offset, diffuse_color);
}
GSET_ITER (gs_iter, bm_other_verts) {
gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
vert_data, &v_index, NULL, NULL,
- cd_vert_mask_offset);
+ cd_vert_mask_offset, diffuse_color);
}
maxvert = v_index;
}
else {
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
- GHASH_ITER (gh_iter, bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
BLI_assert(f->len == 3);
- if (!paint_is_bmesh_face_hidden(f)) {
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMVert *v[3];
float fmask = 0;
int i;
@@ -2131,7 +2199,7 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
for (i = 0; i < 3; i++) {
gpu_bmesh_vert_to_buffer_copy(v[i], vert_data,
&v_index, f->no, &fmask,
- cd_vert_mask_offset);
+ cd_vert_mask_offset, diffuse_color);
}
}
}
@@ -2165,12 +2233,12 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
/* Fill triangle index buffer */
tri_data = gpu_glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
if (tri_data) {
- GHashIterator gh_iter;
+ GSetIterator gs_iter;
- GHASH_ITER (gh_iter, bm_faces) {
- BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ GSET_ITER (gs_iter, bm_faces) {
+ BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
- if (!paint_is_bmesh_face_hidden(f)) {
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMLoop *l_iter;
BMLoop *l_first;
@@ -2216,8 +2284,10 @@ GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
if (smooth_shading)
gpu_glGenBuffers(1, &buffers->index_buf);
gpu_glGenBuffers(1, &buffers->vert_buf);
- buffers->use_bmesh = TRUE;
+ buffers->use_bmesh = true;
buffers->smooth = smooth_shading;
+ buffers->show_diffuse_color = false;
+ buffers->use_matcaps = false;
return buffers;
}
@@ -2230,7 +2300,9 @@ static void gpu_draw_buffers_legacy_mesh(GPU_PBVH_Buffers *buffers)
const MFace *face = &buffers->mface[buffers->face_indices[0]];
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
- if (buffers->show_diffuse_color)
+ if (buffers->use_matcaps)
+ diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ else if (buffers->show_diffuse_color)
GPU_material_diffuse_get(face->mat_nr + 1, diffuse_color);
if (has_mask) {
@@ -2306,7 +2378,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_PBVH_Buffers *buffers)
const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
- if (buffers->show_diffuse_color)
+ if (buffers->use_matcaps)
+ diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
+ else if (buffers->show_diffuse_color)
GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
if (has_mask) {
@@ -2479,19 +2553,19 @@ void GPU_draw_pbvh_buffers(
if (GPU_commit_aspect()) {
if (buffers->tot_quad) {
- char *offset = 0;
+ const char *offset = 0;
int i, last = buffers->has_hidden ? 1 : buffers->totgrid;
for (i = 0; i < last; i++) {
GPU_common_vertex_pointer(3, GL_FLOAT, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, co));
GPU_common_normal_pointer(GL_SHORT, sizeof(VertexBufferFormat), GL_TRUE, offset + offsetof(VertexBufferFormat, no));
GPU_common_color_pointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, color));
- glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0);
+ glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, 0);
offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
}
}
- else {
+ else if (buffers->tot_tri) {
int totelem = buffers->tot_tri * 3;
GPU_common_vertex_pointer(3, GL_FLOAT, sizeof(VertexBufferFormat), (void *)offsetof(VertexBufferFormat, co));
@@ -2527,21 +2601,33 @@ void GPU_draw_pbvh_buffers(
GPU_CHECK_NO_ERROR();
}
-int GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, int show_diffuse_color)
+bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
{
float diffuse_color[4];
+ bool use_matcaps = GPU_material_use_matcaps_get();
if (buffers->show_diffuse_color != show_diffuse_color)
- return TRUE;
+ return true;
- if (buffers->show_diffuse_color == FALSE)
- return FALSE;
+ if (buffers->use_matcaps != use_matcaps)
+ return true;
+
+ if ((buffers->show_diffuse_color == false) || use_matcaps)
+ return false;
if (buffers->mface) {
MFace *f = buffers->mface + buffers->face_indices[0];
GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
}
+ else if (buffers->use_bmesh) {
+ /* due to dynamc nature of dyntopo, only get first material */
+ GSetIterator gs_iter;
+ BMFace *f;
+ BLI_gsetIterator_init(&gs_iter, bm_faces);
+ f = BLI_gsetIterator_getKey(&gs_iter);
+ GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ }
else {
const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
@@ -2601,3 +2687,65 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
MEM_freeN(buffers);
}
}
+
+
+/* debug function, draws the pbvh BB */
+void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
+{
+ float quads[4][4][3] = {
+ {
+ {min[0], min[1], min[2]},
+ {max[0], min[1], min[2]},
+ {max[0], min[1], max[2]},
+ {min[0], min[1], max[2]}
+ },
+
+ {
+ {min[0], min[1], min[2]},
+ {min[0], max[1], min[2]},
+ {min[0], max[1], max[2]},
+ {min[0], min[1], max[2]}
+ },
+
+ {
+ {max[0], max[1], min[2]},
+ {max[0], min[1], min[2]},
+ {max[0], min[1], max[2]},
+ {max[0], max[1], max[2]}
+ },
+
+ {
+ {max[0], max[1], min[2]},
+ {min[0], max[1], min[2]},
+ {min[0], max[1], max[2]},
+ {max[0], max[1], max[2]}
+ },
+ };
+
+ if (leaf)
+ glColor4f(0.0, 1.0, 0.0, 0.5);
+ else
+ glColor4f(1.0, 0.0, 0.0, 0.5);
+
+ glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
+ glDrawArrays(GL_QUADS, 0, 16);
+}
+
+void GPU_init_draw_pbvh_BB(void)
+{
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_CULL_FACE);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glEnable(GL_BLEND);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+}
+
+void GPU_end_draw_pbvh_BB(void)
+{
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPopAttrib();
+}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 6873a6c5b88..d1c50c06a8f 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -51,7 +51,6 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
-#include "BLI_heap.h"
#include "BLI_sys_types.h" /* for intptr_t */
#include "BLI_utildefines.h"
@@ -587,8 +586,15 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
else
BLI_dynstr_appendf(ds, "cons%d", input->id);
}
- else if (input->source == GPU_SOURCE_ATTRIB)
+ else if (input->source == GPU_SOURCE_ATTRIB) {
BLI_dynstr_appendf(ds, "var%d", input->attribid);
+ }
+ else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
+ if (input->oglbuiltin == GPU_MATCAP_NORMAL)
+ BLI_dynstr_append(ds, "gl_SecondaryColor");
+ else if (input->oglbuiltin == GPU_COLOR)
+ BLI_dynstr_append(ds, "gl_Color");
+ }
BLI_dynstr_append(ds, ", ");
}
@@ -675,6 +681,18 @@ static char *code_generate_vertex(ListBase *nodes)
else
BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid);
}
+ /* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */
+ else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
+ if (input->oglbuiltin == GPU_MATCAP_NORMAL) {
+ /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
+ * between shader stages and we want the full range of the normal */
+ BLI_dynstr_appendf(ds, "\tvec3 matcapcol = vec3(0.5, 0.5, 0.5) * varnormal + vec3(0.5, 0.5, 0.5);\n");
+ BLI_dynstr_appendf(ds, "\tgl_FrontSecondaryColor = vec4(matcapcol, 1.0);\n");
+ }
+ else if (input->oglbuiltin == GPU_COLOR) {
+ BLI_dynstr_appendf(ds, "\tgl_FrontColor = gl_Color;\n");
+ }
+ }
BLI_dynstr_append(ds, "}\n\n");
@@ -742,7 +760,8 @@ static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
/* attributes don't need to be bound, they already have
* an id that the drawing functions will use */
if (input->source == GPU_SOURCE_ATTRIB ||
- input->source == GPU_SOURCE_BUILTIN)
+ input->source == GPU_SOURCE_BUILTIN ||
+ input->source == GPU_SOURCE_OPENGL_BUILTIN)
{
continue;
}
@@ -910,6 +929,14 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
MEM_freeN(link);
}
+ else if (link->oglbuiltin) {
+ /* builtin uniform */
+ input->type = type;
+ input->source = GPU_SOURCE_OPENGL_BUILTIN;
+ input->oglbuiltin = link->oglbuiltin;
+
+ MEM_freeN(link);
+ }
else if (link->output) {
/* link to a node output */
input->type = type;
@@ -1147,14 +1174,14 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
{
GPUNodeLink *link = GPU_node_link_create(0);
- link->image= LINK_IMAGE_BLENDER;
- link->ptr1= ima;
- link->ptr2= iuser;
- link->image_isdata= isdata;
+ link->image = LINK_IMAGE_BLENDER;
+ link->ptr1 = ima;
+ link->ptr2 = iuser;
+ link->image_isdata = is_data;
return link;
}
@@ -1202,6 +1229,15 @@ GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
return link;
}
+GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->oglbuiltin = builtin;
+
+ return link;
+}
+
bool GPU_link(GPUMaterial *mat, const char *name, ...)
{
GPUNode *node;
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 0a61bb6c668..7517cdee628 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -62,6 +62,7 @@ GPUFunction *GPU_lookup_function(const char *name);
typedef enum GPUDataSource {
GPU_SOURCE_VEC_UNIFORM,
GPU_SOURCE_BUILTIN,
+ GPU_SOURCE_OPENGL_BUILTIN,
GPU_SOURCE_TEX_PIXEL,
GPU_SOURCE_TEX,
GPU_SOURCE_ATTRIB
@@ -100,6 +101,7 @@ struct GPUNodeLink {
struct GPUTexture *dynamictex;
GPUBuiltin builtin;
+ GPUOpenGLBuiltin oglbuiltin;
struct GPUOutput *output;
};
@@ -147,6 +149,7 @@ typedef struct GPUInput {
char attribname[32]; /* attribute name */
int attribfirst; /* this is the first one that is bound */
GPUBuiltin builtin; /* builtin uniform */
+ GPUOpenGLBuiltin oglbuiltin; /* opengl built in varying */
} GPUInput;
struct GPUPass {
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 0b5118bcfb3..d2976b248af 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -104,7 +104,7 @@ extern Material defmaterial; /* from material.c */
static void gpu_mcol(unsigned int ucol)
{
/* mcol order is swapped */
- char *cp= (char *)&ucol;
+ const char *cp= (char *)&ucol;
gpuColor3ub(cp[3], cp[2], cp[1]);
}
@@ -592,7 +592,7 @@ GLenum GPU_mipmap_2D(GLboolean genmip, GLenum internalFormat, int w, int h, GLen
#endif
}
-int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap, bool is_data)
+int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, bool mipmap, bool is_data)
{
ImBuf *ibuf = NULL;
unsigned int *bind = NULL;
@@ -602,7 +602,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
float *srgb_frect = NULL;
short texwindx, texwindy, texwinsx, texwinsy;
/* flag to determine whether high resolution format is used */
- int use_high_bit_depth = FALSE, do_color_management = FALSE;
+ bool use_high_bit_depth = false, do_color_management = false;
/* initialize tile mode and number of repeats */
GTS.ima = ima;
@@ -658,12 +658,12 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (U.use_16bit_textures) {
/* use high precision textures. This is relatively harmless because OpenGL gives us
* a high precision format only if it is available */
- use_high_bit_depth = TRUE;
+ use_high_bit_depth = true;
}
/* TODO unneeded when float images are correctly treated as linear always */
if (!is_data)
- do_color_management = TRUE;
+ do_color_management = true;
if (ibuf->rect==NULL)
IMB_rect_from_float(ibuf);
@@ -705,7 +705,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
@@ -731,7 +731,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
@@ -816,7 +816,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
}
/* Image *ima can be NULL */
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth,
+ bool mipmap, bool use_high_bit_depth, Image *ima)
{
unsigned int *scalerect = NULL;
float *fscalerect = NULL;
@@ -883,9 +884,9 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int
/**
* GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go.
* This is so the viewport and the BGE can share some code.
- * Returns FALSE if the provided ImBuf doesn't have a supported DXT compression format
+ * Returns false if the provided ImBuf doesn't have a supported DXT compression format
*/
-int GPU_upload_dxt_texture(ImBuf *ibuf)
+bool GPU_upload_dxt_texture(ImBuf *ibuf)
{
#ifdef WITH_DDS
GLint format = 0;
@@ -905,12 +906,12 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
if (format == 0) {
printf("Unable to find a suitable DXT compression, falling back to uncompressed\n");
- return FALSE;
+ return false;
}
if (!is_power_of_2_resolution(width, height)) {
printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
- return FALSE;
+ return false;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
@@ -943,10 +944,10 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
/* set number of mipmap levels we have, needed in case they don't go down to 1x1 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i-1);
- return TRUE;
+ return true;
#else
(void)ibuf;
- return FALSE;
+ return false;
#endif
}
@@ -998,7 +999,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap, int alphablend)
gpu_verify_alpha_blend(alphablend);
gpu_verify_reflection(ima);
- if (GPU_verify_image(ima, NULL, tface->tile, 1, mipmap, FALSE)) {
+ if (GPU_verify_image(ima, NULL, tface->tile, 1, mipmap, false)) {
GTS.curtile= GTS.tile;
GTS.curima= GTS.ima;
GTS.curtilemode= GTS.tilemode;
@@ -1166,7 +1167,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
/* if color correction is needed, we must update the part that needs updating. */
if (ibuf->rect_float) {
float *buffer = (float*)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
- int is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA);
+ bool is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA) != 0;
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
if (GPU_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
@@ -1479,6 +1480,7 @@ static struct GPUMaterialState {
GPUBlendMode *alphablend;
GPUBlendMode alphablend_fixed[FIXEDMAT];
bool use_alpha_pass, is_alpha_pass;
+ bool use_matcaps;
int lastmatnr, lastretval;
GPUBlendMode lastalphablend;
@@ -1643,8 +1645,12 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
const bool use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) != 0; /* assumes v3d->defmaterial->preview is set */
- ob = BKE_object_lod_matob_get(ob, scene);
-
+#ifdef WITH_GAMEENGINE
+ if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
+ ob = BKE_object_lod_matob_get(ob, scene);
+ }
+#endif
+
/* initialize state */
memset(&GMS, 0, sizeof(GMS));
@@ -1652,6 +1658,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.lastretval = -1;
GMS.lastalphablend = GPU_BLEND_SOLID;
+ GMS.use_matcaps = use_matcap;
GMS.lastalphatestenabled = GL_FALSE;
GMS.lastalphatestref = 0.5f;
@@ -1673,7 +1680,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
* - object transparency off: for glsl we draw both in a single pass, and
* for solid we don't use transparency at all. */
GMS.use_alpha_pass = (do_alpha_after != NULL);
- GMS.is_alpha_pass = (v3d->transp != FALSE);
+ GMS.is_alpha_pass = (v3d->transp != false);
if (GMS.use_alpha_pass)
*do_alpha_after = false;
@@ -1692,7 +1699,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
if (use_matcap) {
GMS.gmatbuf[0] = v3d->defmaterial;
GPU_material_matcap(scene, v3d->defmaterial);
-
+
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
@@ -1734,7 +1741,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* fixed function opengl materials */
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
- if (GMS.use_alpha_pass) {
+ if (GMS.use_alpha_pass && ((ma->mode & MA_TRANSP) || (new_shading_nodes && ma->alpha != 1.0f))) {
GMS.matbuf[a].diff[3]= ma->alpha;
alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
}
@@ -1744,7 +1751,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
}
}
- /* setting 'do_alpha_after = TRUE' indicates this object needs to be
+ /* setting 'do_alpha_after = true' indicates this object needs to be
* drawn in a second alpha pass for improved blending */
if (do_alpha_after && !GMS.is_alpha_pass)
if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
@@ -1849,6 +1856,9 @@ int GPU_enable_material(int nr, void *attribs)
else
glDisable(GL_CULL_FACE);
}
+
+ if (GMS.use_matcaps)
+ glColor3f(1.0, 1.0, 1.0f);
}
else {
/* or do a basic material */
@@ -1911,6 +1921,12 @@ void GPU_material_diffuse_get(int nr, float diff[4])
}
}
+bool GPU_material_use_matcaps_get(void)
+{
+ return GMS.use_matcaps;
+}
+
+
void GPU_end_object_materials(void)
{
GPU_disable_material();
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index fa1134caf45..650df8f5287 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -401,7 +401,7 @@ struct GPUTexture {
static unsigned char *GPU_texture_convert_pixels(int length, float *fpixels)
{
unsigned char *pixels, *p;
- float *fp;
+ const float *fp;
int a, len;
len = 4*length;
@@ -669,14 +669,14 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
return tex;
}
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, double time, int mipmap)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data, double time, int mipmap)
{
GPUTexture *tex;
GLint w, h, border, bindcode;
GPU_update_image_time(ima, time);
/* this binds a texture, so that's why to restore it with lastbindcode */
- bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, isdata);
+ bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, is_data);
if (ima->gputexture) {
ima->gputexture->bindcode = bindcode;
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 7d9fc63b4f9..5fca9ae8eac 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -64,6 +64,7 @@
#include "BKE_node.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
+#include "BKE_group.h"
#include "IMB_imbuf_types.h"
@@ -274,18 +275,33 @@ void GPU_material_free(Material *ma)
BLI_freelistN(&ma->gpumaterial);
}
+bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
+{
+ if (srl && srl->light_override)
+ return BKE_group_object_exists(srl->light_override, lamp->ob);
+ else if (ma && ma->group)
+ return BKE_group_object_exists(ma->group, lamp->ob);
+ else
+ return true;
+}
+
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4])
{
if (material->pass) {
LinkData *nlink;
GPULamp *lamp;
GPUShader *shader = GPU_pass_shader(material->pass);
+ SceneRenderLayer *srl = BLI_findlink(&material->scene->r.layers, material->scene->r.actlay);
+
+ if (srl)
+ viewlay &= srl->lay;
/* handle layer lamps */
for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
lamp= nlink->data;
- if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) {
+ if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
+ && GPU_lamp_override_visible(lamp, srl, material->ma)) {
lamp->dynenergy = lamp->energy;
copy_v3_v3(lamp->dyncol, lamp->col);
}
@@ -412,10 +428,10 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
/* Code generation */
-int GPU_material_do_color_management(GPUMaterial *mat)
+bool GPU_material_do_color_management(GPUMaterial *mat)
{
if (!BKE_scene_check_color_management_enabled(mat->scene))
- return FALSE;
+ return false;
return !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT));
}
@@ -672,7 +688,7 @@ static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **
GPU_link(mat, "shade_light_texture",
GPU_builtin(GPU_VIEW_POSITION),
- GPU_image(mtex->tex->ima, &mtex->tex->iuser, FALSE),
+ GPU_image(mtex->tex->ima, &mtex->tex->iuser, false),
GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
&tex_rgb);
texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb);
@@ -995,7 +1011,8 @@ static void do_material_tex(GPUShadeInput *shi)
/*char *lastuvname = NULL;*/ /*UNUSED*/
float one = 1.0f, norfac, ofs[3];
int tex_nr, rgbnor, talpha;
- int init_done = FALSE, iBumpSpacePrev = 0; /* Not necessary, quiting gcc warning. */
+ bool init_done = false;
+ int iBumpSpacePrev = 0; /* Not necessary, quiting gcc warning. */
GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
int iFirstTimeNMap=1;
int found_deriv_map = 0;
@@ -1065,7 +1082,7 @@ static void do_material_tex(GPUShadeInput *shi)
talpha = 0;
if (tex && tex->type == TEX_IMAGE && tex->ima) {
- GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, FALSE), &tin, &trgb);
+ GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
rgbnor= TEX_RGB;
talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
@@ -1140,7 +1157,7 @@ static void do_material_tex(GPUShadeInput *shi)
if (tex->imaflag & TEX_NORMALMAP) {
/* normalmap image */
- GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, TRUE), &tnor);
+ GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor);
if (mtex->norfac < 0.0f)
GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
@@ -1238,7 +1255,7 @@ static void do_material_tex(GPUShadeInput *shi)
// copy shi->vn to vNorg and vNacc, set magnitude to 1
GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
iBumpSpacePrev = 0;
- init_done = TRUE;
+ init_done = true;
}
// find current bump space
@@ -1280,26 +1297,26 @@ static void do_material_tex(GPUShadeInput *shi)
if (found_deriv_map) {
GPU_link(mat, "mtex_bump_deriv",
- texco, GPU_image(tex->ima, &tex->iuser, TRUE), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
&dBs, &dBt );
}
else if ( mtex->texflag & MTEX_3TAP_BUMP)
GPU_link(mat, "mtex_bump_tap3",
- texco, GPU_image(tex->ima, &tex->iuser, TRUE), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
&dBs, &dBt );
else if ( mtex->texflag & MTEX_5TAP_BUMP)
GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, TRUE), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
&dBs, &dBt );
else if ( mtex->texflag & MTEX_BICUBIC_BUMP ) {
if (GPU_bicubic_bump_support()) {
GPU_link(mat, "mtex_bump_bicubic",
- texco, GPU_image(tex->ima, &tex->iuser, TRUE), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
&dBs, &dBt);
}
else {
GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, TRUE), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
&dBs, &dBt);
}
}
@@ -1309,7 +1326,7 @@ static void do_material_tex(GPUShadeInput *shi)
float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
GPU_link(mat, "mtex_bump_apply_texspace",
fDet, dBs, dBt, vR1, vR2,
- GPU_image(tex->ima, &tex->iuser, TRUE), texco,
+ GPU_image(tex->ima, &tex->iuser, true), texco,
GPU_uniform(&imag_tspace_dimension_x), GPU_uniform(&imag_tspace_dimension_y), vNacc,
&vNacc, &shi->vn );
}
@@ -1549,7 +1566,11 @@ static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
{
GPUNodeLink *outlink;
- GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
+ /* some explanations here:
+ * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse
+ * the built in secondary color of opengl. Color is just the regular color, which should include mask value too.
+ * This also needs flat shading so we use the primary opengl color built-in */
+ GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_opengl_builtin(GPU_MATCAP_NORMAL), GPU_opengl_builtin(GPU_COLOR), &outlink);
return outlink;
}
diff --git a/source/blender/gpu/intern/gpu_raster.c b/source/blender/gpu/intern/gpu_raster.c
index 7526cfc7e55..6758aaed6db 100644
--- a/source/blender/gpu/intern/gpu_raster.c
+++ b/source/blender/gpu/intern/gpu_raster.c
@@ -139,6 +139,19 @@ const GLubyte GPU_stipple_diag_stripes_neg[128] = {
+const GLubyte stipple_checker_8px[128] = {
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255
+};
+
+
+
/* State */
static struct RASTER {
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 36f67cc64db..e2514679e36 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -299,6 +299,11 @@ void math_modulo(float val1, float val2, out float outval)
outval = mod(val1, val2);
}
+void math_abs(float val1, out float outval)
+{
+ outval = abs(val1);
+}
+
void squeeze(float val, float width, float center, out float outval)
{
outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));
@@ -944,12 +949,9 @@ void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 in
fact *= facg;
facm = 1.0-fact;
- col= texcol.r + ((1.0 -texcol.r)*facm);
- if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
- col= texcol.g + ((1.0 -texcol.g)*facm);
- if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
- col= texcol.b + ((1.0 -texcol.b)*facm);
- if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
+ incol.r = min(outcol.r, texcol.r) * fact + outcol.r * facm;
+ incol.g = min(outcol.g, texcol.g) * fact + outcol.g * facm;
+ incol.b = min(outcol.b, texcol.b) * fact + outcol.b * facm;
}
void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
@@ -1078,8 +1080,7 @@ void mtex_value_dark(float outcol, float texcol, float fact, float facg, out flo
float facm;
mtex_value_vars(fact, facg, facm);
- float col = fact*texcol;
- if(col < outcol) incol = col; else incol = outcol;
+ incol = facm*outcol + fact*min(outcol, texcol);
}
void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
@@ -2378,7 +2379,9 @@ void node_light_path(
out float is_singular_ray,
out float is_reflection_ray,
out float is_transmission_ray,
- out float ray_length)
+ out float ray_length,
+ out float ray_depth,
+ out float transparent_depth)
{
is_camera_ray = 1.0;
is_shadow_ray = 0.0;
@@ -2388,6 +2391,8 @@ void node_light_path(
is_reflection_ray = 0.0;
is_transmission_ray = 0.0;
ray_length = 1.0;
+ ray_depth = 1.0;
+ transparent_depth = 1.0;
}
void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
@@ -2424,16 +2429,20 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
/* ********************** matcap style render ******************** */
-void material_preview_matcap(vec4 color, sampler2D ima, vec3 N, out vec4 result)
+void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
{
+ vec3 normal;
vec2 tex;
-
- if (N.z < 0.0) {
- N.z = 0.0;
- N = normalize(N);
+
+ /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
+ * between shader stages and we want the full range of the normal */
+ normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0);
+ if (normal.z < 0.0) {
+ normal.z = 0.0;
}
+ normal = normalize(normal);
- tex.x = 0.5 + 0.49 * N.x;
- tex.y = 0.5 + 0.49 * N.y;
- result = texture2D(ima, tex);
+ tex.x = 0.5 + 0.49 * normal.x;
+ tex.y = 0.5 + 0.49 * normal.y;
+ result = texture2D(ima, tex) * mask;
}
diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript
index ec19b9a250a..4a4cb4f2cbd 100644
--- a/source/blender/ikplugin/SConscript
+++ b/source/blender/ikplugin/SConscript
@@ -46,7 +46,4 @@ defs = [
'WITH_IK_SOLVER',
]
-if env['OURPLATFORM']=='darwin' and env['C_COMPILER_ID'] == 'clang' and env['CCVERSION'] >= '3.4': # workaround for friend declaration specifies a default argument expression, not allowed anymore
- env.BlenderLib('bf_ikplugin', sources, incs, defs, libtype=['core', 'player'], priority=[180, 190], cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++')
-else:
- env.BlenderLib('bf_ikplugin', sources, incs, defs, libtype=['core', 'player'], priority=[180, 190])
+env.BlenderLib('bf_ikplugin', sources, incs, defs, libtype=['core', 'player'], priority=[180, 190])
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index c3b6df8ac85..80c508267f3 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -374,7 +374,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
* strictly speaking, it is a posechannel)
*/
- BKE_get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_constraint_target_matrix_get(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
/* and set and transform goal */
mul_m4_m4m4(goal, goalinv, rootmat);
@@ -385,7 +385,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* same for pole vector target */
if (data->poletar) {
- BKE_get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_constraint_target_matrix_get(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
if (data->flag & CONSTRAINT_IK_SETANGLE) {
/* don't solve IK when we are setting the pole angle */
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index e1bc47b107f..dbc4100e287 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -551,7 +551,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram
bConstraint *constraint = (bConstraint *)target->blenderConstraint;
float tarmat[4][4];
- BKE_get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
+ BKE_constraint_target_matrix_get(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
// rootmat contains the target pose in world coordinate
// if enforce is != 1.0, blend the target position with the end effector position
@@ -620,7 +620,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame&
IK_Channel &rootchan = ikscene->channels[0];
// get polar target matrix in world space
- BKE_get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
+ BKE_constraint_target_matrix_get(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
// convert to armature space
mul_m4_m4m4(polemat, imat, mat);
// get the target in world space (was computed before as target object are defined before base object)
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index be0069f5bfa..090e7a66d41 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -240,11 +240,11 @@ int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc);
/**
- * Return the fps contained in movie files (function rval is FALSE,
+ * Return the fps contained in movie files (function rval is false,
* and frs_sec and frs_sec_base untouched if none available!)
*/
-int IMB_anim_get_fps(struct anim *anim,
- short *frs_sec, float *frs_sec_base);
+bool IMB_anim_get_fps(struct anim *anim,
+ short *frs_sec, float *frs_sec_base);
/**
*
@@ -354,7 +354,8 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags);
*
* \attention Defined in util.c
*/
-int IMB_ispic(const char *name);
+bool IMB_ispic(const char *name);
+int IMB_ispic_type(const char *name);
/**
*
@@ -379,23 +380,28 @@ void IMB_interlace(struct ImBuf *ibuf);
void IMB_rect_from_float(struct ImBuf *ibuf);
/* Create char buffer for part of the image, color corrected if necessary,
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
-void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data);
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data);
void IMB_float_from_rect(struct ImBuf *ibuf);
void IMB_color_to_bw(struct ImBuf *ibuf);
void IMB_saturation(struct ImBuf *ibuf, float sat);
/* converting pixel buffers */
void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from,
- int channels_from, float dither, int profile_to, int profile_from, int predivide,
+ int channels_from, float dither, int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from);
+void IMB_buffer_byte_from_float_mask(unsigned char *rect_to, const float *rect_from,
+ int channels_from, float dither, bool predivide,
+ int width, int height, int stride_to, int stride_from, char *mask);
void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from,
- int profile_to, int profile_from, int predivide,
+ int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from);
void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
- int channels_from, int profile_to, int profile_from, int predivide,
+ int channels_from, int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from);
+void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from,
+ int channels_from, int width, int height, int stride_to, int stride_from, char *mask);
void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect_from,
- int profile_to, int profile_from, int predivide,
+ int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from);
void IMB_buffer_float_clamp(float *buf, int width, int height);
void IMB_buffer_float_unpremultiply(float *buf, int width, int height);
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 02b738cc2cd..f4d6d869f1b 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -35,6 +35,9 @@
struct ImBuf;
+void imb_refcounter_lock_init(void);
+void imb_refcounter_lock_exit(void);
+
bool imb_addencodedbufferImBuf(struct ImBuf *ibuf);
bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index d7ca381bae6..612517775f4 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -46,10 +46,22 @@
#include "imbuf.h"
#include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
+static SpinLock refcounter_spin;
+
+void imb_refcounter_lock_init(void)
+{
+ BLI_spin_init(&refcounter_spin);
+}
+
+void imb_refcounter_lock_exit(void)
+{
+ BLI_spin_end(&refcounter_spin);
+}
+
void imb_freemipmapImBuf(ImBuf *ibuf)
{
int a;
@@ -154,10 +166,18 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
void IMB_freeImBuf(ImBuf *ibuf)
{
if (ibuf) {
+ bool needs_free = false;
+
+ BLI_spin_lock(&refcounter_spin);
if (ibuf->refcounter > 0) {
ibuf->refcounter--;
}
else {
+ needs_free = true;
+ }
+ BLI_spin_unlock(&refcounter_spin);
+
+ if (needs_free) {
imb_freerectImBuf(ibuf);
imb_freerectfloatImBuf(ibuf);
imb_freetilesImBuf(ibuf);
@@ -177,7 +197,9 @@ void IMB_freeImBuf(ImBuf *ibuf)
void IMB_refImBuf(ImBuf *ibuf)
{
+ BLI_spin_lock(&refcounter_spin);
ibuf->refcounter++;
+ BLI_spin_unlock(&refcounter_spin);
}
ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index a6c51b1d397..eef7964ef3f 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -67,14 +67,12 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
-#include "BLI_math_base.h"
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
-#include "BKE_depsgraph.h"
#include "imbuf.h"
@@ -147,7 +145,8 @@ static void free_anim_movie(struct anim *UNUSED(anim))
static int an_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
{
unsigned short len, nume, nums = 0;
- short i, found = FALSE;
+ short i;
+ bool found = false;
len = strlen(string);
nume = len;
@@ -161,7 +160,7 @@ static int an_stringdec(const char *string, char *head, char *tail, unsigned sho
else {
nume = i;
nums = i;
- found = TRUE;
+ found = true;
}
}
else {
@@ -178,7 +177,7 @@ static int an_stringdec(const char *string, char *head, char *tail, unsigned sho
tail[0] = '\0';
strcpy(head, string);
*numlen = 0;
- return TRUE;
+ return true;
}
@@ -567,7 +566,7 @@ static int startffmpeg(struct anim *anim)
anim->next_packet.stream_index = -1;
anim->pFrame = avcodec_alloc_frame();
- anim->pFrameComplete = FALSE;
+ anim->pFrameComplete = false;
anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
@@ -690,7 +689,7 @@ static void ffmpeg_postprocess(struct anim *anim)
anim->pCodecCtx->width,
anim->pCodecCtx->height) < 0)
{
- filter_y = TRUE;
+ filter_y = true;
}
else {
input = anim->pFrameDeinterlaced;
@@ -936,18 +935,18 @@ static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
const char **p;
if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
- return TRUE;
+ return true;
}
p = byte_seek_list;
while (*p) {
if (match_format(*p++, pFormatCtx)) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
@@ -1047,7 +1046,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
"TC INDEX seek pos = %lld\n", pos);
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "TC INDEX seek dts = %lld\n", dts);
+ "TC INDEX seek dts = %llu\n", dts);
if (ffmpeg_seek_by_byte(anim->pFormatCtx)) {
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
@@ -1425,15 +1424,15 @@ int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
return IMB_indexer_get_duration(idx);
}
-int IMB_anim_get_fps(struct anim *anim,
+bool IMB_anim_get_fps(struct anim *anim,
short *frs_sec, float *frs_sec_base)
{
if (anim->frs_sec) {
*frs_sec = anim->frs_sec;
*frs_sec_base = anim->frs_sec_base;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
void IMB_anim_set_preseek(struct anim *anim, int preseek)
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index b80a381ebbb..e8cb550fc05 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -37,9 +37,12 @@
#include <string.h>
#include "BLI_fileops.h"
-#include "BLI_math_base.h"
#include "BLI_utildefines.h"
+#if defined(_MSC_VER) && (_MSC_VER <= 1500)
+#include "BLI_math_base.h"
+#endif
+
#include "MEM_guardedalloc.h"
/*
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index ff7d37893c7..84f80faeacc 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -37,9 +37,12 @@
#include <string.h>
#include "BLI_fileops.h"
-#include "BLI_math_base.h"
#include "BLI_utildefines.h"
+#if defined(_MSC_VER) && (_MSC_VER <= 1500)
+#include "BLI_math_base.h"
+#endif
+
#include "MEM_guardedalloc.h"
/*
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index e8ffdc83240..590b21259c3 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -42,9 +42,7 @@
#include "DNA_image_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "DNA_windowmanager_types.h"
#include "IMB_filter.h"
#include "IMB_imbuf.h"
@@ -66,7 +64,6 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
-#include "BKE_utildefines.h"
#include "BKE_main.h"
#include "RNA_define.h"
@@ -1164,22 +1161,16 @@ const char *IMB_colormanagement_role_colorspace_name_get(int role)
switch (role) {
case COLOR_ROLE_SCENE_LINEAR:
return global_role_scene_linear;
- break;
case COLOR_ROLE_COLOR_PICKING:
return global_role_color_picking;
- break;
case COLOR_ROLE_TEXTURE_PAINTING:
return global_role_texture_painting;
- break;
case COLOR_ROLE_DEFAULT_SEQUENCER:
return global_role_default_sequencer;
- break;
case COLOR_ROLE_DEFAULT_FLOAT:
return global_role_default_float;
- break;
case COLOR_ROLE_DEFAULT_BYTE:
return global_role_default_byte;
- break;
default:
printf("Unknown role was passed to %s\n", __func__);
BLI_assert(0);
@@ -1243,7 +1234,7 @@ const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
typedef struct DisplayBufferThread {
ColormanageProcessor *cm_processor;
- float *buffer;
+ const float *buffer;
unsigned char *byte_buffer;
float *display_buffer;
@@ -1264,7 +1255,7 @@ typedef struct DisplayBufferThread {
typedef struct DisplayBufferInitData {
ImBuf *ibuf;
ColormanageProcessor *cm_processor;
- float *buffer;
+ const float *buffer;
unsigned char *byte_buffer;
float *display_buffer;
@@ -1410,12 +1401,12 @@ static void *do_display_buffer_apply_thread(void *handle_v)
if (cm_processor == NULL) {
if (display_buffer_byte) {
IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, width, height, width, width);
+ false, width, height, width, width);
}
if (display_buffer) {
IMB_buffer_float_from_byte(display_buffer, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, width, height, width, width);
+ false, width, height, width, width);
}
}
else {
@@ -1982,7 +1973,7 @@ void IMB_colormanagement_buffer_make_display_space(float *buffer, unsigned char
IMB_buffer_byte_from_float(display_buffer, display_buffer_float,
channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- TRUE, width, height, width, width);
+ true, width, height, width, width);
MEM_freeN(display_buffer_float);
IMB_colormanagement_processor_free(cm_processor);
@@ -2101,7 +2092,7 @@ void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *li
IMB_colormanagement_processor_free(cm_processor);
IMB_buffer_byte_from_float(display_buffer, buffer, channels, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, width, height, width, width);
+ false, width, height, width, width);
MEM_freeN(buffer);
}
@@ -2710,7 +2701,7 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
if (display_buffer_float) {
/* huh, for dither we need float buffer first, no cheaper way. currently */
IMB_buffer_float_from_byte(display_buffer_float, byte_buffer,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB, true,
width, height, width, display_stride);
}
else {
@@ -2729,7 +2720,7 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
int display_index = (ymin * display_stride + xmin) * channels;
IMB_buffer_byte_from_float(display_buffer + display_index, display_buffer_float, channels, dither,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE, width, height, display_stride, width);
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB, true, width, height, display_stride, width);
MEM_freeN(display_buffer_float);
}
@@ -2785,21 +2776,27 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
ColormanageProcessor *cm_processor = NULL;
bool skip_transform = false;
- /* byte buffer is assumed to be in imbuf's rect space, so if byte buffer
+ /* Byte buffer is assumed to be in imbuf's rect space, so if byte buffer
* is known we could skip display->linear->display conversion in case
- * display color space matches imbuf's rect space
+ * display color space matches imbuf's rect space.
+ *
+ * But if there's a float buffer it's likely operation was performed on
+ * it first and byte buffer is likely to be out of date here.
*/
- if (byte_buffer != NULL)
+ if (linear_buffer == NULL && byte_buffer != NULL) {
skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
+ }
- if (!skip_transform)
+ if (!skip_transform) {
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ }
partial_buffer_update_rect(ibuf, display_buffer, linear_buffer, byte_buffer, buffer_width, stride,
offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
- if (cm_processor)
+ if (cm_processor) {
IMB_colormanagement_processor_free(cm_processor);
+ }
IMB_display_buffer_release(cache_handle);
}
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index f6606711cc3..028026527dc 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -1475,20 +1475,20 @@ void DirectDrawSurface::printInfo() const
if (header.pf.fourcc != 0) {
// Display fourcc code even when DDPF_FOURCC flag not set.
printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
- ((header.pf.fourcc >> 0) & 0xFF),
- ((header.pf.fourcc >> 8) & 0xFF),
- ((header.pf.fourcc >> 16) & 0xFF),
- ((header.pf.fourcc >> 24) & 0xFF),
+ (int)((header.pf.fourcc >> 0) & 0xFF),
+ (int)((header.pf.fourcc >> 8) & 0xFF),
+ (int)((header.pf.fourcc >> 16) & 0xFF),
+ (int)((header.pf.fourcc >> 24) & 0xFF),
header.pf.fourcc);
}
if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
{
printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
- (header.pf.bitcount >> 0) & 0xFF,
- (header.pf.bitcount >> 8) & 0xFF,
- (header.pf.bitcount >> 16) & 0xFF,
- (header.pf.bitcount >> 24) & 0xFF,
+ (int)(header.pf.bitcount >> 0) & 0xFF,
+ (int)(header.pf.bitcount >> 8) & 0xFF,
+ (int)(header.pf.bitcount >> 16) & 0xFF,
+ (int)(header.pf.bitcount >> 24) & 0xFF,
header.pf.bitcount);
}
else
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 6f6169b6a92..9975c58bdd2 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -43,7 +43,6 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
-#include "BLI_threads.h"
#include "MEM_guardedalloc.h"
@@ -175,7 +174,7 @@ MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext
/* float to byte pixels, output 4-channel RGBA */
void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
- int channels_from, float dither, int profile_to, int profile_from, int predivide,
+ int channels_from, float dither, int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from)
{
float tmp[4];
@@ -327,9 +326,87 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
clear_dither_context(di);
}
+
+/* float to byte pixels, output 4-channel RGBA */
+void IMB_buffer_byte_from_float_mask(uchar *rect_to, const float *rect_from,
+ int channels_from, float dither, bool predivide,
+ int width, int height, int stride_to, int stride_from, char *mask)
+{
+ int x, y;
+ DitherContext *di = NULL;
+ float inv_width = 1.0f / width,
+ inv_height = 1.0f / height;
+
+ if (dither)
+ di = create_dither_context(dither);
+
+ for (y = 0; y < height; y++) {
+ float t = y * inv_height;
+
+ if (channels_from == 1) {
+ /* single channel input */
+ const float *from = rect_from + stride_from * y;
+ uchar *to = rect_to + stride_to * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]);
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ const float *from = rect_from + stride_from * y * 3;
+ uchar *to = rect_to + stride_to * y * 4;
+
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ rgb_float_to_uchar(to, from);
+ to[3] = 255;
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ const float *from = rect_from + stride_from * y * 4;
+ uchar *to = rect_to + stride_to * y * 4;
+
+ float straight[4];
+
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ premul_to_straight_v4_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di, (float) x * inv_width, t);
+ }
+ }
+ }
+ else if (dither) {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ float_to_byte_dither_v4(to, from, di, (float) x * inv_width, t);
+ }
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ premul_to_straight_v4_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ rgba_float_to_uchar(to, from);
+ }
+ }
+ }
+
+ if (dither)
+ clear_dither_context(di);
+}
+
/* byte to float pixels, input and output 4-channel RGBA */
void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from,
- int profile_to, int profile_from, int predivide,
+ int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from)
{
float tmp[4];
@@ -382,7 +459,7 @@ void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from,
/* float to float pixels, output 4-channel RGBA */
void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
- int channels_from, int profile_to, int profile_from, int predivide,
+ int channels_from, int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from)
{
int x, y;
@@ -466,9 +543,53 @@ void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
}
}
+/* float to float pixels, output 4-channel RGBA */
+void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from, int channels_from,
+ int width, int height, int stride_to, int stride_from, char *mask)
+{
+ int x, y;
+
+ if (channels_from == 1) {
+ /* single channel input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y;
+ float *to = rect_to + stride_to * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ to[0] = to[1] = to[2] = to[3] = from[0];
+ }
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * 3;
+ float *to = rect_to + stride_to * y * 4;
+
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ copy_v3_v3(to, from);
+ to[3] = 1.0f;
+ }
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * 4;
+ float *to = rect_to + stride_to * y * 4;
+
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ copy_v4_v4(to, from);
+ }
+ }
+}
+
/* byte to byte pixels, input and output 4-channel RGBA */
void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
- int profile_to, int profile_from, int predivide,
+ int profile_to, int profile_from, bool predivide,
int width, int height, int stride_to, int stride_from)
{
float tmp[4];
@@ -556,7 +677,7 @@ void IMB_rect_from_float(ImBuf *ibuf)
/* convert float to byte */
IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
MEM_freeN(buffer);
@@ -565,9 +686,9 @@ void IMB_rect_from_float(ImBuf *ibuf)
}
/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
-void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data)
+void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data)
{
- float *rect_float;
+ const float *rect_float;
uchar *rect_byte;
int profile_from = IB_PROFILE_LINEAR_RGB;
@@ -591,12 +712,12 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
/* and do color space conversion to byte */
IMB_buffer_byte_from_float(rect_byte, rect_float,
- 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, TRUE,
+ 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, true,
w, h, ibuf->x, w);
}
else {
IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_SRGB, profile_from, TRUE,
+ ibuf->channels, IB_PROFILE_SRGB, profile_from, true,
w, h, w, ibuf->x);
/* XXX: need to convert to image buffer's rect space */
@@ -637,7 +758,7 @@ void IMB_float_from_rect(ImBuf *ibuf)
/* first, create float buffer in non-linear space */
IMB_buffer_float_from_byte(rect_float, (unsigned char *) ibuf->rect, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
/* then make float be in linear space */
IMB_colormanagement_colorspace_to_scene_linear(rect_float, ibuf->x, ibuf->y, ibuf->channels,
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index d0d7fc2448b..352e230068b 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -263,7 +263,7 @@ void IMB_filter(struct ImBuf *ibuf)
void IMB_mask_filter_extend(char *mask, int width, int height)
{
- char *row1, *row2, *row3;
+ const char *row1, *row2, *row3;
int rowlen, x, y;
char *temprect;
@@ -333,7 +333,7 @@ static int filter_make_index(const int x, const int y, const int w, const int h)
else return y * w + x;
}
-static int check_pixel_assigned(const void *buffer, const char *mask, const int index, const int depth, const int is_float)
+static int check_pixel_assigned(const void *buffer, const char *mask, const int index, const int depth, const bool is_float)
{
int res = 0;
@@ -364,7 +364,7 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
const int depth = 4; /* always 4 channels */
const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
const int bsize = width * height * depth * chsize;
- const int is_float = ibuf->rect_float != NULL;
+ const bool is_float = (ibuf->rect_float != NULL);
void *dstbuf = (void *) MEM_dupallocN(ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect);
char *dstmask = mask == NULL ? NULL : (char *) MEM_dupallocN(mask);
void *srcbuf = ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect;
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index e0a6e034f94..cf875bb247b 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -42,7 +42,6 @@
#include "BLI_utildefines.h"
#include "BLI_task.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "IMB_imbuf_types.h"
@@ -221,7 +220,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
/* NEAREST INTERPOLATION */
void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- float *dataF;
+ const float *dataF;
unsigned char *dataI;
int y1, x1;
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index 999aae81cb7..897a149a45c 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -69,9 +69,6 @@
typedef unsigned char uchar;
-#define TRUE 1
-#define FALSE 0
-
#define IMB_DPI_DEFAULT 72.0f
#endif /* __IMBUF_H__ */
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 3eaf42b1b22..547a8df4438 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -35,14 +35,12 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
-#include "BLI_math_base.h"
#include "IMB_indexer.h"
#include "IMB_anim.h"
#include "imbuf.h"
#include "MEM_guardedalloc.h"
-#include "DNA_userdef_types.h"
#include "BKE_global.h"
#ifdef WITH_AVI
@@ -336,7 +334,6 @@ int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
default:
return 0;
}
- return 0;
}
int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
@@ -356,7 +353,6 @@ int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
default:
return 0;
}
- return 0;
}
@@ -378,7 +374,7 @@ static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_l
}
static void get_proxy_filename(struct anim *anim, IMB_Proxy_Size preview_size,
- char *fname, int temp)
+ char *fname, bool temp)
{
char index_dir[FILE_MAXDIR];
int i = IMB_proxy_size_to_array_index(preview_size);
@@ -486,7 +482,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
rv->proxy_size = proxy_size;
rv->anim = anim;
- get_proxy_filename(rv->anim, rv->proxy_size, fname, TRUE);
+ get_proxy_filename(rv->anim, rv->proxy_size, fname, true);
BLI_make_existing_file(fname);
rv->of = avformat_alloc_context();
@@ -679,14 +675,14 @@ static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx,
}
get_proxy_filename(ctx->anim, ctx->proxy_size,
- fname_tmp, TRUE);
+ fname_tmp, true);
if (rollback) {
unlink(fname_tmp);
}
else {
get_proxy_filename(ctx->anim, ctx->proxy_size,
- fname, FALSE);
+ fname, false);
unlink(fname);
BLI_rename(fname_tmp, fname);
}
@@ -858,7 +854,7 @@ static void index_rebuild_ffmpeg_proc_decoded_frame(
if (!context->start_pts_set) {
context->start_pts = pts;
- context->start_pts_set = TRUE;
+ context->start_pts_set = true;
}
context->frameno = floor((pts - context->start_pts) *
@@ -919,7 +915,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
if (*progress != next_progress) {
*progress = next_progress;
- *do_update = TRUE;
+ *do_update = true;
}
if (*stop) {
@@ -1058,7 +1054,7 @@ static IndexBuildContext *index_fallback_create_context(struct anim *anim, IMB_T
if (context->proxy_sizes_in_use & proxy_sizes[i]) {
char fname[FILE_MAX];
- get_proxy_filename(anim, proxy_sizes[i], fname, TRUE);
+ get_proxy_filename(anim, proxy_sizes[i], fname, true);
BLI_make_existing_file(fname);
context->proxy_ctx[i] = alloc_proxy_output_avi(anim, fname,
@@ -1081,8 +1077,8 @@ static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context,
AVI_close_compress(context->proxy_ctx[i]);
MEM_freeN(context->proxy_ctx[i]);
- get_proxy_filename(anim, proxy_sizes[i], fname_tmp, TRUE);
- get_proxy_filename(anim, proxy_sizes[i], fname, FALSE);
+ get_proxy_filename(anim, proxy_sizes[i], fname_tmp, true);
+ get_proxy_filename(anim, proxy_sizes[i], fname, false);
if (stop) {
unlink(fname_tmp);
@@ -1109,7 +1105,7 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
if (*progress != next_progress) {
*progress = next_progress;
- *do_update = TRUE;
+ *do_update = true;
}
if (*stop) {
@@ -1263,10 +1259,10 @@ struct anim *IMB_anim_open_proxy(
return NULL;
}
- get_proxy_filename(anim, preview_size, fname, FALSE);
+ get_proxy_filename(anim, preview_size, fname, false);
- /* proxies are generated in default color space */
- anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, NULL);
+ /* proxies are generated in the same color space as animation itself */
+ anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, anim->colorspace);
anim->proxies_tried |= preview_size;
diff --git a/source/blender/imbuf/intern/indexer_dv.c b/source/blender/imbuf/intern/indexer_dv.c
index 4e8c13d2e99..f456fc420b2 100644
--- a/source/blender/imbuf/intern/indexer_dv.c
+++ b/source/blender/imbuf/intern/indexer_dv.c
@@ -351,8 +351,8 @@ static void indexer_dv_proc_frame(anim_index_builder *idx,
isPAL = (buffer[3] & 0x80);
- This->got_record_date = FALSE;
- This->got_record_time = FALSE;
+ This->got_record_date = false;
+ This->got_record_time = false;
parse_frame(This, buffer, isPAL);
proc_frame(This, buffer, isPAL);
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index ac1bb246dce..8f98f240053 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -72,7 +72,7 @@ typedef struct {
unsigned int offset;
unsigned int rleend; /* for rle images */
unsigned int *rowstart; /* for rle images */
- int *rowsize; /* for rle images */
+ const int *rowsize; /* for rle images */
} IMAGE;
#define RINTLUM (79)
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index f4ac4322747..18c096450af 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -122,8 +122,8 @@ static void info_callback(const char *msg, void *client_data)
struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
struct ImBuf *ibuf = NULL;
- int use_float = FALSE; /* for precision higher then 8 use float */
- int use_alpha = FALSE;
+ bool use_float = false; /* for precision higher then 8 use float */
+ bool use_alpha = false;
long signed_offsets[4] = {0, 0, 0, 0};
int float_divs[4] = {1, 1, 1, 1};
@@ -201,11 +201,11 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char co
case 1: /* Grayscale */
case 3: /* Color */
planes = 24;
- use_alpha = FALSE;
+ use_alpha = false;
break;
default: /* 2 or 4 - Grayscale or Color + alpha */
planes = 32; /* grayscale + alpha */
- use_alpha = TRUE;
+ use_alpha = true;
break;
}
@@ -217,7 +217,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char co
i--;
if (image->comps[i].prec > 8)
- use_float = TRUE;
+ use_float = true;
if (image->comps[i].sgnd)
signed_offsets[i] = 1 << (image->comps[i].prec - 1);
@@ -432,7 +432,7 @@ static int initialise_4K_poc(opj_poc_t *POC, int numres)
static void cinema_parameters(opj_cparameters_t *parameters)
{
- parameters->tile_size_on = 0; /* FALSE */
+ parameters->tile_size_on = 0; /* false */
parameters->cp_tdx = 1;
parameters->cp_tdy = 1;
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index a31ed5e7420..f4b5f987869 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
@@ -157,7 +156,7 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo)
src->terminal[0] = (JOCTET) 0xFF;
src->terminal[1] = (JOCTET) JPEG_EOI;
- return TRUE;
+ return true;
}
@@ -234,7 +233,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t
/* Read a byte into variable V.
- * If must suspend, take the specified action (typically "return FALSE").
+ * If must suspend, take the specified action (typically "return false").
*/
#define INPUT_BYTE(cinfo, V, action) \
MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
@@ -262,18 +261,18 @@ handle_app1(j_decompress_ptr cinfo)
INPUT_VARS(cinfo);
- INPUT_2BYTES(cinfo, length, return FALSE);
+ INPUT_2BYTES(cinfo, length, return false);
length -= 2;
if (length < 16) {
- for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return FALSE);
+ for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return false);
length = 0;
if (strncmp(neogeo, "NeoGeo", 6) == 0) memcpy(&ibuf_ftype, neogeo + 6, 4);
ibuf_ftype = BIG_LONG(ibuf_ftype);
}
INPUT_SYNC(cinfo); /* do before skip_input_data */
if (length > 0) (*cinfo->src->skip_input_data)(cinfo, length);
- return TRUE;
+ return true;
}
@@ -294,7 +293,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
cinfo->dct_method = JDCT_FLOAT;
jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
- if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) {
+ if (jpeg_read_header(cinfo, false) == JPEG_HEADER_OK) {
x = cinfo->image_width;
y = cinfo->image_height;
depth = cinfo->num_components;
@@ -482,7 +481,7 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
ImMetaData *iptr;
char *text;
- jpeg_start_compress(cinfo, TRUE);
+ jpeg_start_compress(cinfo, true);
strcpy(neogeo, "NeoGeo");
ibuf_ftype = BIG_LONG(ibuf->ftype);
@@ -600,7 +599,7 @@ static int init_jpeg(FILE *outfile, struct jpeg_compress_struct *cinfo, struct I
/* own settings */
cinfo->dct_method = JDCT_FLOAT;
- jpeg_set_quality(cinfo, quality, TRUE);
+ jpeg_set_quality(cinfo, quality, true);
return(0);
}
diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c
index 9141dad6f9c..4097deb00ed 100644
--- a/source/blender/imbuf/intern/module.c
+++ b/source/blender/imbuf/intern/module.c
@@ -26,12 +26,17 @@
#include <stddef.h>
+
+#include "BLI_utildefines.h"
+
+#include "IMB_allocimbuf.h"
#include "IMB_imbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement_intern.h"
void IMB_init(void)
{
+ imb_refcounter_lock_init();
imb_filetypes_init();
imb_tile_cache_init();
colormanagement_init();
@@ -42,5 +47,6 @@ void IMB_exit(void)
imb_tile_cache_exit();
imb_filetypes_exit();
colormanagement_exit();
+ imb_refcounter_lock_exit();
}
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 07ce3c39d73..ea75673e5f0 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -200,6 +200,18 @@ static size_t IMB_get_size_in_memory(ImBuf *ibuf)
int a;
size_t size = 0, channel_size = 0;
+ /* Persistent images should have no affect on how "normal"
+ * images are cached.
+ *
+ * This is a bit arbitrary, but would make it so only movies
+ * and sequences are memory limited, keeping textures in the
+ * memory in order to avoid constant file reload on viewport
+ * update.
+ */
+ if (ibuf->userflags & IB_PERSISTENT) {
+ return 0;
+ }
+
size += sizeof(ImBuf);
if (ibuf->rect)
@@ -294,9 +306,9 @@ MovieCache *IMB_moviecache_create(const char *name, int keysize, GHashHashFP has
BLI_strncpy(cache->name, name, sizeof(cache->name));
- cache->keys_pool = BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
- cache->items_pool = BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
- cache->userkeys_pool = BLI_mempool_create(keysize, 64, 64, 0);
+ cache->keys_pool = BLI_mempool_create(sizeof(MovieCacheKey), 0, 64, BLI_MEMPOOL_NOP);
+ cache->items_pool = BLI_mempool_create(sizeof(MovieCacheItem), 0, 64, BLI_MEMPOOL_NOP);
+ cache->userkeys_pool = BLI_mempool_create(keysize, 0, 64, BLI_MEMPOOL_NOP);
cache->hash = BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
cache->keysize = keysize;
@@ -323,7 +335,7 @@ void IMB_moviecache_set_priority_callback(struct MovieCache *cache, MovieCacheGe
cache->prioritydeleterfp = prioritydeleterfp;
}
-static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, int need_lock)
+static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, bool need_lock)
{
MovieCacheKey *key;
MovieCacheItem *item;
@@ -381,7 +393,7 @@ static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, int
void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
{
- do_moviecache_put(cache, userkey, ibuf, TRUE);
+ do_moviecache_put(cache, userkey, ibuf, true);
}
bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibuf)
@@ -396,8 +408,8 @@ bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibu
mem_in_use = MEM_CacheLimiter_get_memory_in_use(limitor);
if (mem_in_use + elem_size <= mem_limit) {
- do_moviecache_put(cache, userkey, ibuf, FALSE);
- result = TRUE;
+ do_moviecache_put(cache, userkey, ibuf, false);
+ result = true;
}
BLI_mutex_unlock(&limitor_lock);
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index ec9c8fdbb4d..6e3f97a4902 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -100,9 +100,9 @@ static ImBuf *imb_oiio_load_image(ImageInput *in, int width, int height, int com
{
if (!in->read_image(TypeDesc::UINT8,
(uchar *)ibuf->rect + (height - 1) * scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride))
+ AutoStride,
+ -scanlinesize,
+ AutoStride))
{
std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
<< in->geterror() << std::endl;
@@ -139,9 +139,9 @@ static ImBuf *imb_oiio_load_image_float(ImageInput *in, int width, int height, i
{
if (!in->read_image(TypeDesc::FLOAT,
(uchar *)ibuf->rect_float + (height - 1) * scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride))
+ AutoStride,
+ -scanlinesize,
+ AutoStride))
{
std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
<< in->geterror() << std::endl;
@@ -185,7 +185,8 @@ int imb_is_a_photoshop(const char *filename)
int imb_save_photoshop(struct ImBuf *ibuf, const char *name, int flags)
{
if (flags & IB_mem) {
- printf("Photoshop PSD-save: Create PSD in memory CURRENTLY NOT SUPPORTED !\n");
+ std::cerr << __func__ << ": Photoshop PSD-save: Create PSD in memory"
+ << " currently not supported" << std::endl;
imb_addencodedbufferImBuf(ibuf);
ibuf->encodedsize = 0;
return(0);
@@ -202,6 +203,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
bool is_float, is_alpha;
TypeDesc typedesc;
int basesize;
+ char file_colorspace[IM_MAX_SPACE];
/* load image from file through OIIO */
if (imb_is_a_photoshop(filename) == 0) return (NULL);
@@ -226,7 +228,15 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
}
string ics = spec.get_string_attribute("oiio:ColorSpace");
- BLI_strncpy(colorspace, ics.c_str(), IM_MAX_SPACE);
+ BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);
+
+ /* only use colorspaces exis */
+ if (colormanage_colorspace_get_named(file_colorspace))
+ strcpy(colorspace, file_colorspace);
+ else
+ std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
+ << "\") not supported in existent OCIO configuration file. Fallback "
+ << "to system default colorspace (\"" << colorspace << "\")." << std::endl;
width = spec.width;
height = spec.height;
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index d45438e2853..db268546480 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -43,7 +43,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "imbuf.h"
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 6988687e4ed..f0bcfcea62d 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -37,9 +37,6 @@
# include <stddef.h>
# include <sys/types.h>
# include "mmap_win.h"
-# define open _open
-# define read _read
-# define close _close
#endif
#include <stdlib.h>
@@ -215,7 +212,8 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_S
imb_cache_filename(filepath_tx, filepath, flags);
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
- if (file < 0) return NULL;
+ if (file == -1)
+ return NULL;
ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
@@ -242,7 +240,8 @@ ImBuf *IMB_testiffname(const char *filepath, int flags)
imb_cache_filename(filepath_tx, filepath, flags);
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
- if (file < 0) return NULL;
+ if (file == -1)
+ return NULL;
ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
@@ -285,7 +284,8 @@ void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
int file;
file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
- if (file < 0) return;
+ if (file == -1)
+ return;
imb_loadtilefile(ibuf, file, tx, ty, rect);
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 3c24864c671..c98b39c826b 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -618,7 +618,7 @@ static void enlarge_picture_float(
y_src = 0;
for (y_dst = 0; y_dst < dst_height; y_dst++) {
float *line1 = src + ((int) y_src) * 4 * src_width;
- float *line2 = line1 + 4 * src_width;
+ const float *line2 = line1 + 4 * src_width;
const float weight1y = (float)(1.0 - (y_src - (int) y_src));
const float weight2y = 1.0f - weight1y;
@@ -674,7 +674,7 @@ struct scale_outpix_float {
};
static void shrink_picture_float(
- float *src, float *dst, int src_width,
+ const float *src, float *dst, int src_width,
int src_height, int dst_width, int dst_height)
{
double ratiox = (double) (dst_width) / (double) (src_width);
@@ -684,7 +684,7 @@ static void shrink_picture_float(
float dx_dst, x_dst;
float dy_dst, y_dst;
float y_counter;
- float *dst_begin = dst;
+ const float *dst_begin = dst;
struct scale_outpix_float *dst_line1;
struct scale_outpix_float *dst_line2;
@@ -702,7 +702,7 @@ static void shrink_picture_float(
y_dst = 0;
y_counter = 1.0;
for (y_src = 0; y_src < src_height; y_src++) {
- float *line = src + y_src * 4 * src_width;
+ const float *line = src + y_src * 4 * src_width;
uintptr_t weight1y = 1.0f - (y_dst - (int) y_dst);
uintptr_t weight2y = 1.0f - weight1y;
x_dst = 0;
@@ -821,13 +821,13 @@ static void q_scale_float(float *in, float *out, int in_width,
*
* NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug #18609 (ton)
*/
-static int q_scale_linear_interpolation(
+static bool q_scale_linear_interpolation(
struct ImBuf *ibuf, int newx, int newy)
{
if ((newx >= ibuf->x && newy <= ibuf->y) ||
(newx <= ibuf->x && newy >= ibuf->y))
{
- return FALSE;
+ return false;
}
if (ibuf->rect) {
@@ -853,7 +853,7 @@ static int q_scale_linear_interpolation(
ibuf->x = newx;
ibuf->y = newy;
- return TRUE;
+ return true;
}
static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
@@ -1141,12 +1141,12 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
if (ibuf->rect) {
- do_rect = TRUE;
+ do_rect = true;
_newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx");
if (_newrect == NULL) return(ibuf);
}
if (ibuf->rect_float) {
- do_float = TRUE;
+ do_float = true;
_newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf");
if (_newrectf == NULL) {
if (_newrect) MEM_freeN(_newrect);
@@ -1298,7 +1298,8 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
float val_bf, nval_bf, diff_bf;
float val_gf, nval_gf, diff_gf;
float val_rf, nval_rf, diff_rf;
- int x, y, do_rect = FALSE, do_float = FALSE, skipx;
+ int x, y, skipx;
+ bool do_rect = false, do_float = false;
val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
@@ -1308,12 +1309,12 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
if (ibuf->rect) {
- do_rect = TRUE;
+ do_rect = true;
_newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy");
if (_newrect == NULL) return(ibuf);
}
if (ibuf->rect_float) {
- do_float = TRUE;
+ do_float = true;
_newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf");
if (_newrectf == NULL) {
if (_newrect) MEM_freeN(_newrect);
@@ -1527,16 +1528,17 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
{
unsigned int *rect, *_newrect, *newrect;
struct imbufRGBA *rectf, *_newrectf, *newrectf;
- int x, y, do_float = FALSE, do_rect = FALSE;
+ int x, y;
+ bool do_float = false, do_rect = false;
int ofsx, ofsy, stepx, stepy;
rect = NULL; _newrect = NULL; newrect = NULL;
rectf = NULL; _newrectf = NULL; newrectf = NULL;
if (ibuf == NULL) return(NULL);
- if (ibuf->rect) do_rect = TRUE;
- if (ibuf->rect_float) do_float = TRUE;
- if (do_rect == FALSE && do_float == FALSE) return(ibuf);
+ if (ibuf->rect) do_rect = true;
+ if (ibuf->rect_float) do_float = true;
+ if (do_rect == false && do_float == false) return(ibuf);
if (newx == ibuf->x && newy == ibuf->y) return(ibuf);
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index 7e6116b242c..2dcb27a05d4 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -117,7 +117,7 @@ static int tga_out4(unsigned int data, FILE *file)
return ~EOF;
}
-static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE *))
+static bool makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE *))
{
register int last, this;
register int copy, bytes;
@@ -163,7 +163,7 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
rect = temp;
last = this;
- copy = FALSE;
+ copy = 0;
}
else {
while (*rect++ == this) { /* seek for first different byte */
@@ -189,14 +189,14 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
}
if (out(last, file) == EOF) return 0;
}
- copy = TRUE;
+ copy = 1;
}
}
}
return 1;
}
-static int dumptarga(struct ImBuf *ibuf, FILE *file)
+static bool dumptarga(struct ImBuf *ibuf, FILE *file)
{
int size;
uchar *rect;
@@ -253,7 +253,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
{
char buf[20] = {0};
FILE *fildes;
- short ok = 0;
+ bool ok = false;
(void)flags; /* unused */
@@ -618,6 +618,9 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
}
if (flags & IB_test) {
+ if (cmap) {
+ MEM_freeN(cmap);
+ }
return ibuf;
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 499934017f7..fe5080f69d0 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -29,16 +29,15 @@
* \ingroup imbuf
*/
-
#include <stdio.h>
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_md5.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -59,17 +58,27 @@
# endif
# include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff
* because 'near' is disabled through BLI_windstuff */
-# include <process.h> /* getpid */
# include <direct.h> /* chdir */
# include "BLI_winstuff.h"
# include "utfconv.h"
+#endif
+
+#if defined(WIN32) || defined(__APPLE__)
+ /* pass */
+#else
+# define USE_FREEDESKTOP
+#endif
+
+/* '$HOME/.cache/thumbnails' or '$HOME/.thumbnails' */
+#ifdef USE_FREEDESKTOP
+# define THUMBNAILS "thumbnails"
#else
-# include <unistd.h>
+# define THUMBNAILS ".thumbnails"
#endif
#define URI_MAX (FILE_MAX * 3 + 8)
-static int get_thumb_dir(char *dir, ThumbSize size)
+static bool get_thumb_dir(char *dir, ThumbSize size)
{
char *s = dir;
const char *subdir;
@@ -80,19 +89,30 @@ static int get_thumb_dir(char *dir, ThumbSize size)
conv_utf_16_to_8(dir_16, dir, FILE_MAX);
s += strlen(dir);
#else
+#if defined(USE_FREEDESKTOP)
+ const char *home_cache = getenv("XDG_CACHE_HOME");
+ const char *home = home_cache ? home_cache : getenv("HOME");
+#else
const char *home = getenv("HOME");
+#endif
if (!home) return 0;
s += BLI_strncpy_rlen(s, home, FILE_MAX);
+
+#ifdef USE_FREEDESKTOP
+ if (!home_cache) {
+ s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir));
+ }
+#endif
#endif
switch (size) {
case THB_NORMAL:
- subdir = "/.thumbnails/normal/";
+ subdir = "/" THUMBNAILS "/normal/";
break;
case THB_LARGE:
- subdir = "/.thumbnails/large/";
+ subdir = "/" THUMBNAILS "/large/";
break;
case THB_FAIL:
- subdir = "/.thumbnails/fail/blender/";
+ subdir = "/" THUMBNAILS "/fail/blender/";
break;
default:
return 0; /* unknown size */
@@ -104,6 +124,9 @@ static int get_thumb_dir(char *dir, ThumbSize size)
return 1;
}
+#undef THUMBNAILS
+
+
/** ----- begin of adapted code from glib ---
* The following code is adapted from function g_escape_uri_string from the gnome glib
* Source: http://svn.gnome.org/viewcvs/glib/trunk/glib/gconvert.c?view=markup
@@ -137,7 +160,7 @@ static const char hex[17] = "0123456789abcdef";
/* Note: This escape function works on file: URIs, but if you want to
* escape something else, please read RFC-2396 */
-static void escape_uri_string(const char *string, char *escaped_string, int len, UnsafeCharacterSet mask)
+static void escape_uri_string(const char *string, char *escaped_string, int escaped_string_size, UnsafeCharacterSet mask)
{
#define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a) - 32] & use_mask))
@@ -147,17 +170,27 @@ static void escape_uri_string(const char *string, char *escaped_string, int len,
UnsafeCharacterSet use_mask;
use_mask = mask;
- for (q = escaped_string, p = string; (*p != '\0') && len; p++) {
+ BLI_assert(escaped_string_size > 0);
+
+ /* space for \0 */
+ escaped_string_size -= 1;
+
+ for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) {
c = (unsigned char) *p;
- len--;
if (!ACCEPTABLE(c)) {
+ if (escaped_string_size < 3) {
+ break;
+ }
+
*q++ = '%'; /* means hex coming */
*q++ = hex[c >> 4];
*q++ = hex[c & 15];
+ escaped_string_size -= 3;
}
else {
*q++ = *p;
+ escaped_string_size -= 1;
}
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 05e9a4fa134..eb8f94cbc6e 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -859,7 +859,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
if (TIFFWriteEncodedStrip(image, 0,
(bitspersample == 16) ? (unsigned char *)pixels16 : pixels,
- ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
+ (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
{
fprintf(stderr,
"imb_savetiff: Could not write encoded TIFF.\n");
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 12dfcc3a791..fbb28849ce6 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -34,9 +34,6 @@
#ifdef _WIN32
# include <io.h>
-# define open _open
-# define read _read
-# define close _close
#endif
#include <stdlib.h>
@@ -119,6 +116,7 @@ const char *imb_ext_image_qt[] = {
NULL
};
+#if 0 /* UNUSED */
const char *imb_ext_movie_qt[] = {
".avi",
".flc",
@@ -129,6 +127,7 @@ const char *imb_ext_movie_qt[] = {
".mv",
NULL
};
+#endif
const char *imb_ext_movie[] = {
".avi",
@@ -177,10 +176,11 @@ const char *imb_ext_audio[] = {
".aif",
".aiff",
".m4a",
+ ".mka",
NULL
};
-int IMB_ispic(const char *name)
+int IMB_ispic_type(const char *name)
{
/* increased from 32 to 64 because of the bitmaps header size */
#define HEADER_SIZE 64
@@ -193,17 +193,17 @@ int IMB_ispic(const char *name)
if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
if (BLI_stat(name, &st) == -1)
- return FALSE;
+ return false;
if (((st.st_mode) & S_IFMT) != S_IFREG)
- return FALSE;
+ return false;
- if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0)
- return FALSE;
+ if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) == -1)
+ return false;
memset(buf, 0, sizeof(buf));
if (read(fp, buf, HEADER_SIZE) <= 0) {
close(fp);
- return FALSE;
+ return false;
}
close(fp);
@@ -225,11 +225,15 @@ int IMB_ispic(const char *name)
}
}
- return FALSE;
+ return 0;
#undef HEADER_SIZE
}
+bool IMB_ispic(const char *name)
+{
+ return (IMB_ispic_type(name) != 0);
+}
static int isavi(const char *name)
{
@@ -237,7 +241,7 @@ static int isavi(const char *name)
return AVI_is_avi(name);
#else
(void)name;
- return FALSE;
+ return false;
#endif
}
@@ -250,7 +254,7 @@ static int isqtime(const char *name)
#ifdef WITH_FFMPEG
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && _MSC_VER < 1800
#define va_copy(dst, src) ((dst) = (src))
#endif
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index 1519fc1990d..d4a9bf7dc09 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -64,13 +64,13 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
{
ImFileType *type;
- if (ibuf == NULL) return (FALSE);
+ if (ibuf == NULL) return (false);
ibuf->flags = flags;
for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->save && type->ftype(type, ibuf)) {
ImBuf *write_ibuf;
- short result = FALSE;
+ short result = false;
write_ibuf = prepare_write_imbuf(type, ibuf);
@@ -85,6 +85,6 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
fprintf(stderr, "Couldn't save picture.\n");
- return FALSE;
+ return false;
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 76aacb5bebc..dab825c856e 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -655,7 +655,11 @@ typedef enum eAnimEdit_AutoSnap {
/* snap to actual frames/seconds (nla-action time) */
SACTSNAP_FRAME = 2,
/* snap to nearest marker */
- SACTSNAP_MARKER = 3
+ SACTSNAP_MARKER = 3,
+ /* snap to actual seconds (nla-action time) */
+ SACTSNAP_SECOND = 4,
+ /* snap to 1.0 second increments */
+ SACTSNAP_TSTEP = 5
} eAnimEdit_AutoSnap;
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index f4e2ff43fc5..99f0c999a29 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -264,7 +264,7 @@ typedef struct bActuator {
* For ipo's and props: to find out which object the actuator
* belongs to */
struct Object *ob;
-
+
} bActuator;
/* objectactuator->flag */
@@ -322,6 +322,7 @@ typedef struct bActuator {
#define ACT_LINKED 8
#define ACT_VISIBLE 16
#define ACT_PIN 32
+#define ACT_DEACTIVATE 64
/* link codes */
#define LINK_SENSOR 0
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 8c04c41650d..390233a433d 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -791,7 +791,8 @@ typedef enum eInsertKeyFlags {
INSERTKEY_FAST = (1<<2), /* don't recalculate handles,etc. after adding key */
INSERTKEY_FASTR = (1<<3), /* don't realloc mem (or increase count, as array has already been set out) */
INSERTKEY_REPLACE = (1<<4), /* only replace an existing keyframe (this overrides INSERTKEY_NEEDED) */
- INSERTKEY_XYZ2RGB = (1<<5) /* transform F-Curves should have XYZ->RGB color mode */
+ INSERTKEY_XYZ2RGB = (1<<5), /* transform F-Curves should have XYZ->RGB color mode */
+ INSERTKEY_NO_USERPREF = (1 << 6), /* ignore user-prefs (needed for predictable API use) */
} eInsertKeyFlags;
/* ************************************************ */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 29e49a970d8..e35e4673684 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -338,9 +338,18 @@ typedef struct bTransformConstraint {
float from_min[3]; /* from_min/max defines range of target transform */
float from_max[3]; /* to map on to to_min/max range. */
-
float to_min[3]; /* range of motion on owner caused by target */
float to_max[3];
+
+ float from_min_rot[3]; /* from_min/max defines range of target transform */
+ float from_max_rot[3]; /* to map on to to_min/max range. */
+ float to_min_rot[3]; /* range of motion on owner caused by target */
+ float to_max_rot[3];
+
+ float from_min_scale[3]; /* from_min/max defines range of target transform */
+ float from_max_scale[3]; /* to map on to to_min/max range. */
+ float to_min_scale[3]; /* range of motion on owner caused by target */
+ float to_max_scale[3];
} bTransformConstraint;
/* Pivot Constraint */
@@ -557,6 +566,13 @@ typedef enum eCopyScale_Flags {
SIZELIKE_OFFSET = (1<<3)
} eCopyScale_Flags;
+/* bTransformConstraint.to/from */
+typedef enum eTransform_ToFrom {
+ TRANS_LOCATION = 0,
+ TRANS_ROTATION = 1,
+ TRANS_SCALE = 2,
+} eTransform_ToFrom;
+
/* bSameVolumeConstraint.flag */
typedef enum eSameVolume_Modes {
SAMEVOL_X = 0,
diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h
index 0c1aaf5fd20..154542d60c5 100644
--- a/source/blender/makesdna/DNA_controller_types.h
+++ b/source/blender/makesdna/DNA_controller_types.h
@@ -83,6 +83,7 @@ typedef struct bController {
#define CONT_NEW 4
#define CONT_MASK 8
#define CONT_PRIO 16
+#define CONT_DEACTIVATE 32
/* pyctrl->flag */
#define CONT_PY_DEBUG 1
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index f0c555792fc..0321c1cad12 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -108,10 +108,19 @@ typedef struct BevPoint {
typedef struct BezTriple {
float vec[3][3];
float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
- short ipo; /* ipo: interpolation mode for segment from this BezTriple to the next */
+
+ char ipo; /* ipo: interpolation mode for segment from this BezTriple to the next */
+
char h1, h2; /* h1, h2: the handle type of the two handles */
char f1, f2, f3; /* f1, f2, f3: used for selection status */
+
char hide; /* hide: used to indicate whether BezTriple is hidden (3D), type of keyframe (eBezTriple_KeyframeTypes) */
+
+ char easing; /* easing: easing type for interpolation mode (eBezTriple_Easing) */
+ float back; /* BEZT_IPO_BACK */
+ float amplitude, period; /* BEZT_IPO_ELASTIC */
+
+ char pad[4];
} BezTriple;
/* note; alfa location in struct is abused by Key system */
@@ -248,8 +257,10 @@ typedef struct Curve {
float ctime; /* current evaltime - for use by Objects parented to curves */
float bevfac1, bevfac2;
+ char bevfac1_mapping, bevfac2_mapping;
+
+ char pad2[2];
- char pad2[4];
} Curve;
/* **************** CURVE ********************* */
@@ -286,6 +297,13 @@ typedef struct Curve {
#define CU_TWIST_MINIMUM 3
#define CU_TWIST_TANGENT 4
+/* bevel factor mapping */
+enum {
+ CU_BEVFAC_MAP_RESOLU = 0,
+ CU_BEVFAC_MAP_SEGMENT = 1,
+ CU_BEVFAC_MAP_SPLINE = 2
+};
+
/* spacemode */
#define CU_LEFT 0
#define CU_MIDDLE 1
@@ -336,16 +354,39 @@ typedef enum eBezTriple_Handle {
HD_AUTO = 1,
HD_VECT = 2,
HD_ALIGN = 3,
- HD_AUTO_ANIM = 4 /* auto-clamped handles for animation */
+ HD_AUTO_ANIM = 4, /* auto-clamped handles for animation */
+ HD_ALIGN_DOUBLESIDE = 5, /* align handles, displayed both of them. used for masks */
} eBezTriple_Handle;
/* interpolation modes (used only for BezTriple->ipo) */
typedef enum eBezTriple_Interpolation {
+ /* traditional interpolation */
BEZT_IPO_CONST = 0, /* constant interpolation */
BEZT_IPO_LIN = 1, /* linear interpolation */
- BEZT_IPO_BEZ = 2 /* bezier interpolation */
+ BEZT_IPO_BEZ = 2, /* bezier interpolation */
+
+ /* easing equations */
+ BEZT_IPO_BACK = 3,
+ BEZT_IPO_BOUNCE = 4,
+ BEZT_IPO_CIRC = 5,
+ BEZT_IPO_CUBIC = 6,
+ BEZT_IPO_ELASTIC = 7,
+ BEZT_IPO_EXPO = 8,
+ BEZT_IPO_QUAD = 9,
+ BEZT_IPO_QUART = 10,
+ BEZT_IPO_QUINT = 11,
+ BEZT_IPO_SINE = 12
} eBezTriple_Interpolation;
+/* easing modes (used only for Keyframes - BezTriple->easing) */
+typedef enum eBezTriple_Easing {
+ BEZT_IPO_EASE_AUTO = 0,
+
+ BEZT_IPO_EASE_IN = 1,
+ BEZT_IPO_EASE_OUT = 2,
+ BEZT_IPO_EASE_IN_OUT = 3
+} eBezTriple_Easing;
+
/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
typedef enum eBezTriple_KeyframeType {
BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 325c2a8df54..70dc43676ac 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -63,13 +63,12 @@ typedef struct CustomDataExternal {
* layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
- int typemap[40]; /* runtime only! - maps types to indices of first layer of that type,
+ int typemap[41]; /* runtime only! - maps types to indices of first layer of that type,
* MUST be >= CD_NUMTYPES, but we cant use a define here.
* Correct size is ensured in CustomData_update_typemap assert() */
- int pad[1];
int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize; /* in editmode, total size of all data layers */
- void *pool; /* Bmesh: Memory pool for allocation of blocks */
+ struct BLI_mempool *pool; /* (BMesh Only): Memory pool for allocation of blocks */
CustomDataExternal *external; /* external file storing customdata layers */
} CustomData;
@@ -119,7 +118,9 @@ enum {
CD_FREESTYLE_EDGE = 37,
CD_FREESTYLE_FACE = 38,
CD_MLOOPTANGENT = 39,
- CD_NUMTYPES = 40,
+ CD_TESSLOOPNORMAL = 40,
+
+ CD_NUMTYPES = 41
};
/* Bits for CustomDataMask */
@@ -164,7 +165,8 @@ enum {
#define CD_MASK_MVERT_SKIN (1LL << CD_MVERT_SKIN)
#define CD_MASK_FREESTYLE_EDGE (1LL << CD_FREESTYLE_EDGE)
#define CD_MASK_FREESTYLE_FACE (1LL << CD_FREESTYLE_FACE)
-#define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT)
+#define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT)
+#define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL)
/* CustomData.flag */
enum {
@@ -184,6 +186,8 @@ enum {
#define MAX_MTFACE 8
#define MAX_MCOL 8
+#define DYNTOPO_NODE_NONE -1
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h
index 19c4e057a96..f7ba53c1f79 100644
--- a/source/blender/makesdna/DNA_linestyle_types.h
+++ b/source/blender/makesdna/DNA_linestyle_types.h
@@ -35,8 +35,16 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+#ifndef MAX_MTEX
+#define MAX_MTEX 18
+#endif
+
+/* texco (also in DNA_material_types.h) */
+#define TEXCO_STROKE 16 /* actually it's UV */
+
struct ColorBand;
struct CurveMapping;
+struct MTex;
typedef struct LineStyleModifier {
struct LineStyleModifier *next, *prev;
@@ -354,7 +362,8 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_PANEL_ALPHA 3
#define LS_PANEL_THICKNESS 4
#define LS_PANEL_GEOMETRY 5
-#define LS_PANEL_MISC 6
+#define LS_PANEL_TEXTURE 6
+#define LS_PANEL_MISC 7
/* FreestyleLineStyle::flag */
#define LS_DS_EXPAND (1 << 0) /* for animation editors */
@@ -368,6 +377,9 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_MAX_2D_ANGLE (1 << 8)
#define LS_SPLIT_LENGTH (1 << 9)
#define LS_SPLIT_PATTERN (1 << 10)
+#define LS_NO_SORTING (1 << 11)
+#define LS_REVERSE_ORDER (1 << 12) /* for sorting */
+#define LS_TEXTURE (1 << 13)
/* FreestyleLineStyle::chaining */
#define LS_CHAINING_PLAIN 1
@@ -384,6 +396,17 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_THICKNESS_OUTSIDE 3
#define LS_THICKNESS_RELATIVE 4 /* thickness_ratio is used */
+/* FreestyleLineStyle::sort_key */
+#define LS_SORT_KEY_DISTANCE_FROM_CAMERA 1
+#define LS_SORT_KEY_2D_LENGTH 2
+
+/* FreestyleLineStyle::integration_type */
+#define LS_INTEGRATION_MEAN 1
+#define LS_INTEGRATION_MIN 2
+#define LS_INTEGRATION_MAX 3
+#define LS_INTEGRATION_FIRST 4
+#define LS_INTEGRATION_LAST 5
+
typedef struct FreestyleLineStyle {
ID id;
struct AnimData *adt;
@@ -401,10 +424,17 @@ typedef struct FreestyleLineStyle {
unsigned short split_dash1, split_gap1;
unsigned short split_dash2, split_gap2;
unsigned short split_dash3, split_gap3;
- int pad;
+ int sort_key, integration_type;
+ float texstep;
+ short texact, pr_texture;
+ short use_nodes, pad;
unsigned short dash1, gap1, dash2, gap2, dash3, gap3;
int panel; /* for UI */
+ struct MTex *mtex[18]; /* MAX_MTEX */
+ /* nodes */
+ struct bNodeTree *nodetree;
+
ListBase color_modifiers;
ListBase alpha_modifiers;
ListBase thickness_modifiers;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index a6478f2ae69..6bcbabc226d 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -117,6 +117,7 @@ typedef struct Material {
short shade_flag; /* like Cubic interpolation */
int mode, mode_l; /* mode_l is the or-ed result of all layer modes */
+ int mode2, mode2_l; /* additional mode flags */
short flarec, starc, linec, ringc;
float hasize, flaresize, subsize, flareboost;
float strand_sta, strand_end, strand_ease, strand_surfnor;
@@ -278,6 +279,13 @@ typedef struct Material {
#define MA_STR_SURFDIFF 0x80000000
#define MA_MODE_MASK 0x6fffffff /* all valid mode bits */
+#define MA_MODE_PIPELINE (MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP \
+ | MA_TRACEBLE | MA_FULL_OSA | MA_ENV | MA_ZINV \
+ | MA_ONLYCAST | MA_SHADBUF)
+
+/* mode2 (is int) */
+#define MA_CASTSHADOW (1 << 0)
+#define MA_MODE2_PIPELINE (MA_CASTSHADOW)
/* mapflag */
#define MA_MAPFLAG_UVPROJECT (1 << 0)
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index b942197e52c..e535e6012b3 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -116,8 +116,9 @@ typedef struct Mesh {
float rot[3];
int drawflag;
- short texflag, pad2[3];
- short smoothresh, flag;
+ short texflag, flag;
+ float smoothresh;
+ int pad2;
/* customdata flag, for bevel-weight and crease, which are now optional */
char cd_flag, pad;
@@ -212,6 +213,9 @@ typedef struct TFace {
/* draw stats */
#define ME_DRAW_STATVIS (1 << 17)
+/* draw loop normals */
+#define ME_DRAW_LNORMALS (1 << 18)
+
/* Subsurf Type */
#define ME_CC_SUBSURF 0
#define ME_SIMPLE_SUBSURF 1
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index c370e677df0..3304980f964 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -303,7 +303,6 @@ enum {
/* mvert->flag */
enum {
/* SELECT = (1 << 0), */
- ME_SPHERETEST = (1 << 1),
ME_VERT_TMP_TAG = (1 << 2),
ME_HIDE = (1 << 4),
ME_VERT_MERGED = (1 << 6),
@@ -315,7 +314,6 @@ enum {
/* SELECT = (1 << 0), */
ME_EDGEDRAW = (1 << 1),
ME_SEAM = (1 << 2),
- ME_FGON = (1 << 3), /* no longer used (now we have ngons), only defined so we can clear it */
/* ME_HIDE = (1 << 4), */
ME_EDGERENDER = (1 << 5),
ME_LOOSEEDGE = (1 << 7),
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 6eebbd6b47d..7c5846e5819 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1221,7 +1221,7 @@ enum {
/* Triangulate methods - NGons */
enum {
MOD_TRIANGULATE_NGON_BEAUTY = 0,
- MOD_TRIANGULATE_NGON_SCANFILL,
+ MOD_TRIANGULATE_NGON_EARCLIP,
};
/* Triangulate methods - Quads */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 4f7c49a0ca3..e13d53934cb 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -112,7 +112,8 @@ typedef struct bNodeSocket {
short stack_index; /* local stack index */
/* XXX deprecated, kept for forward compatibility */
short stack_type DNA_DEPRECATED;
- int resizemode; /* compositor resize mode of the socket */
+ int pad;
+
void *cache; /* cached data from execution */
/* internal data to retrieve relations and groups
@@ -131,16 +132,17 @@ typedef struct bNodeSocket {
} bNodeSocket;
/* sock->type */
-#define SOCK_CUSTOM -1 /* socket has no integer type */
-#define SOCK_FLOAT 0
-#define SOCK_VECTOR 1
-#define SOCK_RGBA 2
-#define SOCK_SHADER 3
-#define SOCK_BOOLEAN 4
-#define __SOCK_MESH 5 /* deprecated */
-#define SOCK_INT 6
-#define SOCK_STRING 7
-#define NUM_SOCKET_TYPES 8 /* must be last! */
+typedef enum eNodeSocketDatatype {
+ SOCK_CUSTOM = -1, /* socket has no integer type */
+ SOCK_FLOAT = 0,
+ SOCK_VECTOR = 1,
+ SOCK_RGBA = 2,
+ SOCK_SHADER = 3,
+ SOCK_BOOLEAN = 4,
+ __SOCK_MESH = 5, /* deprecated */
+ SOCK_INT = 6,
+ SOCK_STRING = 7
+} eNodeSocketDatatype;
/* socket side (input/output) */
typedef enum eNodeSocketInOut {
@@ -157,7 +159,8 @@ typedef enum eNodeSocketFlag {
// SOCK_INTERNAL = 32, /* DEPRECATED group socket should not be exposed */
SOCK_COLLAPSED = 64, /* socket collapsed in UI */
SOCK_HIDE_VALUE = 128, /* hide socket value, if it gets auto default */
- SOCK_AUTO_HIDDEN__DEPRECATED = 256 /* socket hidden automatically, to distinguish from manually hidden */
+ SOCK_AUTO_HIDDEN__DEPRECATED = 256, /* socket hidden automatically, to distinguish from manually hidden */
+ SOCK_NO_INTERNAL_LINK = 512
} eNodeSocketFlag;
/* limit data in bNode to what we want to see saved? */
@@ -722,7 +725,7 @@ typedef struct NodeTexImage {
int color_space;
int projection;
float projection_blend;
- int pad;
+ int interpolation;
} NodeTexImage;
typedef struct NodeTexChecker {
@@ -845,6 +848,10 @@ typedef struct NodeShaderNormalMap {
char uv_map[64];
} NodeShaderNormalMap;
+typedef struct NodeShaderUVMap {
+ char uv_map[64];
+} NodeShaderUVMap;
+
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1
@@ -949,6 +956,12 @@ typedef struct NodeShaderNormalMap {
#define SHD_PROJ_FLAT 0
#define SHD_PROJ_BOX 1
+/* image texture interpolation */
+#define SHD_INTERP_LINEAR 0
+#define SHD_INTERP_CLOSEST 1
+#define SHD_INTERP_CUBIC 2
+#define SHD_INTERP_SMART 3
+
/* tangent */
#define SHD_TANGENT_RADIAL 0
#define SHD_TANGENT_UVMAP 1
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 1f18b054d0e..811c33befca 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -176,8 +176,6 @@ typedef struct Object {
float imat_ren[4][4];
unsigned int lay; /* copy of Base's layer in the scene */
-
- float sf; /* sf is time-offset */
short flag; /* copy of Base */
short colbits DNA_DEPRECATED; /* deprecated, use 'matbits' */
@@ -192,6 +190,8 @@ typedef struct Object {
int dupon, dupoff, dupsta, dupend;
+ int pad;
+
/* during realtime */
/* note that inertia is only called inertia for historical reasons
@@ -208,11 +208,10 @@ typedef struct Object {
*/
float formfactor;
- float rdamping, sizefac;
+ float rdamping;
float margin;
float max_vel; /* clamp the maximum velocity 0.0 is disabled */
float min_vel; /* clamp the minimum velocity 0.0 is disabled */
- float m_contactProcessingThreshold;
float obstacleRad;
/* "Character" physics properties */
@@ -239,7 +238,8 @@ typedef struct Object {
ListBase controllers; /* game logic controllers */
ListBase actuators; /* game logic actuators */
- float bbsize[3] DNA_DEPRECATED;
+ float sf; /* sf is time-offset */
+
short index; /* custom index, for renderpasses */
unsigned short actdef; /* current deformation group, note: index starts at 1 */
float col[4]; /* object color */
@@ -270,8 +270,10 @@ typedef struct Object {
struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */
+ /* Runtime valuated curve-specific data, not stored in the file */
+ struct CurveCache *curve_cache;
+
struct DerivedMesh *derivedDeform, *derivedFinal;
- int *pad;
uint64_t lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
uint64_t customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */
unsigned int state; /* bit masks of game controllers that are active */
@@ -289,9 +291,6 @@ typedef struct Object {
ListBase lodlevels; /* contains data for levels of detail */
LodLevel *currentlod;
-
- /* Runtime valuated curve-specific data, not stored in the file */
- struct CurveCache *curve_cache;
} Object;
/* Warning, this is not used anymore because hooks are now modifiers */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 170d1376908..a2a724b6a32 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -304,13 +304,11 @@ typedef struct ParticleSystem {
ParticleSpring *fluid_springs;
int tot_fluidsprings, alloc_fluidsprings;
- struct KDTree *tree; /* used for interactions with self and other systems */
- struct BVHTree *bvhtree; /* used for interactions with self and other systems */
+ struct KDTree *tree; /* used for interactions with self and other systems */
+ struct BVHTree *bvhtree; /* used for interactions with self and other systems */
struct ParticleDrawData *pdd;
- float *frand; /* array of 1024 random floats for fast lookups */
-
float dt_frac; /* current time step, as a fraction of a frame */
float _pad; /* spare capacity */
} ParticleSystem;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 8c4026e8b67..ceb938c3af2 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -60,6 +60,7 @@ struct Editing;
struct SceneStats;
struct bGPdata;
struct MovieClip;
+struct ColorSpace;
/* ************************************************************* */
/* Scene Data */
@@ -209,37 +210,39 @@ typedef struct SceneRenderLayer {
#define SCE_LAY_NEG_ZMASK 0x80000
/* srl->passflag */
-#define SCE_PASS_COMBINED (1<<0)
-#define SCE_PASS_Z (1<<1)
-#define SCE_PASS_RGBA (1<<2)
-#define SCE_PASS_DIFFUSE (1<<3)
-#define SCE_PASS_SPEC (1<<4)
-#define SCE_PASS_SHADOW (1<<5)
-#define SCE_PASS_AO (1<<6)
-#define SCE_PASS_REFLECT (1<<7)
-#define SCE_PASS_NORMAL (1<<8)
-#define SCE_PASS_VECTOR (1<<9)
-#define SCE_PASS_REFRACT (1<<10)
-#define SCE_PASS_INDEXOB (1<<11)
-#define SCE_PASS_UV (1<<12)
-#define SCE_PASS_INDIRECT (1<<13)
-#define SCE_PASS_MIST (1<<14)
-#define SCE_PASS_RAYHITS (1<<15)
-#define SCE_PASS_EMIT (1<<16)
-#define SCE_PASS_ENVIRONMENT (1<<17)
-#define SCE_PASS_INDEXMA (1<<18)
-#define SCE_PASS_DIFFUSE_DIRECT (1<<19)
-#define SCE_PASS_DIFFUSE_INDIRECT (1<<20)
-#define SCE_PASS_DIFFUSE_COLOR (1<<21)
-#define SCE_PASS_GLOSSY_DIRECT (1<<22)
-#define SCE_PASS_GLOSSY_INDIRECT (1<<23)
-#define SCE_PASS_GLOSSY_COLOR (1<<24)
-#define SCE_PASS_TRANSM_DIRECT (1<<25)
-#define SCE_PASS_TRANSM_INDIRECT (1<<26)
-#define SCE_PASS_TRANSM_COLOR (1<<27)
-#define SCE_PASS_SUBSURFACE_DIRECT (1<<28)
-#define SCE_PASS_SUBSURFACE_INDIRECT (1<<29)
-#define SCE_PASS_SUBSURFACE_COLOR (1<<30)
+typedef enum ScenePassType {
+ SCE_PASS_COMBINED = (1 << 0),
+ SCE_PASS_Z = (1 << 1),
+ SCE_PASS_RGBA = (1 << 2),
+ SCE_PASS_DIFFUSE = (1 << 3),
+ SCE_PASS_SPEC = (1 << 4),
+ SCE_PASS_SHADOW = (1 << 5),
+ SCE_PASS_AO = (1 << 6),
+ SCE_PASS_REFLECT = (1 << 7),
+ SCE_PASS_NORMAL = (1 << 8),
+ SCE_PASS_VECTOR = (1 << 9),
+ SCE_PASS_REFRACT = (1 << 10),
+ SCE_PASS_INDEXOB = (1 << 11),
+ SCE_PASS_UV = (1 << 12),
+ SCE_PASS_INDIRECT = (1 << 13),
+ SCE_PASS_MIST = (1 << 14),
+ SCE_PASS_RAYHITS = (1 << 15),
+ SCE_PASS_EMIT = (1 << 16),
+ SCE_PASS_ENVIRONMENT = (1 << 17),
+ SCE_PASS_INDEXMA = (1 << 18),
+ SCE_PASS_DIFFUSE_DIRECT = (1 << 19),
+ SCE_PASS_DIFFUSE_INDIRECT = (1 << 20),
+ SCE_PASS_DIFFUSE_COLOR = (1 << 21),
+ SCE_PASS_GLOSSY_DIRECT = (1 << 22),
+ SCE_PASS_GLOSSY_INDIRECT = (1 << 23),
+ SCE_PASS_GLOSSY_COLOR = (1 << 24),
+ SCE_PASS_TRANSM_DIRECT = (1 << 25),
+ SCE_PASS_TRANSM_INDIRECT = (1 << 26),
+ SCE_PASS_TRANSM_COLOR = (1 << 27),
+ SCE_PASS_SUBSURFACE_DIRECT = (1 << 28),
+ SCE_PASS_SUBSURFACE_INDIRECT = (1 << 29),
+ SCE_PASS_SUBSURFACE_COLOR = (1 << 30),
+} ScenePassType;
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -357,6 +360,42 @@ typedef struct ImageFormatData {
/* ImageFormatData.cineon_flag */
#define R_IMF_CINEON_FLAG_LOG (1<<0) /* was R_CINEON_LOG */
+typedef struct BakeData {
+ struct ImageFormatData im_format;
+
+ char filepath[1024]; /* FILE_MAX */
+
+ short width, height;
+ short margin, flag;
+
+ float cage_extrusion;
+ float pad2;
+
+ char normal_swizzle[3];
+ char normal_space;
+
+ char save_mode;
+ char pad[3];
+
+ char cage[64]; /* MAX_NAME */
+} BakeData;
+
+/* (char) normal_swizzle */
+typedef enum BakeNormalSwizzle {
+ R_BAKE_POSX = 0,
+ R_BAKE_POSY = 1,
+ R_BAKE_POSZ = 2,
+ R_BAKE_NEGX = 3,
+ R_BAKE_NEGY = 4,
+ R_BAKE_NEGZ = 5,
+} BakeNormalSwizzle;
+
+/* (char) save_mode */
+typedef enum BakeSaveMode {
+ R_BAKE_SAVE_INTERNAL = 0,
+ R_BAKE_SAVE_EXTERNAL = 1,
+} BakeSaveMode;
+
/* *************************************************************** */
/* Render Data */
@@ -562,6 +601,9 @@ typedef struct RenderData {
/* render engine */
char engine[32];
+
+ /* Cycles baking */
+ struct BakeData bake;
} RenderData;
/* *************************************************************** */
@@ -848,14 +890,16 @@ typedef struct Sculpt {
int radial_symm[3];
/* Maximum edge length for dynamic topology sculpting (in pixels) */
- int detail_size;
+ float detail_size;
/* Direction used for SCULPT_OT_symmetrize operator */
int symmetrize_direction;
/* gravity factor for sculpting */
float gravity_factor;
- int pad;
+
+ /* scale for constant detail size */
+ float constant_detail;
struct Object *gravity_object;
void *pad2;
@@ -930,7 +974,9 @@ typedef struct UnifiedPaintSettings {
float brush_rotation;
- // all this below is used to communicate with the cursor drawing routine
+ /*********************************************************************************
+ * all data below are used to communicate with cursor drawing and tex sampling *
+ *********************************************************************************/
int draw_anchored;
int anchored_size;
float anchored_initial_mouse[2];
@@ -939,7 +985,7 @@ typedef struct UnifiedPaintSettings {
int stroke_active;
/* drawing pressure */
- float pressure_value;
+ float size_pressure_value;
/* position of mouse, used to sample the texture */
float tex_mouse[2];
@@ -947,9 +993,14 @@ typedef struct UnifiedPaintSettings {
/* position of mouse, used to sample the mask texture */
float mask_tex_mouse[2];
+ /* ColorSpace cache to avoid locking up during sampling */
+ int do_linear_conversion;
+ struct ColorSpace *colorspace;
+
/* radius of brush, premultiplied with pressure.
* In case of anchored brushes contains that radius */
float pixel_radius;
+ int pad2;
} UnifiedPaintSettings;
typedef enum {
@@ -1163,7 +1214,8 @@ typedef struct Scene {
short flag; /* various settings */
- short use_nodes;
+ char use_nodes;
+ char pad[1];
struct bNodeTree *nodetree;
@@ -1224,13 +1276,14 @@ typedef struct Scene {
struct RigidBodyWorld *rigidbody_world;
} Scene;
-
/* **************** RENDERDATA ********************* */
/* flag */
/* use preview range */
#define SCER_PRV_RANGE (1<<0)
#define SCER_LOCK_FRAME_SELECTION (1<<1)
+ /* timeline/keyframe jumping - only selected items (on by default) */
+#define SCE_KEYS_NO_SELONLY (1<<2)
/* mode (int now) */
#define R_OSA 0x0001
@@ -1293,7 +1346,7 @@ typedef struct Scene {
/* raytrace structure */
#define R_RAYSTRUCTURE_AUTO 0
#define R_RAYSTRUCTURE_OCTREE 1
-#define R_RAYSTRUCTURE_BLIBVH 2
+#define R_RAYSTRUCTURE_BLIBVH 2 /* removed */
#define R_RAYSTRUCTURE_VBVH 3
#define R_RAYSTRUCTURE_SIMD_SVBVH 4 /* needs SIMD */
#define R_RAYSTRUCTURE_SIMD_QBVH 5 /* needs SIMD */
@@ -1389,6 +1442,8 @@ enum {
#define R_BAKE_LORES_MESH 32
#define R_BAKE_VCOL 64
#define R_BAKE_USERSCALE 128
+#define R_BAKE_SPLIT_MAT 256
+#define R_BAKE_AUTO_NAME 512
/* bake_normal_space */
#define R_BAKE_SPACE_CAMERA 0
@@ -1626,7 +1681,10 @@ typedef enum SculptFlags {
/* If set, dynamic-topology brushes will subdivide short edges */
SCULPT_DYNTOPO_SUBDIVIDE = (1 << 12),
/* If set, dynamic-topology brushes will collapse short edges */
- SCULPT_DYNTOPO_COLLAPSE = (1 << 11)
+ SCULPT_DYNTOPO_COLLAPSE = (1 << 11),
+
+ /* If set, dynamic-topology detail size will be constant in object space */
+ SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13)
} SculptFlags;
#if (DNA_DEPRECATED_GCC_POISON == 1)
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index beb230e467c..41d26e34f03 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -154,6 +154,12 @@ typedef struct uiListDyn {
int items_len; /* Number of items in collection. */
int items_shown; /* Number of items actually visible after filtering. */
+ /* Those are temp data used during drag-resize with GRIP button (they are in pixels, the meaningful data is the
+ * difference between resize_prev and resize)...
+ */
+ int resize;
+ int resize_prev;
+
/* Filtering data. */
int *items_filter_flags; /* items_len length. */
int *items_filter_neworder; /* org_idx -> new_idx, items_len length. */
@@ -186,6 +192,14 @@ typedef struct uiList { /* some list UI data need to be saved in file
uiListDyn *dyn_data;
} uiList;
+typedef struct uiPreview { /* some preview UI data need to be saved in file */
+ struct uiPreview *next, *prev;
+
+ char preview_id[64]; /* defined as UI_MAX_NAME_STR */
+ short height;
+ short pad1[3];
+} uiPreview;
+
typedef struct ScrArea {
struct ScrArea *next, *prev;
@@ -241,6 +255,7 @@ typedef struct ARegion {
ListBase panels; /* Panel */
ListBase panels_category_active; /* Stack of panel categories */
ListBase ui_lists; /* uiList */
+ ListBase ui_previews; /* uiPreview */
ListBase handlers; /* wmEventHandler */
ListBase panels_category; /* Panel categories runtime */
@@ -310,9 +325,11 @@ enum {
/* uiList flag */
enum {
UILST_SCROLL_TO_ACTIVE_ITEM = 1 << 0, /* Scroll list to make active item visible. */
- UILST_RESIZING = 1 << 1, /* We are currently resizing, deactivate autosize! */
};
+/* Value (in number of items) we have to go below minimum shown items to enable auto size. */
+#define UI_LIST_AUTO_SIZE_THRESHOLD 1
+
/* uiList filter flags (dyn_data) */
enum {
UILST_FLT_ITEM = 1 << 31, /* This item has passed the filter process successfully. */
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index 1b946c829fd..fcdbbe31541 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -257,6 +257,7 @@ typedef struct bJoystickSensor {
#define SENS_NOT 8
#define SENS_VISIBLE 16
#define SENS_PIN 32
+#define SENS_DEACTIVATE 64
/* sensor->pulse */
#define SENS_PULSE_CONT 0
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 54fcb5c857b..c7a6d4809a5 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -209,6 +209,7 @@ typedef enum eSpaceButtons_Texture_Context {
SB_TEXC_LAMP = 2,
SB_TEXC_PARTICLES = 3,
SB_TEXC_OTHER = 4,
+ SB_TEXC_LINESTYLE = 5,
} eSpaceButtons_Texture_Context;
/* sbuts->align */
@@ -981,6 +982,7 @@ typedef enum eSpaceNode_TexFrom {
SNODE_TEX_OBJECT = 0,
SNODE_TEX_WORLD = 1,
SNODE_TEX_BRUSH = 2,
+ SNODE_TEX_LINESTYLE = 3,
} eSpaceNode_TexFrom;
/* snode->shaderfrom */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index a3025a7fb31..1906f71a230 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -479,6 +479,7 @@ typedef struct ColorMapping {
#define MTEX_BUMP_OBJECTSPACE 1024
#define MTEX_BUMP_TEXTURESPACE 2048
/* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */
+#define MTEX_TIPS 4096 /* should use with_freestyle flag? */
#define MTEX_BICUBIC_BUMP 8192
#define MTEX_MAPTO_BOUNDS 16384
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 78faf5d8547..c471cb26892 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -61,14 +61,21 @@ typedef struct MovieReconstructedCamera {
typedef struct MovieTrackingCamera {
void *intrinsics; /* intrinsics handle */
+ short distortion_model;
+ short pad;
+
float sensor_width; /* width of CCD sensor */
float pixel_aspect; /* pixel aspect ratio */
- float pad;
float focal; /* focal length */
short units; /* units of focal length user is working with */
short pad1;
float principal[2]; /* principal point */
- float k1, k2, k3; /* radial distortion */
+
+ /* Polynomial distortion */
+ float k1, k2, k3; /* polynomial radial distortion */
+
+ /* Division distortion model coefficients */
+ float division_k1, division_k2;
} MovieTrackingCamera;
typedef struct MovieTrackingMarker {
@@ -210,6 +217,7 @@ typedef struct MovieTrackingSettings {
short default_margin; /* margin from frame boundaries */
short default_pattern_match; /* re-adjust every N frames */
short default_flag; /* default flags like color channels used by default */
+ float default_weight; /* default weight of the track */
short motion_flag; /* flags describes motion type */
@@ -222,7 +230,7 @@ typedef struct MovieTrackingSettings {
* were moved to per-tracking object settings
*/
- int reconstruction_flag, pad;
+ int reconstruction_flag;
/* which camera intrinsics to refine. uses on the REFINE_* flags */
short refine_camera_intrinsics, pad2;
@@ -347,6 +355,12 @@ typedef struct MovieTracking {
MovieTrackingDopesheet dopesheet; /* dopesheet data */
} MovieTracking;
+/* MovieTrackingCamera->distortion_model */
+enum {
+ TRACKING_DISTORTION_MODEL_POLYNOMIAL = 0,
+ TRACKING_DISTORTION_MODEL_DIVISION = 1
+};
+
/* MovieTrackingCamera->units */
enum {
CAMERA_UNITS_PX = 0,
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index dca007f83ec..4f5670d16c1 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -233,8 +233,10 @@ typedef struct ThemeSpace {
char hilite[4];
char grid[4];
+ char view_overlay[4];
+
char wire[4], wire_edit[4], select[4];
- char lamp[4], speaker[4], empty[4], camera[4], pad[4];
+ char lamp[4], speaker[4], empty[4], camera[4];
char active[4], group[4], group_active[4], transform[4];
char vertex[4], vertex_select[4], vertex_unreferenced[4];
char edge[4], edge_select[4];
@@ -483,8 +485,9 @@ typedef struct UserDef {
short glreslimit;
short curssize;
short color_picker_type;
- short ipo_new; /* interpolation mode for newly added F-Curves */
- short keyhandles_new; /* handle types for newly added keyframes */
+ char ipo_new; /* interpolation mode for newly added F-Curves */
+ char keyhandles_new; /* handle types for newly added keyframes */
+ char pad1[2];
short scrcastfps; /* frame rate for screencast to be played back */
short scrcastwait; /* milliseconds between screencast snapshots */
@@ -733,10 +736,11 @@ typedef enum eGP_UserdefSettings {
/* color picker types */
typedef enum eColorPicker_Types {
- USER_CP_CIRCLE = 0,
+ USER_CP_CIRCLE_HSV = 0,
USER_CP_SQUARE_SV = 1,
USER_CP_SQUARE_HS = 2,
USER_CP_SQUARE_HV = 3,
+ USER_CP_CIRCLE_HSL = 4,
} eColorPicker_Types;
/* timecode display styles */
@@ -782,28 +786,27 @@ typedef enum eNdof_Flag {
NDOF_SHOULD_ZOOM = (1 << 4),
NDOF_SHOULD_ROTATE = (1 << 5),
- /* orbit navigation modes
- * only two options, so it's sort of a hybrid bool/enum
- * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */
+ /* orbit navigation modes */
- // NDOF_ORBIT_MODE = (1 << 6),
- // #define NDOF_OM_TARGETCAMERA 0
- // #define NDOF_OM_OBJECT NDOF_ORBIT_MODE
+ /* exposed as Orbit|Explore in the UI */
+ NDOF_MODE_ORBIT = (1 << 6),
/* actually... users probably don't care about what the mode
* is called, just that it feels right */
/* zoom is up/down if this flag is set (otherwise forward/backward) */
- NDOF_ZOOM_UPDOWN = (1 << 7),
+ NDOF_PAN_YZ_SWAP_AXIS = (1 << 7),
NDOF_ZOOM_INVERT = (1 << 8),
- NDOF_ROTATE_INVERT_AXIS = (1 << 9),
- NDOF_TILT_INVERT_AXIS = (1 << 10),
- NDOF_ROLL_INVERT_AXIS = (1 << 11),
+ NDOF_ROTX_INVERT_AXIS = (1 << 9),
+ NDOF_ROTY_INVERT_AXIS = (1 << 10),
+ NDOF_ROTZ_INVERT_AXIS = (1 << 11),
NDOF_PANX_INVERT_AXIS = (1 << 12),
NDOF_PANY_INVERT_AXIS = (1 << 13),
NDOF_PANZ_INVERT_AXIS = (1 << 14),
NDOF_TURNTABLE = (1 << 15),
} eNdof_Flag;
+#define NDOF_PIXELS_PER_SECOND 600.0f
+
/* compute_device_type */
typedef enum eCompute_Device_Type {
USER_COMPUTE_DEVICE_NONE = 0,
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index a154f6fed15..98c12e9cc11 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -101,8 +101,6 @@ typedef struct RegionView3D {
float clip_local[6][4]; /* clip in object space, means we can test for clipping in editmode without first going into worldspace */
struct BoundBox *clipbb;
- struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */
-
struct RegionView3D *localvd; /* allocated backup of its self while in localview */
struct RenderInfo *ri;
struct RenderEngine *render_engine;
@@ -125,7 +123,7 @@ typedef struct RegionView3D {
* also matches -viewinv[3][0:3] in ortho mode.*/
float camzoom; /* viewport zoom on the camera frame, see BKE_screen_view3d_zoom_to_fac */
char is_persp; /* check if persp/ortho view, since 'persp' cant be used for this since
- * it can have cameras assigned as well. (only set in setwinmatrixview3d) */
+ * it can have cameras assigned as well. (only set in view3d_winmatrix_set) */
char persp;
char view;
char viewlock;
@@ -142,7 +140,7 @@ typedef struct RegionView3D {
short lpersp, lview; /* lpersp can never be set to 'RV3D_CAMOB' */
float gridview;
- float twangle[3];
+ float tw_idot[3]; /* manipulator runtime: (1 - dot) product with view vector (used to check view alignment) */
/* active rotation from NDOF or elsewhere */
@@ -218,7 +216,7 @@ typedef struct View3D {
void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
struct Material *defmaterial; /* used by matcap now */
-
+
/* XXX deprecated? */
struct bGPdata *gpd DNA_DEPRECATED; /* Grease-Pencil Data (annotation layers) */
@@ -247,6 +245,7 @@ typedef struct View3D {
#define RV3D_CLIPPING 4
#define RV3D_NAVIGATING 8
#define RV3D_GPULIGHT_UPDATE 16
+#define RV3D_IS_GAME_ENGINE 32 /* runtime flag, used to check if LoD's should be used */
/* RegionView3d->viewlock */
#define RV3D_LOCKED (1 << 0)
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index 35b4ff262ed..50c26eb6732 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -85,15 +85,9 @@ dna.Depends ('dna.c', makesdna)
dna.Depends ('dna.c', header_files)
if env['OURPLATFORM'] != 'linuxcross':
- if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw', 'win64-mingw'):
- dna.Command ('dna.c', '', "\"" + root_build_dir+os.sep+"makesdna\" $TARGET")
- else:
- dna.Command ('dna.c', '', "\"" + root_build_dir+os.sep+"makesdna\" $TARGET")
+ dna.Command ('dna.c', '', "\"" + root_build_dir+os.sep+"makesdna\" $TARGET")
else:
- if USE_WINE:
- dna.Command ('dna.c', '', 'wine ' + root_build_dir+os.sep+"makesdna $TARGET")
- else:
- dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET")
+ dna.Command ('dna.c', '', ('', 'wine ')[USE_WINE] + root_build_dir+os.sep+"makesdna $TARGET")
# TODO, get WITH_DNA_GHASH working, see CMake's 'WITH_DNA_GHASH'
obj = ['intern/dna.c', 'intern/dna_genfile.c']
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 525c7030029..bc1ee28d582 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -51,17 +51,9 @@
#include "DNA_genfile.h"
#include "DNA_sdna_types.h" // for SDNA ;-)
-
-/* gcc 4.1 on mingw was complaining that __int64 was already defined
- * actually is saw the line below as typedef long long long long...
- * Anyhow, since its already defined, its safe to do an ifndef here- Campbell */
-#ifdef FREE_WINDOWS
-# ifndef __int64
-typedef long long __int64;
-# endif
-#endif
-
-/*
+/**
+ * \section dna_genfile Overview
+ *
* - please note: no builtin security to detect input of double structs
* - if you want a struct not to be in DNA file: add two hash marks above it (#<enter>#<enter>)
*
@@ -72,6 +64,7 @@ typedef long long __int64;
*
* Create a structDNA: only needed when one of the input include (.h) files change.
* File Syntax:
+ * <pre>
* SDNA (4 bytes) (magic number)
* NAME (4 bytes)
* <nr> (4 bytes) amount of names (int)
@@ -93,12 +86,13 @@ typedef long long __int64;
* STRC (4 bytes)
* <nr> amount of structs (int)
* <typenr><nr_of_elems> <typenr><namenr> <typenr><namenr> ...
+ *</pre>
*
- * !!Remember to read/write integer and short aligned!!
+ * **Remember to read/write integer and short aligned!**
*
* While writing a file, the names of a struct is indicated with a type number,
- * to be found with: type = findstruct_nr(SDNA *, char *)
- * The value of 'type' corresponds with the the index within the structs array
+ * to be found with: ``type = DNA_struct_find_nr(SDNA *, const char *)``
+ * The value of ``type`` corresponds with the the index within the structs array
*
* For the moment: the complete DNA file is included in a .blend file. For
* the future we can think of smarter methods, like only included the used
@@ -114,7 +108,7 @@ typedef long long __int64;
* - change of a pointer type: when the name doesn't change the contents is copied
*
* NOT YET:
- * - array (vec[3]) to float struct (vec3f)
+ * - array (``vec[3]``) to float struct (``vec3f``)
*
* DONE:
* - endian compatibility
@@ -307,7 +301,7 @@ static short *findstruct_name(SDNA *sdna, const char *str)
*/
int DNA_struct_find_nr(SDNA *sdna, const char *str)
{
- short *sp = NULL;
+ const short *sp = NULL;
if (sdna->lastfind < sdna->nr_structs) {
sp = sdna->structs[sdna->lastfind];
@@ -566,7 +560,7 @@ SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swa
static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structnr)
{
int a, b, typenr, elems;
- short *sp;
+ const short *sp;
const char *cp;
/* check all structs, test if it's inside another struct */
@@ -810,11 +804,7 @@ static void cast_elem(
*/
static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata, const char *olddata)
{
-#ifdef WIN32
- __int64 lval;
-#else
- long long lval;
-#endif
+ int64_t lval;
int arrlen;
arrlen = DNA_elem_array_size(name);
@@ -825,22 +815,15 @@ static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata
memcpy(curdata, olddata, curlen);
}
else if (curlen == 4 && oldlen == 8) {
-#ifdef WIN32
- lval = *( (__int64 *)olddata);
-#else
- lval = *( (long long *)olddata);
-#endif
+ lval = *((int64_t *)olddata);
+
/* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
* pointers may lose uniqueness on truncation! (Hopefully this wont
* happen unless/until we ever get to multi-gigabyte .blend files...) */
*((int *)curdata) = lval >> 3;
}
else if (curlen == 8 && oldlen == 4) {
-#ifdef WIN32
- *( (__int64 *)curdata) = *((int *)olddata);
-#else
- *( (long long *)curdata) = *((int *)olddata);
-#endif
+ *((int64_t *)curdata) = *((int *)olddata);
}
else {
/* for debug */
@@ -1307,7 +1290,7 @@ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const ch
const int SDNAnr = DNA_struct_find_nr(sdna, stype);
const short * const spo = sdna->structs[SDNAnr];
- char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
+ const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
BLI_assert(SDNAnr != -1);
return (int)((intptr_t)cp);
}
@@ -1319,7 +1302,7 @@ bool DNA_struct_elem_find(SDNA *sdna, const char *stype, const char *vartype, co
if (SDNAnr != -1) {
const short * const spo = sdna->structs[SDNAnr];
- char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
+ const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
if (cp) return true;
return (int)((intptr_t)cp);
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index d95c394b60f..51a0c5a7b0f 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -520,7 +520,7 @@ static int preprocess_include(char *maindata, int len)
return newlen;
}
-static void *read_file_data(char *filename, int *len_r)
+static void *read_file_data(char *filename, int *r_len)
{
#ifdef WIN32
FILE *fp = fopen(filename, "rb");
@@ -530,23 +530,23 @@ static void *read_file_data(char *filename, int *len_r)
void *data;
if (!fp) {
- *len_r = -1;
+ *r_len = -1;
return NULL;
}
fseek(fp, 0L, SEEK_END);
- *len_r = ftell(fp);
+ *r_len = ftell(fp);
fseek(fp, 0L, SEEK_SET);
- data = MEM_mallocN(*len_r, "read_file_data");
+ data = MEM_mallocN(*r_len, "read_file_data");
if (!data) {
- *len_r = -1;
+ *r_len = -1;
fclose(fp);
return NULL;
}
- if (fread(data, *len_r, 1, fp) != 1) {
- *len_r = -1;
+ if (fread(data, *r_len, 1, fp) != 1) {
+ *r_len = -1;
MEM_freeN(data);
fclose(fp);
return NULL;
@@ -723,7 +723,7 @@ static int arraysize(const char *str)
static int calculate_structlens(int firststruct)
{
int a, b, len_native, len_32, len_64, unknown = nr_structs, lastunknown, structtype, type, mul, namelen;
- short *sp, *structpoin;
+ const short *sp, *structpoin;
const char *cp;
int has_pointer, dna_error = 0;
@@ -907,7 +907,7 @@ static void dna_write(FILE *file, const void *pntr, const int size)
{
static int linelength = 0;
int i;
- char *data;
+ const char *data;
data = (char *) pntr;
@@ -925,7 +925,7 @@ void printStructLengths(void)
{
int a, unknown = nr_structs, structtype;
/*int lastunknown;*/ /*UNUSED*/
- short *structpoin;
+ const short *structpoin;
printf("\n\n*** All detected structs:\n");
while (unknown) {
@@ -948,7 +948,7 @@ void printStructLengths(void)
static int make_structDNA(const char *baseDirectory, FILE *file)
{
int len, i;
- short *sp;
+ const short *sp;
/* str contains filenames. Since we now include paths, I stretched */
/* it a bit. Hope this is enough :) -nzc- */
char str[SDNA_MAX_FILENAME_LENGTH], *cp;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 07c7d3e58c3..add59bafc3f 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -331,6 +331,7 @@ extern StructRNA RNA_LineStyleGeometryModifier_SinusDisplacement;
extern StructRNA RNA_LineStyleGeometryModifier_SpatialNoise;
extern StructRNA RNA_LineStyleGeometryModifier_TipRemover;
extern StructRNA RNA_LineStyleModifier;
+extern StructRNA RNA_LineStyleTextureSlot;
extern StructRNA RNA_LineStyleThicknessModifier;
extern StructRNA RNA_LineStyleThicknessModifier_AlongStroke;
extern StructRNA RNA_LineStyleThicknessModifier_Calligraphy;
@@ -692,22 +693,22 @@ extern const PointerRNA PointerRNA_NULL;
StructRNA *RNA_struct_find(const char *identifier);
-const char *RNA_struct_identifier(StructRNA *type);
-const char *RNA_struct_ui_name(StructRNA *type);
-const char *RNA_struct_ui_name_raw(StructRNA *type);
-const char *RNA_struct_ui_description(StructRNA *type);
-const char *RNA_struct_ui_description_raw(StructRNA *type);
-const char *RNA_struct_translation_context(StructRNA *type);
-int RNA_struct_ui_icon(StructRNA *type);
+const char *RNA_struct_identifier(const StructRNA *type);
+const char *RNA_struct_ui_name(const StructRNA *type);
+const char *RNA_struct_ui_name_raw(const StructRNA *type);
+const char *RNA_struct_ui_description(const StructRNA *type);
+const char *RNA_struct_ui_description_raw(const StructRNA *type);
+const char *RNA_struct_translation_context(const StructRNA *type);
+int RNA_struct_ui_icon(const StructRNA *type);
PropertyRNA *RNA_struct_name_property(StructRNA *type);
PropertyRNA *RNA_struct_iterator_property(StructRNA *type);
StructRNA *RNA_struct_base(StructRNA *type);
-bool RNA_struct_is_ID(StructRNA *type);
-bool RNA_struct_is_a(StructRNA *type, StructRNA *srna);
+bool RNA_struct_is_ID(const StructRNA *type);
+bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna);
-bool RNA_struct_undo_check(StructRNA *type);
+bool RNA_struct_undo_check(const StructRNA *type);
StructRegisterFunc RNA_struct_register(StructRNA *type);
StructUnregisterFunc RNA_struct_unregister(StructRNA *type);
@@ -721,7 +722,7 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type);
struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create);
bool RNA_struct_idprops_check(StructRNA *srna);
-bool RNA_struct_idprops_register_check(StructRNA *type);
+bool RNA_struct_idprops_register_check(const StructRNA *type);
bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
@@ -786,13 +787,14 @@ bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **
int RNA_enum_from_value(EnumPropertyItem *item, const int value);
int RNA_enum_from_identifier(EnumPropertyItem *item, const char *identifier);
-void RNA_property_enum_items(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item,
- int *r_totitem, bool *r_free);
-void RNA_property_enum_items_gettexted(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item,
- int *r_totitem, bool *r_free);
+void RNA_property_enum_items(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop,
+ EnumPropertyItem **item, int *r_totitem, bool *r_free);
+void RNA_property_enum_items_gettexted(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop,
+ EnumPropertyItem **r_item, int *r_totitem, bool *r_free);
bool RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value);
bool RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
bool RNA_property_enum_name(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
+bool RNA_property_enum_name_gettexted(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
int RNA_property_enum_bitflag_identifiers(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
@@ -913,14 +915,14 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path,
PointerRNA *r_ptr, PropertyRNA **r_prop);
bool RNA_path_resolve_full(PointerRNA *ptr, const char *path,
- PointerRNA *r_ptr, PropertyRNA **r_prop, int *index);
-
+ PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
+
/* path_resolve_property() variants ensure that pointer + property both exist */
bool RNA_path_resolve_property(PointerRNA *ptr, const char *path,
- PointerRNA *r_ptr, PropertyRNA **r_prop);
+ PointerRNA *r_ptr, PropertyRNA **r_prop);
bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path,
- PointerRNA *r_ptr, PropertyRNA **r_prop, int *index);
+ PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 49ff04192b8..3d4ed0d6f51 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -65,13 +65,19 @@ extern EnumPropertyItem modifier_triangulate_ngon_method_items[];
extern EnumPropertyItem image_type_items[];
extern EnumPropertyItem image_color_mode_items[];
-extern EnumPropertyItem image_depth_mode_items[];
+extern EnumPropertyItem image_color_depth_items[];
extern EnumPropertyItem image_generated_type_items[];
+extern EnumPropertyItem normal_space_items[];
+extern EnumPropertyItem normal_swizzle_items[];
+extern EnumPropertyItem bake_save_mode_items[];
+
+extern EnumPropertyItem exr_codec_items[];
extern EnumPropertyItem color_sets_items[];
extern EnumPropertyItem beztriple_keyframe_type_items[];
extern EnumPropertyItem beztriple_interpolation_mode_items[];
+extern EnumPropertyItem beztriple_interpolation_easing_items[];
extern EnumPropertyItem keyframe_handle_type_items[];
extern EnumPropertyItem keyblock_type_items[];
@@ -118,6 +124,8 @@ extern EnumPropertyItem object_axis_unsigned_items[];
extern EnumPropertyItem controller_type_items[];
+extern EnumPropertyItem render_pass_type_items[];
+
extern EnumPropertyItem keymap_propvalue_items[];
extern EnumPropertyItem operator_context_items[];
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 4bf0719f5c0..83f3870c29a 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -236,12 +236,40 @@ typedef enum PropertyFlag {
PROP_ENUM_NO_TRANSLATE = (1 << 29), /* for enums not to be translated (e.g. renderlayers' names in nodes) */
} PropertyFlag;
+struct CollectionPropertyIterator;
+struct Link;
+typedef int (*IteratorSkipFunc)(struct CollectionPropertyIterator *iter, void *data);
+
+typedef struct ListBaseIterator {
+ struct Link *link;
+ int flag;
+ IteratorSkipFunc skip;
+} ListBaseIterator;
+
+typedef struct ArrayIterator {
+ char *ptr;
+ char *endptr; /* past the last valid pointer, only for comparisons, ignores skipped values */
+ void *free_ptr; /* will be freed if set */
+ int itemsize;
+
+ /* array length with no skip functions applied, take care not to compare against index from animsys
+ * or python indices */
+ int length;
+
+ /* optional skip function, when set the array as viewed by rna can contain only a subset of the members.
+ * this changes indices so quick array index lookups are not possible when skip function is used. */
+ IteratorSkipFunc skip;
+} ArrayIterator;
+
typedef struct CollectionPropertyIterator {
/* internal */
PointerRNA parent;
PointerRNA builtin_parent;
struct PropertyRNA *prop;
- void *internal;
+ union {
+ ArrayIterator array;
+ ListBaseIterator listbase;
+ } internal;
int idprop;
int level;
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 29d84a8d245..ff75d9a1721 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -211,10 +211,7 @@ if env['OURPLATFORM'] != 'linuxcross':
else:
rna.Command (generated_files, '', "\"" + root_build_dir+os.sep+"makesrna\" \"" + build_dir + '"' )
else:
- if USE_WINE:
- rna.Command (generated_files, '', 'wine ' + root_build_dir+os.sep+"makesrna.exe " + build_dir)
- else:
- rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir)
+ rna.Command (generated_files, '', ('', 'wine ')[USE_WINE] + root_build_dir+os.sep+"makesrna.exe " + build_dir)
obj = ['intern/rna_access.c']
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index f1ecb8ddf1e..7f1f04cdb6a 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -659,7 +659,7 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (dp->dnaarraylength == 1) {
if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
- fprintf(f, " values[i] = %s((data->%s & (%d << i)) != 0);\n",
+ fprintf(f, " values[i] = %s((data->%s & (%du << i)) != 0);\n",
(dp->booleannegative) ? "!" : "", dp->dnaname, dp->booleanbit);
}
else {
@@ -897,14 +897,14 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (prop->flag & PROP_DYNAMIC) {
char *lenfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier),
"set_length");
- fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
- fprintf(f, " int len = %s(ptr, arraylen);\n\n", lenfunc);
+ fprintf(f, " unsigned int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
+ fprintf(f, " unsigned int len = %s(ptr, arraylen);\n\n", lenfunc);
rna_clamp_value_range(f, prop);
fprintf(f, " for (i = 0; i < len; i++) {\n");
MEM_freeN(lenfunc);
}
else {
- fprintf(f, " int i;\n\n");
+ fprintf(f, " unsigned int i;\n\n");
rna_clamp_value_range(f, prop);
fprintf(f, " for (i = 0; i < %u; i++) {\n", prop->totarraylength);
}
@@ -913,7 +913,7 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
fprintf(f, " if (%svalues[i]) data->%s |= (%d<<i);\n",
(dp->booleannegative) ? "!" : "", dp->dnaname, dp->booleanbit);
- fprintf(f, " else data->%s &= ~(%d << i);\n", dp->dnaname, dp->booleanbit);
+ fprintf(f, " else data->%s &= ~(%du << i);\n", dp->dnaname, dp->booleanbit);
}
else {
fprintf(f, " (&data->%s)[i] = %s", dp->dnaname, (dp->booleannegative) ? "!" : "");
@@ -1147,7 +1147,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
fprintf(f, " if (iter.valid) {\n");
if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {
- fprintf(f, " ArrayIterator *internal = iter.internal;\n");
+ fprintf(f, " ArrayIterator *internal = &iter.internal.array;\n");
fprintf(f, " if (index < 0 || index >= internal->length) {\n");
fprintf(f, "#ifdef __GNUC__\n");
fprintf(f, " printf(\"Array iterator out of range: %%s (index %%d)\\n\", __func__, index);\n");
@@ -1167,7 +1167,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
fprintf(f, " }\n");
}
else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {
- fprintf(f, " ListBaseIterator *internal = iter.internal;\n");
+ fprintf(f, " ListBaseIterator *internal = &iter.internal.listbase;\n");
fprintf(f, " if (internal->skip) {\n");
fprintf(f, " while (index-- > 0 && iter.valid) {\n");
fprintf(f, " rna_iterator_listbase_next(&iter);\n");
@@ -1536,7 +1536,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
{
PropertyRNA *prop;
- char *func;
+ const char *func;
prop = dp->prop;
@@ -1768,12 +1768,12 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
if (cprop->item_type)
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier,
- rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"),
- (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
+ rna_safe_id(prop->identifier), (cprop->length ? "true" : "false"),
+ (cprop->lookupint ? "true" : "false"), (cprop->lookupstring ? "true" : "false"));
else
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, "UnknownType", srna->identifier,
- rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"),
- (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
+ rna_safe_id(prop->identifier), (cprop->length ? "true" : "false"),
+ (cprop->lookupint ? "true" : "false"), (cprop->lookupstring ? "true" : "false"));
break;
}
}
@@ -1949,12 +1949,12 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe
if (cprop->type)
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", (const char *)cprop->type, srna->identifier,
- prop->identifier, (cprop->length ? "TRUE" : "FALSE"),
- (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
+ prop->identifier, (cprop->length ? "true" : "false"),
+ (cprop->lookupint ? "true" : "false"), (cprop->lookupstring ? "true" : "false"));
else
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", "UnknownType", srna->identifier,
- prop->identifier, (cprop->length ? "TRUE" : "FALSE"),
- (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
+ prop->identifier, (cprop->length ? "true" : "false"),
+ (cprop->lookupint ? "true" : "false"), (cprop->lookupstring ? "true" : "false"));
#endif
break;
}
@@ -2156,7 +2156,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
PropertyType type;
const char *funcname, *valstr;
const char *ptrstr;
- const short has_data = (dfunc->cont.properties.first != NULL);
+ const bool has_data = (dfunc->cont.properties.first != NULL);
int flag, pout, cptr, first;
srna = dsrna->srna;
@@ -3517,7 +3517,7 @@ static const char *cpp_classes = ""
"#define POINTER_PROPERTY(type, sname, identifier) \\\n"
" inline type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n"
"\n"
-"#define COLLECTION_PROPERTY_LENGTH_FALSE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LENGTH_false(sname, identifier) \\\n"
" inline static int sname##_##identifier##_length_wrap(PointerRNA *ptr) \\\n"
" { \\\n"
" CollectionPropertyIterator iter; \\\n"
@@ -3530,11 +3530,11 @@ static const char *cpp_classes = ""
" sname##_##identifier##_end(&iter); \\\n"
" return length; \\\n"
" } \n"
-"#define COLLECTION_PROPERTY_LENGTH_TRUE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LENGTH_true(sname, identifier) \\\n"
" inline static int sname##_##identifier##_length_wrap(PointerRNA *ptr) \\\n"
" { return sname##_##identifier##_length(ptr); } \n"
"\n"
-"#define COLLECTION_PROPERTY_LOOKUP_INT_FALSE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LOOKUP_INT_false(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n"
" { \\\n"
" CollectionPropertyIterator iter; \\\n"
@@ -3554,7 +3554,7 @@ static const char *cpp_classes = ""
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" return found; \\\n"
" } \n"
-"#define COLLECTION_PROPERTY_LOOKUP_INT_TRUE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LOOKUP_INT_true(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n"
" { \\\n"
" int found = sname##_##identifier##_lookup_int(ptr, key, r_ptr); \\\n"
@@ -3562,7 +3562,7 @@ static const char *cpp_classes = ""
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" return found; \\\n"
" } \n"
-"#define COLLECTION_PROPERTY_LOOKUP_STRING_FALSE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LOOKUP_STRING_false(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
" { \\\n"
" CollectionPropertyIterator iter; \\\n"
@@ -3587,7 +3587,7 @@ static const char *cpp_classes = ""
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" return found; \\\n"
" } \n"
-"#define COLLECTION_PROPERTY_LOOKUP_STRING_TRUE(sname, identifier) \\\n"
+"#define COLLECTION_PROPERTY_LOOKUP_STRING_true(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
" { \\\n"
" int found = sname##_##identifier##_lookup_string(ptr, key, r_ptr); \\\n"
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index a36bd8e27c2..7959e60da33 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -58,7 +58,7 @@ EnumPropertyItem id_type_items[] = {
{ID_KE, "KEY", ICON_SHAPEKEY_DATA, "Key", ""},
{ID_LA, "LAMP", ICON_LAMP_DATA, "Lamp", ""},
{ID_LI, "LIBRARY", ICON_LIBRARY_DATA_DIRECT, "Library", ""},
- {ID_LS, "LINESTYLE", ICON_BRUSH_DATA, "Line Style", ""}, /* FIXME proper icon */
+ {ID_LS, "LINESTYLE", ICON_LINE_DATA, "Line Style", ""},
{ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""},
{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
{ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
@@ -115,10 +115,10 @@ static int rna_ID_name_editable(PointerRNA *ptr)
if (GS(id->name) == ID_VF) {
VFont *vfont = (VFont *)id;
if (BKE_vfont_is_builtin(vfont))
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
short RNA_type_to_ID_code(StructRNA *type)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7946d24b83b..ded0278b44d 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -460,7 +460,7 @@ static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
}
}
-static const char *rna_ensure_property_identifier(PropertyRNA *prop)
+static const char *rna_ensure_property_identifier(const PropertyRNA *prop)
{
if (prop->magic == RNA_MAGIC)
return prop->identifier;
@@ -491,7 +491,7 @@ static const char *rna_ensure_property_description(PropertyRNA *prop)
return description;
}
-static const char *rna_ensure_property_name(PropertyRNA *prop)
+static const char *rna_ensure_property_name(const PropertyRNA *prop)
{
const char *name;
@@ -516,22 +516,22 @@ StructRNA *RNA_struct_find(const char *identifier)
return NULL;
}
-const char *RNA_struct_identifier(StructRNA *type)
+const char *RNA_struct_identifier(const StructRNA *type)
{
return type->identifier;
}
-const char *RNA_struct_ui_name(StructRNA *type)
+const char *RNA_struct_ui_name(const StructRNA *type)
{
return CTX_IFACE_(type->translation_context, type->name);
}
-const char *RNA_struct_ui_name_raw(StructRNA *type)
+const char *RNA_struct_ui_name_raw(const StructRNA *type)
{
return type->name;
}
-int RNA_struct_ui_icon(StructRNA *type)
+int RNA_struct_ui_icon(const StructRNA *type)
{
if (type)
return type->icon;
@@ -539,17 +539,17 @@ int RNA_struct_ui_icon(StructRNA *type)
return ICON_DOT;
}
-const char *RNA_struct_ui_description(StructRNA *type)
+const char *RNA_struct_ui_description(const StructRNA *type)
{
return TIP_(type->description);
}
-const char *RNA_struct_ui_description_raw(StructRNA *type)
+const char *RNA_struct_ui_description_raw(const StructRNA *type)
{
return type->description;
}
-const char *RNA_struct_translation_context(StructRNA *type)
+const char *RNA_struct_translation_context(const StructRNA *type)
{
return type->translation_context;
}
@@ -569,17 +569,17 @@ StructRNA *RNA_struct_base(StructRNA *type)
return type->base;
}
-bool RNA_struct_is_ID(StructRNA *type)
+bool RNA_struct_is_ID(const StructRNA *type)
{
return (type->flag & STRUCT_ID) != 0;
}
-bool RNA_struct_undo_check(StructRNA *type)
+bool RNA_struct_undo_check(const StructRNA *type)
{
return (type->flag & STRUCT_UNDO) != 0;
}
-bool RNA_struct_idprops_register_check(StructRNA *type)
+bool RNA_struct_idprops_register_check(const StructRNA *type)
{
return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
}
@@ -600,9 +600,9 @@ bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
return false;
}
-bool RNA_struct_is_a(StructRNA *type, StructRNA *srna)
+bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
{
- StructRNA *base;
+ const StructRNA *base;
if (srna == &RNA_AnyType)
return true;
@@ -1214,7 +1214,7 @@ EnumPropertyItem DummyRNA_DEFAULT_items[] = {
{0, NULL, 0, NULL, NULL}
};
-void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item,
+void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **r_item,
int *r_totitem, bool *r_free)
{
EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
@@ -1222,37 +1222,42 @@ void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, En
*r_free = false;
if (eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
- int tot = 0;
+ EnumPropertyItem *item;
if (prop->flag & PROP_ENUM_NO_CONTEXT)
- *item = eprop->itemf(NULL, ptr, prop, r_free);
+ item = eprop->itemf(NULL, ptr, prop, r_free);
else
- *item = eprop->itemf(C, ptr, prop, r_free);
+ item = eprop->itemf(C, ptr, prop, r_free);
+
+ /* any callbacks returning NULL should be fixed */
+ BLI_assert(item != NULL);
if (r_totitem) {
- if (*item) {
- for (; (*item)[tot].identifier; tot++) ;
+ int tot;
+ for (tot = 0; item[tot].identifier; tot++) {
+ /* pass */
}
-
*r_totitem = tot;
}
+ *r_item = item;
}
else {
- *item = eprop->item;
+ *r_item = eprop->item;
if (r_totitem)
*r_totitem = eprop->totitem;
}
}
-void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item,
- int *r_totitem, bool *r_free)
+void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop,
+ EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
{
- RNA_property_enum_items(C, ptr, prop, item, r_totitem, r_free);
+ RNA_property_enum_items(C, ptr, prop, r_item, r_totitem, r_free);
#ifdef WITH_INTERNATIONAL
if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
int i;
+
/* Note: Only do those tests once, and then use BLF_pgettext. */
bool do_iface = BLF_translate_iface();
bool do_tooltip = BLF_translate_tooltips();
@@ -1262,19 +1267,24 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
return;
if (*r_free) {
- nitem = *item;
+ nitem = *r_item;
}
else {
- int totitem = 0;
+ EnumPropertyItem *item = *r_item;
+ int tot;
- /* count */
- for (i = 0; (*item)[i].identifier; i++)
- totitem++;
-
- nitem = MEM_callocN(sizeof(EnumPropertyItem) * (totitem + 1), "enum_items_gettexted");
+ if (r_totitem) {
+ tot = *r_totitem;
+ }
+ else {
+ /* count */
+ for (tot = 0; item[tot].identifier; tot++) {
+ /* pass */
+ }
+ }
- for (i = 0; (*item)[i].identifier; i++)
- nitem[i] = (*item)[i];
+ nitem = MEM_mallocN(sizeof(EnumPropertyItem) * (tot + 1), "enum_items_gettexted");
+ memcpy(nitem, item, sizeof(EnumPropertyItem) * (tot + 1));
*r_free = true;
}
@@ -1288,7 +1298,7 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
}
}
- *item = nitem;
+ *r_item = nitem;
}
#endif
}
@@ -1427,6 +1437,23 @@ bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, con
return false;
}
+bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
+{
+ bool result;
+
+ result = RNA_property_enum_name(C, ptr, prop, value, name);
+
+ if (result) {
+ if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
+ if (BLF_translate_iface()) {
+ *name = BLF_pgettext(prop->translation_context, *name);
+ }
+ }
+ }
+
+ return result;
+}
+
int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
const char **identifier)
{
@@ -2008,7 +2035,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
values[0] = RNA_property_int_get(ptr, prop);
else
@@ -2097,7 +2124,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
IDP_Int(idprop) = values[0];
else
@@ -2270,7 +2297,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0)
values[0] = RNA_property_float_get(ptr, prop);
else if (idprop->subtype == IDP_FLOAT) {
@@ -2365,7 +2392,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
- BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+ BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
if (prop->arraydimension == 0) {
if (idprop->type == IDP_FLOAT)
IDP_Float(idprop) = values[0];
@@ -2594,7 +2621,7 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
group = RNA_struct_idprops(ptr, 1);
if (group)
- IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop) - 1));
+ IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop)));
}
}
@@ -2859,7 +2886,7 @@ void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num)
if (num > 1 && (iter->idprop || (cprop->property.flag & PROP_RAW_ARRAY))) {
/* fast skip for array */
- ArrayIterator *internal = iter->internal;
+ ArrayIterator *internal = &iter->internal.array;
if (!internal->skip) {
internal->ptr += internal->itemsize * (num - 1);
@@ -3200,7 +3227,7 @@ int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, Proper
if (iter.valid) {
/* get data from array iterator and item property */
- internal = iter.internal;
+ internal = &iter.internal.array;
arrayp = (iter.valid) ? iter.ptr.data : NULL;
if (internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
@@ -3617,13 +3644,11 @@ int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, Proper
void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
{
- ListBaseIterator *internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
- internal = MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
internal->link = (lb) ? lb->first : NULL;
internal->skip = skip;
- iter->internal = internal;
iter->valid = (internal->link != NULL);
if (skip && iter->valid && skip(iter, internal->link))
@@ -3632,7 +3657,7 @@ void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb,
void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
if (internal->skip) {
do {
@@ -3648,15 +3673,13 @@ void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
return internal->link;
}
-void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
+void rna_iterator_listbase_end(CollectionPropertyIterator *UNUSED(iter))
{
- MEM_freeN(iter->internal);
- iter->internal = NULL;
}
PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct ListBase *lb, int index)
@@ -3677,7 +3700,7 @@ void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int i
itemsize = 0;
}
- internal = MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
+ internal = &iter->internal.array;
internal->ptr = ptr;
internal->free_ptr = free_ptr ? ptr : NULL;
internal->endptr = ((char *)ptr) + length * itemsize;
@@ -3685,7 +3708,6 @@ void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int i
internal->skip = skip;
internal->length = length;
- iter->internal = internal;
iter->valid = (internal->ptr != internal->endptr);
if (skip && iter->valid && skip(iter, internal->ptr))
@@ -3694,7 +3716,7 @@ void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int i
void rna_iterator_array_next(CollectionPropertyIterator *iter)
{
- ArrayIterator *internal = iter->internal;
+ ArrayIterator *internal = &iter->internal.array;
if (internal->skip) {
do {
@@ -3710,14 +3732,14 @@ void rna_iterator_array_next(CollectionPropertyIterator *iter)
void *rna_iterator_array_get(CollectionPropertyIterator *iter)
{
- ArrayIterator *internal = iter->internal;
+ ArrayIterator *internal = &iter->internal.array;
return internal->ptr;
}
void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
{
- ArrayIterator *internal = iter->internal;
+ ArrayIterator *internal = &iter->internal.array;
/* for ** arrays */
return *(void **)(internal->ptr);
@@ -3725,14 +3747,12 @@ void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
void rna_iterator_array_end(CollectionPropertyIterator *iter)
{
- ArrayIterator *internal = iter->internal;
+ ArrayIterator *internal = &iter->internal.array;
if (internal->free_ptr) {
MEM_freeN(internal->free_ptr);
internal->free_ptr = NULL;
}
- MEM_freeN(iter->internal);
- iter->internal = NULL;
}
PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
@@ -3846,65 +3866,186 @@ static int rna_token_strip_quotes(char *token)
return 0;
}
-/* Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path
- * ! This is a convenience method to avoid logic errors and ugly syntax
- * ! Assumes all pointers provided are valid
- * > returns: True only if both a valid pointer and property are found after resolving the path
- */
-bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_nextptr)
{
- return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL) && (*r_prop != NULL);
-}
+ char fixedbuf[256];
+ int intkey;
+
+ *r_nextptr = *ptr;
-/* Resolve the given RNA Path to find the pointer AND property (as well as the array index) indicated by fully resolving the path
- * ! This is a convenience method to avoid logic errors and ugly syntax
- * ! Assumes all pointers provided are valid
- * > returns: True only if both a valid pointer and property are found after resolving the path
- */
-bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
-{
- return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, index) && (*r_prop != NULL);
+ /* end of path, ok */
+ if (!(**path))
+ return true;
+
+ if (**path == '[') {
+ char *token;
+
+ /* resolve the lookup with [] brackets */
+ token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
+
+ if (!token)
+ return false;
+
+ /* check for "" to see if it is a string */
+ if (rna_token_strip_quotes(token)) {
+ if (RNA_property_collection_lookup_string(ptr, prop, token + 1, r_nextptr)) {
+ /* pass */
+ }
+ else {
+ r_nextptr->data = NULL;
+ }
+ }
+ else {
+ /* otherwise do int lookup */
+ intkey = atoi(token);
+ if (intkey == 0 && (token[0] != '0' || token[1] != '\0')) {
+ return false; /* we can be sure the fixedbuf was used in this case */
+ }
+ if (RNA_property_collection_lookup_int(ptr, prop, intkey, r_nextptr)) {
+ /* pass */
+ }
+ else {
+ r_nextptr->data = NULL;
+ }
+ }
+
+ if (token != fixedbuf) {
+ MEM_freeN(token);
+ }
+ }
+ else {
+ if (RNA_property_collection_type_get(ptr, prop, r_nextptr)) {
+ /* pass */
+ }
+ else {
+ /* ensure we quit on invalid values */
+ r_nextptr->data = NULL;
+ }
+ }
+
+ return true;
}
-/* Resolve the given RNA Path to find the pointer and/or property indicated by fully resolving the path
- * ! Assumes all pointers provided are valid
- * > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
- */
-bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, PropertyRNA *prop, int *r_index)
{
- return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
+ char fixedbuf[256];
+ int index_arr[RNA_MAX_ARRAY_DIMENSION] = {0};
+ int len[RNA_MAX_ARRAY_DIMENSION];
+ const int dim = RNA_property_array_dimension(ptr, prop, len);
+ int i;
+
+ *r_index = -1;
+
+ /* end of path, ok */
+ if (!(**path))
+ return true;
+
+ for (i = 0; i < dim; i++) {
+ int temp_index = -1;
+ char *token;
+
+ /* multi index resolve */
+ if (**path == '[') {
+ token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
+
+ if (token == NULL) {
+ /* invalid syntax blah[] */
+ return false;
+ }
+ /* check for "" to see if it is a string */
+ else if (rna_token_strip_quotes(token)) {
+ temp_index = RNA_property_array_item_index(prop, *(token + 1));
+ }
+ else {
+ /* otherwise do int lookup */
+ temp_index = atoi(token);
+
+ if (temp_index == 0 && (token[0] != '0' || token[1] != '\0')) {
+ if (token != fixedbuf) {
+ MEM_freeN(token);
+ }
+
+ return false;
+ }
+ }
+ }
+ else if (dim == 1) {
+ /* location.x || scale.X, single dimension arrays only */
+ token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 0);
+ if (token == NULL) {
+ /* invalid syntax blah.. */
+ return false;
+ }
+ temp_index = RNA_property_array_item_index(prop, *token);
+ }
+ else {
+ /* just to avoid uninitialized pointer use */
+ token = fixedbuf;
+ }
+
+ if (token != fixedbuf) {
+ MEM_freeN(token);
+ }
+
+ /* out of range */
+ if (temp_index < 0 || temp_index >= len[i])
+ return false;
+
+ index_arr[i] = temp_index;
+ /* end multi index resolve */
+ }
+
+ /* arrays always contain numbers so further values are not valid */
+ if (**path)
+ return false;
+
+ /* flatten index over all dimensions */
+ {
+ int totdim = 1;
+ int flat_index = 0;
+
+ for (i = dim - 1; i >= 0; i--) {
+ flat_index += index_arr[i] * totdim;
+ totdim *= len[i];
+ }
+
+ *r_index = flat_index;
+ }
+ return true;
}
-/* Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path
- * ! Assumes all pointers provided are valid
- * > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
- */
-bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
+static bool rna_path_parse(PointerRNA *ptr, const char *path,
+ PointerRNA *r_ptr, PropertyRNA **r_prop, int *index,
+ const bool eval_pointer)
{
PropertyRNA *prop;
PointerRNA curptr;
- PointerRNA nextptr; /* keep uninitialized, helps expose bugs in collection accessor functions */
- char fixedbuf[256], *token;
- int type, intkey;
+ char fixedbuf[256];
+ int type;
prop = NULL;
curptr = *ptr;
if (path == NULL || *path == '\0')
- return 0;
+ return false;
while (*path) {
int use_id_prop = (*path == '[') ? 1 : 0;
+ char *token;
/* custom property lookup ?
* C.object["someprop"]
*/
+ if (!curptr.data)
+ return false;
+
/* look up property name in current struct */
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
if (!token)
- return 0;
+ return false;
+ prop = NULL;
if (use_id_prop) { /* look up property name in current struct */
IDProperty *group = RNA_struct_idprops(&curptr, 0);
if (group && rna_token_strip_quotes(token))
@@ -3918,7 +4059,7 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
MEM_freeN(token);
if (!prop)
- return 0;
+ return false;
type = RNA_property_type(prop);
@@ -3926,161 +4067,108 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
* collection, otherwise return the property rna so that the
* caller can read the value of the property itself */
switch (type) {
- case PROP_POINTER:
- nextptr = RNA_property_pointer_get(&curptr, prop);
-
- if (nextptr.data) {
+ case PROP_POINTER: {
+ /* resolve pointer if further path elements follow
+ * or explicitly requested
+ */
+ if (eval_pointer || *path) {
+ PointerRNA nextptr = RNA_property_pointer_get(&curptr, prop);
+
curptr = nextptr;
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
if (index) *index = -1;
}
- else
- return 0;
-
break;
- case PROP_COLLECTION:
+ }
+ case PROP_COLLECTION: {
+ /* Resolve pointer if further path elements follow.
+ * Note that if path is empty, rna_path_parse_collection_key will do nothing anyway,
+ * so eval_pointer is of no use here (esp. as in this case, we want to keep found prop,
+ * erasing it breaks operators - e.g. bpy.types.Operator.bl_rna.foobar errors...).
+ */
if (*path) {
- if (*path == '[') {
- /* resolve the lookup with [] brackets */
- token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
-
- if (!token)
- return 0;
-
- /* check for "" to see if it is a string */
- if (rna_token_strip_quotes(token)) {
- if (RNA_property_collection_lookup_string(&curptr, prop, token + 1, &nextptr)) {
- /* pass */
- }
- else {
- nextptr.data = NULL;
- }
- }
- else {
- /* otherwise do int lookup */
- intkey = atoi(token);
- if (intkey == 0 && (token[0] != '0' || token[1] != '\0')) {
- return 0; /* we can be sure the fixedbuf was used in this case */
- }
- if (RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr)) {
- /* pass */
- }
- else {
- nextptr.data = NULL;
- }
- }
-
- if (token != fixedbuf) {
- MEM_freeN(token);
- }
- }
- else {
- PointerRNA c_ptr;
-
- if (RNA_property_collection_type_get(&curptr, prop, &c_ptr)) {
- nextptr = c_ptr;
- }
- else {
- /* ensure we quit on invalid values */
- nextptr.data = NULL;
- }
- }
+ PointerRNA nextptr;
+ if (!rna_path_parse_collection_key(&path, &curptr, prop, &nextptr))
+ return false;
- if (nextptr.data) {
- curptr = nextptr;
- prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
- if (index) *index = -1;
- }
- else
- return 0;
+ curptr = nextptr;
+ prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
+ if (index) *index = -1;
}
-
break;
+ }
default:
- if (index == NULL)
- break;
-
- *index = -1;
-
- if (*path) {
- int index_arr[RNA_MAX_ARRAY_DIMENSION] = {0};
- int len[RNA_MAX_ARRAY_DIMENSION];
- const int dim = RNA_property_array_dimension(&curptr, prop, len);
- int i, temp_index;
-
- for (i = 0; i < dim; i++) {
- temp_index = -1;
-
- /* multi index resolve */
- if (*path == '[') {
- token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
-
- if (token == NULL) {
- /* invalid syntax blah[] */
- return 0;
- }
- /* check for "" to see if it is a string */
- else if (rna_token_strip_quotes(token)) {
- temp_index = RNA_property_array_item_index(prop, *(token + 1));
- }
- else {
- /* otherwise do int lookup */
- temp_index = atoi(token);
+ if (index) {
+ if (!rna_path_parse_array_index(&path, &curptr, prop, index))
+ return false;
+ }
+ break;
+ }
+ }
- if (temp_index == 0 && (token[0] != '0' || token[1] != '\0')) {
- if (token != fixedbuf) {
- MEM_freeN(token);
- }
+ *r_ptr = curptr;
+ *r_prop = prop;
- return 0;
- }
- }
- }
- else if (dim == 1) {
- /* location.x || scale.X, single dimension arrays only */
- token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
- if (token == NULL) {
- /* invalid syntax blah.. */
- return 0;
- }
- temp_index = RNA_property_array_item_index(prop, *token);
- }
+ return true;
+}
- if (token != fixedbuf) {
- MEM_freeN(token);
- }
+/**
+ * Resolve the given RNA Path to find the pointer and/or property indicated by fully resolving the path.
+ *
+ * \note Assumes all pointers provided are valid
+ * \return True if path can be resolved to a valid "pointer + property" OR "pointer only"
+ */
+bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+{
+ if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, true))
+ return false;
- /* out of range */
- if (temp_index < 0 || temp_index >= len[i])
- return 0;
+ return r_ptr->data != NULL;
+}
- index_arr[i] = temp_index;
- /* end multi index resolve */
- }
+/**
+ * Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path.
+ *
+ * \note Assumes all pointers provided are valid.
+ * \return True if path can be resolved to a valid "pointer + property" OR "pointer only"
+ */
+bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
+{
+ if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, true))
+ return false;
- /* arrays always contain numbers so further values are not valid */
- if (*path) {
- return 0;
- }
- else {
- int totdim = 1;
- int flat_index = 0;
+ return r_ptr->data != NULL;
+}
- for (i = dim - 1; i >= 0; i--) {
- flat_index += index_arr[i] * totdim;
- totdim *= len[i];
- }
+/**
+ * Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path.
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax.
+ * \note Assumes all pointers provided are valid
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+{
+ if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, false))
+ return false;
- *index = flat_index;
- }
- }
- }
- }
+ return r_ptr->data != NULL && *r_prop != NULL;
+}
- *r_ptr = curptr;
- *r_prop = prop;
+/**
+ * Resolve the given RNA Path to find the pointer AND property (as well as the array index)
+ * indicated by fully resolving the path.
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax.
+ * \note Assumes all pointers provided are valid
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
+{
+ if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, false))
+ return false;
- return 1;
+ return r_ptr->data != NULL && *r_prop != NULL;
}
@@ -4139,7 +4227,7 @@ char *RNA_path_back(const char *path)
{
char fixedbuf[256];
const char *previous, *current;
- char *result, *token;
+ char *result;
int i;
if (!path)
@@ -4151,6 +4239,8 @@ char *RNA_path_back(const char *path)
/* parse token by token until the end, then we back up to the previous
* position and strip of the next token to get the path one step back */
while (*current) {
+ char *token;
+
token = rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
if (!token)
@@ -4317,7 +4407,7 @@ static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr)
* of an armature or object */
RNA_id_pointer_create(ptr->id.data, &id_ptr);
- haystack = RNA_struct_idprops(&id_ptr, FALSE);
+ haystack = RNA_struct_idprops(&id_ptr, false);
if (haystack) { /* can fail when called on bones */
needle = ptr->data;
return rna_idp_path(&id_ptr, haystack, needle, NULL);
@@ -4471,7 +4561,7 @@ char *RNA_path_full_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
data_path = RNA_path_from_ID_to_property(ptr, prop);
- if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ if ((index == -1) || (RNA_property_array_check(prop) == false)) {
ret = BLI_sprintfN("%s.%s",
id_path, data_path);
}
@@ -4513,7 +4603,7 @@ char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
}
}
- if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ if ((index == -1) || (RNA_property_array_check(prop) == false)) {
ret = BLI_sprintfN("%s",
data_path);
}
@@ -4537,7 +4627,7 @@ char *RNA_path_property_py(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index
{
char *ret;
- if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ if ((index == -1) || (RNA_property_array_check(prop) == false)) {
ret = BLI_sprintfN("%s",
RNA_property_identifier(prop));
}
@@ -5636,7 +5726,7 @@ void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, const void *valu
size *= data_alloc->array_tot;
if (data_alloc->array)
MEM_freeN(data_alloc->array);
- data_alloc->array = MEM_mallocN(size, AT);
+ data_alloc->array = MEM_mallocN(size, __func__);
memcpy(data_alloc->array, value, size);
}
else {
@@ -6014,7 +6104,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
}
case PROP_STRING:
{
- char *arg = va_arg(args, char *);
+ const char *arg = va_arg(args, char *);
err = rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg,
NULL, tid, fid, pid);
break;
@@ -6086,7 +6176,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
}
case PROP_STRING:
{
- char **arg = va_arg(args, char **);
+ const char **arg = va_arg(args, const char **);
err = rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata,
NULL, tid, fid, pid);
break;
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 9146677eb5e..ecfa1286a78 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -56,7 +56,7 @@
static void rna_ActionGroup_channels_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
FCurve *fcu = (FCurve *)internal->link;
bActionGroup *grp = fcu->grp;
@@ -80,7 +80,7 @@ static void rna_Action_groups_remove(bAction *act, ReportList *reports, PointerR
FCurve *fcu, *fcn;
/* try to remove the F-Curve from the action */
- if (BLI_remlink_safe(&act->groups, agrp) == FALSE) {
+ if (BLI_remlink_safe(&act->groups, agrp) == false) {
BKE_reportf(reports, RPT_ERROR, "Action group '%s' not found in action '%s'", agrp->name, act->id.name + 2);
return;
}
@@ -205,7 +205,7 @@ static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min,
static void rna_Action_frame_range_get(PointerRNA *ptr, float *values)
{ /* don't include modifiers because they too easily can have very large
* ranges: MINAFRAMEF to MAXFRAMEF. */
- calc_action_range(ptr->id.data, values, values + 1, FALSE);
+ calc_action_range(ptr->id.data, values, values + 1, false);
}
@@ -406,7 +406,7 @@ static void rna_def_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_linestyles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOLINESTYLE);
RNA_def_property_ui_text(prop, "Display Line Style", "Include visualization of Line Style related Animation data");
- RNA_def_property_ui_icon(prop, ICON_BRUSH_DATA, 0); /* FIXME */
+ RNA_def_property_ui_icon(prop, ICON_LINE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
prop = RNA_def_property(srna, "show_textures", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 7747c5e78b3..fd04fb46cf1 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -573,6 +573,11 @@ static void rna_def_actuator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Expanded", "Set actuator expanded in the user interface");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
+ prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ACT_DEACTIVATE);
+ RNA_def_property_ui_text(prop, "Active", "Set the active state of the actuator");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
RNA_api_actuator(srna);
}
@@ -656,7 +661,7 @@ static void rna_def_action_actuator(BlenderRNA *brna)
RNA_def_property_update(prop, NC_LOGIC, NULL);
prop = RNA_def_property(srna, "layer", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 0, 7); /* This should match BL_ActionManager::MAX_ACTION_LAYERS - 1 */
+ RNA_def_property_range(prop, 0, 32766); /* This should match BL_ActionManager::MAX_ACTION_LAYERS - 1 */
RNA_def_property_ui_text(prop, "Layer", "The animation layer to play the action on");
RNA_def_property_update(prop, NC_LOGIC, NULL);
@@ -1479,10 +1484,10 @@ static void rna_def_scene_actuator(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
- /*XXX filter only camera objects */
+
prop = RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Camera_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Camera Object", "Set this Camera (leave empty to refer to self object)");
RNA_def_property_update(prop, NC_LOGIC, NULL);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 18c3f107876..f2881bf2541 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -460,7 +460,7 @@ static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports
KS_Path *ksp = ksp_ptr->data;
/* if data is valid, call the API function for this */
- if ((keyingset && ksp) == FALSE) {
+ if ((keyingset && ksp) == false) {
BKE_report(reports, RPT_ERROR, "Keying set path could not be removed");
return;
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 9d4e7a1da04..1bccceab5ab 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -401,6 +401,12 @@ static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values)
ED_armature_ebone_to_mat4(ebone, (float(*)[4])values);
}
+static void rna_EditBone_matrix_set(PointerRNA *ptr, const float *values)
+{
+ EditBone *ebone = (EditBone *)(ptr->data);
+ ED_armature_ebone_from_mat4(ebone, (float(*)[4])values);
+}
+
static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->id.data;
@@ -441,7 +447,7 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po
static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
Bone *bone = (Bone *)internal->link;
if (bone->childbase.first)
@@ -795,11 +801,12 @@ static void rna_def_edit_bone(BlenderRNA *brna)
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
/*RNA_def_property_float_sdna(prop, NULL, ""); *//* doesnt access any real data */
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ //RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_THICK_WRAP); /* no reference to original data */
- RNA_def_property_ui_text(prop, "Editbone Matrix", "Read-only matrix calculated from the roll (armature space)");
- /* TODO - this could be made writable also */
- RNA_def_property_float_funcs(prop, "rna_EditBone_matrix_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Editbone Matrix",
+ "Matrix combining loc/rot of the bone (head position, direction and roll), "
+ "in armature space (WARNING: does not include/support bone's length/size)");
+ RNA_def_property_float_funcs(prop, "rna_EditBone_matrix_get", "rna_EditBone_matrix_set", NULL);
RNA_api_armature_edit_bone(srna);
diff --git a/source/blender/makesrna/intern/rna_armature_api.c b/source/blender/makesrna/intern/rna_armature_api.c
index 96c5350e5b7..1a4a9492543 100644
--- a/source/blender/makesrna/intern/rna_armature_api.c
+++ b/source/blender/makesrna/intern/rna_armature_api.c
@@ -46,7 +46,7 @@
static void rna_EditBone_align_roll(EditBone *ebo, float no[3])
{
- ebo->roll = ED_rollBoneToVector(ebo, no, FALSE);
+ ebo->roll = ED_rollBoneToVector(ebo, no, false);
}
static float rna_Bone_do_envelope(Bone *bone, float *vec)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 34c44565456..9c81d5893bf 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -49,6 +49,16 @@ static EnumPropertyItem prop_direction_items[] = {
{0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem sculpt_stroke_method_items[] = {
+ {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
+ {BRUSH_DRAG_DOT, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"},
+ {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
+ {BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
+ {BRUSH_ANCHORED, "ANCHORED", 0, "Anchored", "Keep the brush anchored to the initial location"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_BLOB, "BLOB", ICON_BRUSH_BLOB, "Blob", ""},
{SCULPT_TOOL_CLAY, "CLAY", ICON_BRUSH_CLAY, "Clay", ""},
@@ -465,6 +475,26 @@ static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerR
}
}
+static EnumPropertyItem *rna_Brush_stroke_itemf(bContext *C, PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
+{
+ PaintMode mode = BKE_paintmode_get_active_from_context(C);
+
+ static EnumPropertyItem brush_stroke_method_items[] = {
+ {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
+ {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
+ {BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ return sculpt_stroke_method_items;
+
+ default:
+ return brush_stroke_method_items;
+ }
+}
#else
static void rna_def_brush_texture_slot(BlenderRNA *brna)
@@ -613,22 +643,6 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem sculpt_stroke_method_items[] = {
- {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
- {BRUSH_DRAG_DOT, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"},
- {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
- {BRUSH_ANCHORED, "ANCHORED", 0, "Anchored", "Keep the brush anchored to the initial location"},
- {BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
- {0, NULL, 0, NULL, NULL}
- };
-
- static EnumPropertyItem brush_stroke_method_items[] = {
- {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
- {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
- {BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem texture_angle_source_items[] = {
{0, "USER", 0, "User", "Rotate the brush texture by given angle"},
{BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"},
@@ -693,13 +707,8 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "stroke_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
- RNA_def_property_enum_items(prop, brush_stroke_method_items);
- RNA_def_property_ui_text(prop, "Stroke Method", "");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
-
- prop = RNA_def_property(srna, "sculpt_stroke_method", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, sculpt_stroke_method_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Brush_stroke_itemf");
RNA_def_property_ui_text(prop, "Stroke Method", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
diff --git a/source/blender/makesrna/intern/rna_camera_api.c b/source/blender/makesrna/intern/rna_camera_api.c
index bf916806e40..ae15c58dd29 100644
--- a/source/blender/makesrna/intern/rna_camera_api.c
+++ b/source/blender/makesrna/intern/rna_camera_api.c
@@ -42,16 +42,16 @@
#include "BKE_object.h"
static void rna_camera_view_frame(struct Camera *camera, struct Scene *scene,
- float vec1_r[3], float vec2_r[3], float vec3_r[3], float vec4_r[3])
+ float r_vec1[3], float r_vec2[3], float r_vec3[3], float r_vec4[3])
{
float vec[4][3];
BKE_camera_view_frame(scene, camera, vec);
- copy_v3_v3(vec1_r, vec[0]);
- copy_v3_v3(vec2_r, vec[1]);
- copy_v3_v3(vec3_r, vec[2]);
- copy_v3_v3(vec4_r, vec[3]);
+ copy_v3_v3(r_vec1, vec[0]);
+ copy_v3_v3(r_vec2, vec[1]);
+ copy_v3_v3(r_vec3, vec[2]);
+ copy_v3_v3(r_vec4, vec[3]);
}
#else
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 408f99bd96a..df9a08480cb 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -62,6 +62,7 @@
#include "ED_node.h"
#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
static int rna_CurveMapping_curves_length(PointerRNA *ptr)
{
@@ -89,7 +90,7 @@ static void rna_CurveMapping_clip_set(PointerRNA *ptr, int value)
if (value) cumap->flag |= CUMA_DO_CLIP;
else cumap->flag &= ~CUMA_DO_CLIP;
- curvemapping_changed(cumap, FALSE);
+ curvemapping_changed(cumap, false);
}
static void rna_CurveMapping_black_level_set(PointerRNA *ptr, const float *values)
@@ -369,7 +370,7 @@ static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *repo
{
CBData *element = element_ptr->data;
int index = (int)(element - coba->data);
- if (colorband_element_remove(coba, index) == FALSE) {
+ if (colorband_element_remove(coba, index) == false) {
BKE_report(reports, RPT_ERROR, "Element not found in element collection or last element");
return;
}
@@ -380,7 +381,7 @@ static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *repo
void rna_CurveMap_remove_point(CurveMap *cuma, ReportList *reports, PointerRNA *point_ptr)
{
CurveMapPoint *point = point_ptr->data;
- if (curvemap_remove_point(cuma, point) == FALSE) {
+ if (curvemap_remove_point(cuma, point) == false) {
BKE_report(reports, RPT_ERROR, "Unable to remove curve point");
return;
}
@@ -595,13 +596,13 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
if (scene->ed) {
ColorManagedColorspaceSettings *colorspace_settings = (ColorManagedColorspaceSettings *) ptr->data;
Sequence *seq;
- int seq_found = FALSE;
+ bool seq_found = false;
if (&scene->sequencer_colorspace_settings != colorspace_settings) {
SEQ_BEGIN(scene->ed, seq);
{
if (seq->strip && &seq->strip->colorspace_settings == colorspace_settings) {
- seq_found = TRUE;
+ seq_found = true;
break;
}
}
@@ -609,10 +610,24 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
}
if (seq_found) {
+ if (seq->anim) {
+ IMB_free_anim(seq->anim);
+ seq->anim = NULL;
+ }
+
BKE_sequence_invalidate_cache(scene, seq);
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
}
else {
+ SEQ_BEGIN(scene->ed, seq);
+ {
+ if (seq->anim) {
+ IMB_free_anim(seq->anim);
+ seq->anim = NULL;
+ }
+ }
+ SEQ_END;
+
BKE_sequencer_cache_cleanup();
BKE_sequencer_preprocessed_cache_cleanup();
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index c0ad4fecc39..5fbaae71482 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -237,7 +237,7 @@ static void rna_Constraint_name_set(PointerRNA *ptr, const char *value)
/* if we have the list, check for unique name, otherwise give up */
if (list)
- BKE_unique_constraint_name(con, list);
+ BKE_constraint_unique_name(con, list);
}
/* fix all the animation data which may link to this */
@@ -323,7 +323,7 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSED(C),
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
{
bConstraint *con = (bConstraint *)ptr->data;
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1581,9 +1581,9 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem transform_items[] = {
- {0, "LOCATION", 0, "Loc", ""},
- {1, "ROTATION", 0, "Rot", ""},
- {2, "SCALE", 0, "Scale", ""},
+ {TRANS_LOCATION, "LOCATION", 0, "Loc", ""},
+ {TRANS_ROTATION, "ROTATION", 0, "Rot", ""},
+ {TRANS_SCALE, "SCALE", 0, "Scale", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1644,6 +1644,7 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Extrapolate Motion", "Extrapolate ranges");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ /* Loc */
prop = RNA_def_property(srna, "from_min_x", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "from_min[0]");
RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
@@ -1715,6 +1716,152 @@ static void rna_def_constraint_transform(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
RNA_def_property_ui_text(prop, "To Maximum Z", "Top range of Z axis destination motion");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ /* Rot */
+ prop = RNA_def_property(srna, "from_min_x_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_rot[0]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum X", "Bottom range of X axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_min_y_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_rot[1]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum Y", "Bottom range of Y axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_min_z_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_rot[2]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum Z", "Bottom range of Z axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_x_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_rot[0]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum X", "Top range of X axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_y_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_rot[1]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum Y", "Top range of Y axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_z_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_rot[2]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum Z", "Top range of Z axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_x_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_rot[0]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum X", "Bottom range of X axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_y_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_rot[1]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum Y", "Bottom range of Y axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_z_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_rot[2]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum Z", "Bottom range of Z axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_x_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_rot[0]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum X", "Top range of X axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_y_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_rot[1]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum Y", "Top range of Y axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_z_rot", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_rot[2]");
+ RNA_def_property_ui_range(prop, DEG2RADF(-180.0f), DEG2RADF(180.0f), 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum Z", "Top range of Z axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ /* Scale */
+ prop = RNA_def_property(srna, "from_min_x_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_scale[0]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum X", "Bottom range of X axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_min_y_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_scale[1]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum Y", "Bottom range of Y axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_min_z_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_min_scale[2]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Minimum Z", "Bottom range of Z axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_x_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_scale[0]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum X", "Top range of X axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_y_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_scale[1]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum Y", "Top range of Y axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "from_max_z_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "from_max_scale[2]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "From Maximum Z", "Top range of Z axis source motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_x_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_scale[0]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum X", "Bottom range of X axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_y_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_scale[1]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum Y", "Bottom range of Y axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_min_z_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_min_scale[2]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Minimum Z", "Bottom range of Z axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_x_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_scale[0]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum X", "Top range of X axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_y_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_scale[1]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum Y", "Top range of Y axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "to_max_z_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "to_max_scale[2]");
+ RNA_def_property_ui_range(prop, -1000.0f, 1000.0f, 10, 3);
+ RNA_def_property_ui_text(prop, "To Maximum Z", "Top range of Z axis destination motion");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
static void rna_def_constraint_location_limit(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index 3b789b16f52..8b5074eaf0d 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -228,6 +228,11 @@ void RNA_def_controller(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
RNA_def_property_update(prop, NC_LOGIC, NULL);
+ prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONT_DEACTIVATE);
+ RNA_def_property_ui_text(prop, "Active", "Set the active state of the controller");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
prop = RNA_def_property(srna, "use_priority", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONT_PRIO);
RNA_def_property_ui_text(prop, "Priority",
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index ff2d69ca05e..142b4ed6574 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -34,6 +34,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_font.h"
#include "RNA_access.h"
@@ -67,9 +69,27 @@ EnumPropertyItem keyframe_handle_type_items[] = {
};
EnumPropertyItem beztriple_interpolation_mode_items[] = {
- {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", "No interpolation, value of A gets held until B is encountered"},
- {BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"},
- {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"},
+ /* interpolation */
+ {0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"},
+ {BEZT_IPO_CONST, "CONSTANT", ICON_IPO_CONSTANT, "Constant", "No interpolation, value of A gets held until B is encountered"},
+ {BEZT_IPO_LIN, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"},
+ {BEZT_IPO_BEZ, "BEZIER", ICON_IPO_BEZIER, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"},
+
+ /* easing */
+ {0, "", 0, N_("Easing (by strength)"), "Predefined inertial transitions, useful for motion graphics (from least to most ''dramatic'')"},
+ {BEZT_IPO_SINE, "SINE", ICON_IPO_SINE, "Sinusoidal", "Sinusoidal easing (weakest, almost linear but with a slight curvature)"},
+ {BEZT_IPO_QUAD, "QUAD", ICON_IPO_QUAD, "Quadratic", "Quadratic easing"},
+ {BEZT_IPO_CUBIC, "CUBIC", ICON_IPO_CUBIC, "Cubic", "Cubic easing"},
+ {BEZT_IPO_QUART, "QUART", ICON_IPO_QUART, "Quartic", "Quartic easing"},
+ {BEZT_IPO_QUINT, "QUINT", ICON_IPO_QUINT, "Quintic", "Quintic easing"},
+ {BEZT_IPO_EXPO, "EXPO", ICON_IPO_EXPO, "Exponential", "Exponential easing (dramatic)"},
+ {BEZT_IPO_CIRC, "CIRC", ICON_IPO_CIRC, "Circular", "Circular easing (strongest and most dynamic)"},
+
+ {0, "", 0, N_("Dynamic Effects"), "Simple physics-inspired easing effects"},
+ {BEZT_IPO_BACK, "BACK", ICON_IPO_BACK, "Back", "Cubic easing with overshoot and settle"},
+ {BEZT_IPO_BOUNCE, "BOUNCE", ICON_IPO_BOUNCE, "Bounce", "Exponentially decaying parabolic bounce, like when objects collide"},
+ {BEZT_IPO_ELASTIC, "ELASTIC", ICON_IPO_ELASTIC, "Elastic", "Exponentially decaying sine wave, like an elastic band"},
+
{0, NULL, 0, NULL, NULL}
};
@@ -92,6 +112,7 @@ static const EnumPropertyItem curve3d_fill_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifdef RNA_RUNTIME
static const EnumPropertyItem curve2d_fill_mode_items[] = {
{0, "NONE", 0, "None", ""},
{CU_BACK, "BACK", 0, "Back", ""},
@@ -99,6 +120,7 @@ static const EnumPropertyItem curve2d_fill_mode_items[] = {
{CU_FRONT | CU_BACK, "BOTH", 0, "Both", ""},
{0, NULL, 0, NULL, NULL}
};
+#endif
#ifdef RNA_RUNTIME
@@ -252,6 +274,19 @@ static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max,
*max = max_ii(0, cu->totcol - 1);
}
+/* simply offset by don't expose -1 */
+static int rna_ChariInfo_material_index_get(PointerRNA *ptr)
+{
+ CharInfo *info = ptr->data;
+ return info->mat_nr ? info->mat_nr - 1 : 0;
+}
+
+static void rna_ChariInfo_material_index_set(PointerRNA *ptr, int value)
+{
+ CharInfo *info = ptr->data;
+ info->mat_nr = value + 1;
+}
+
static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int *max,
int *UNUSED(softmin), int *UNUSED(softmax))
{
@@ -591,7 +626,7 @@ static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, PointerRNA *
Nurb *nu = nu_ptr->data;
ListBase *nurbs = BKE_curve_nurbs_get(cu);
- if (BLI_remlink_safe(nurbs, nu) == FALSE) {
+ if (BLI_remlink_safe(nurbs, nu) == false) {
BKE_reportf(reports, RPT_ERROR, "Curve '%s' does not contain spline given", cu->id.name + 2);
return;
}
@@ -1138,6 +1173,12 @@ static void rna_def_charinfo(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_CHINFO_SMALLCAPS);
RNA_def_property_ui_text(prop, "Small Caps", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+
+ prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
+ // RNA_def_property_int_sdna(prop, NULL, "mat_nr");
+ RNA_def_property_ui_text(prop, "Material Index", "");
+ RNA_def_property_int_funcs(prop, "rna_ChariInfo_material_index_get", "rna_ChariInfo_material_index_set", "rna_Curve_material_index_range");
+ RNA_def_property_update(prop, 0, "rna_Curve_update_data");
}
static void rna_def_surface(BlenderRNA *brna)
@@ -1283,7 +1324,14 @@ static void rna_def_curve(BlenderRNA *brna)
"Allow editing on the Z axis of this curve, also allows tilt and curve radius to be used"},
{0, NULL, 0, NULL, NULL}
};
-
+
+ static EnumPropertyItem bevfac_mapping_items[] = {
+ {CU_BEVFAC_MAP_RESOLU, "RESOLUTION", 0, "Resolution", "Map the bevel factor to the number of subdivisions of a spline (U resolution)"},
+ {CU_BEVFAC_MAP_SEGMENT, "SEGMENTS", 0, "Segments", "Map the bevel factor to the length of a segment and to the number of subdivisions of a segment"},
+ {CU_BEVFAC_MAP_SPLINE, "SPLINE", 0, "Spline", "Map the bevel factor to the length of a spline"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "Curve", "ID");
RNA_def_struct_ui_text(srna, "Curve", "Curve datablock storing curves, splines and NURBS");
RNA_def_struct_ui_icon(srna, ICON_CURVE_DATA);
@@ -1368,14 +1416,14 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_range(prop, 0, 64, 1, -1);
RNA_def_property_ui_text(prop, "Render Resolution U",
- "Surface resolution in U direction used while rendering (zero skips this property)");
+ "Surface resolution in U direction used while rendering (zero uses preview resolution)");
prop = RNA_def_property(srna, "render_resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv_ren");
RNA_def_property_ui_range(prop, 0, 64, 1, -1);
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Render Resolution V",
- "Surface resolution in V direction used while rendering (zero skips this property)");
+ "Surface resolution in V direction used while rendering (zero uses preview resolution)");
prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_NONE);
@@ -1426,6 +1474,18 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Twist Method", "The type of tilt calculation for 3D Curves");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+ prop = RNA_def_property(srna, "bevel_factor_mapping_start", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "bevfac1_mapping");
+ RNA_def_property_enum_items(prop, bevfac_mapping_items);
+ RNA_def_property_ui_text(prop, "Start Mapping Type", "Determines how the start bevel factor is mapped to a spline");
+ RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+
+ prop = RNA_def_property(srna, "bevel_factor_mapping_end", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "bevfac2_mapping");
+ RNA_def_property_enum_items(prop, bevfac_mapping_items);
+ RNA_def_property_ui_text(prop, "End Mapping Type", "Determines how the end bevel factor is mapped to a spline");
+ RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+
/* XXX - would be nice to have a better way to do this, only add for testing. */
prop = RNA_def_property(srna, "twist_smooth", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "twist_smooth");
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 4baca862682..6668ce812cf 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -324,7 +324,7 @@ static int rna_member_cmp(const char *name, const char *oname)
static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *membername, DNAStructMember *smember)
{
const char *dnaname;
- short *sp;
+ const short *sp;
int a, b, structnr, totmember, cmp;
structnr = DNA_struct_find_nr(sdna, structname);
@@ -382,7 +382,7 @@ static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *
return 0;
}
-static int rna_validate_identifier(const char *identifier, char *error, int property)
+static int rna_validate_identifier(const char *identifier, char *error, bool property)
{
int a = 0;
@@ -706,7 +706,7 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, FALSE) == 0) {
+ if (rna_validate_identifier(identifier, error, false) == 0) {
fprintf(stderr, "%s: struct identifier \"%s\" error - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
@@ -1000,7 +1000,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, TRUE) == 0) {
+ if (rna_validate_identifier(identifier, error, true) == 0) {
fprintf(stderr, "%s: property identifier \"%s.%s\" - %s\n", __func__,
CONTAINER_RNA_ID(cont), identifier, error);
DefRNA.error = 1;
@@ -1020,7 +1020,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
else {
#ifdef DEBUG
char error[512];
- if (rna_validate_identifier(identifier, error, TRUE) == 0) {
+ if (rna_validate_identifier(identifier, error, true) == 0) {
fprintf(stderr, "%s: runtime property identifier \"%s.%s\" - %s\n", __func__,
CONTAINER_RNA_ID(cont), identifier, error);
DefRNA.error = 1;
@@ -1068,7 +1068,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
fprop->hardmax = FLT_MAX;
if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
- fprop->softmin = 0.0f;
+ fprop->softmin = fprop->hardmin = 0.0f;
fprop->softmax = 1.0f;
}
else if (subtype == PROP_FACTOR) {
@@ -2143,7 +2143,7 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
{
- prop->update = func;
+ prop->update = (void *)func;
}
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
@@ -2990,7 +2990,7 @@ static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, FALSE) == 0) {
+ if (rna_validate_identifier(identifier, error, false) == 0) {
fprintf(stderr, "%s: function identifier \"%s\" - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index f37925a6ff5..4288bf2dddb 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -736,12 +736,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
/* whether this surface has preview data for 3D view */
- RNA_define_verify_sdna(FALSE);
+ RNA_define_verify_sdna(false);
prop = RNA_def_property(srna, "use_color_preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_DynamicPaint_use_color_preview_get", NULL);
RNA_def_property_ui_text(prop, "Use Color Preview", "Whether this surface has some color preview for 3D view");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
- RNA_define_verify_sdna(TRUE);
+ RNA_define_verify_sdna(true);
}
static void rna_def_dynamic_paint_canvas_settings(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 3f7a00d33b4..266bc1bf0a5 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include "DNA_anim_types.h"
+#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -49,23 +50,42 @@
EnumPropertyItem fmodifier_type_items[] = {
{FMODIFIER_TYPE_NULL, "NULL", 0, "Invalid", ""},
- {FMODIFIER_TYPE_GENERATOR, "GENERATOR", 0, "Generator", ""},
- {FMODIFIER_TYPE_FN_GENERATOR, "FNGENERATOR", 0, "Built-In Function", ""},
- {FMODIFIER_TYPE_ENVELOPE, "ENVELOPE", 0, "Envelope", ""},
- {FMODIFIER_TYPE_CYCLES, "CYCLES", 0, "Cycles", ""},
- {FMODIFIER_TYPE_NOISE, "NOISE", 0, "Noise", ""},
+ {FMODIFIER_TYPE_GENERATOR, "GENERATOR", 0, "Generator",
+ "Generate a curve using a factorized or expanded polynomial"},
+ {FMODIFIER_TYPE_FN_GENERATOR, "FNGENERATOR", 0, "Built-In Function",
+ "Generate a curve using standard math functions such as sin and cos"},
+ {FMODIFIER_TYPE_ENVELOPE, "ENVELOPE", 0, "Envelope",
+ "Reshape F-Curve values - e.g. change amplitude of movements"},
+ {FMODIFIER_TYPE_CYCLES, "CYCLES", 0, "Cycles",
+ "Cyclic extend/repeat keyframe sequence"},
+ {FMODIFIER_TYPE_NOISE, "NOISE", 0, "Noise",
+ "Add pseudo-random noise on top of F-Curves"},
/*{FMODIFIER_TYPE_FILTER, "FILTER", 0, "Filter", ""},*/ /* FIXME: not implemented yet! */
/*{FMODIFIER_TYPE_PYTHON, "PYTHON", 0, "Python", ""}, *//* FIXME: not implemented yet! */
- {FMODIFIER_TYPE_LIMITS, "LIMITS", 0, "Limits", ""},
- {FMODIFIER_TYPE_STEPPED, "STEPPED", 0, "Stepped Interpolation", ""},
+ {FMODIFIER_TYPE_LIMITS, "LIMITS", 0, "Limits",
+ "Restrict maximum and minimum values of F-Curve"},
+ {FMODIFIER_TYPE_STEPPED, "STEPPED", 0, "Stepped Interpolation",
+ "Snap values to nearest grid-step - e.g. for a stop-motion look"},
{0, NULL, 0, NULL, NULL}
};
EnumPropertyItem beztriple_keyframe_type_items[] = {
- {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""},
- {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""},
- {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""},
- {BEZT_KEYTYPE_JITTER, "JITTER", 0, "Jitter", ""},
+ {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", "Normal keyframe - e.g. for key poses"},
+ {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", "A breakdown pose - e.g. for transitions between key poses"},
+ {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", "An 'extreme' pose, or some other purpose as needed"},
+ {BEZT_KEYTYPE_JITTER, "JITTER", 0, "Jitter", "A filler or baked keyframe for keying on ones, or some other purpose as needed"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem beztriple_interpolation_easing_items[] = {
+ /* XXX: auto-easing is currently using a placeholder icon... */
+ {BEZT_IPO_EASE_AUTO, "AUTO", ICON_IPO_EASE_IN_OUT, "Automatic Easing",
+ "Easing type is chosen automatically based on what the type of interpolation used "
+ "(e.g. 'Ease In' for transitional types, and 'Ease Out' for dynamic effects)"},
+
+ {BEZT_IPO_EASE_IN, "EASE_IN", ICON_IPO_EASE_IN, "Ease In", "Only on the end closest to the next keyframe"},
+ {BEZT_IPO_EASE_OUT, "EASE_OUT", ICON_IPO_EASE_OUT, "Ease Out", "Only on the end closest to the first keyframe"},
+ {BEZT_IPO_EASE_IN_OUT, "EASE_IN_OUT", ICON_IPO_EASE_IN_OUT, "Ease In and Out", "Segment between both keyframes"},
{0, NULL, 0, NULL, NULL}
};
@@ -124,7 +144,11 @@ static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA
static void rna_ChannelDriver_update_expr(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ChannelDriver *driver = ptr->data;
+
+ /* tag driver as needing to be recompiled */
driver->flag |= DRIVER_FLAG_RECOMPILE;
+
+ /* update_data() clears invalid flag and schedules for updates */
rna_ChannelDriver_update_data(bmain, scene, ptr);
}
@@ -251,6 +275,26 @@ static void rna_DriverVariable_type_set(PointerRNA *ptr, int value)
driver_change_variable_type(dvar, value);
}
+/* ----------- */
+
+static DriverVar *rna_Driver_new_variable(ChannelDriver *driver)
+{
+ /* call the API function for this */
+ return driver_add_new_variable(driver);
+}
+
+static void rna_Driver_remove_variable(ChannelDriver *driver, ReportList *reports, PointerRNA *dvar_ptr)
+{
+ DriverVar *dvar = dvar_ptr->data;
+ if (BLI_findindex(&driver->variables, dvar) == -1) {
+ BKE_report(reports, RPT_ERROR, "Variable does not exist in this driver");
+ return;
+ }
+
+ driver_free_variable(driver, dvar);
+ RNA_POINTER_INVALIDATE(dvar_ptr);
+}
+
/* ****************************** */
static void rna_FKeyframe_handle1_get(PointerRNA *ptr, float *values)
@@ -402,22 +446,25 @@ static void rna_FCurve_group_set(PointerRNA *ptr, PointerRNA value)
}
}
-static DriverVar *rna_Driver_new_variable(ChannelDriver *driver)
+/* calculate time extents of F-Curve */
+static void rna_FCurve_range(FCurve *fcu, float range[2])
{
- /* call the API function for this */
- return driver_add_new_variable(driver);
+ calc_fcurve_range(fcu, range, range + 1, false, false);
}
-static void rna_Driver_remove_variable(ChannelDriver *driver, ReportList *reports, PointerRNA *dvar_ptr)
+
+/* allow scripts to update curve after editing manually */
+static void rna_FCurve_update_data_ex(FCurve *fcu)
{
- DriverVar *dvar = dvar_ptr->data;
- if (BLI_findindex(&driver->variables, dvar) == -1) {
- BKE_report(reports, RPT_ERROR, "Variable does not exist in this driver");
- return;
- }
+ sort_time_fcurve(fcu);
+ testhandles_fcurve(fcu, true);
+}
- driver_free_variable(driver, dvar);
- RNA_POINTER_INVALIDATE(dvar_ptr);
+/* RNA update callback for F-Curves after curve shape changes */
+static void rna_FCurve_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ BLI_assert(ptr->type == &RNA_FCurve);
+ rna_FCurve_update_data_ex((FCurve *)ptr->data);
}
@@ -695,7 +742,7 @@ static void rna_FModifierStepped_end_frame_range(PointerRNA *ptr, float *min, fl
static BezTriple *rna_FKeyframe_points_insert(FCurve *fcu, float frame, float value, int flag)
{
- int index = insert_vert_fcurve(fcu, frame, value, flag);
+ int index = insert_vert_fcurve(fcu, frame, value, flag | INSERTKEY_NO_USERPREF);
return ((fcu->bezt) && (index >= 0)) ? (fcu->bezt + index) : NULL;
}
@@ -703,15 +750,8 @@ static void rna_FKeyframe_points_add(FCurve *fcu, int tot)
{
if (tot > 0) {
BezTriple *bezt;
- if (fcu->totvert) {
- BezTriple *nbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + tot), "rna_FKeyframe_points_add");
- memcpy(nbezt, fcu->bezt, sizeof(BezTriple) * fcu->totvert);
- MEM_freeN(fcu->bezt);
- fcu->bezt = nbezt;
- }
- else {
- fcu->bezt = MEM_callocN(sizeof(BezTriple) * tot, "rna_FKeyframe_points_add");
- }
+
+ fcu->bezt = MEM_recallocN(fcu->bezt, sizeof(BezTriple) * (fcu->totvert + tot));
bezt = fcu->bezt + fcu->totvert;
fcu->totvert += tot;
@@ -739,12 +779,6 @@ static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, Pointe
RNA_POINTER_INVALIDATE(bezt_ptr);
}
-static void rna_fcurve_range(FCurve *fcu, float range[2])
-{
- calc_fcurve_range(fcu, range, range + 1, FALSE, FALSE);
-}
-
-
static FCM_EnvelopeData *rna_FModifierEnvelope_points_add(FModifier *fmod, ReportList *reports, float frame)
{
FCM_EnvelopeData fed;
@@ -1628,6 +1662,31 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type", "Type of keyframe (for visual purposes only)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "easing", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "easing");
+ RNA_def_property_enum_items(prop, beztriple_interpolation_easing_items);
+ RNA_def_property_ui_text(prop, "Easing",
+ "Which ends of the segment between this and the next keyframe easing "
+ "interpolation is applied to");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "back");
+ RNA_def_property_ui_text(prop, "Back", "Amount of overshoot for 'back' easing");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "amplitude");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX); /* only positive values... */
+ RNA_def_property_ui_text(prop, "Amplitude", "Amount to boost elastic bounces for 'elastic' easing");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "period");
+ RNA_def_property_ui_text(prop, "Period", "Time between bounces for elastic easing");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
/* Vector values */
prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
@@ -1746,14 +1805,17 @@ static void rna_def_fcurve(BlenderRNA *brna)
PropertyRNA *parm;
static EnumPropertyItem prop_mode_extend_items[] = {
- {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant", ""},
- {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear", ""},
+ {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant", "Hold values of endpoint keyframes"},
+ {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear", "Use slope of curve leading in/out of endpoint keyframes"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem prop_mode_color_items[] = {
- {FCURVE_COLOR_AUTO_RAINBOW, "AUTO_RAINBOW", 0, "Auto Rainbow", ""},
- {FCURVE_COLOR_AUTO_RGB, "AUTO_RGB", 0, "Auto XYZ to RGB", ""},
- {FCURVE_COLOR_CUSTOM, "CUSTOM", 0, "User Defined", ""},
+ {FCURVE_COLOR_AUTO_RAINBOW, "AUTO_RAINBOW", 0, "Auto Rainbow",
+ "Cycle through the rainbow, trying to give each curve a unique color"},
+ {FCURVE_COLOR_AUTO_RGB, "AUTO_RGB", 0, "Auto XYZ to RGB",
+ "Use axis colors for transform and color properties, and auto-rainbow for the rest"},
+ {FCURVE_COLOR_CUSTOM, "CUSTOM", 0, "User Defined",
+ "Use custom hand-picked color for F-Curve"},
{0, NULL, 0, NULL, NULL}
};
@@ -1765,9 +1827,9 @@ static void rna_def_fcurve(BlenderRNA *brna)
prop = RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extend");
RNA_def_property_enum_items(prop, prop_mode_extend_items);
- RNA_def_property_ui_text(prop, "Extrapolation", "");
- /* XXX need an update callback for this so that animation gets evaluated */
- RNA_def_property_update(prop, NC_ANIMATION, NULL);
+ RNA_def_property_ui_text(prop, "Extrapolation",
+ "Method used for evaluating value of F-Curve outside first and last keyframes");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FCurve_update_data");
/* Pointers */
prop = RNA_def_property(srna, "driver", PROP_POINTER, PROP_NONE);
@@ -1855,23 +1917,30 @@ static void rna_def_fcurve(BlenderRNA *brna)
rna_def_fcurve_modifiers(brna, prop);
/* Functions */
+ /* -- evaluate -- */
func = RNA_def_function(srna, "evaluate", "evaluate_fcurve"); /* calls the C/API direct */
RNA_def_function_ui_description(func, "Evaluate F-Curve");
parm = RNA_def_float(func, "frame", 1.0f, -FLT_MAX, FLT_MAX, "Frame",
"Evaluate F-Curve at given frame", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return value */
- parm = RNA_def_float(func, "position", 0, -FLT_MAX, FLT_MAX, "Position", "F-Curve position", -FLT_MAX, FLT_MAX);
+ parm = RNA_def_float(func, "value", 0, -FLT_MAX, FLT_MAX, "Value", "Value of F-Curve specific frame", -FLT_MAX, FLT_MAX);
RNA_def_function_return(func, parm);
-
- func = RNA_def_function(srna, "range", "rna_fcurve_range");
+
+ /* -- update / recalculate -- */
+ func = RNA_def_function(srna, "update", "rna_FCurve_update_data_ex");
+ RNA_def_function_ui_description(func, "Ensure keyframes are sorted in chronological order and handles are set correctly");
+
+ /* -- time extents/range -- */
+ func = RNA_def_function(srna, "range", "rna_FCurve_range");
RNA_def_function_ui_description(func, "Get the time extents for F-Curve");
/* return value */
parm = RNA_def_float_vector(func, "range", 2, NULL, -FLT_MAX, FLT_MAX, "Range",
"Min/Max values", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(parm, PROP_THICK_WRAP);
RNA_def_function_output(func, parm);
-
+
+ /* -- auto-flag validity (ensures valid handling for data type) -- */
func = RNA_def_function(srna, "update_autoflags", "update_autoflags_fcurve"); /* calls the C/API direct */
RNA_def_function_ui_description(func, "Update FCurve flags set automatically from affected property "
"(currently, integer/discrete flags set when the property is not a float)");
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 0706d974562..2f9c12c713b 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -47,7 +47,7 @@
static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
/* we are actually iterating a GroupObject list, so override get */
return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((GroupObject *)internal->link)->ob);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 99f427a9ab6..0b129bab524 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -388,7 +388,7 @@ static int rna_Image_is_float_get(PointerRNA *ptr)
Image *im = (Image *)ptr->data;
ImBuf *ibuf;
void *lock;
- int is_float = FALSE;
+ bool is_float = false;
ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
if (ibuf)
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index b81913ddc02..51d541c5af9 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -37,6 +37,7 @@
#include "DNA_packedFile_types.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "GPU_glew.h"
@@ -285,6 +286,11 @@ static void rna_Image_gl_free(Image *image)
image->flag &= ~IMA_NOCOLLECT;
}
+static void rna_Image_filepath_from_user(Image *image, ImageUser *image_user, char *filepath)
+{
+ BKE_image_user_file_path(image_user, image, filepath);
+}
+
#else
void RNA_api_image(StructRNA *srna)
@@ -358,6 +364,15 @@ void RNA_api_image(StructRNA *srna)
func = RNA_def_function(srna, "gl_free", "rna_Image_gl_free");
RNA_def_function_ui_description(func, "Free the image from OpenGL graphics memory");
+ /* path to an frame specified by image user */
+ func = RNA_def_function(srna, "filepath_from_user", "rna_Image_filepath_from_user");
+ RNA_def_function_ui_description(func, "Return the absolute path to the filepath of an image frame specified by the image user");
+ RNA_def_pointer(func, "image_user", "ImageUser", "", "Image user of the image to get filepath for");
+ parm = RNA_def_string_file_path(func, "filepath", NULL, FILE_MAX, "File Path",
+ "The resulting filepath from the image and it's user");
+ RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */
+ RNA_def_function_output(func, parm);
+
/* TODO, pack/unpack, maybe should be generic functions? */
}
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index d75ee256cb1..ecfb7f5e5f5 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -355,35 +355,12 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
/* Iterators */
-typedef int (*IteratorSkipFunc)(struct CollectionPropertyIterator *iter, void *data);
-
-typedef struct ListBaseIterator {
- Link *link;
- int flag;
- IteratorSkipFunc skip;
-} ListBaseIterator;
-
void rna_iterator_listbase_begin(struct CollectionPropertyIterator *iter, struct ListBase *lb, IteratorSkipFunc skip);
void rna_iterator_listbase_next(struct CollectionPropertyIterator *iter);
void *rna_iterator_listbase_get(struct CollectionPropertyIterator *iter);
void rna_iterator_listbase_end(struct CollectionPropertyIterator *iter);
PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct ListBase *lb, int index);
-typedef struct ArrayIterator {
- char *ptr;
- char *endptr; /* past the last valid pointer, only for comparisons, ignores skipped values */
- void *free_ptr; /* will be freed if set */
- int itemsize;
-
- /* array length with no skip functions applied, take care not to compare against index from animsys
- * or python indices */
- int length;
-
- /* optional skip function, when set the array as viewed by rna can contain only a subset of the members.
- * this changes indices so quick array index lookups are not possible when skip function is used. */
- IteratorSkipFunc skip;
-} ArrayIterator;
-
void rna_iterator_array_begin(struct CollectionPropertyIterator *iter, void *ptr, int itemsize, int length,
bool free_ptr, IteratorSkipFunc skip);
void rna_iterator_array_next(struct CollectionPropertyIterator *iter);
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index e03a3352bac..2b20dc2485d 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -84,6 +84,8 @@ EnumPropertyItem linestyle_geometry_modifier_type_items[] = {
#ifdef RNA_RUNTIME
#include "BKE_linestyle.h"
+#include "BKE_texture.h"
+#include "BKE_depsgraph.h"
static StructRNA *rna_LineStyle_color_modifier_refine(struct PointerRNA *ptr)
{
@@ -249,10 +251,148 @@ static void rna_LineStyleGeometryModifier_name_set(PointerRNA *ptr, const char *
offsetof(LineStyleModifier, name), sizeof(m->name));
}
+static void rna_LineStyle_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+ rna_iterator_array_begin(iter, (void *)linestyle->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL);
+}
+
+static PointerRNA rna_LineStyle_active_texture_get(PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+ Tex *tex;
+
+ tex = give_current_linestyle_texture(linestyle);
+ return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex);
+}
+
+static void rna_LineStyle_active_texture_set(PointerRNA *ptr, PointerRNA value)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ptr->id.data;
+
+ set_current_linestyle_texture(linestyle, value.data);
+}
+
+static void rna_LineStyle_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ FreestyleLineStyle *linestyle = ptr->id.data;
+
+ DAG_id_tag_update(&linestyle->id, 0);
+ WM_main_add_notifier(NC_LINESTYLE, linestyle);
+}
+
#else
#include "BLI_math.h"
+static void rna_def_linestyle_mtex(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem texco_items[] = {
+ {TEXCO_WINDOW, "WINDOW", 0, "Window", "Use screen coordinates as texture coordinates"},
+ {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates"},
+ {TEXCO_STROKE, "ALONG_STROKE", 0, "Along stroke", "Use stroke lenght for texture coordinates"},
+ {TEXCO_ORCO, "ORCO", 0, "Generated", "Use the original undeformed coordinates of the object"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_mapping_items[] = {
+ {MTEX_FLAT, "FLAT", 0, "Flat", "Map X and Y coordinates directly"},
+ {MTEX_CUBE, "CUBE", 0, "Cube", "Map using the normal vector"},
+ {MTEX_TUBE, "TUBE", 0, "Tube", "Map with Z as central axis"},
+ {MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_x_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_y_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_z_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "LineStyleTextureSlot", "TextureSlot");
+ RNA_def_struct_sdna(srna, "MTex");
+ RNA_def_struct_ui_text(srna, "LineStyle Texture Slot", "Texture slot for textures in a LineStyle datablock");
+
+ prop = RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projx");
+ RNA_def_property_enum_items(prop, prop_x_mapping_items);
+ RNA_def_property_ui_text(prop, "X Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projy");
+ RNA_def_property_enum_items(prop, prop_y_mapping_items);
+ RNA_def_property_ui_text(prop, "Y Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projz");
+ RNA_def_property_enum_items(prop, prop_z_mapping_items);
+ RNA_def_property_ui_text(prop, "Z Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_mapping_items);
+ RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ /* map to */
+ prop = RNA_def_property(srna, "use_map_color_diffuse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COL);
+ RNA_def_property_ui_text(prop, "Diffuse Color", "The texture affects basic color of the stroke");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "use_map_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ALPHA);
+ RNA_def_property_ui_text(prop, "Alpha", "The texture affects the alpha value");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "use_tips", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_TIPS);
+ RNA_def_property_ui_text(prop, "Use tips", "Lower half of the texture is for tips of the stroke");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "texco");
+ RNA_def_property_enum_items(prop, texco_items);
+ RNA_def_property_ui_text(prop, "Texture Coordinates",
+ "Texture coordinates used to map the texture onto the background");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "alpha_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "alphafac");
+ RNA_def_property_ui_range(prop, -1, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Alpha Factor", "Amount texture affects alpha");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "diffuse_color_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "colfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Diffuse Color Factor", "Amount texture affects diffuse color");
+ RNA_def_property_update(prop, 0, "rna_LineStyle_update");
+}
+
static void rna_def_modifier_type_common(StructRNA *srna, EnumPropertyItem *modifier_type_items,
const char *set_name_func, const bool blend, const bool color)
{
@@ -310,25 +450,25 @@ static void rna_def_modifier_type_common(StructRNA *srna, EnumPropertyItem *modi
static void rna_def_color_modifier(StructRNA *srna)
{
rna_def_modifier_type_common(srna, linestyle_color_modifier_type_items,
- "rna_LineStyleColorModifier_name_set", TRUE, TRUE);
+ "rna_LineStyleColorModifier_name_set", true, true);
}
static void rna_def_alpha_modifier(StructRNA *srna)
{
rna_def_modifier_type_common(srna, linestyle_alpha_modifier_type_items,
- "rna_LineStyleAlphaModifier_name_set", TRUE, FALSE);
+ "rna_LineStyleAlphaModifier_name_set", true, false);
}
static void rna_def_thickness_modifier(StructRNA *srna)
{
rna_def_modifier_type_common(srna, linestyle_thickness_modifier_type_items,
- "rna_LineStyleThicknessModifier_name_set", TRUE, FALSE);
+ "rna_LineStyleThicknessModifier_name_set", true, false);
}
static void rna_def_geometry_modifier(StructRNA *srna)
{
rna_def_modifier_type_common(srna, linestyle_geometry_modifier_type_items,
- "rna_LineStyleGeometryModifier_name_set", FALSE, FALSE);
+ "rna_LineStyleGeometryModifier_name_set", false, false);
}
static void rna_def_modifier_color_ramp_common(StructRNA *srna, int range)
@@ -354,7 +494,7 @@ static void rna_def_modifier_color_ramp_common(StructRNA *srna, int range)
}
}
-static void rna_def_modifier_curve_common(StructRNA *srna, int range, int value)
+static void rna_def_modifier_curve_common(StructRNA *srna, bool range, bool value)
{
PropertyRNA *prop;
@@ -467,17 +607,17 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LineStyleColorModifier_AlongStroke", "LineStyleColorModifier");
RNA_def_struct_ui_text(srna, "Along Stroke", "Change line color along stroke");
rna_def_color_modifier(srna);
- rna_def_modifier_color_ramp_common(srna, FALSE);
+ rna_def_modifier_color_ramp_common(srna, false);
srna = RNA_def_struct(brna, "LineStyleColorModifier_DistanceFromCamera", "LineStyleColorModifier");
RNA_def_struct_ui_text(srna, "Distance from Camera", "Change line color based on the distance from the camera");
rna_def_color_modifier(srna);
- rna_def_modifier_color_ramp_common(srna, TRUE);
+ rna_def_modifier_color_ramp_common(srna, true);
srna = RNA_def_struct(brna, "LineStyleColorModifier_DistanceFromObject", "LineStyleColorModifier");
RNA_def_struct_ui_text(srna, "Distance from Object", "Change line color based on the distance from an object");
rna_def_color_modifier(srna);
- rna_def_modifier_color_ramp_common(srna, TRUE);
+ rna_def_modifier_color_ramp_common(srna, true);
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target");
@@ -490,7 +630,7 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Material", "Change line color based on a material attribute");
rna_def_color_modifier(srna);
rna_def_modifier_material_common(srna);
- rna_def_modifier_color_ramp_common(srna, FALSE);
+ rna_def_modifier_color_ramp_common(srna, false);
prop = RNA_def_property(srna, "use_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", LS_MODIFIER_USE_RAMP);
@@ -508,19 +648,19 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LineStyleAlphaModifier_AlongStroke", "LineStyleAlphaModifier");
RNA_def_struct_ui_text(srna, "Along Stroke", "Change alpha transparency along stroke");
rna_def_alpha_modifier(srna);
- rna_def_modifier_curve_common(srna, FALSE, FALSE);
+ rna_def_modifier_curve_common(srna, false, false);
srna = RNA_def_struct(brna, "LineStyleAlphaModifier_DistanceFromCamera", "LineStyleAlphaModifier");
RNA_def_struct_ui_text(srna, "Distance from Camera",
"Change alpha transparency based on the distance from the camera");
rna_def_alpha_modifier(srna);
- rna_def_modifier_curve_common(srna, TRUE, FALSE);
+ rna_def_modifier_curve_common(srna, true, false);
srna = RNA_def_struct(brna, "LineStyleAlphaModifier_DistanceFromObject", "LineStyleAlphaModifier");
RNA_def_struct_ui_text(srna, "Distance from Object",
"Change alpha transparency based on the distance from an object");
rna_def_alpha_modifier(srna);
- rna_def_modifier_curve_common(srna, TRUE, FALSE);
+ rna_def_modifier_curve_common(srna, true, false);
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target");
@@ -533,7 +673,7 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Material", "Change alpha transparency based on a material attribute");
rna_def_alpha_modifier(srna);
rna_def_modifier_material_common(srna);
- rna_def_modifier_curve_common(srna, FALSE, FALSE);
+ rna_def_modifier_curve_common(srna, false, false);
/* line thickness modifiers */
@@ -546,17 +686,17 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LineStyleThicknessModifier_AlongStroke", "LineStyleThicknessModifier");
RNA_def_struct_ui_text(srna, "Along Stroke", "Change line thickness along stroke");
rna_def_thickness_modifier(srna);
- rna_def_modifier_curve_common(srna, FALSE, TRUE);
+ rna_def_modifier_curve_common(srna, false, true);
srna = RNA_def_struct(brna, "LineStyleThicknessModifier_DistanceFromCamera", "LineStyleThicknessModifier");
RNA_def_struct_ui_text(srna, "Distance from Camera", "Change line thickness based on the distance from the camera");
rna_def_thickness_modifier(srna);
- rna_def_modifier_curve_common(srna, TRUE, TRUE);
+ rna_def_modifier_curve_common(srna, true, true);
srna = RNA_def_struct(brna, "LineStyleThicknessModifier_DistanceFromObject", "LineStyleThicknessModifier");
RNA_def_struct_ui_text(srna, "Distance from Object", "Change line thickness based on the distance from an object");
rna_def_thickness_modifier(srna);
- rna_def_modifier_curve_common(srna, TRUE, TRUE);
+ rna_def_modifier_curve_common(srna, true, true);
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target");
@@ -569,7 +709,7 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Material", "Change line thickness based on a material attribute");
rna_def_thickness_modifier(srna);
rna_def_modifier_material_common(srna);
- rna_def_modifier_curve_common(srna, FALSE, TRUE);
+ rna_def_modifier_curve_common(srna, false, true);
srna = RNA_def_struct(brna, "LineStyleThicknessModifier_Calligraphy", "LineStyleThicknessModifier");
RNA_def_struct_ui_text(srna, "Calligraphy",
@@ -892,6 +1032,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
{LS_PANEL_ALPHA, "ALPHA", 0, "Alpha", "Show the panel for alpha transparency options"},
{LS_PANEL_THICKNESS, "THICKNESS", 0, "Thickness", "Show the panel for line thickness options"},
{LS_PANEL_GEOMETRY, "GEOMETRY", 0, "Geometry", "Show the panel for stroke geometry options"},
+ {LS_PANEL_TEXTURE, "TEXTURE", 0, "Texture", "Show the panel for stroke texture options"},
#if 0 /* hidden for now */
{LS_PANEL_MISC, "MISC", 0, "Misc", "Show the panel for miscellaneous options"},
#endif
@@ -909,16 +1050,37 @@ static void rna_def_linestyle(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem thickness_position_items[] = {
- {LS_THICKNESS_CENTER, "CENTER", 0, "Center", "Stroke is centered along stroke geometry"},
- {LS_THICKNESS_INSIDE, "INSIDE", 0, "Inside", "Stroke is drawn inside stroke geometry"},
- {LS_THICKNESS_OUTSIDE, "OUTSIDE", 0, "Outside", "Stroke is drawn outside stroke geometry"},
- {LS_THICKNESS_RELATIVE, "RELATIVE", 0, "Relative", "Stroke thickness is split by a user-defined ratio"},
+ {LS_THICKNESS_CENTER, "CENTER", 0, "Center", "Silhouettes and border edges are centered along stroke geometry"},
+ {LS_THICKNESS_INSIDE, "INSIDE", 0, "Inside", "Silhouettes and border edges are drawn inside of stroke geometry"},
+ {LS_THICKNESS_OUTSIDE, "OUTSIDE", 0, "Outside", "Silhouettes and border edges are drawn outside of stroke geometry"},
+ {LS_THICKNESS_RELATIVE, "RELATIVE", 0, "Relative", "Silhouettes and border edges are shifted by a user-defined ratio"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ 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)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem sort_order_items[] = {
+ {0, "DEFAULT", 0, "Default", "Default order of the sort key"},
+ {LS_REVERSE_ORDER, "REVERSE", 0, "Reverse", "Reverse order"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem integration_type_items[] = {
+ {LS_INTEGRATION_MEAN, "MEAN", 0, "Mean", "The value computed for the chain is the mean of the values obtained for chain vertices"},
+ {LS_INTEGRATION_MIN, "MIN", 0, "Min", "The value computed for the chain is the minimum of the values obtained for chain vertices"},
+ {LS_INTEGRATION_MAX, "MAX", 0, "Max", "The value computed for the chain is the maximum of the values obtained for chain vertices"},
+ {LS_INTEGRATION_FIRST, "FIRST", 0, "First", "The value computed for the chain is the value obtained for the first chain vertex"},
+ {LS_INTEGRATION_LAST, "LAST", 0, "Last", "The value computed for the chain is the value obtained for the last chain vertex"},
{0, NULL, 0, NULL, NULL}
};
srna = RNA_def_struct(brna, "FreestyleLineStyle", "ID");
RNA_def_struct_ui_text(srna, "Freestyle Line Style", "Freestyle line style, reusable by multiple line sets");
- RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); /* FIXME: use a proper icon */
+ RNA_def_struct_ui_icon(srna, ICON_LINE_DATA);
+
+ rna_def_mtex_common(brna, srna, "rna_LineStyle_mtex_begin", "rna_LineStyle_active_texture_get",
+ "rna_LineStyle_active_texture_set", NULL, "LineStyleTextureSlot", "LineStyleTextureSlots", "rna_LineStyle_update");
prop = RNA_def_property(srna, "panel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "panel");
@@ -935,7 +1097,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "alpha");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Alpha",
+ RNA_def_property_ui_text(prop, "Alpha Transparency",
"Base alpha transparency, possibly modified by alpha transparency modifiers");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
@@ -948,7 +1110,8 @@ static void rna_def_linestyle(BlenderRNA *brna)
prop = RNA_def_property(srna, "thickness_position", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "thickness_position");
RNA_def_property_enum_items(prop, thickness_position_items);
- RNA_def_property_ui_text(prop, "Thickness Position", "Select the position of stroke thickness");
+ RNA_def_property_ui_text(prop, "Thickness Position",
+ "Thickness position of silhouettes and border edges (applicable when plain chaining is used with the Same Object option)");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
prop = RNA_def_property(srna, "thickness_ratio", PROP_FLOAT, PROP_FACTOR);
@@ -982,7 +1145,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
prop = RNA_def_property(srna, "chaining", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "chaining");
RNA_def_property_enum_items(prop, chaining_items);
- RNA_def_property_ui_text(prop, "Chaining", "Select the way how feature edges are jointed to form chains");
+ RNA_def_property_ui_text(prop, "Chaining Method", "Select the way how feature edges are jointed to form chains");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
prop = RNA_def_property(srna, "rounds", PROP_INT, PROP_UNSIGNED);
@@ -1104,6 +1267,29 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Material Boundary", "If true, chains of feature edges are split at material boundaries");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+ prop = RNA_def_property(srna, "use_sorting", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", LS_NO_SORTING);
+ RNA_def_property_ui_text(prop, "Sorting", "Arrange the stacking order of strokes");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "sort_key", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "sort_key");
+ RNA_def_property_enum_items(prop, sort_key_items);
+ RNA_def_property_ui_text(prop, "Sort Key", "Select the sort key to determine the stacking order of chains");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "sort_order", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, sort_order_items);
+ RNA_def_property_ui_text(prop, "Sort Order", "Select the sort order");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "integration_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "integration_type");
+ RNA_def_property_enum_items(prop, integration_type_items);
+ RNA_def_property_ui_text(prop, "Integration Type", "Select the way how the sort key is computed for each chain");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
prop = RNA_def_property(srna, "use_dashed_line", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_DASHED_LINE);
RNA_def_property_ui_text(prop, "Dashed Line", "Enable or disable dashed line");
@@ -1112,7 +1298,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
prop = RNA_def_property(srna, "caps", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "caps");
RNA_def_property_enum_items(prop, cap_items);
- RNA_def_property_ui_text(prop, "Cap", "Select the shape of both ends of strokes");
+ RNA_def_property_ui_text(prop, "Caps", "Select the shape of both ends of strokes");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
prop = RNA_def_property(srna, "dash1", PROP_INT, PROP_UNSIGNED);
@@ -1150,12 +1336,36 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_property_range(prop, 0, USHRT_MAX);
RNA_def_property_ui_text(prop, "Gap 3", "Length of the 3rd gap for dashed lines");
RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_TEXTURE);
+ RNA_def_property_ui_text(prop, "Use Textures", "Enable or disable textured strokes");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ prop = RNA_def_property(srna, "texture_spacing", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "texstep");
+ RNA_def_property_range(prop, 0.01f, 100.0f);
+ RNA_def_property_ui_text(prop, "Texture spacing", "Spacing for textures along stroke lenght");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
+
+ /* nodes */
+ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
+ RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based textures");
+
+ prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_ui_text(prop, "Use Nodes", "Use texture nodes for the line style");
+ RNA_def_property_update(prop, NC_LINESTYLE, NULL);
}
void RNA_def_linestyle(BlenderRNA *brna)
{
rna_def_linestyle_modifiers(brna);
rna_def_linestyle(brna);
+ rna_def_linestyle_mtex(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index b7b793ebeaf..f163808c61b 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -72,7 +72,7 @@ static int rna_Main_is_dirty_get(PointerRNA *ptr)
return !wm->file_saved;
}
- return TRUE;
+ return true;
}
static void rna_Main_filepath_get(PointerRNA *ptr, char *value)
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 5d0d7bf20df..bac1f132126 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -104,6 +104,10 @@
#include "BLF_translation.h"
+#ifdef WITH_PYTHON
+# include "BPY_extern.h"
+#endif
+
static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
{
ID *id = BKE_camera_add(bmain, name);
@@ -138,7 +142,17 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
{
bScreen *sc = CTX_wm_screen(C);
if (sc->scene == scene) {
+
+#ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+#endif
+
ED_screen_set_scene(C, sc, scene_new);
+
+#ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+#endif
+
}
BKE_scene_unlink(bmain, scene, scene_new);
@@ -278,215 +292,19 @@ Mesh *rna_Main_meshes_new_from_object(
Main *bmain, ReportList *reports, Scene *sce,
Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
{
- Mesh *tmpmesh;
- Curve *tmpcu = NULL, *copycu;
- Object *tmpobj = NULL;
- int render = settings == eModifierMode_Render, i;
- int cage = !apply_modifiers;
-
- /* perform the mesh extraction based on type */
switch (ob->type) {
case OB_FONT:
case OB_CURVE:
case OB_SURF:
- {
- ListBase dispbase = {NULL, NULL};
- DerivedMesh *derivedFinal = NULL;
- int uv_from_orco;
-
- /* copies object and modifiers (but not the data) */
- tmpobj = BKE_object_copy_ex(bmain, ob, TRUE);
- tmpcu = (Curve *)tmpobj->data;
- tmpcu->id.us--;
-
- /* if getting the original caged mesh, delete object modifiers */
- if (cage)
- BKE_object_free_modifiers(tmpobj);
-
- /* copies the data */
- copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
-
- /* temporarily set edit so we get updates from edit mode, but
- * also because for text datablocks copying it while in edit
- * mode gives invalid data structures */
- copycu->editfont = tmpcu->editfont;
- copycu->editnurb = tmpcu->editnurb;
-
- /* get updated display list, and convert to a mesh */
- BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE, render);
-
- copycu->editfont = NULL;
- copycu->editnurb = NULL;
-
- tmpobj->derivedFinal = derivedFinal;
-
- /* convert object type to mesh */
- uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
- BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
-
- tmpmesh = tmpobj->data;
-
- BKE_displist_free(&dispbase);
-
- /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked.
- * if it didn't the curve did not have any segments or otherwise
- * would have generated an empty mesh */
- if (tmpobj->type != OB_MESH) {
- BKE_libblock_free_us(G.main, tmpobj);
- return NULL;
- }
-
- BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
-
- BKE_libblock_free_us(bmain, tmpobj);
- break;
- }
-
case OB_MBALL:
- {
- /* metaballs don't have modifiers, so just convert to mesh */
- Object *basis_ob = BKE_mball_basis_find(sce, ob);
- /* todo, re-generatre for render-res */
- /* metaball_polygonize(scene, ob) */
-
- if (ob != basis_ob)
- return NULL; /* only do basis metaball */
-
- tmpmesh = BKE_mesh_add(bmain, "Mesh");
- /* BKE_mesh_add gives us a user count we don't need */
- tmpmesh->id.us--;
-
- if (render) {
- ListBase disp = {NULL, NULL};
- /* TODO(sergey): This is gonna to work for until EvaluationContext
- * only contains for_render flag. As soon as CoW is
- * implemented, this is to be rethinked.
- */
- EvaluationContext eval_ctx = {0};
- eval_ctx.for_render = render;
- BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp);
- BKE_mesh_from_metaball(&disp, tmpmesh);
- BKE_displist_free(&disp);
- }
- else {
- ListBase disp = {NULL, NULL};
- if (ob->curve_cache) {
- disp = ob->curve_cache->disp;
- }
- BKE_mesh_from_metaball(&disp, tmpmesh);
- }
-
- BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
-
- break;
-
- }
case OB_MESH:
- /* copies object and modifiers (but not the data) */
- if (cage) {
- /* copies the data */
- tmpmesh = BKE_mesh_copy_ex(bmain, ob->data);
- /* if not getting the original caged mesh, get final derived mesh */
- }
- else {
- /* Make a dummy mesh, saves copying */
- DerivedMesh *dm;
- /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
- CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
- * for example, needs CD_MASK_MDEFORMVERT */
-
- if (calc_undeformed)
- mask |= CD_MASK_ORCO;
-
- /* Write the display mesh into the dummy mesh */
- if (render)
- dm = mesh_create_derived_render(sce, ob, mask);
- else
- dm = mesh_create_derived_view(sce, ob, mask);
-
- tmpmesh = BKE_mesh_add(bmain, "Mesh");
- DM_to_mesh(dm, tmpmesh, ob, mask);
- dm->release(dm);
- }
-
- /* BKE_mesh_add/copy gives us a user count we don't need */
- tmpmesh->id.us--;
-
break;
default:
BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
return NULL;
}
- /* Copy materials to new mesh */
- switch (ob->type) {
- case OB_SURF:
- case OB_FONT:
- case OB_CURVE:
- tmpmesh->totcol = tmpcu->totcol;
-
- /* free old material list (if it exists) and adjust user counts */
- if (tmpcu->mat) {
- for (i = tmpcu->totcol; i-- > 0; ) {
- /* are we an object material or data based? */
-
- tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
-
- if (tmpmesh->mat[i]) {
- tmpmesh->mat[i]->id.us++;
- }
- }
- }
- break;
-
-#if 0
- /* Crashes when assigning the new material, not sure why */
- case OB_MBALL:
- tmpmb = (MetaBall *)ob->data;
- tmpmesh->totcol = tmpmb->totcol;
-
- /* free old material list (if it exists) and adjust user counts */
- if (tmpmb->mat) {
- for (i = tmpmb->totcol; i-- > 0; ) {
- tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
- if (tmpmesh->mat[i]) {
- tmpmb->mat[i]->id.us++;
- }
- }
- }
- break;
-#endif
-
- case OB_MESH:
- if (!cage) {
- Mesh *origmesh = ob->data;
- tmpmesh->flag = origmesh->flag;
- tmpmesh->mat = MEM_dupallocN(origmesh->mat);
- tmpmesh->totcol = origmesh->totcol;
- tmpmesh->smoothresh = origmesh->smoothresh;
- if (origmesh->mat) {
- for (i = origmesh->totcol; i-- > 0; ) {
- /* are we an object material or data based? */
- tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
-
- if (tmpmesh->mat[i]) {
- tmpmesh->mat[i]->id.us++;
- }
- }
- }
- }
- break;
- } /* end copy materials */
-
- if (calc_tessface) {
- /* cycles and exporters rely on this still */
- BKE_mesh_tessface_ensure(tmpmesh);
- }
-
- /* make sure materials get updated in objects */
- test_object_materials(bmain, &tmpmesh->id);
-
- return tmpmesh;
+ return BKE_mesh_new_from_object(bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed);
}
static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
@@ -942,6 +760,7 @@ static int rna_Main_armatures_is_updated_get(PointerRNA *ptr) { return DAG_id_ty
static int rna_Main_actions_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AC); }
static int rna_Main_particles_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_PA); }
static int rna_Main_gpencil_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GD); }
+static int rna_Main_linestyle_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LS); }
#else
@@ -1964,6 +1783,7 @@ void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
+ PropertyRNA *prop;
RNA_def_property_srna(cprop, "BlendDataLineStyles");
srna = RNA_def_struct(brna, "BlendDataLineStyles", NULL);
@@ -1987,6 +1807,10 @@ void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Remove a line style instance from the current blendfile");
parm = RNA_def_pointer(func, "linestyle", "FreestyleLineStyle", "", "Line style to remove");
RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Main_linestyle_is_updated_get", NULL);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index 31e6b0e48e2..afd149a755a 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -312,12 +312,83 @@ static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr)
return bezt->h1;
}
+static MaskSpline *mask_spline_from_point(Mask *mask, MaskSplinePoint *point)
+{
+ MaskLayer *mask_layer;
+ for (mask_layer = mask->masklayers.first;
+ mask_layer;
+ mask_layer = mask_layer->next)
+ {
+ MaskSpline *spline;
+ for (spline = mask_layer->splines.first;
+ spline;
+ spline = spline->next)
+ {
+ if (point >= spline->points && point < spline->points + spline->tot_point) {
+ return spline;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void mask_point_check_stick(MaskSplinePoint *point)
+{
+ BezTriple *bezt = &point->bezt;
+ if (bezt->h1 == HD_ALIGN && bezt->h2 == HD_ALIGN) {
+ float vec[3];
+ sub_v3_v3v3(vec, bezt->vec[0], bezt->vec[1]);
+ add_v3_v3v3(bezt->vec[2], bezt->vec[1], vec);
+ }
+}
+
static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value)
{
MaskSplinePoint *point = (MaskSplinePoint *) ptr->data;
BezTriple *bezt = &point->bezt;
+ MaskSpline *spline = mask_spline_from_point((Mask *) ptr->id.data, point);
bezt->h1 = bezt->h2 = value;
+ mask_point_check_stick(point);
+ BKE_mask_calc_handle_point(spline, point);
+}
+
+static int rna_MaskSplinePoint_handle_left_type_get(PointerRNA *ptr)
+{
+ MaskSplinePoint *point = (MaskSplinePoint *) ptr->data;
+ BezTriple *bezt = &point->bezt;
+
+ return bezt->h1;
+}
+
+static void rna_MaskSplinePoint_handle_left_type_set(PointerRNA *ptr, int value)
+{
+ MaskSplinePoint *point = (MaskSplinePoint *) ptr->data;
+ BezTriple *bezt = &point->bezt;
+ MaskSpline *spline = mask_spline_from_point((Mask *) ptr->id.data, point);
+
+ bezt->h1 = value;
+ mask_point_check_stick(point);
+ BKE_mask_calc_handle_point(spline, point);
+}
+
+static int rna_MaskSplinePoint_handle_right_type_get(PointerRNA *ptr)
+{
+ MaskSplinePoint *point = (MaskSplinePoint *) ptr->data;
+ BezTriple *bezt = &point->bezt;
+
+ return bezt->h2;
+}
+
+static void rna_MaskSplinePoint_handle_right_type_set(PointerRNA *ptr, int value)
+{
+ MaskSplinePoint *point = (MaskSplinePoint *) ptr->data;
+ BezTriple *bezt = &point->bezt;
+ MaskSpline *spline = mask_spline_from_point((Mask *) ptr->id.data, point);
+
+ bezt->h2 = value;
+ mask_point_check_stick(point);
+ BKE_mask_calc_handle_point(spline, point);
}
/* ** API ** */
@@ -369,7 +440,7 @@ static void rna_MaskLayer_spline_remove(ID *id, MaskLayer *mask_layer, ReportLis
Mask *mask = (Mask *) id;
MaskSpline *spline = spline_ptr->data;
- if (BKE_mask_spline_remove(mask_layer, spline) == FALSE) {
+ if (BKE_mask_spline_remove(mask_layer, spline) == false) {
BKE_reportf(reports, RPT_ERROR, "Mask layer '%s' does not contain spline given", mask_layer->name);
return;
}
@@ -442,7 +513,7 @@ static void rna_MaskSpline_points_add(ID *id, MaskSpline *spline, int count)
int point_index = spline->tot_point - count + i;
MaskSplinePoint *new_point = spline->points + point_index;
new_point->bezt.h1 = new_point->bezt.h2 = HD_ALIGN;
- BKE_mask_calc_handle_point_auto(spline, new_point, TRUE);
+ BKE_mask_calc_handle_point_auto(spline, new_point, true);
BKE_mask_parent_init(&new_point->parent);
/* Not efficient, but there's no other way for now */
@@ -608,7 +679,9 @@ static void rna_def_maskSplinePoint(BlenderRNA *brna)
static EnumPropertyItem handle_type_items[] = {
{HD_AUTO, "AUTO", 0, "Auto", ""},
{HD_VECT, "VECTOR", 0, "Vector", ""},
- {HD_ALIGN, "ALIGNED", 0, "Aligned", ""},
+ {HD_ALIGN, "ALIGNED", 0, "Aligned Single", ""},
+ {HD_ALIGN_DOUBLESIDE, "ALIGNED_DOUBLESIDE", 0, "Aligned", ""},
+ {HD_FREE, "FREE", 0, "Free", ""},
{0, NULL, 0, NULL, NULL}};
rna_def_maskSplinePointUW(brna);
@@ -642,6 +715,27 @@ static void rna_def_maskSplinePoint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Handle Type", "Handle type");
RNA_def_property_update(prop, 0, "rna_Mask_update_data");
+ /* handle_type */
+ prop = RNA_def_property(srna, "handle_left_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, "rna_MaskSplinePoint_handle_left_type_get", "rna_MaskSplinePoint_handle_left_type_set", NULL);
+ RNA_def_property_enum_items(prop, handle_type_items);
+ RNA_def_property_ui_text(prop, "Handle 1 Type", "Handle type");
+ RNA_def_property_update(prop, 0, "rna_Mask_update_data");
+
+ /* handle_right */
+ prop = RNA_def_property(srna, "handle_right_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, "rna_MaskSplinePoint_handle_right_type_get", "rna_MaskSplinePoint_handle_right_type_set", NULL);
+ RNA_def_property_enum_items(prop, handle_type_items);
+ RNA_def_property_ui_text(prop, "Handle 2 Type", "Handle type");
+ RNA_def_property_update(prop, 0, "rna_Mask_update_data");
+
+ /* weight */
+ prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "bezt.weight");
+ RNA_def_property_range(prop, 0.0, 1.0);
+ RNA_def_property_ui_text(prop, "Weight", "Weight of the point");
+ RNA_def_property_update(prop, 0, "rna_Mask_update_data");
+
/* select */
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bezt.f1", SELECT);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 807d9fc35e1..061f1595c8c 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -744,7 +744,7 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering");
RNA_def_property_update(prop, 0, "rna_Material_update");
-
+
prop = RNA_def_property(srna, "reflection_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "reflfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
@@ -1750,7 +1750,7 @@ void RNA_def_material(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRANSP);
RNA_def_property_ui_text(prop, "Transparency", "Render material as transparent");
- RNA_def_property_update(prop, 0, "rna_Material_update");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop = RNA_def_property(srna, "transparency_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
@@ -1907,6 +1907,12 @@ void RNA_def_material(BlenderRNA *brna)
"Replace the object's base alpha value with alpha from UV map image textures");
RNA_def_property_update(prop, 0, "rna_Material_update");
+ prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode2", MA_CASTSHADOW);
+ RNA_def_property_ui_text(prop, "Cast Shadows",
+ "Allow this material to cast shadows");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
+
prop = RNA_def_property(srna, "use_cast_shadows_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYCAST);
RNA_def_property_ui_text(prop, "Cast Shadows Only",
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 5d4f3e68d5b..8c0f9980108 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -398,7 +398,7 @@ static float rna_MeshPolygon_area_get(PointerRNA *ptr)
Mesh *me = (Mesh *)ptr->id.data;
MPoly *mp = (MPoly *)ptr->data;
- return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert, NULL);
+ return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert);
}
static void rna_MeshTessFace_normal_get(PointerRNA *ptr, float *values)
@@ -413,6 +413,21 @@ static void rna_MeshTessFace_normal_get(PointerRNA *ptr, float *values)
normal_tri_v3(values, me->mvert[mface->v1].co, me->mvert[mface->v2].co, me->mvert[mface->v3].co);
}
+static void rna_MeshTessFace_split_normals_get(PointerRNA *ptr, float *values)
+{
+ Mesh *me = rna_mesh(ptr);
+ MFace *mface = (MFace *)ptr->data;
+ const short (*vec)[4][3] = CustomData_get(&me->fdata, (int)(mface - me->mface), CD_TESSLOOPNORMAL);
+ int i = 4;
+
+ if (!vec) {
+ while (i--) zero_v3(&values[i * 3]);
+ }
+ else {
+ while (i--) normal_short_to_float_v3(&values[i * 3], (const short *)(*vec)[i]);
+ }
+}
+
static float rna_MeshTessFace_area_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -727,6 +742,58 @@ static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int
CustomData_set_layer_clone_index(data, type, n);
}
+static int rna_MEdge_freestyle_edge_mark_get(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ MEdge *medge = (MEdge *)ptr->data;
+ FreestyleEdge *fed = CustomData_get(&me->edata, (int)(medge - me->medge), CD_FREESTYLE_EDGE);
+
+ return fed && (fed->flag & FREESTYLE_EDGE_MARK) != 0;
+}
+
+static void rna_MEdge_freestyle_edge_mark_set(PointerRNA *ptr, int value)
+{
+ Mesh *me = rna_mesh(ptr);
+ MEdge *medge = (MEdge *)ptr->data;
+ FreestyleEdge *fed = CustomData_get(&me->edata, (int)(medge - me->medge), CD_FREESTYLE_EDGE);
+
+ if (!fed) {
+ fed = CustomData_add_layer(&me->edata, CD_FREESTYLE_EDGE, CD_CALLOC, NULL, me->totedge);
+ }
+ if (value) {
+ fed->flag |= FREESTYLE_EDGE_MARK;
+ }
+ else {
+ fed->flag &= ~FREESTYLE_EDGE_MARK;
+ }
+}
+
+static int rna_MPoly_freestyle_face_mark_get(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ MPoly *mpoly = (MPoly *)ptr->data;
+ FreestyleFace *ffa = CustomData_get(&me->pdata, (int)(mpoly - me->mpoly), CD_FREESTYLE_FACE);
+
+ return ffa && (ffa->flag & FREESTYLE_FACE_MARK) != 0;
+}
+
+static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, int value)
+{
+ Mesh *me = rna_mesh(ptr);
+ MPoly *mpoly = (MPoly *)ptr->data;
+ FreestyleFace *ffa = CustomData_get(&me->pdata, (int)(mpoly - me->mpoly), CD_FREESTYLE_FACE);
+
+ if (!ffa) {
+ ffa = CustomData_add_layer(&me->pdata, CD_FREESTYLE_FACE, CD_CALLOC, NULL, me->totpoly);
+ }
+ if (value) {
+ ffa->flag |= FREESTYLE_FACE_MARK;
+ }
+ else {
+ ffa->flag &= ~FREESTYLE_FACE_MARK;
+ }
+}
+
/* Generic UV rename! */
static void rna_MeshUVLayer_name_set(PointerRNA *ptr, const char *name)
{
@@ -1105,20 +1172,6 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value)
tf->tpage = (struct Image *)id;
}
-static void rna_Mesh_auto_smooth_angle_set(PointerRNA *ptr, float value)
-{
- Mesh *me = rna_mesh(ptr);
- value = RAD2DEGF(value);
- CLAMP(value, 1.0f, 80.0f);
- me->smoothresh = (int)value;
-}
-
-static float rna_Mesh_auto_smooth_angle_get(PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- return DEG2RADF((float)me->smoothresh);
-}
-
static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
MFace *face = (MFace *)ptr->data;
@@ -1807,6 +1860,11 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE);
RNA_def_property_ui_text(prop, "Loose", "Loose edge");
+ prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_MEdge_freestyle_edge_mark_get", "rna_MEdge_freestyle_edge_mark_set");
+ RNA_def_property_ui_text(prop, "Freestyle Edge Mark", "Edge mark for Freestyle line rendering");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_MeshEdge_index_get", NULL, NULL);
@@ -1817,6 +1875,7 @@ static void rna_def_mface(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ const int splitnor_dim[] = {4, 3};
srna = RNA_def_struct(brna, "MeshTessFace", NULL);
RNA_def_struct_sdna(srna, "MFace");
@@ -1868,6 +1927,16 @@ static void rna_def_mface(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_MeshTessFace_normal_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Face Normal", "Local space unit length normal vector for this face");
+ prop = RNA_def_property(srna, "split_normals", PROP_FLOAT, PROP_DIRECTION);
+ RNA_def_property_multi_array(prop, 2, splitnor_dim);
+ RNA_def_property_range(prop, -1.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_float_funcs(prop, "rna_MeshTessFace_split_normals_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Split Normals",
+ "Local space unit length split normals vectors of the vertices of this face "
+ "(must be computed beforehand using calc_normals_split or calc_tangents, "
+ "and then calc_tessface)");
+
prop = RNA_def_property(srna, "area", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_MeshTessFace_area_get", NULL, NULL);
@@ -1995,6 +2064,11 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Smooth", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_MPoly_freestyle_face_mark_get", "rna_MPoly_freestyle_face_mark_set");
+ RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle line rendering");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -1.0f, 1.0f);
@@ -2002,7 +2076,7 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_MeshPolygon_normal_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Polygon Normal", "Local space unit length normal vector for this polygon");
- prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_MeshPolygon_center_get", NULL, NULL);
@@ -3113,19 +3187,17 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_AUTOSMOOTH);
RNA_def_property_ui_text(prop, "Auto Smooth",
"Treat all set-smoothed faces with angles less than the specified angle "
- "as 'smooth' during render");
+ "as 'smooth', unless they are linked by a sharp edge");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-#if 1 /* expose as radians */
prop = RNA_def_property(srna, "auto_smooth_angle", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_float_funcs(prop, "rna_Mesh_auto_smooth_angle_get", "rna_Mesh_auto_smooth_angle_set", NULL);
- RNA_def_property_ui_range(prop, DEG2RAD(1.0), DEG2RAD(80), 1.0, 1);
-#else
- prop = RNA_def_property(srna, "auto_smooth_angle", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "smoothresh");
- RNA_def_property_range(prop, 1, 80);
-#endif
+ RNA_def_property_float_sdna(prop, NULL, "smoothresh");
+ RNA_def_property_float_default(prop, DEG2RADF(180.0f));
+ RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
+ RNA_def_property_ui_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f), 1.0, 1);
RNA_def_property_ui_text(prop, "Auto Smooth Angle",
"Maximum angle between face normals that 'Auto Smooth' will operate on");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "show_double_sided", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_TWOSIDED);
@@ -3183,6 +3255,11 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Normals", "Display face normals as lines");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+ prop = RNA_def_property(srna, "show_normal_loop", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_LNORMALS);
+ RNA_def_property_ui_text(prop, "Draw Split Normals", "Display vertex-per-face normals as lines");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
+
prop = RNA_def_property(srna, "show_normal_vertex", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_VNORMALS);
RNA_def_property_ui_text(prop, "Draw Vertex Normals", "Display vertex normals as lines");
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 2627e628538..5f4a7706c0e 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -132,7 +132,7 @@ static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, Poin
{
MetaElem *ml = ml_ptr->data;
- if (BLI_remlink_safe(&mb->elems, ml) == FALSE) {
+ if (BLI_remlink_safe(&mb->elems, ml) == false) {
BKE_reportf(reports, RPT_ERROR, "Metaball '%s' does not contain spline given", mb->id.name + 2);
return;
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 91b522032ae..191d6d230db 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -122,8 +122,8 @@ EnumPropertyItem modifier_triangulate_quad_method_items[] = {
};
EnumPropertyItem modifier_triangulate_ngon_method_items[] = {
- {MOD_TRIANGULATE_NGON_SCANFILL, "SCANFILL", 0, "Scanfill", "Split the polygons using a scanfill algorithm"},
- {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY", 0, "Beauty", "Arrange the new triangles nicely, slower method"},
+ {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY", 0, "Beauty", "Arrange the new triangles evenly (slow)"},
+ {MOD_TRIANGULATE_NGON_EARCLIP, "CLIP", 0, "Clip", "Split the polygons with an ear clipping algorithm"},
{0, NULL, 0, NULL, NULL}
};
@@ -296,32 +296,42 @@ static void rna_Modifier_dependency_update(Main *bmain, Scene *scene, PointerRNA
DAG_relations_tag_update(bmain);
}
-static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
- SmokeModifierData *smd = (SmokeModifierData *)ptr->data;
- Object *ob = (Object *)ptr->id.data;
-
- /* nothing changed */
- if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
- return;
-
- smokeModifier_free(smd); /* XXX TODO: completely free all 3 pointers */
- smokeModifier_createType(smd); /* create regarding of selected type */
-
- switch (smd->type) {
- case MOD_SMOKE_TYPE_DOMAIN:
- ob->dt = OB_WIRE;
- break;
- case MOD_SMOKE_TYPE_FLOW:
- case MOD_SMOKE_TYPE_COLL:
- case 0:
- default:
- break;
- }
-
- /* update dependency since a domain - other type switch could have happened */
- rna_Modifier_dependency_update(bmain, scene, ptr);
-}
+/* Vertex Groups */
+
+#define RNA_MOD_VGROUP_NAME_SET(_type, _prop) \
+static void rna_##_type##Modifier_##_prop##_set(PointerRNA *ptr, const char *value) \
+{ \
+ _type##ModifierData *tmd = (_type##ModifierData *)ptr->data; \
+ rna_object_vgroup_name_set(ptr, value, tmd->_prop, sizeof(tmd->_prop)); \
+}
+
+RNA_MOD_VGROUP_NAME_SET(Armature, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Bevel, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Cast, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Curve, name);
+RNA_MOD_VGROUP_NAME_SET(Decimate, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Displace, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Hook, name);
+RNA_MOD_VGROUP_NAME_SET(LaplacianDeform, anchor_grp_name);
+RNA_MOD_VGROUP_NAME_SET(LaplacianSmooth, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Lattice, name);
+RNA_MOD_VGROUP_NAME_SET(Mask, vgroup);
+RNA_MOD_VGROUP_NAME_SET(MeshDeform, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
+RNA_MOD_VGROUP_NAME_SET(SimpleDeform, vgroup_name);
+RNA_MOD_VGROUP_NAME_SET(Smooth, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Solidify, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(UVWarp, vgroup_name);
+RNA_MOD_VGROUP_NAME_SET(Warp, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Wave, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(WeightVGEdit, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(WeightVGEdit, mask_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(WeightVGMix, defgrp_name_a);
+RNA_MOD_VGROUP_NAME_SET(WeightVGMix, defgrp_name_b);
+RNA_MOD_VGROUP_NAME_SET(WeightVGMix, mask_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(WeightVGProximity, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(WeightVGProximity, mask_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Wireframe, defgrp_name);
static void rna_ExplodeModifier_vgroup_get(PointerRNA *ptr, char *value)
{
@@ -341,175 +351,109 @@ static void rna_ExplodeModifier_vgroup_set(PointerRNA *ptr, const char *value)
rna_object_vgroup_name_index_set(ptr, value, &emd->vgroup);
}
-static void rna_SimpleDeformModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, smd->vgroup_name, sizeof(smd->vgroup_name));
-}
-
-static void rna_ShrinkwrapModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, smd->vgroup_name, sizeof(smd->vgroup_name));
-}
-
-static void rna_LatticeModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- LatticeModifierData *lmd = (LatticeModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->name, sizeof(lmd->name));
-}
-
-static void rna_ArmatureModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- ArmatureModifierData *lmd = (ArmatureModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
-}
+#undef RNA_MOD_VGROUP_NAME_SET
-static void rna_CurveModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- CurveModifierData *lmd = (CurveModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->name, sizeof(lmd->name));
-}
+/* UV layers */
-static void rna_DisplaceModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- DisplaceModifierData *lmd = (DisplaceModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
+#define RNA_MOD_UVLAYER_NAME_SET(_type, _prop) \
+static void rna_##_type##Modifier_##_prop##_set(PointerRNA *ptr, const char *value) \
+{ \
+ _type##ModifierData *tmd = (_type##ModifierData *)ptr->data; \
+ rna_object_uvlayer_name_set(ptr, value, tmd->_prop, sizeof(tmd->_prop)); \
}
-static void rna_HookModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- HookModifierData *lmd = (HookModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->name, sizeof(lmd->name));
-}
+RNA_MOD_UVLAYER_NAME_SET(MappingInfo, uvlayer_name);
+RNA_MOD_UVLAYER_NAME_SET(UVProject, uvlayer_name);
+RNA_MOD_UVLAYER_NAME_SET(UVWarp, uvlayer_name);
+RNA_MOD_UVLAYER_NAME_SET(WeightVGEdit, mask_tex_uvlayer_name);
+RNA_MOD_UVLAYER_NAME_SET(WeightVGMix, mask_tex_uvlayer_name);
+RNA_MOD_UVLAYER_NAME_SET(WeightVGProximity, mask_tex_uvlayer_name);
-static void rna_MaskModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- MaskModifierData *lmd = (MaskModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->vgroup, sizeof(lmd->vgroup));
-}
+#undef RNA_MOD_UVLAYER_NAME_SET
-static void rna_MeshDeformModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- MeshDeformModifierData *lmd = (MeshDeformModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
-}
+/* Objects */
-static void rna_SmoothModifier_vgroup_set(PointerRNA *ptr, const char *value)
+static void modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value)
{
- SmoothModifierData *lmd = (SmoothModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
-}
+ Object *ob = value.data;
-static void rna_LaplacianSmoothModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- LaplacianSmoothModifierData *lmd = (LaplacianSmoothModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
+ if (!self || ob != self) {
+ if (!ob || type == OB_EMPTY || ob->type == type) {
+ id_lib_extern((ID *)ob);
+ *ob_p = ob;
+ }
+ }
}
-static void rna_WaveModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- WaveModifierData *lmd = (WaveModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
+#define RNA_MOD_OBJECT_SET(_type, _prop, _obtype) \
+static void rna_##_type##Modifier_##_prop##_set(PointerRNA *ptr, PointerRNA value) \
+{ \
+ _type##ModifierData *tmd = (_type##ModifierData *)ptr->data; \
+ modifier_object_set(ptr->id.data, &tmd->_prop, _obtype, value); \
}
-static void rna_CastModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- CastModifierData *lmd = (CastModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->defgrp_name, sizeof(lmd->defgrp_name));
-}
+RNA_MOD_OBJECT_SET(Armature, object, OB_ARMATURE);
+RNA_MOD_OBJECT_SET(Array, start_cap, OB_MESH);
+RNA_MOD_OBJECT_SET(Array, end_cap, OB_MESH);
+RNA_MOD_OBJECT_SET(Array, curve_ob, OB_CURVE);
+RNA_MOD_OBJECT_SET(Boolean, object, OB_MESH);
+RNA_MOD_OBJECT_SET(Cast, object, OB_EMPTY);
+RNA_MOD_OBJECT_SET(Curve, object, OB_CURVE);
+RNA_MOD_OBJECT_SET(Lattice, object, OB_LATTICE);
+RNA_MOD_OBJECT_SET(Mask, ob_arm, OB_ARMATURE);
+RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
+RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
+RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
-static void rna_SolidifyModifier_vgroup_set(PointerRNA *ptr, const char *value)
+static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
{
- SolidifyModifierData *smd = (SolidifyModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, smd->defgrp_name, sizeof(smd->defgrp_name));
-}
+ HookModifierData *hmd = ptr->data;
-static void rna_DecimateModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- DecimateModifierData *dmd = (DecimateModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, dmd->defgrp_name, sizeof(dmd->defgrp_name));
+ hmd->object = (Object *)value.data;
+ BKE_object_modifier_hook_reset((Object *)ptr->id.data, hmd);
}
-static void rna_WeightVGModifier_vgroup_set(PointerRNA *ptr, const char *value)
+static PointerRNA rna_UVProjector_object_get(PointerRNA *ptr)
{
- ModifierData *md = (ModifierData *)ptr->data;
- if (md->type == eModifierType_WeightVGEdit) {
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->defgrp_name, sizeof(wmd->defgrp_name));
- }
- else if (md->type == eModifierType_WeightVGMix) {
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->defgrp_name_a, sizeof(wmd->defgrp_name_a));
- }
- else if (md->type == eModifierType_WeightVGProximity) {
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->defgrp_name, sizeof(wmd->defgrp_name));
- }
+ Object **ob = (Object **)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Object, *ob);
}
-static void rna_WeightVGModifier_mask_vgroup_set(PointerRNA *ptr, const char *value)
+static void rna_UVProjector_object_set(PointerRNA *ptr, PointerRNA value)
{
- ModifierData *md = (ModifierData *)ptr->data;
- if (md->type == eModifierType_WeightVGEdit) {
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->mask_defgrp_name, sizeof(wmd->mask_defgrp_name));
- }
- else if (md->type == eModifierType_WeightVGMix) {
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->mask_defgrp_name, sizeof(wmd->mask_defgrp_name));
- }
- else if (md->type == eModifierType_WeightVGProximity) {
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- rna_object_vgroup_name_set(ptr, value, wmd->mask_defgrp_name, sizeof(wmd->mask_defgrp_name));
- }
+ Object **ob = (Object **)ptr->data;
+ *ob = value.data;
}
-static void rna_WeightVGMixModifier_vgroup2_set(PointerRNA *ptr, const char *value)
-{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, wmd->defgrp_name_b, sizeof(wmd->defgrp_name_b));
-}
+#undef RNA_MOD_OBJECT_SET
-static void rna_MappingInfo_uvlayer_set(PointerRNA *ptr, const char *value)
-{
- MappingInfoModifierData *mmd = (MappingInfoModifierData *)ptr->data;
- rna_object_uvlayer_name_set(ptr, value, mmd->uvlayer_name, sizeof(mmd->uvlayer_name));
-}
+/* Other rna callbacks */
-static void rna_UVProjectModifier_uvlayer_set(PointerRNA *ptr, const char *value)
+static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- UVProjectModifierData *umd = (UVProjectModifierData *)ptr->data;
- rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name));
-}
+ SmokeModifierData *smd = (SmokeModifierData *)ptr->data;
+ Object *ob = (Object *)ptr->id.data;
-static void RNA_WarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- WarpModifierData *tmd = (WarpModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name));
-}
+ /* nothing changed */
+ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+ return;
-static void RNA_WireframeModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- WireframeModifierData *wmd = (WireframeModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, wmd->defgrp_name, sizeof(wmd->defgrp_name));
-}
+ smokeModifier_free(smd); /* XXX TODO: completely free all 3 pointers */
+ smokeModifier_createType(smd); /* create regarding of selected type */
-static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *value)
-{
- ModifierData *md = (ModifierData *)ptr->data;
- if (md->type == eModifierType_WeightVGEdit) {
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- rna_object_uvlayer_name_set(ptr, value, wmd->mask_tex_uvlayer_name, sizeof(wmd->mask_tex_uvlayer_name));
- }
- else if (md->type == eModifierType_WeightVGMix) {
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- rna_object_uvlayer_name_set(ptr, value, wmd->mask_tex_uvlayer_name, sizeof(wmd->mask_tex_uvlayer_name));
- }
- else if (md->type == eModifierType_WeightVGProximity) {
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- rna_object_uvlayer_name_set(ptr, value, wmd->mask_tex_uvlayer_name, sizeof(wmd->mask_tex_uvlayer_name));
+ switch (smd->type) {
+ case MOD_SMOKE_TYPE_DOMAIN:
+ ob->dt = OB_WIRE;
+ break;
+ case MOD_SMOKE_TYPE_FLOW:
+ case MOD_SMOKE_TYPE_COLL:
+ case 0:
+ default:
+ break;
}
+
+ /* update dependency since a domain - other type switch could have happened */
+ rna_Modifier_dependency_update(bmain, scene, ptr);
}
static void rna_MultiresModifier_type_set(PointerRNA *ptr, int value)
@@ -565,66 +509,6 @@ static int rna_MultiresModifier_filepath_length(PointerRNA *ptr)
return strlen((external) ? external->filename : "");
}
-static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- HookModifierData *hmd = ptr->data;
-
- hmd->object = (Object *)value.data;
- BKE_object_modifier_hook_reset((Object *)ptr->id.data, hmd);
-}
-
-static void modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value)
-{
- Object *ob = value.data;
-
- if (!self || ob != self) {
- if (!ob || type == OB_EMPTY || ob->type == type) {
- id_lib_extern((ID *)ob);
- *ob_p = ob;
- }
- }
-}
-
-static void rna_LatticeModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((LatticeModifierData *)ptr->data)->object, OB_LATTICE, value);
-}
-
-static void rna_BooleanModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((BooleanModifierData *)ptr->data)->object, OB_MESH, value);
-}
-
-static void rna_CurveModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((CurveModifierData *)ptr->data)->object, OB_CURVE, value);
-}
-
-static void rna_CastModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((CastModifierData *)ptr->data)->object, OB_EMPTY, value);
-}
-
-static void rna_ArmatureModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ArmatureModifierData *)ptr->data)->object, OB_ARMATURE, value);
-}
-
-static void rna_MaskModifier_armature_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((MaskModifierData *)ptr->data)->ob_arm, OB_ARMATURE, value);
-}
-
-static void rna_ShrinkwrapModifier_auxiliary_target_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ShrinkwrapModifierData *)ptr->data)->auxTarget, OB_MESH, value);
-}
-
-static void rna_ShrinkwrapModifier_target_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ShrinkwrapModifierData *)ptr->data)->target, OB_MESH, value);
-}
-
static int rna_ShrinkwrapModifier_face_cull_get(PointerRNA *ptr)
{
ShrinkwrapModifierData *swm = (ShrinkwrapModifierData *)ptr->data;
@@ -639,26 +523,6 @@ static void rna_ShrinkwrapModifier_face_cull_set(struct PointerRNA *ptr, int val
(swm->shrinkOpts & ~(MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE | MOD_SHRINKWRAP_CULL_TARGET_BACKFACE)) | value;
}
-static void rna_MeshDeformModifier_object_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((MeshDeformModifierData *)ptr->data)->object, OB_MESH, value);
-}
-
-static void rna_ArrayModifier_end_cap_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ArrayModifierData *)ptr->data)->end_cap, OB_MESH, value);
-}
-
-static void rna_ArrayModifier_start_cap_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ArrayModifierData *)ptr->data)->start_cap, OB_MESH, value);
-}
-
-static void rna_ArrayModifier_curve_set(PointerRNA *ptr, PointerRNA value)
-{
- modifier_object_set(ptr->id.data, &((ArrayModifierData *)ptr->data)->curve_ob, OB_CURVE, value);
-}
-
static int rna_MeshDeformModifier_is_bound_get(PointerRNA *ptr)
{
return (((MeshDeformModifierData *)ptr->data)->bindcagecos != NULL);
@@ -682,24 +546,6 @@ static PointerRNA rna_CollisionModifier_settings_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_CollisionSettings, ob->pd);
}
-static PointerRNA rna_UVProjector_object_get(PointerRNA *ptr)
-{
- Object **ob = (Object **)ptr->data;
- return rna_pointer_inherit_refine(ptr, &RNA_Object, *ob);
-}
-
-static void rna_UVProjector_object_set(PointerRNA *ptr, PointerRNA value)
-{
- Object **ob = (Object **)ptr->data;
-
- if (*ob)
- id_us_min((ID *)*ob);
- if (value.data)
- id_us_plus((ID *)value.data);
-
- *ob = value.data;
-}
-
static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value)
{
UVProjectModifierData *md = (UVProjectModifierData *)ptr->data;
@@ -752,30 +598,6 @@ static void rna_OceanModifier_ocean_chop_set(PointerRNA *ptr, float value)
}
}
-static void rna_BevelModifier_defgrp_name_set(PointerRNA *ptr, const char *value)
-{
- BevelModifierData *md = (BevelModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, md->defgrp_name, sizeof(md->defgrp_name));
-}
-
-static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name));
-}
-
-static void rna_UVWarpModifier_uvlayer_set(PointerRNA *ptr, const char *value)
-{
- UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
- rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name));
-}
-
-static void rna_LaplacianDeformModifier_vgroup_set(PointerRNA *ptr, const char *value)
-{
- LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)ptr->data;
- rna_object_vgroup_name_set(ptr, value, lmd->anchor_grp_name, sizeof(lmd->anchor_grp_name));
-}
-
static int rna_LaplacianDeformModifier_is_bind_get(PointerRNA *ptr)
{
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)ptr->data;
@@ -865,7 +687,7 @@ static void rna_def_modifier_generic_map_info(StructRNA *srna)
prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
RNA_def_property_ui_text(prop, "UV Map", "UV map name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MappingInfo_uvlayer_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MappingInfoModifier_uvlayer_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "texture_coords_object", PROP_POINTER, PROP_NONE);
@@ -936,7 +758,7 @@ static void rna_def_modifier_warp(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform");
- RNA_def_property_string_funcs(prop, NULL, NULL, "RNA_WarpModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WarpModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
rna_def_modifier_generic_map_info(srna);
@@ -1020,7 +842,7 @@ static void rna_def_modifier_lattice(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LatticeModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LatticeModifier_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
@@ -1060,7 +882,7 @@ static void rna_def_modifier_curve(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CurveModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CurveModifier_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "deform_axis", PROP_ENUM, PROP_NONE);
@@ -1223,7 +1045,7 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name (collapse only)");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DecimateModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DecimateModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
@@ -1353,7 +1175,7 @@ static void rna_def_modifier_wave(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the wave");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
@@ -1427,7 +1249,7 @@ static void rna_def_modifier_armature(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ArmatureModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ArmatureModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
@@ -1473,7 +1295,7 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookModifier_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
@@ -1570,7 +1392,7 @@ static void rna_def_modifier_array(BlenderRNA *brna)
prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curve_ob");
RNA_def_property_ui_text(prop, "Curve", "Curve object to fit array length to");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_set", NULL, "rna_Curve_object_poll");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_ob_set", NULL, "rna_Curve_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@@ -1696,7 +1518,7 @@ static void rna_def_modifier_displace(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "mid_level", PROP_FLOAT, PROP_FACTOR);
@@ -1733,7 +1555,7 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna)
prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
RNA_def_property_ui_text(prop, "UV Map", "UV map name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVProjectModifier_uvlayer_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVProjectModifier_uvlayer_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "projector_count", PROP_INT, PROP_NONE);
@@ -1844,7 +1666,7 @@ static void rna_def_modifier_smooth(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmoothModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmoothModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
@@ -1907,7 +1729,7 @@ static void rna_def_modifier_laplaciansmooth(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
"Name of Vertex Group which determines influence of modifier per point");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LaplacianSmoothModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LaplacianSmoothModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
@@ -1990,7 +1812,7 @@ static void rna_def_modifier_cast(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CastModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CastModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
@@ -2030,7 +1852,7 @@ static void rna_def_modifier_meshdeform(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshDeformModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshDeformModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "precision", PROP_INT, PROP_NONE);
@@ -2466,15 +2288,14 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
prop = RNA_def_property(srna, "auxiliary_target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "auxTarget");
RNA_def_property_ui_text(prop, "Auxiliary Target", "Additional mesh target to shrink to");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_ShrinkwrapModifier_auxiliary_target_set", NULL,
- "rna_Mesh_object_poll");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_ShrinkwrapModifier_auxTarget_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShrinkwrapModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShrinkwrapModifier_vgroup_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
@@ -2571,7 +2392,7 @@ static void rna_def_modifier_mask(BlenderRNA *brna)
prop = RNA_def_property(srna, "armature", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ob_arm");
RNA_def_property_ui_text(prop, "Armature", "Armature to use as source of bones to mask");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_MaskModifier_armature_set", NULL, "rna_Armature_object_poll");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_MaskModifier_ob_arm_set", NULL, "rna_Armature_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@@ -2616,7 +2437,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SimpleDeformModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SimpleDeformModifier_vgroup_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "origin", PROP_POINTER, PROP_NONE);
@@ -2634,7 +2455,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "factor");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_float_default(prop, DEG2RADF(45.0f));
- RNA_def_property_ui_range(prop, -10, 10, 1, 3);
+ RNA_def_property_ui_range(prop, -M_PI, M_PI, DEG2RAD(1), 3);
RNA_def_property_ui_text(prop, "Angle", "Angle of deformation");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -2744,7 +2565,7 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_rim", PROP_BOOLEAN, PROP_NONE);
@@ -2932,17 +2753,18 @@ static void rna_def_modifier_uvwarp(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
RNA_def_property_ui_text(prop, "UV Layer", "UV Layer name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
-static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna)
+static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna,
+ const char *mask_vgroup_setter, const char *mask_uvlayer_setter)
{
static EnumPropertyItem weightvg_mask_tex_map_items[] = {
{MOD_DISP_MAP_LOCAL, "LOCAL", 0, "Local", "Use local generated coordinates"},
@@ -2975,7 +2797,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *
prop = RNA_def_property(srna, "mask_vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "mask_defgrp_name");
RNA_def_property_ui_text(prop, "Mask VGroup", "Masking vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_mask_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, mask_vgroup_setter);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "mask_texture", PROP_POINTER, PROP_NONE);
@@ -2997,7 +2819,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *
prop = RNA_def_property(srna, "mask_tex_uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "mask_tex_uvlayer_name");
RNA_def_property_ui_text(prop, "UV Map", "UV map name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_mask_uvlayer_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, mask_uvlayer_setter);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "mask_tex_map_object", PROP_POINTER, PROP_NONE);
@@ -3035,7 +2857,7 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGEditModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
@@ -3085,7 +2907,8 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* Common masking properties. */
- rna_def_modifier_weightvg_mask(brna, srna);
+ rna_def_modifier_weightvg_mask(brna, srna, "rna_WeightVGEditModifier_mask_defgrp_name_set",
+ "rna_WeightVGEditModifier_mask_tex_uvlayer_name_set");
}
static void rna_def_modifier_weightvgmix(BlenderRNA *brna)
@@ -3123,13 +2946,13 @@ static void rna_def_modifier_weightvgmix(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group_a", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name_a");
RNA_def_property_ui_text(prop, "Vertex Group A", "First vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGMixModifier_defgrp_name_a_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "vertex_group_b", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name_b");
RNA_def_property_ui_text(prop, "Vertex Group B", "Second vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGMixModifier_vgroup2_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGMixModifier_defgrp_name_b_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "default_weight_a", PROP_FLOAT, PROP_NONE);
@@ -3158,7 +2981,8 @@ static void rna_def_modifier_weightvgmix(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* Common masking properties. */
- rna_def_modifier_weightvg_mask(brna, srna);
+ rna_def_modifier_weightvg_mask(brna, srna, "rna_WeightVGMixModifier_mask_defgrp_name_set",
+ "rna_WeightVGMixModifier_mask_tex_uvlayer_name_set");
}
static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
@@ -3205,7 +3029,7 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGProximityModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "proximity_mode", PROP_ENUM, PROP_NONE);
@@ -3249,7 +3073,8 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* Common masking properties. */
- rna_def_modifier_weightvg_mask(brna, srna);
+ rna_def_modifier_weightvg_mask(brna, srna, "rna_WeightVGProximityModifier_mask_defgrp_name_set",
+ "rna_WeightVGProximityModifier_mask_tex_uvlayer_name_set");
}
static void rna_def_modifier_remesh(BlenderRNA *brna)
@@ -3722,7 +3547,7 @@ static void rna_def_modifier_laplaciandeform(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "anchor_grp_name");
RNA_def_property_ui_text(prop, "Vertex Group for Anchors",
"Name of Vertex Group which determines Anchors");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LaplacianDeformModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LaplacianDeformModifier_anchor_grp_name_set");
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "repeat");
@@ -3813,7 +3638,7 @@ static void rna_def_modifier_wireframe(BlenderRNA *brna)
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for selecting the affected areas");
- RNA_def_property_string_funcs(prop, NULL, NULL, "RNA_WireframeModifier_vgroup_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WireframeModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 4a95bd4e51b..37de1d670f5 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -231,6 +231,34 @@ static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
data->blendout = value;
}
+static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
+{
+ NlaStrip *data = (NlaStrip *)ptr->data;
+
+ if (value) {
+ /* set the flag */
+ data->flag |= NLASTRIP_FLAG_AUTO_BLENDS;
+
+ /* validate state to ensure that auto-blend gets applied immediately */
+ if (ptr->id.data) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data;
+
+ if (iat->adt) {
+ BKE_nla_validate_state(iat->adt);
+ }
+ }
+ }
+ else {
+ /* clear the flag */
+ data->flag &= ~NLASTRIP_FLAG_AUTO_BLENDS;
+
+ /* clear the values too, so that it's clear that there has been an effect */
+ /* TODO: it's somewhat debatable whether it's better to leave these in instead... */
+ data->blendin = 0.0f;
+ data->blendout = 0.0f;
+ }
+}
+
static int rna_NlaStrip_action_editable(PointerRNA *ptr)
{
NlaStrip *strip = (NlaStrip *)ptr->data;
@@ -502,6 +530,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_auto_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_use_auto_blend_set");
RNA_def_property_ui_text(prop, "Auto Blend In/Out",
"Number of frames for Blending In/Out is automatically determined from "
"overlapping strips");
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 57713e7a037..c39d3826d8b 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -129,7 +129,8 @@ EnumPropertyItem node_math_items[] = {
{14, "ROUND", 0, "Round", ""},
{15, "LESS_THAN", 0, "Less Than", ""},
{16, "GREATER_THAN", 0, "Greater Than", ""},
- {17, "MODULO", 0, "Modulo", ""},
+ {17, "MODULO", 0, "Modulo", ""},
+ {18, "ABSOLUTE", 0, "Absolute", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1393,7 +1394,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
func = RNA_def_function_runtime(nt->ext.srna, "is_registered_node_type", rna_Node_is_registered_node_type_runtime);
RNA_def_function_ui_description(func, "True if a registered node type");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
- parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ parm = RNA_def_boolean(func, "result", false, "Result", "");
RNA_def_function_return(func, parm);
/* XXX bad level call! needed to initialize the basic draw functions ... */
@@ -1532,13 +1533,13 @@ static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
* in the future should have a poll function or so to test possible attachment.
*/
if (parent->type != NODE_FRAME)
- return FALSE;
+ return false;
/* make sure parent is not attached to the node */
if (nodeAttachNodeCheck(parent, node))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -2414,7 +2415,7 @@ static StructRNA *rna_NodeCustomGroup_register(
static void rna_CompositorNode_tag_need_exec(bNode *node)
{
- node->need_exec = TRUE;
+ node->need_exec = true;
}
static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -2482,7 +2483,7 @@ static StructRNA *rna_NodeGroup_interface_typef(PointerRNA *ptr)
bNodeTree *ngroup = (bNodeTree *)node->id;
if (ngroup) {
- StructRNA *srna = ntreeInterfaceTypeGet(ngroup, TRUE);
+ StructRNA *srna = ntreeInterfaceTypeGet(ngroup, true);
if (srna)
return srna;
}
@@ -2494,7 +2495,7 @@ static StructRNA *rna_NodeGroupInputOutput_interface_typef(PointerRNA *ptr)
bNodeTree *ntree = ptr->id.data;
if (ntree) {
- StructRNA *srna = ntreeInterfaceTypeGet(ntree, TRUE);
+ StructRNA *srna = ntreeInterfaceTypeGet(ntree, true);
if (srna)
return srna;
}
@@ -2613,10 +2614,14 @@ static EnumPropertyItem *rna_Node_image_layer_itemf(bContext *UNUSED(C), Pointer
EnumPropertyItem *item = NULL;
RenderLayer *rl;
- if (!ima || !(ima->rr)) return NULL;
-
- rl = ima->rr->layers.first;
- item = renderresult_layers_add_enum(rl);
+ if (ima && ima->rr) {
+ rl = ima->rr->layers.first;
+ item = renderresult_layers_add_enum(rl);
+ }
+ else {
+ int totitem = 0;
+ RNA_enum_item_end(&item, &totitem);
+ }
*r_free = true;
@@ -2631,10 +2636,14 @@ static EnumPropertyItem *rna_Node_scene_layer_itemf(bContext *UNUSED(C), Pointer
EnumPropertyItem *item = NULL;
RenderLayer *rl;
- if (!sce) return NULL;
-
- rl = sce->r.layers.first;
- item = renderresult_layers_add_enum(rl);
+ if (sce) {
+ rl = sce->r.layers.first;
+ item = renderresult_layers_add_enum(rl);
+ }
+ else {
+ int totitem = 0;
+ RNA_enum_item_end(&item, &totitem);
+ }
*r_free = true;
@@ -3420,6 +3429,17 @@ static void def_sh_tex_image(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ static const EnumPropertyItem prop_interpolation_items[] = {
+ {SHD_INTERP_LINEAR, "Linear", 0, "Linear",
+ "Linear interpolation"},
+ {SHD_INTERP_CLOSEST, "Closest", 0, "Closest",
+ "No interpolation (sample closest texel)"},
+ {SHD_INTERP_CUBIC, "Cubic", 0, "Cubic",
+ "Cubic interpolation (OSL only)"},
+ {SHD_INTERP_SMART, "Smart", 0, "Smart",
+ "Bicubic when magnifying, else bilinear (OSL only)"},
+ {0, NULL, 0, NULL, NULL}
+ };
PropertyRNA *prop;
@@ -3443,6 +3463,11 @@ static void def_sh_tex_image(StructRNA *srna)
RNA_def_property_ui_text(prop, "Projection", "Method to project 2D image on object with a 3D texture vector");
RNA_def_property_update(prop, 0, "rna_Node_update");
+ prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_interpolation_items);
+ RNA_def_property_ui_text(prop, "Interpolation", "Texture interpolation");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
prop = RNA_def_property(srna, "projection_blend", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "Projection Blend", "For box projection, amount of blend to use between sides");
RNA_def_property_update(prop, 0, "rna_Node_update");
@@ -3706,6 +3731,24 @@ static void def_hair(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_sh_uvmap(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
+ RNA_def_property_ui_text(prop, "From Dupli", "Use the parent of the dupli object if possible");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "NodeShaderUVMap", "storage");
+
+ prop = RNA_def_property(srna, "uv_map", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "UV Map", "UV coordinates to be used for mapping");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "bNode", NULL);
+}
+
static void def_sh_normal_map(StructRNA *srna)
{
static EnumPropertyItem prop_space_items[] = {
@@ -3835,7 +3878,7 @@ static void def_sh_script(StructRNA *srna)
RNA_def_function_ui_description(func, "Find a socket by name");
parm = RNA_def_string(func, "name", NULL, 0, "Socket name", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output");
+ /*parm =*/ RNA_def_boolean(func, "is_output", false, "Output", "Whether the socket is an output");
parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
RNA_def_function_return(func, parm);
@@ -3846,7 +3889,7 @@ static void def_sh_script(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output");
+ /*parm =*/ RNA_def_boolean(func, "is_output", false, "Output", "Whether the socket is an output");
parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
RNA_def_function_return(func, parm);
@@ -4235,7 +4278,7 @@ static void rna_def_cmp_output_file_slot_file(BlenderRNA *brna)
prop = RNA_def_property(srna, "format", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ImageFormatSettings");
- prop = RNA_def_property(srna, "path", PROP_STRING, PROP_FILEPATH);
+ prop = RNA_def_property(srna, "path", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "path");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NodeOutputFileSlotFile_path_set");
RNA_def_struct_name_property(srna, prop);
@@ -5714,19 +5757,19 @@ static void def_cmp_colorcorrection(StructRNA *srna)
PropertyRNA *prop;
prop = RNA_def_property(srna, "red", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
- RNA_def_property_boolean_default(prop, TRUE);
+ RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Red", "Red channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "green", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 2);
- RNA_def_property_boolean_default(prop, TRUE);
+ RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Green", "Green channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "blue", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 4);
- RNA_def_property_boolean_default(prop, TRUE);
+ RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Blue", "Blue channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -6445,6 +6488,20 @@ static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, cons
{
StructRNA *srna;
PropertyRNA *prop;
+ float value_default;
+
+ /* choose sensible common default based on subtype */
+ switch (subtype) {
+ case PROP_FACTOR:
+ value_default = 1.0f;
+ break;
+ case PROP_PERCENTAGE:
+ value_default = 100.0f;
+ break;
+ default:
+ value_default = 0.0f;
+ break;
+ }
srna = RNA_def_struct(brna, idname, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Float Node Socket", "Floating point number socket of a node");
@@ -6470,6 +6527,7 @@ static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, cons
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
+ RNA_def_property_float_default(prop, value_default);
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_float_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
@@ -6491,6 +6549,20 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co
{
StructRNA *srna;
PropertyRNA *prop;
+ int value_default;
+
+ /* choose sensible common default based on subtype */
+ switch (subtype) {
+ case PROP_FACTOR:
+ value_default = 1;
+ break;
+ case PROP_PERCENTAGE:
+ value_default = 100;
+ break;
+ default:
+ value_default = 0;
+ break;
+ }
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Integer Node Socket", "Integer number socket of a node");
@@ -6500,6 +6572,7 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co
prop = RNA_def_property(srna, "default_value", PROP_INT, subtype);
RNA_def_property_int_sdna(prop, NULL, "value");
+ RNA_def_property_int_default(prop, value_default);
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_int_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
@@ -6571,6 +6644,21 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier,
{
StructRNA *srna;
PropertyRNA *prop;
+ const float *value_default;
+
+ /* choose sensible common default based on subtype */
+ switch (subtype) {
+ case PROP_DIRECTION: {
+ static const float default_direction[3] = {0.0f, 0.0f, 1.0f};
+ value_default = default_direction;
+ break;
+ }
+ default: {
+ static const float default_vector[3] = {0.0f, 0.0f, 0.0f};
+ value_default = default_vector;
+ break;
+ }
+ }
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Vector Node Socket", "3D vector socket of a node");
@@ -6580,6 +6668,7 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier,
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
+ RNA_def_property_float_array_default(prop, value_default);
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_vector_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
@@ -6859,13 +6948,13 @@ static void rna_def_internal_node(BlenderRNA *brna)
func = RNA_def_function(srna, "poll", "rna_NodeInternal_poll");
RNA_def_function_ui_description(func, "If non-null output is returned, the node type can be added to the tree");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
- RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
func = RNA_def_function(srna, "poll_instance", "rna_NodeInternal_poll_instance");
RNA_def_function_ui_description(func, "If non-null output is returned, the node can be added to the tree");
- RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -7091,7 +7180,7 @@ static void rna_def_node(BlenderRNA *brna)
func = RNA_def_function(srna, "is_registered_node_type", "rna_Node_is_registered_node_type");
RNA_def_function_ui_description(func, "True if a registered node type");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
- parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ parm = RNA_def_boolean(func, "result", false, "Result", "");
RNA_def_function_return(func, parm);
/* registration */
@@ -7153,14 +7242,14 @@ static void rna_def_node(BlenderRNA *brna)
func = RNA_def_function(srna, "poll", NULL);
RNA_def_function_ui_description(func, "If non-null output is returned, the node type can be added to the tree");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER);
- RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
func = RNA_def_function(srna, "poll_instance", NULL);
RNA_def_function_ui_description(func, "If non-null output is returned, the node can be added to the tree");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
- RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -7324,7 +7413,7 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
parm = RNA_def_pointer(func, "output", "NodeSocket", "", "The output socket");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- RNA_def_boolean(func, "verify_limits", TRUE, "Verify Limits", "Remove existing links if connection limit is exceeded");
+ RNA_def_boolean(func, "verify_limits", true, "Verify Limits", "Remove existing links if connection limit is exceeded");
/* return */
parm = RNA_def_pointer(func, "link", "NodeLink", "", "New node link");
RNA_def_function_return(func, parm);
@@ -7501,7 +7590,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
/* update */
func = RNA_def_function(srna, "update", NULL);
@@ -7606,7 +7695,7 @@ static StructRNA *define_specific_node(BlenderRNA *brna, const char *struct_name
func = RNA_def_function(srna, "is_registered_node_type", "rna_Node_is_registered_node_type");
RNA_def_function_ui_description(func, "True if a registered node type");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
- parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ parm = RNA_def_boolean(func, "result", false, "Result", "");
RNA_def_function_return(func, parm);
/* Exposes the socket template type lists in RNA for use in scripts
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 066b6f6654e..38073293df8 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -213,7 +213,7 @@ static void rna_Object_internal_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
static void rna_Object_matrix_world_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
/* don't use compat so we get predictable rotation */
- BKE_object_apply_mat4(ptr->id.data, ((Object *)ptr->id.data)->obmat, FALSE, TRUE);
+ BKE_object_apply_mat4(ptr->id.data, ((Object *)ptr->id.data)->obmat, false, true);
rna_Object_internal_update(bmain, scene, ptr);
}
@@ -245,7 +245,7 @@ static void rna_Object_matrix_local_set(PointerRNA *ptr, const float values[16])
}
/* don't use compat so we get predictable rotation */
- BKE_object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
+ BKE_object_apply_mat4(ob, ob->obmat, false, false);
}
static void rna_Object_matrix_basis_get(PointerRNA *ptr, float values[16])
@@ -257,7 +257,7 @@ static void rna_Object_matrix_basis_get(PointerRNA *ptr, float values[16])
static void rna_Object_matrix_basis_set(PointerRNA *ptr, const float values[16])
{
Object *ob = ptr->id.data;
- BKE_object_apply_mat4(ob, (float(*)[4])values, FALSE, FALSE);
+ BKE_object_apply_mat4(ob, (float(*)[4])values, false, false);
}
void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -987,7 +987,7 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
switch (ob->body_type) {
case OB_BODY_TYPE_SENSOR:
- ob->gameflag |= OB_SENSOR | OB_COLLISION | OB_GHOST;
+ ob->gameflag |= OB_SENSOR | OB_COLLISION;
ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break;
@@ -1009,7 +1009,7 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH);
break;
case OB_BODY_TYPE_CHARACTER:
- ob->gameflag |= OB_COLLISION | OB_GHOST | OB_CHARACTER;
+ ob->gameflag |= OB_COLLISION | OB_CHARACTER;
ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break;
@@ -1284,20 +1284,20 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
static PointerRNA rna_Object_active_constraint_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
- bConstraint *con = BKE_constraints_get_active(&ob->constraints);
+ bConstraint *con = BKE_constraints_active_get(&ob->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_Object_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob = (Object *)ptr->id.data;
- BKE_constraints_set_active(&ob->constraints, (bConstraint *)value.data);
+ BKE_constraints_active_set(&ob->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_Object_constraints_new(Object *object, int type)
{
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_ADDED, object);
- return BKE_add_ob_constraint(object, NULL, type);
+ return BKE_constraint_add_for_object(object, NULL, type);
}
static void rna_Object_constraints_remove(Object *object, ReportList *reports, PointerRNA *con_ptr)
@@ -1308,7 +1308,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
return;
}
- BKE_remove_constraint(&object->constraints, con);
+ BKE_constraint_remove(&object->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(object);
@@ -1318,7 +1318,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
static void rna_Object_constraints_clear(Object *object)
{
- BKE_free_constraints(&object->constraints);
+ BKE_constraints_free(&object->constraints);
ED_object_constraint_update(object);
ED_object_constraint_set_active(object, NULL);
@@ -1335,7 +1335,7 @@ static ModifierData *rna_Object_modifier_new(Object *object, bContext *C, Report
static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, PointerRNA *md_ptr)
{
ModifierData *md = md_ptr->data;
- if (ED_object_modifier_remove(reports, CTX_data_main(C), object, md) == FALSE) {
+ if (ED_object_modifier_remove(reports, CTX_data_main(C), object, md) == false) {
/* error is already set */
return;
}
@@ -1482,7 +1482,12 @@ int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
static void rna_Object_lod_distance_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
+
+#ifdef WITH_GAMEENGINE
BKE_object_lod_sort(ob);
+#else
+ (void)ob;
+#endif
}
#else
@@ -2310,7 +2315,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "dimensions", PROP_FLOAT, PROP_XYZ_LENGTH);
RNA_def_property_array(prop, 3);
RNA_def_property_float_funcs(prop, "rna_Object_dimensions_get", "rna_Object_dimensions_set", NULL);
- RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3);
+ RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 3);
RNA_def_property_ui_text(prop, "Dimensions", "Absolute bounding box dimensions of the object");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
@@ -2646,7 +2651,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "dt");
RNA_def_property_enum_items(prop, drawtype_items);
RNA_def_property_ui_text(prop, "Maximum Draw Type", "Maximum draw type to display object with in viewport");
- 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, "show_bounds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWBOUNDOX);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index e672a7ef2a7..0b6d6b36e7c 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -382,7 +382,7 @@ static int rna_Object_is_deform_modified(Object *ob, Scene *scene, int settings)
void rna_Object_dm_info(struct Object *ob, int type, char *result)
{
DerivedMesh *dm = NULL;
- int dm_release = FALSE;
+ bool dm_release = false;
char *ret = NULL;
result[0] = '\0';
@@ -392,7 +392,7 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result)
if (ob->type == OB_MESH) {
dm = CDDM_from_mesh(ob->data);
ret = DM_debug_info(dm);
- dm_release = TRUE;
+ dm_release = true;
}
break;
case 1:
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 31e87f44a6a..f6f133c5114 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -475,7 +475,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
if (particle_no < totpart) {
/* get uvco & mcol */
- num = particle->num_dmcache;
+ num = (ELEM(particle->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ?
+ particle->num : particle->num_dmcache;
if (num == DMCACHE_NOTFOUND)
if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 4050b9b2df3..18e4ac6b004 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -481,14 +481,14 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
static PointerRNA rna_PoseChannel_active_constraint_get(PointerRNA *ptr)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- bConstraint *con = BKE_constraints_get_active(&pchan->constraints);
+ bConstraint *con = BKE_constraints_active_get(&pchan->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_PoseChannel_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- BKE_constraints_set_active(&pchan->constraints, (bConstraint *)value.data);
+ BKE_constraints_active_set(&pchan->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int type)
@@ -496,7 +496,7 @@ static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int typ
/*WM_main_add_notifier(NC_OBJECT|ND_CONSTRAINT|NA_ADDED, object); */
/* TODO, pass object also */
/* TODO, new pose bones don't have updated draw flags */
- return BKE_add_pose_constraint(NULL, pchan, NULL, type);
+ return BKE_constraint_add_for_pose(NULL, pchan, NULL, type);
}
static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, ReportList *reports, PointerRNA *con_ptr)
@@ -510,12 +510,12 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo
return;
}
- BKE_remove_constraint(&pchan->constraints, con);
+ BKE_constraint_remove(&pchan->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(ob);
- BKE_constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
+ BKE_constraints_active_set(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id);
@@ -605,10 +605,10 @@ static int rna_PoseBones_lookup_string(PointerRNA *ptr, const char *key, Pointer
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, key);
if (pchan) {
RNA_pointer_create(ptr->id.data, &RNA_PoseBone, pchan, r_ptr);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -621,7 +621,7 @@ static void rna_PoseChannel_matrix_basis_get(PointerRNA *ptr, float *values)
static void rna_PoseChannel_matrix_basis_set(PointerRNA *ptr, const float *values)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- BKE_pchan_apply_mat4(pchan, (float (*)[4])values, FALSE); /* no compat for predictable result */
+ BKE_pchan_apply_mat4(pchan, (float (*)[4])values, false); /* no compat for predictable result */
}
static void rna_PoseChannel_matrix_set(PointerRNA *ptr, const float *values)
@@ -632,7 +632,7 @@ static void rna_PoseChannel_matrix_set(PointerRNA *ptr, const float *values)
BKE_armature_mat_pose_to_bone_ex(ob, pchan, (float (*)[4])values, tmat);
- BKE_pchan_apply_mat4(pchan, tmat, FALSE); /* no compat for predictable result */
+ BKE_pchan_apply_mat4(pchan, tmat, false); /* no compat for predictable result */
}
#else
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 1ec11c280cb..16cc82bbca1 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -38,7 +38,41 @@
#include "RE_engine.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
+
+EnumPropertyItem render_pass_type_items[] = {
+ {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
+ {SCE_PASS_Z, "Z", 0, "Z", ""},
+ {SCE_PASS_RGBA, "COLOR", 0, "Color", ""},
+ {SCE_PASS_DIFFUSE, "DIFFUSE", 0, "Diffuse", ""},
+ {SCE_PASS_SPEC, "SPECULAR", 0, "Specular", ""},
+ {SCE_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
+ {SCE_PASS_AO, "AO", 0, "AO", ""},
+ {SCE_PASS_REFLECT, "REFLECTION", 0, "Reflection", ""},
+ {SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
+ {SCE_PASS_VECTOR, "VECTOR", 0, "Vector", ""},
+ {SCE_PASS_REFRACT, "REFRACTION", 0, "Refraction", ""},
+ {SCE_PASS_INDEXOB, "OBJECT_INDEX", 0, "Object Index", ""},
+ {SCE_PASS_UV, "UV", 0, "UV", ""},
+ {SCE_PASS_MIST, "MIST", 0, "Mist", ""},
+ {SCE_PASS_EMIT, "EMIT", 0, "Emit", ""},
+ {SCE_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
+ {SCE_PASS_INDEXMA, "MATERIAL_INDEX", 0, "Material Index", ""},
+ {SCE_PASS_DIFFUSE_DIRECT, "DIFFUSE_DIRECT", 0, "Diffuse Direct", ""},
+ {SCE_PASS_DIFFUSE_INDIRECT, "DIFFUSE_INDIRECT", 0, "Diffuse Indirect", ""},
+ {SCE_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""},
+ {SCE_PASS_GLOSSY_DIRECT, "GLOSSY_DIRECT", 0, "Glossy Direct", ""},
+ {SCE_PASS_GLOSSY_INDIRECT, "GLOSSY_INDIRECT", 0, "Glossy Indirect", ""},
+ {SCE_PASS_GLOSSY_COLOR, "GLOSSY_COLOR", 0, "Glossy Color", ""},
+ {SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""},
+ {SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""},
+ {SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""},
+ {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", ""},
+ {0, NULL, 0, NULL, NULL}
+};
#ifdef RNA_RUNTIME
@@ -117,6 +151,30 @@ static void engine_render(RenderEngine *engine, struct Scene *scene)
RNA_parameter_list_free(&list);
}
+static void engine_bake(RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type,
+ const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result)
+{
+ extern FunctionRNA rna_RenderEngine_bake_func;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+ func = &rna_RenderEngine_bake_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "scene", &scene);
+ RNA_parameter_set_lookup(&list, "object", &object);
+ RNA_parameter_set_lookup(&list, "pass_type", &pass_type);
+ RNA_parameter_set_lookup(&list, "pixel_array", &pixel_array);
+ RNA_parameter_set_lookup(&list, "num_pixels", &num_pixels);
+ RNA_parameter_set_lookup(&list, "depth", &depth);
+ RNA_parameter_set_lookup(&list, "result", &result);
+ engine->type->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
static void engine_view_update(RenderEngine *engine, const struct bContext *context)
{
extern FunctionRNA rna_RenderEngine_view_update_func;
@@ -189,7 +247,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine = {NULL};
PointerRNA dummyptr;
- int have_function[5];
+ int have_function[6];
/* setup dummy engine & engine type to store static properties in */
dummyengine.type = &dummyet;
@@ -226,9 +284,10 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et->update = (have_function[0]) ? engine_update : NULL;
et->render = (have_function[1]) ? engine_render : NULL;
- et->view_update = (have_function[2]) ? engine_view_update : NULL;
- et->view_draw = (have_function[3]) ? engine_view_draw : NULL;
- et->update_script_node = (have_function[4]) ? engine_update_script_node : NULL;
+ et->bake = (have_function[2]) ? engine_bake : NULL;
+ et->view_update = (have_function[3]) ? engine_view_update : NULL;
+ et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
+ et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
BLI_addtail(&R_engines, et);
@@ -317,6 +376,12 @@ void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values)
memcpy(rpass->rect, values, sizeof(float) * rpass->rectx * rpass->recty * rpass->channels);
}
+static PointerRNA rna_BakePixel_next_get(PointerRNA *ptr)
+{
+ BakePixel *bp = ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_BakePixel, bp + 1);
+}
+
#else /* RNA_RUNTIME */
static void rna_def_render_engine(BlenderRNA *brna)
@@ -344,6 +409,25 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
RNA_def_pointer(func, "scene", "Scene", "", "");
+ func = RNA_def_function(srna, "bake", NULL);
+ RNA_def_function_ui_description(func, "Bake passes");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ prop = RNA_def_pointer(func, "scene", "Scene", "", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_pointer(func, "object", "Object", "", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_enum(func, "pass_type", render_pass_type_items, 0, "Pass", "Pass to bake");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_pointer(func, "pixel_array", "BakePixel", "", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_int(func, "num_pixels", 0, 0, INT_MAX, "Number of Pixels", "Size of the baking batch", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_int(func, "depth", 0, 0, INT_MAX, "Pixels depth", "Number of channels", 1, INT_MAX);
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ prop = RNA_def_pointer(func, "result", "AnyType", "", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+
/* viewport render callbacks */
func = RNA_def_function(srna, "view_update", NULL);
RNA_def_function_ui_description(func, "Update on data changes for viewport render");
@@ -588,39 +672,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem pass_type_items[] = {
- {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
- {SCE_PASS_Z, "Z", 0, "Z", ""},
- {SCE_PASS_RGBA, "COLOR", 0, "Color", ""},
- {SCE_PASS_DIFFUSE, "DIFFUSE", 0, "Diffuse", ""},
- {SCE_PASS_SPEC, "SPECULAR", 0, "Specular", ""},
- {SCE_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
- {SCE_PASS_AO, "AO", 0, "AO", ""},
- {SCE_PASS_REFLECT, "REFLECTION", 0, "Reflection", ""},
- {SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
- {SCE_PASS_VECTOR, "VECTOR", 0, "Vector", ""},
- {SCE_PASS_REFRACT, "REFRACTION", 0, "Refraction", ""},
- {SCE_PASS_INDEXOB, "OBJECT_INDEX", 0, "Object Index", ""},
- {SCE_PASS_UV, "UV", 0, "UV", ""},
- {SCE_PASS_MIST, "MIST", 0, "Mist", ""},
- {SCE_PASS_EMIT, "EMIT", 0, "Emit", ""},
- {SCE_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
- {SCE_PASS_INDEXMA, "MATERIAL_INDEX", 0, "Material Index", ""},
- {SCE_PASS_DIFFUSE_DIRECT, "DIFFUSE_DIRECT", 0, "Diffuse Direct", ""},
- {SCE_PASS_DIFFUSE_INDIRECT, "DIFFUSE_INDIRECT", 0, "Diffuse Indirect", ""},
- {SCE_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""},
- {SCE_PASS_GLOSSY_DIRECT, "GLOSSY_DIRECT", 0, "Glossy Direct", ""},
- {SCE_PASS_GLOSSY_INDIRECT, "GLOSSY_INDIRECT", 0, "Glossy Indirect", ""},
- {SCE_PASS_GLOSSY_COLOR, "GLOSSY_COLOR", 0, "Glossy Color", ""},
- {SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""},
- {SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""},
- {SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""},
- {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", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
srna = RNA_def_struct(brna, "RenderPass", NULL);
RNA_def_struct_ui_text(srna, "Render Pass", "");
@@ -641,7 +692,7 @@ static void rna_def_render_pass(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "passtype");
- RNA_def_property_enum_items(prop, pass_type_items);
+ RNA_def_property_enum_items(prop, render_pass_type_items);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "rect", PROP_FLOAT, PROP_NONE);
@@ -653,12 +704,56 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_define_verify_sdna(1);
}
+static void rna_def_render_bake_pixel(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BakePixel", NULL);
+ RNA_def_struct_ui_text(srna, "Bake Pixel", "");
+
+ RNA_define_verify_sdna(0);
+
+ prop = RNA_def_property(srna, "primitive_id", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "primitive_id");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_sdna(prop, NULL, "uv");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "du_dx", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "du_dx");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "du_dy", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "du_dy");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "dv_dx", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dv_dx");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "dv_dy", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dv_dy");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "next", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "BakePixel");
+ RNA_def_property_pointer_funcs(prop, "rna_BakePixel_next_get", NULL, NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ RNA_define_verify_sdna(1);
+}
+
void RNA_def_render(BlenderRNA *brna)
{
rna_def_render_engine(brna);
rna_def_render_result(brna);
rna_def_render_layer(brna);
rna_def_render_pass(brna);
+ rna_def_render_bake_pixel(brna);
}
#endif /* RNA_RUNTIME */
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 6e24397d066..78cd8d4bad4 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -825,7 +825,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
/* Dynamics Parameters - Deactivation */
prop = RNA_def_property(srna, "use_deactivation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_DEACTIVATION);
- RNA_def_property_boolean_default(prop, TRUE);
+ RNA_def_property_boolean_default(prop, true);
RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_activation_state_set");
RNA_def_property_ui_text(prop, "Enable Deactivation",
"Enable deactivation of resting rigid bodies (increases performance and stability "
@@ -897,7 +897,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
/* Collision Parameters - Sensitivity */
prop = RNA_def_property(srna, "use_margin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_MARGIN);
- RNA_def_property_boolean_default(prop, FALSE);
+ RNA_def_property_boolean_default(prop, false);
RNA_def_property_ui_text(prop, "Collision Margin",
"Use custom collision margin (some shapes will have a visible gap around them)");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_reset");
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 8d7a679bea2..8f2537105c1 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -253,7 +253,7 @@ static void rna_inheritance_functions_listbase_next(CollectionPropertyIterator *
static void rna_Struct_properties_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
IDProperty *group;
if (internal->flag) {
@@ -271,7 +271,7 @@ static void rna_Struct_properties_next(CollectionPropertyIterator *iter)
if (group) {
rna_iterator_listbase_end(iter);
rna_iterator_listbase_begin(iter, &group->data.group, rna_idproperty_known);
- internal = iter->internal;
+ internal = &iter->internal.listbase;
internal->flag = 1;
}
}
@@ -295,7 +295,7 @@ static void rna_Struct_properties_begin(CollectionPropertyIterator *iter, Pointe
static PointerRNA rna_Struct_properties_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
/* we return either PropertyRNA* or IDProperty*, the rna_access.c
* functions can handle both as PropertyRNA* with some tricks */
@@ -324,7 +324,7 @@ static void rna_Struct_functions_begin(CollectionPropertyIterator *iter, Pointer
static PointerRNA rna_Struct_functions_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
/* we return either PropertyRNA* or IDProperty*, the rna_access.c
* functions can handle both as PropertyRNA* with some tricks */
@@ -381,7 +381,7 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
propptr.data = prop;
*r_ptr = propptr;
- return TRUE;
+ return true;
}
}
else {
@@ -391,7 +391,7 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
propptr.data = prop;
*r_ptr = propptr;
- return TRUE;
+ return true;
}
}
}
@@ -413,13 +413,13 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
propptr.data = idp;
*r_ptr = propptr;
- return TRUE;
+ return true;
}
}
}
}
#endif
- return FALSE;
+ return false;
}
PointerRNA rna_builtin_type_get(PointerRNA *ptr)
@@ -821,7 +821,9 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA
(ptr->type == &RNA_EnumProperty) ||
(C == NULL))
{
- return eprop->item;
+ if (eprop->item) {
+ return eprop->item;
+ }
}
return eprop->itemf(C, ptr, prop, r_free);
@@ -990,10 +992,10 @@ static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, Pointer
if (srna) {
RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
@@ -1002,11 +1004,11 @@ static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key
for (; srna; srna = srna->cont.next) {
if (key[0] == srna->identifier[0] && strcmp(key, srna->identifier) == 0) {
RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
@@ -1086,7 +1088,7 @@ static void rna_def_property(BlenderRNA *brna)
static EnumPropertyItem subtype_items[] = {
{PROP_NONE, "NONE", 0, "None", ""},
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
- {PROP_DIRPATH, "DIRECTORY_PATH", 0, "Directory Path", ""},
+ {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
{PROP_PIXEL, "PIXEL", 0, "Pixel", ""},
{PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned Number", ""},
{PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index a98737e500b..bf2858c44e6 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -43,6 +43,7 @@
#include "BKE_freestyle.h"
#include "BKE_editmesh.h"
#include "BKE_paint.h"
+#include "BKE_scene.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -74,6 +75,17 @@
#include "BLI_threads.h"
+#ifdef WITH_OPENEXR
+EnumPropertyItem exr_codec_items[] = {
+ {R_IMF_EXR_CODEC_NONE, "NONE", 0, "None", ""},
+ {R_IMF_EXR_CODEC_PXR24, "PXR24", 0, "Pxr24 (lossy)", ""},
+ {R_IMF_EXR_CODEC_ZIP, "ZIP", 0, "ZIP (lossless)", ""},
+ {R_IMF_EXR_CODEC_PIZ, "PIZ", 0, "PIZ (lossless)", ""},
+ {R_IMF_EXR_CODEC_RLE, "RLE", 0, "RLE (lossless)", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+#endif
+
EnumPropertyItem uv_sculpt_relaxation_items[] = {
{UV_SCULPT_TOOL_RELAX_LAPLACIAN, "LAPLACIAN", 0, "Laplacian", "Use Laplacian method for relaxation"},
{UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"},
@@ -294,6 +306,28 @@ EnumPropertyItem image_color_depth_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem normal_space_items[] = {
+ {R_BAKE_SPACE_OBJECT, "OBJECT", 0, "Object", "Bake the normals in object space"},
+ {R_BAKE_SPACE_TANGENT, "TANGENT", 0, "Tangent", "Bake the normals in tangent space"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem normal_swizzle_items[] = {
+ {R_BAKE_POSX, "POS_X", 0, "+X", ""},
+ {R_BAKE_POSY, "POS_Y", 0, "+Y", ""},
+ {R_BAKE_POSZ, "POS_Z", 0, "+Z", ""},
+ {R_BAKE_NEGX, "NEG_X", 0, "-X", ""},
+ {R_BAKE_NEGY, "NEG_Y", 0, "-Y", ""},
+ {R_BAKE_NEGZ, "NEG_Z", 0, "-Z", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem bake_save_mode_items[] = {
+ {R_BAKE_SAVE_INTERNAL, "INTERNAL", 0, "Internal", "Save the baking map in an internal image datablock"},
+ {R_BAKE_SAVE_EXTERNAL, "EXTERNAL", 0, "External", "Save the baking map in an external file"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "DNA_anim_types.h"
@@ -347,16 +381,16 @@ static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key
for (base = scene->base.first; base; base = base->next) {
if (strncmp(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2) == 0) {
*r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBase, base);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
/* we are actually iterating a Base list, so override get */
return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base *)internal->link)->object);
@@ -663,7 +697,7 @@ static void rna_Scene_all_keyingsets_begin(CollectionPropertyIterator *iter, Poi
static void rna_Scene_all_keyingsets_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
KeyingSet *ks = (KeyingSet *)internal->link;
/* if we've run out of links in Scene list, jump over to the builtins list unless we're there already */
@@ -729,7 +763,7 @@ static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value)
ID *id = ptr->id.data;
const char is_render = (id && GS(id->name) == ID_SCE);
/* see note below on why this is */
- const char chan_flag = BKE_imtype_valid_channels(imf->imtype) | (is_render ? IMA_CHAN_FLAG_BW : 0);
+ const char chan_flag = BKE_imtype_valid_channels(imf->imtype, true) | (is_render ? IMA_CHAN_FLAG_BW : 0);
imf->imtype = value;
@@ -800,7 +834,7 @@ static EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext *UNUS
* where 'BW' will force grayscale even if the output format writes
* as RGBA, this is age old blender convention and not sure how useful
* it really is but keep it for now - campbell */
- char chan_flag = BKE_imtype_valid_channels(imf->imtype) | (is_render ? IMA_CHAN_FLAG_BW : 0);
+ char chan_flag = BKE_imtype_valid_channels(imf->imtype, true) | (is_render ? IMA_CHAN_FLAG_BW : 0);
#ifdef WITH_FFMPEG
/* a WAY more crappy case than B&W flag: depending on codec, file format MIGHT support
@@ -1056,6 +1090,7 @@ static SceneRenderLayer *rna_RenderLayer_new(ID *id, RenderData *UNUSED(rd), con
Scene *scene = (Scene *)id;
SceneRenderLayer *srl = BKE_scene_add_render_layer(scene, name);
+ DAG_id_tag_update(&scene->id, 0);
WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
return srl;
@@ -1075,6 +1110,7 @@ static void rna_RenderLayer_remove(ID *id, RenderData *UNUSED(rd), Main *bmain,
RNA_POINTER_INVALIDATE(srl_ptr);
+ DAG_id_tag_update(&scene->id, 0);
WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
}
@@ -1399,7 +1435,7 @@ static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[], int frame)
static void rna_TimeLine_remove(Scene *scene, ReportList *reports, PointerRNA *marker_ptr)
{
TimeMarker *marker = marker_ptr->data;
- if (BLI_remlink_safe(&scene->markers, marker) == FALSE) {
+ if (BLI_remlink_safe(&scene->markers, marker) == false) {
BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'",
marker->name, scene->id.name + 2);
return;
@@ -1547,6 +1583,34 @@ static void rna_FreestyleLineSet_linestyle_set(PointerRNA *ptr, PointerRNA value
lineset->linestyle->id.us++;
}
+static FreestyleLineSet *FreestyleSettings_lineset_add(ID *id, struct FreestyleSettings *config, const char *name)
+{
+ Scene *scene = (Scene *)id;
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_add((FreestyleConfig *)config, name);
+
+ DAG_id_tag_update(&scene->id, 0);
+ WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ return lineset;
+}
+
+static void FreestyleSettings_lineset_remove(ID *id, struct FreestyleSettings *config, ReportList *reports,
+ PointerRNA *lineset_ptr)
+{
+ FreestyleLineSet *lineset = lineset_ptr->data;
+ Scene *scene = (Scene *)id;
+
+ if (!BKE_freestyle_lineset_delete((FreestyleConfig *)config, lineset)) {
+ BKE_reportf(reports, RPT_ERROR, "Line set '%s' could not be removed", lineset->name);
+ return;
+ }
+
+ RNA_POINTER_INVALIDATE(lineset_ptr);
+
+ DAG_id_tag_update(&scene->id, 0);
+ WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
+}
+
static PointerRNA rna_FreestyleSettings_active_lineset_get(PointerRNA *ptr)
{
FreestyleConfig *config = (FreestyleConfig *)ptr->data;
@@ -2251,6 +2315,8 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
else RNA_def_property_boolean_funcs(prop, NULL, "rna_RenderLayer_layer_set");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ /* this seems to be too much trouble with depsgraph updates/etc. currently (20140423) */
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "layers_zmask", PROP_BOOLEAN, PROP_LAYER);
RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1);
@@ -2344,10 +2410,8 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "layflag", SCE_LAY_FRS);
RNA_def_property_ui_text(prop, "Freestyle", "Render stylized strokes in this Layer");
- if (scene)
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- else
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
/* passes */
prop = RNA_def_property(srna, "use_pass_combined", PROP_BOOLEAN, PROP_NONE);
@@ -2591,6 +2655,8 @@ static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
RNA_def_property_srna(cprop, "Linesets");
srna = RNA_def_struct(brna, "Linesets", NULL);
@@ -2609,6 +2675,21 @@ static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop)
"rna_FreestyleSettings_active_lineset_index_range");
RNA_def_property_ui_text(prop, "Active Line Set Index", "Index of active line set slot");
RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ func = RNA_def_function(srna, "new", "FreestyleSettings_lineset_add");
+ RNA_def_function_ui_description(func, "Add a line set to scene render layer Freestyle settings");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ parm = RNA_def_string(func, "name", "LineSet", 0, "", "New name for the line set (not unique)");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "lineset", "FreestyleLineSet", "", "Newly created line set");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "FreestyleSettings_lineset_remove");
+ RNA_def_function_ui_description(func, "Remove a line set from scene render layer Freestyle settings");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "lineset", "FreestyleLineSet", "", "Line set to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
}
static void rna_def_freestyle_settings(BlenderRNA *brna)
@@ -2624,9 +2705,9 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
};
static EnumPropertyItem edge_type_combination_items[] = {
- {0, "OR", 0, "Logical OR", "Combine feature edge type conditions by logical OR (logical disjunction)"},
+ {0, "OR", 0, "Logical OR", "Select feature edges satisfying at least one of edge type conditions"},
{FREESTYLE_LINESET_FE_AND, "AND", 0, "Logical AND",
- "Combine feature edge type conditions by logical AND (logical conjunction)"},
+ "Select feature edges satisfying all edge type conditions"},
{0, NULL, 0, NULL, NULL}
};
@@ -2645,15 +2726,15 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
};
static EnumPropertyItem face_mark_condition_items[] = {
- {0, "ONE", 0, "One Face", "Select feature edges if one of faces on the right and left has a face mark"},
+ {0, "ONE", 0, "One Face", "Select a feature edge if either of its adjacent faces is marked"},
{FREESTYLE_LINESET_FM_BOTH, "BOTH", 0, "Both Faces",
- "Select feature edges if both faces on the right and left faces have a face mark"},
+ "Select a feature edge if both of its adjacent faces are marked"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem freestyle_ui_mode_items[] = {
{FREESTYLE_CONTROL_SCRIPT_MODE, "SCRIPT", 0, "Python Scripting Mode",
- "Advanced mode for using style modules in Python"},
+ "Advanced mode for using style modules written in Python"},
{FREESTYLE_CONTROL_EDITOR_MODE, "EDITOR", 0, "Parameter Editor Mode",
"Basic mode for interactive style parameter editing"},
{0, NULL, 0, NULL, NULL}
@@ -2724,14 +2805,14 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, edge_type_negation_items);
RNA_def_property_ui_text(prop, "Edge Type Negation",
- "Set the negation operation for conditions on feature edge types");
+ "Specify either inclusion or exclusion of feature edges selected by edge types");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "edge_type_combination", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, edge_type_combination_items);
RNA_def_property_ui_text(prop, "Edge Type Combination",
- "Set the combination operation for conditions on feature edge types");
+ "Specify a logical combination of selection conditions on feature edge types");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
@@ -2745,45 +2826,45 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, group_negation_items);
RNA_def_property_ui_text(prop, "Group Negation",
- "Set the negation operation for conditions on feature edge types");
+ "Specify either inclusion or exclusion of feature edges belonging to a group of objects");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "face_mark_negation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, face_mark_negation_items);
RNA_def_property_ui_text(prop, "Face Mark Negation",
- "Set the negation operation for the condition on face marks");
+ "Specify either inclusion or exclusion of feature edges selected by face marks");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "face_mark_condition", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
RNA_def_property_enum_items(prop, face_mark_condition_items);
- RNA_def_property_ui_text(prop, "Face Mark Condition", "Set a feature edge selection condition on face marks");
+ RNA_def_property_ui_text(prop, "Face Mark Condition", "Specify a feature edge selection condition based on face marks");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_silhouette", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_SILHOUETTE);
- RNA_def_property_ui_text(prop, "Silhouette", "Select silhouette edges");
+ RNA_def_property_ui_text(prop, "Silhouette", "Select silhouettes (edges at the boundary of visible and hidden faces)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_BORDER);
- RNA_def_property_ui_text(prop, "Border", "Select border edges");
+ RNA_def_property_ui_text(prop, "Border", "Select border edges (open mesh edges)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_crease", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_CREASE);
- RNA_def_property_ui_text(prop, "Crease", "Select crease edges");
+ RNA_def_property_ui_text(prop, "Crease", "Select crease edges (those between two faces making an angle smaller than the Crease Angle)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_ridge_valley", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_RIDGE_VALLEY);
- RNA_def_property_ui_text(prop, "Ridge & Valley", "Select ridges and valleys");
+ RNA_def_property_ui_text(prop, "Ridge & Valley", "Select ridges and valleys (boundary lines between convex and concave areas of surface)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_suggestive_contour", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_SUGGESTIVE_CONTOUR);
- RNA_def_property_ui_text(prop, "Suggestive Contour", "Select suggestive contours");
+ RNA_def_property_ui_text(prop, "Suggestive Contour", "Select suggestive contours (almost silhouette/contour edges)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_material_boundary", PROP_BOOLEAN, PROP_NONE);
@@ -2793,17 +2874,17 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "select_contour", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_CONTOUR);
- RNA_def_property_ui_text(prop, "Contour", "Select contours");
+ RNA_def_property_ui_text(prop, "Contour", "Select contours (outer silhouettes of each object)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_external_contour", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_EXTERNAL_CONTOUR);
- RNA_def_property_ui_text(prop, "External Contour", "Select external contours");
+ RNA_def_property_ui_text(prop, "External Contour", "Select external contours (outer silhouettes of occluding and occluded objects)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "select_edge_mark", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_EDGE_MARK);
- RNA_def_property_ui_text(prop, "Edge Mark", "Select edge marks");
+ RNA_def_property_ui_text(prop, "Edge Mark", "Select edge marks (edges annotated by Freestyle edge marks)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "exclude_silhouette", PROP_BOOLEAN, PROP_NONE);
@@ -3059,6 +3140,110 @@ static void rna_def_scene_game_recast_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE, NULL);
}
+
+static void rna_def_bake_data(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BakeSettings", NULL);
+ RNA_def_struct_sdna(srna, "BakeData");
+ RNA_def_struct_nested(brna, srna, "RenderSettings");
+ RNA_def_struct_ui_text(srna, "Bake Data", "Bake data for a Scene datablock");
+
+ prop = RNA_def_property(srna, "cage", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Cage", "Object to use as cage");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_ui_text(prop, "File Path", "Image filepath to use when saving externally");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "width", PROP_INT, PROP_PIXEL);
+ RNA_def_property_range(prop, 4, 10000);
+ RNA_def_property_ui_text(prop, "Width", "Horizontal dimension of the baking map");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "height", PROP_INT, PROP_PIXEL);
+ RNA_def_property_range(prop, 4, 10000);
+ RNA_def_property_ui_text(prop, "Height", "Vertical dimension of the baking map");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "margin", PROP_INT, PROP_PIXEL);
+ RNA_def_property_range(prop, 0, SHRT_MAX);
+ RNA_def_property_ui_range(prop, 0, 64, 1, 1);
+ RNA_def_property_ui_text(prop, "Margin", "Extends the baked result as a post process filter");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "cage_extrusion", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, MAXFLOAT);
+ RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3);
+ RNA_def_property_ui_text(prop, "Cage Extrusion",
+ "Distance to use for the inward ray cast when using selected to active");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "normal_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "normal_space");
+ RNA_def_property_enum_items(prop, normal_space_items);
+ RNA_def_property_ui_text(prop, "Normal Space", "Choose normal space for baking");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "normal_r", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "normal_swizzle[0]");
+ RNA_def_property_enum_items(prop, normal_swizzle_items);
+ RNA_def_property_ui_text(prop, "Normal Space", "Axis to bake in red channel");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "normal_g", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "normal_swizzle[1]");
+ RNA_def_property_enum_items(prop, normal_swizzle_items);
+ RNA_def_property_ui_text(prop, "Normal Space", "Axis to bake in green channel");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "normal_b", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "normal_swizzle[2]");
+ RNA_def_property_enum_items(prop, normal_swizzle_items);
+ RNA_def_property_ui_text(prop, "Normal Space", "Axis to bake in blue channel");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "image_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "im_format");
+ RNA_def_property_struct_type(prop, "ImageFormatSettings");
+ RNA_def_property_ui_text(prop, "Image Format", "");
+
+ prop = RNA_def_property(srna, "save_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "save_mode");
+ RNA_def_property_enum_items(prop, bake_save_mode_items);
+ RNA_def_property_ui_text(prop, "Save Mode", "Choose how to save the baking map");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ /* flags */
+ prop = RNA_def_property(srna, "use_selected_to_active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", R_BAKE_TO_ACTIVE);
+ RNA_def_property_ui_text(prop, "Selected to Active",
+ "Bake shading on the surface of selected objects to the active object");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_clear", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", R_BAKE_CLEAR);
+ RNA_def_property_ui_text(prop, "Clear",
+ "Clear Images before baking (internal only)");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_split_materials", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", R_BAKE_SPLIT_MAT);
+ RNA_def_property_ui_text(prop, "Split Materials",
+ "Split external images per material (external only)");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_automatic_name", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", R_BAKE_AUTO_NAME);
+ RNA_def_property_ui_text(prop, "Automatic Name",
+ "Automatically name the output file with the pass type (external only)");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+}
+
static void rna_def_scene_game_data(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3588,16 +3773,6 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_scene_image_format_data(BlenderRNA *brna)
{
-#ifdef WITH_OPENEXR
- static EnumPropertyItem exr_codec_items[] = {
- {R_IMF_EXR_CODEC_NONE, "NONE", 0, "None", ""},
- {R_IMF_EXR_CODEC_PXR24, "PXR24", 0, "Pxr24 (lossy)", ""},
- {R_IMF_EXR_CODEC_ZIP, "ZIP", 0, "ZIP (lossless)", ""},
- {R_IMF_EXR_CODEC_PIZ, "PIZ", 0, "PIZ (lossless)", ""},
- {R_IMF_EXR_CODEC_RLE, "RLE", 0, "RLE (lossless)", ""},
- {0, NULL, 0, NULL, NULL}
- };
-#endif
#ifdef WITH_OPENJPEG
static EnumPropertyItem jp2_codec_items[] = {
@@ -4093,7 +4268,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
static EnumPropertyItem raytrace_structure_items[] = {
{R_RAYSTRUCTURE_AUTO, "AUTO", 0, "Auto", "Automatically select acceleration structure"},
{R_RAYSTRUCTURE_OCTREE, "OCTREE", 0, "Octree", "Use old Octree structure"},
- {R_RAYSTRUCTURE_BLIBVH, "BLIBVH", 0, "BLI BVH", "Use BLI K-Dop BVH.c"},
{R_RAYSTRUCTURE_VBVH, "VBVH", 0, "vBVH", "Use vBVH"},
{R_RAYSTRUCTURE_SIMD_SVBVH, "SIMD_SVBVH", 0, "SIMD SVBVH", "Use SIMD SVBVH"},
{R_RAYSTRUCTURE_SIMD_QBVH, "SIMD_QBVH", 0, "SIMD QBVH", "Use SIMD QBVH"},
@@ -4870,6 +5044,21 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 0.f, 10000.f);
RNA_def_property_ui_text(prop, "Line Thickness", "Line thickness in pixels");
+ /* Bake Settings */
+ prop = RNA_def_property(srna, "bake", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "bake");
+ RNA_def_property_struct_type(prop, "BakeSettings");
+ RNA_def_property_ui_text(prop, "Bake Data", "");
+
+ /* Nestled Data */
+ /* *** Non-Animated *** */
+ RNA_define_animate_sdna(false);
+ rna_def_bake_data(brna);
+ RNA_define_animate_sdna(true);
+
+ /* *** Animated *** */
+
/* Scene API */
RNA_api_scene_render(srna);
}
@@ -5233,6 +5422,14 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Preview Range End Frame", "Alternative end frame for UI playback");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
+ /* Timeline / Time Navigation settings */
+ prop = RNA_def_property(srna, "show_keys_from_selected_only", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SCE_KEYS_NO_SELONLY);
+ RNA_def_property_ui_text(prop, "Only Keyframes from Selected Channels",
+ "Consider keyframes for active Object and/or its selected bones only "
+ "(in timeline and when jumping between keyframes)");
+ RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
+
/* Stamp */
prop = RNA_def_property(srna, "use_stamp_note", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "r.stamp_udata");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a4f1f84f94d..84134e7cd3a 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -69,7 +69,8 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
BPy_BEGIN_ALLOW_THREADS;
#endif
- BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, (1 << 20) - 1);
+ /* It's possible that here we're including layers which were never visible before. */
+ BKE_scene_update_for_newframe_ex(G.main->eval_ctx, G.main, scene, (1 << 20) - 1, true);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -107,8 +108,8 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name
if (BKE_imtype_is_movie(rd->im_format.imtype))
BKE_movie_filepath_get(name, rd);
else
- BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame, &rd->im_format,
- rd->scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame,
+ &rd->im_format, (rd->scemode & R_EXTENSION) != 0, true);
}
static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3],
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 5f652601637..e0431fcff16 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -60,6 +60,10 @@ EnumPropertyItem region_type_items[] = {
#include "UI_view2d.h"
+#ifdef WITH_PYTHON
+# include "BPY_extern.h"
+#endif
+
static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
{
bScreen *sc = (bScreen *)ptr->data;
@@ -76,7 +80,16 @@ static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
/* exception: must use context so notifier gets to the right window */
if (sc->newscene) {
+#ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+#endif
+
ED_screen_set_scene(C, sc, sc->newscene);
+
+#ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+#endif
+
WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, sc->newscene);
if (G.debug & G_DEBUG)
@@ -144,7 +157,7 @@ static void rna_Area_type_update(bContext *C, PointerRNA *ptr)
/* It is possible that new layers becomes visible. */
if (sa->spacetype == SPACE_VIEW3D) {
- DAG_on_visible_update(CTX_data_main(C), FALSE);
+ DAG_on_visible_update(CTX_data_main(C), false);
}
CTX_wm_window_set(C, prevwin);
@@ -163,9 +176,9 @@ static void rna_View2D_region_to_view(struct View2D *v2d, int x, int y, float re
static void rna_View2D_view_to_region(struct View2D *v2d, float x, float y, int clip, int result[2])
{
if (clip)
- UI_view2d_view_to_region(v2d, x, y, &result[0], &result[1]);
+ UI_view2d_view_to_region_clip(v2d, x, y, &result[0], &result[1]);
else
- UI_view2d_to_region_no_clip(v2d, x, y, &result[0], &result[1]);
+ UI_view2d_view_to_region(v2d, x, y, &result[0], &result[1]);
}
#else
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 75a00581611..54af55260e5 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -357,6 +357,14 @@ static void rna_def_sculpt(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem detail_type_items[] = {
+ {0, "RELATIVE", 0,
+ "Relative Detail", "Mesh detail is relative to the brush size and detail size"},
+ {SCULPT_DYNTOPO_DETAIL_CONSTANT, "CONSTANT", 0,
+ "Constant Detail", "Mesh detail is constant in object space according to detail size"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
StructRNA *srna;
PropertyRNA *prop;
@@ -406,9 +414,16 @@ static void rna_def_sculpt(BlenderRNA *brna)
"Show diffuse color of object and overlay sculpt mask on top of it");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowDiffuseColor_update");
- prop = RNA_def_property(srna, "detail_size", PROP_INT, PROP_PIXEL);
- RNA_def_property_ui_range(prop, 2, 100, 0, -1);
+ prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_PIXEL);
+ RNA_def_property_ui_range(prop, 0.5, 40.0, 10, 2);
RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (in pixels)");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "constant_detail", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_range(prop, 0.001, 10000.0);
+ RNA_def_property_ui_range(prop, 0.1, 100.0, 10, 2);
+ RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (as percentage of blender unit)");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_smooth_shading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_SMOOTH_SHADING);
@@ -428,6 +443,13 @@ static void rna_def_sculpt(BlenderRNA *brna)
"In dynamic-topology mode, how to add or remove mesh detail");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ prop = RNA_def_property(srna, "detail_type_method", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
+ RNA_def_property_enum_items(prop, detail_type_items);
+ RNA_def_property_ui_text(prop, "Detail Type Method",
+ "In dynamic-topology mode, how mesh detail size is calculated");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
prop = RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "gravity_factor");
RNA_def_property_range(prop, 0.0f, 1.0f);
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index e570daa8281..f5e59119baa 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -296,6 +296,11 @@ static void rna_def_sensor(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1);
RNA_def_property_update(prop, NC_LOGIC, NULL);
+ prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SENS_DEACTIVATE);
+ RNA_def_property_ui_text(prop, "Active", "Set active state of the sensor");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_SHOW);
RNA_def_property_ui_text(prop, "Expanded", "Set sensor expanded in the user interface");
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index ba5f42f311f..d478bf41287 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -76,6 +76,8 @@ EnumPropertyItem sequence_modifier_type_items[] = {
#include "WM_api.h"
#include "WM_types.h"
+#include "IMB_imbuf.h"
+
typedef struct SequenceSearchData {
Sequence *seq;
void *data;
@@ -96,7 +98,7 @@ static void meta_tmp_ref(Sequence *seq_par, Sequence *seq)
static void rna_SequenceElement_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
StripElem *se = (StripElem *)ptr->data;
@@ -113,7 +115,7 @@ static void rna_SequenceElement_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
static void rna_Sequence_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq = (Sequence *) ptr->data;
@@ -125,7 +127,7 @@ static void rna_Sequence_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
static void rna_SequenceEditor_sequences_all_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
meta_tmp_ref(NULL, ed->seqbase.first);
@@ -134,7 +136,7 @@ static void rna_SequenceEditor_sequences_all_begin(CollectionPropertyIterator *i
static void rna_SequenceEditor_sequences_all_next(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
Sequence *seq = (Sequence *)internal->link;
if (seq->seqbase.first)
@@ -177,7 +179,7 @@ static void rna_SequenceEditor_elements_begin(CollectionPropertyIterator *iter,
static void do_sequence_frame_change_update(Scene *scene, Sequence *seq)
{
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
Sequence *tseq;
BKE_sequence_calc_disp(scene, seq);
@@ -245,7 +247,7 @@ static void rna_Sequence_anim_startofs_final_set(PointerRNA *ptr, int value)
seq->anim_startofs = MIN2(value, seq->len + seq->anim_startofs);
- BKE_sequence_reload_new_file(scene, seq, FALSE);
+ BKE_sequence_reload_new_file(scene, seq, false);
do_sequence_frame_change_update(scene, seq);
}
@@ -256,7 +258,7 @@ static void rna_Sequence_anim_endofs_final_set(PointerRNA *ptr, int value)
seq->anim_endofs = MIN2(value, seq->len + seq->anim_endofs);
- BKE_sequence_reload_new_file(scene, seq, FALSE);
+ BKE_sequence_reload_new_file(scene, seq, false);
do_sequence_frame_change_update(scene, seq);
}
@@ -272,7 +274,7 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
static int rna_Sequence_frame_length_get(PointerRNA *ptr)
{
Sequence *seq = (Sequence *)ptr->data;
- return BKE_sequence_tx_get_final_right(seq, 0) - BKE_sequence_tx_get_final_left(seq, 0);
+ return BKE_sequence_tx_get_final_right(seq, false) - BKE_sequence_tx_get_final_left(seq, false);
}
static int rna_Sequence_frame_editable(PointerRNA *ptr)
@@ -286,7 +288,7 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
{
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
seq->machine = value;
@@ -369,7 +371,7 @@ static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transfor
static char *rna_SequenceTransform_path(PointerRNA *ptr)
{
Scene *scene = ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_transform(ed, ptr->data);
if (seq && seq->name + 2) {
@@ -386,7 +388,7 @@ static char *rna_SequenceTransform_path(PointerRNA *ptr)
static void rna_SequenceTransform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_transform(ed, ptr->data);
BKE_sequence_invalidate_cache(scene, seq);
@@ -419,7 +421,7 @@ static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop)
static char *rna_SequenceCrop_path(PointerRNA *ptr)
{
Scene *scene = ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_crop(ed, ptr->data);
if (seq && seq->name + 2) {
@@ -436,7 +438,7 @@ static char *rna_SequenceCrop_path(PointerRNA *ptr)
static void rna_SequenceCrop_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_crop(ed, ptr->data);
BKE_sequence_invalidate_cache(scene, seq);
@@ -554,7 +556,7 @@ static char *rna_Sequence_path(PointerRNA *ptr)
static PointerRNA rna_SequenceEditor_meta_stack_get(CollectionPropertyIterator *iter)
{
- ListBaseIterator *internal = iter->internal;
+ ListBaseIterator *internal = &iter->internal.listbase;
MetaStack *ms = (MetaStack *)internal->link;
return rna_pointer_inherit_refine(&iter->parent, &RNA_Sequence, ms->parseq);
@@ -601,6 +603,10 @@ static void rna_Sequence_proxy_filepath_set(PointerRNA *ptr, const char *value)
{
StripProxy *proxy = (StripProxy *)(ptr->data);
BLI_split_dirfile(value, proxy->dir, proxy->file, sizeof(proxy->dir), sizeof(proxy->file));
+ if (proxy->anim) {
+ IMB_free_anim(proxy->anim);
+ proxy->anim = NULL;
+ }
}
static void rna_Sequence_proxy_filepath_get(PointerRNA *ptr, char *value)
@@ -672,9 +678,9 @@ static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value)
static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
- BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
if (RNA_struct_is_a(ptr->type, &RNA_SoundSequence))
BKE_sequencer_update_sound_bounds(scene, ptr->data);
@@ -683,7 +689,7 @@ static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *UNUSED(
static void rna_Sequence_mute_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
BKE_sequencer_update_muting(ed);
rna_Sequence_update(bmain, scene, ptr);
@@ -693,7 +699,7 @@ static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), Poin
{
Scene *scene = (Scene *) ptr->id.data;
Sequence *seq = (Sequence *)(ptr->data);
- BKE_sequence_reload_new_file(scene, seq, TRUE);
+ BKE_sequence_reload_new_file(scene, seq, true);
BKE_sequence_calc(scene, seq);
rna_Sequence_update(bmain, scene, ptr);
}
@@ -723,17 +729,17 @@ static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
static void rna_Sequence_tcindex_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
- BKE_sequence_reload_new_file(scene, seq, FALSE);
+ BKE_sequence_reload_new_file(scene, seq, false);
do_sequence_frame_change_update(scene, seq);
}
static void rna_SequenceProxy_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
BKE_sequence_invalidate_cache(scene, seq);
@@ -795,7 +801,7 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
{
Scene *scene = ptr->id.data;
SequenceModifierData *smd;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data, &smd);
if (seq && seq->name + 2) {
@@ -825,7 +831,7 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
SequenceModifierData *smd;
Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data, &smd);
@@ -838,7 +844,7 @@ static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *UNUSED(s
static void rna_SequenceEditor_overlay_lock_set(PointerRNA *ptr, int value)
{
Scene *scene = ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL)
return;
@@ -857,7 +863,7 @@ static void rna_SequenceEditor_overlay_lock_set(PointerRNA *ptr, int value)
static int rna_SequenceEditor_overlay_frame_get(PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL)
return scene->r.cfra;
@@ -872,7 +878,7 @@ static int rna_SequenceEditor_overlay_frame_get(PointerRNA *ptr)
static void rna_SequenceEditor_overlay_frame_set(PointerRNA *ptr, int value)
{
Scene *scene = (Scene *)ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL)
return;
@@ -930,7 +936,7 @@ static StructRNA *rna_SequenceModifier_refine(struct PointerRNA *ptr)
static char *rna_SequenceModifier_path(PointerRNA *ptr)
{
Scene *scene = ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
SequenceModifierData *smd = ptr->data;
Sequence *seq = sequence_get_by_modifier(ed, smd);
@@ -952,7 +958,7 @@ static void rna_SequenceModifier_name_set(PointerRNA *ptr, const char *value)
{
SequenceModifierData *smd = ptr->data;
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_modifier(ed, smd);
AnimData *adt;
char oldname[sizeof(smd->name)];
@@ -980,7 +986,7 @@ static void rna_SequenceModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene
{
/* strip from other scenes could be modified, so using active scene is not reliable */
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
BKE_sequence_invalidate_cache_for_modifier(scene, seq);
@@ -989,17 +995,14 @@ static void rna_SequenceModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene
static int rna_SequenceModifier_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
{
Scene *scene = (Scene *) ptr->id.data;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
Sequence *cur = (Sequence *) value.data;
if (seq == cur)
- return FALSE;
-
- if (BKE_sequence_check_depend(seq, cur))
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
static SequenceModifierData *rna_Sequence_modifier_new(Sequence *seq, bContext *C, ReportList *reports, const char *name, int type)
@@ -1028,7 +1031,7 @@ static void rna_Sequence_modifier_remove(Sequence *seq, bContext *C, ReportList
SequenceModifierData *smd = smd_ptr->data;
Scene *scene = CTX_data_scene(C);
- if (BKE_sequence_modifier_remove(seq, smd) == FALSE) {
+ if (BKE_sequence_modifier_remove(seq, smd) == false) {
BKE_report(reports, RPT_ERROR, "Modifier was not found in the stack");
return;
}
@@ -1224,19 +1227,19 @@ static void rna_def_color_balance(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Sequence Color Balance Data", "Color balance parameters for a sequence strip and it's modifiers");
RNA_def_struct_sdna(srna, "StripColorBalance");
- prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Lift", "Color balance lift (shadows)");
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
- prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Gamma", "Color balance gamma (midtones)");
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
- prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Gain", "Color balance gain (highlights)");
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
@@ -1556,13 +1559,13 @@ static void rna_def_editor(BlenderRNA *brna)
prop = RNA_def_property(srna, "sequences", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "seqbase", NULL);
RNA_def_property_struct_type(prop, "Sequence");
- RNA_def_property_ui_text(prop, "Sequences", "");
+ RNA_def_property_ui_text(prop, "Sequences", "Top-level strips only");
RNA_api_sequences(brna, prop);
prop = RNA_def_property(srna, "sequences_all", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "seqbase", NULL);
RNA_def_property_struct_type(prop, "Sequence");
- RNA_def_property_ui_text(prop, "Sequences", "");
+ RNA_def_property_ui_text(prop, "All Sequences", "All strips, recursively including those inside metastrips");
RNA_def_property_collection_funcs(prop, "rna_SequenceEditor_sequences_all_begin",
"rna_SequenceEditor_sequences_all_next", NULL, NULL, NULL, NULL, NULL, NULL);
@@ -2127,13 +2130,13 @@ static void rna_def_transform(StructRNA *srna)
prop = RNA_def_property(srna, "translate_start_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xIni");
RNA_def_property_ui_text(prop, "Translate X", "");
- RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 6);
+ RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "translate_start_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yIni");
RNA_def_property_ui_text(prop, "Translate Y", "");
- RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 6);
+ RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "rotation_start", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index aee9c054b6f..b3a37a4ce8e 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -325,7 +325,7 @@ static void rna_Sequences_remove(ID *id, Editing *ed, ReportList *reports, Point
Sequence *seq = seq_ptr->data;
Scene *scene = (Scene *)id;
- if (BLI_remlink_safe(&ed->seqbase, seq) == FALSE) {
+ if (BLI_remlink_safe(&ed->seqbase, seq) == false) {
BKE_reportf(reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2);
return;
}
@@ -336,7 +336,7 @@ static void rna_Sequences_remove(ID *id, Editing *ed, ReportList *reports, Point
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
}
-static StripElem *rna_SequenceElements_push(ID *id, Sequence *seq, const char *filename)
+static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char *filename)
{
Scene *scene = (Scene *)id;
StripElem *se;
@@ -430,7 +430,7 @@ void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "Sequence");
RNA_def_struct_ui_text(srna, "SequenceElements", "Collection of SequenceElement");
- func = RNA_def_function(srna, "push", "rna_SequenceElements_push");
+ func = RNA_def_function(srna, "append", "rna_SequenceElements_append");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Push an image from ImageSequence.directory");
parm = RNA_def_string(func, "filename", "File", 0, "", "Filepath to image");
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 502b547e4a6..6e0d374e3e9 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -36,6 +36,8 @@
#include "BKE_modifier.h"
#include "BKE_smoke.h"
+#include "BLI_threads.h"
+
#include "DNA_modifier_types.h"
#include "DNA_object_force.h"
#include "DNA_object_types.h"
@@ -125,33 +127,120 @@ static char *rna_SmokeCollSettings_path(PointerRNA *ptr)
return BLI_sprintfN("modifiers[\"%s\"].coll_settings", name_esc);
}
-static int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
+static int rna_SmokeModifier_grid_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
- SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
+#ifdef WITH_SMOKE
+ SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
+ float *density = NULL;
+ int size = 0;
- if (settings->fluid) {
- float *density = smoke_get_density(settings->fluid);
- unsigned int size = settings->res[0] * settings->res[1] * settings->res[2];
+ if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt) {
+ /* high resolution smoke */
+ int res[3];
- if (density)
- length[0] = size;
- else
- length[0] = 0;
+ smoke_turbulence_get_res(sds->wt, res);
+ size = res[0] * res[1] * res[2];
+
+ density = smoke_turbulence_get_density(sds->wt);
}
- else {
- length[0] = 0; /* No smoke domain created yet */
+ else if (sds->fluid) {
+ /* regular resolution */
+ size = sds->res[0] * sds->res[1] * sds->res[2];
+ density = smoke_get_density(sds->fluid);
}
+ length[0] = (density) ? size : 0;
+#else
+ (void)ptr;
+ length[0] = 0;
+#endif
return length[0];
}
-static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values)
+static int rna_SmokeModifier_color_grid_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
- SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
- float *density = smoke_get_density(settings->fluid);
- unsigned int size = settings->res[0] * settings->res[1] * settings->res[2];
+ rna_SmokeModifier_grid_get_length(ptr, length);
+
+ length[0] *= 4;
+ return length[0];
+}
+
+static void rna_SmokeModifier_density_grid_get(PointerRNA *ptr, float *values)
+{
+#ifdef WITH_SMOKE
+ SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
+ int length[RNA_MAX_ARRAY_DIMENSION];
+ int size = rna_SmokeModifier_grid_get_length(ptr, length);
+ float *density;
+
+ BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
+
+ if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt)
+ density = smoke_turbulence_get_density(sds->wt);
+ else
+ density = smoke_get_density(sds->fluid);
memcpy(values, density, size * sizeof(float));
+
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+#else
+ (void)ptr;
+ (void)values;
+#endif
+}
+
+static void rna_SmokeModifier_color_grid_get(PointerRNA *ptr, float *values)
+{
+#ifdef WITH_SMOKE
+ SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
+
+ BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
+
+ if (sds->flags & MOD_SMOKE_HIGHRES) {
+ if (smoke_turbulence_has_colors(sds->wt))
+ smoke_turbulence_get_rgba(sds->wt, values, 0);
+ else
+ smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, values, 0);
+ }
+ else {
+ if (smoke_has_colors(sds->fluid))
+ smoke_get_rgba(sds->fluid, values, 0);
+ else
+ smoke_get_rgba_from_density(sds->fluid, sds->active_color, values, 0);
+ }
+
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+#else
+ (void)ptr;
+ memset(values, 0, 4 * sizeof(float));
+#endif
+}
+
+static void rna_SmokeModifier_flame_grid_get(PointerRNA *ptr, float *values)
+{
+#ifdef WITH_SMOKE
+ SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
+ int length[RNA_MAX_ARRAY_DIMENSION];
+ int size = rna_SmokeModifier_grid_get_length(ptr, length);
+ float *flame;
+
+ BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
+
+ if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt)
+ flame = smoke_turbulence_get_flame(sds->wt);
+ else
+ flame = smoke_get_flame(sds->fluid);
+
+ if (flame)
+ memcpy(values, flame, size * sizeof(float));
+ else
+ memset(values, 0, size * sizeof(float));
+
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+#else
+ (void)ptr;
+ (void)values;
+#endif
}
static void rna_SmokeFlow_density_vgroup_get(PointerRNA *ptr, char *value)
@@ -356,13 +445,29 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache");
- prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "density_grid", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_array(prop, 32);
+ RNA_def_property_flag(prop, PROP_DYNAMIC);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_grid_get_length");
+ RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_grid_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Density Grid", "Smoke density grid");
+
+ prop = RNA_def_property(srna, "flame_grid", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_array(prop, 32);
+ RNA_def_property_flag(prop, PROP_DYNAMIC);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_grid_get_length");
+ RNA_def_property_float_funcs(prop, "rna_SmokeModifier_flame_grid_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Flame Grid", "Smoke flame grid");
+
+ prop = RNA_def_property(srna, "color_grid", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 32);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_density_get_length");
- RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_get", NULL, NULL);
- RNA_def_property_ui_text(prop, "Density", "Smoke density");
+ RNA_def_property_dynamic_array_funcs(prop, "rna_SmokeModifier_color_grid_get_length");
+ RNA_def_property_float_funcs(prop, "rna_SmokeModifier_color_grid_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Color Grid", "Smoke color grid");
prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 0feebbd94ba..39d6e665077 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -112,8 +112,13 @@ static EnumPropertyItem transform_orientation_items[] = {
#ifndef RNA_RUNTIME
static EnumPropertyItem autosnap_items[] = {
{SACTSNAP_OFF, "NONE", 0, "No Auto-Snap", ""},
- {SACTSNAP_STEP, "STEP", 0, "Time Step", "Snap to 1.0 frame/second intervals"},
- {SACTSNAP_FRAME, "FRAME", 0, "Nearest Frame", "Snap to actual frames/seconds (nla-action time)"},
+ /* {-1, "", 0, "", ""}, */
+ {SACTSNAP_STEP, "STEP", 0, "Frame Step", "Snap to 1.0 frame intervals"},
+ {SACTSNAP_TSTEP, "TIME_STEP", 0, "Second Step", "Snap to 1.0 second intervals"},
+ /* {-1, "", 0, "", ""}, */
+ {SACTSNAP_FRAME, "FRAME", 0, "Nearest Frame", "Snap to actual frames (nla-action time)"},
+ {SACTSNAP_SECOND, "SECOND", 0, "Nearest Second", "Snap to actual seconds (nla-action time)"},
+ /* {-1, "", 0, "", ""}, */
{SACTSNAP_MARKER, "MARKER", 0, "Nearest Marker", "Snap to nearest marker"},
{0, NULL, 0, NULL, NULL}
};
@@ -161,6 +166,7 @@ static EnumPropertyItem buttons_texture_context_items[] = {
{SB_TEXC_WORLD, "WORLD", ICON_WORLD, "", "Show world textures"},
{SB_TEXC_LAMP, "LAMP", ICON_LAMP, "", "Show lamp textures"},
{SB_TEXC_PARTICLES, "PARTICLES", ICON_PARTICLES, "", "Show particles textures"},
+ {SB_TEXC_LINESTYLE, "LINESTYLE", ICON_LINE_DATA, "", "Show linestyle textures"},
{SB_TEXC_OTHER, "OTHER", ICON_TEXTURE, "", "Show other data textures"},
{0, NULL, 0, NULL, NULL}
};
@@ -284,6 +290,55 @@ static void rna_area_region_from_regiondata(PointerRNA *ptr, ScrArea **r_sa, ARe
area_region_from_regiondata(sc, regiondata, r_sa, r_ar);
}
+static int rna_Space_view2d_sync_get(PointerRNA *ptr)
+{
+ ScrArea *sa;
+ ARegion *ar;
+
+ sa = rna_area_from_space(ptr); /* can be NULL */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar) {
+ View2D *v2d = &ar->v2d;
+ return (v2d->flag & V2D_VIEWSYNC_SCREEN_TIME) != 0;
+ }
+
+ return false;
+}
+
+static void rna_Space_view2d_sync_set(PointerRNA *ptr, int value)
+{
+ ScrArea *sa;
+ ARegion *ar;
+
+ sa = rna_area_from_space(ptr); /* can be NULL */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar) {
+ View2D *v2d = &ar->v2d;
+ if (value) {
+ v2d->flag |= V2D_VIEWSYNC_SCREEN_TIME;
+ }
+ else {
+ v2d->flag &= ~V2D_VIEWSYNC_SCREEN_TIME;
+ }
+ }
+}
+
+static void rna_Space_view2d_sync_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ ScrArea *sa;
+ ARegion *ar;
+
+ sa = rna_area_from_space(ptr); /* can be NULL */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+
+ if (ar) {
+ bScreen *sc = (bScreen *)ptr->id.data;
+ View2D *v2d = &ar->v2d;
+
+ UI_view2d_sync(sc, sa, v2d, V2D_LOCK_SET);
+ }
+}
+
static PointerRNA rna_CurrentOrientation_get(PointerRNA *ptr)
{
Scene *scene = ((bScreen *)ptr->id.data)->scene;
@@ -396,7 +451,7 @@ static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values)
static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
- DAG_on_visible_update(bmain, FALSE);
+ DAG_on_visible_update(bmain, false);
}
static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -472,22 +527,33 @@ static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_RegionView3D, regiondata);
}
-static PointerRNA rna_SpaceView3D_region_quadview_get(PointerRNA *ptr)
+static void rna_SpaceView3D_region_quadviews_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
ScrArea *sa = rna_area_from_space(ptr);
- void *regiondata = NULL;
- if (sa) {
- ListBase *regionbase = (sa->spacedata.first == v3d) ? &sa->regionbase : &v3d->regionbase;
- ARegion *ar = regionbase->last; /* always before last in list, weak .. */
+ int i = 3;
- ar = (ar->alignment == RGN_ALIGN_QSPLIT) ? ar->prev : NULL;
- if (ar) {
- regiondata = ar->regiondata;
+ ARegion *ar = ((sa && sa->spacedata.first == v3d) ? &sa->regionbase : &v3d->regionbase)->last;
+ ListBase lb = {NULL, NULL};
+
+ if (ar && ar->alignment == RGN_ALIGN_QSPLIT) {
+ while (i-- && ar) {
+ ar = ar->prev;
+ }
+
+ if (i < 0) {
+ lb.first = ar;
}
}
- return rna_pointer_inherit_refine(ptr, &RNA_RegionView3D, regiondata);
+ rna_iterator_listbase_begin(iter, &lb, NULL);
+}
+
+static PointerRNA rna_SpaceView3D_region_quadviews_get(CollectionPropertyIterator *iter)
+{
+ void *regiondata = ((ARegion *)rna_iterator_listbase_get(iter))->regiondata;
+
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_RegionView3D, regiondata);
}
static void rna_RegionView3D_quadview_update(Main *UNUSED(main), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -497,10 +563,10 @@ static void rna_RegionView3D_quadview_update(Main *UNUSED(main), Scene *UNUSED(s
rna_area_region_from_regiondata(ptr, &sa, &ar);
if (sa && ar && ar->alignment == RGN_ALIGN_QSPLIT)
- ED_view3d_quadview_update(sa, ar, FALSE);
+ ED_view3d_quadview_update(sa, ar, false);
}
-/* same as above but call clip==TRUE */
+/* same as above but call clip==true */
static void rna_RegionView3D_quadview_clip_update(Main *UNUSED(main), Scene *UNUSED(scene), PointerRNA *ptr)
{
ScrArea *sa;
@@ -508,7 +574,7 @@ static void rna_RegionView3D_quadview_clip_update(Main *UNUSED(main), Scene *UNU
rna_area_region_from_regiondata(ptr, &sa, &ar);
if (sa && ar && ar->alignment == RGN_ALIGN_QSPLIT)
- ED_view3d_quadview_update(sa, ar, TRUE);
+ ED_view3d_quadview_update(sa, ar, true);
}
static void rna_RegionView3D_view_location_get(PointerRNA *ptr, float *values)
@@ -918,6 +984,10 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C,
RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_PARTICLES);
}
+ if (ED_texture_context_check_linestyle(C)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_LINESTYLE);
+ }
+
if (ED_texture_context_check_others(C)) {
RNA_enum_items_add_value(&item, &totitem, buttons_texture_context_items, SB_TEXC_OTHER);
}
@@ -1184,7 +1254,7 @@ static int rna_SpaceNodeEditor_tree_type_poll(void *Cv, bNodeTreeType *type)
if (type->poll)
return type->poll(C, type);
else
- return TRUE;
+ return true;
}
static EnumPropertyItem *rna_SpaceNodeEditor_tree_type_itemf(bContext *C, PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), bool *r_free)
@@ -1216,7 +1286,7 @@ void rna_SpaceNodeEditor_path_start(SpaceNode *snode, bContext *C, PointerRNA *n
ED_node_tree_update(C);
}
-void rna_SpaceNodeEditor_path_push(SpaceNode *snode, bContext *C, PointerRNA *node_tree, PointerRNA *node)
+void rna_SpaceNodeEditor_path_append(SpaceNode *snode, bContext *C, PointerRNA *node_tree, PointerRNA *node)
{
ED_node_tree_push(snode, node_tree->data, node->data);
ED_node_tree_update(C);
@@ -1304,6 +1374,12 @@ static void rna_def_space(BlenderRNA *brna)
RNA_def_property_enum_items(prop, space_type_items);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "Space data type");
+
+ /* access to V2D_VIEWSYNC_SCREEN_TIME */
+ prop = RNA_def_property(srna, "show_locked_time", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Space_view2d_sync_get", "rna_Space_view2d_sync_set");
+ RNA_def_property_ui_text(prop, "Lock Time to Other Windows", "");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, "rna_Space_view2d_sync_update");
}
/* for all spaces that use a mask */
@@ -2033,10 +2109,13 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_SpaceView3D_region_3d_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "3D Region", "3D region in this space, in case of quad view the camera region");
- prop = RNA_def_property(srna, "region_quadview", PROP_POINTER, PROP_NONE);
+ prop = RNA_def_property(srna, "region_quadviews", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "RegionView3D");
- RNA_def_property_pointer_funcs(prop, "rna_SpaceView3D_region_quadview_get", NULL, NULL, NULL);
- RNA_def_property_ui_text(prop, "Quad View Region", "3D region that defines the quad view settings");
+ RNA_def_property_collection_funcs(prop, "rna_SpaceView3D_region_quadviews_begin", "rna_iterator_listbase_next",
+ "rna_iterator_listbase_end", "rna_SpaceView3D_region_quadviews_get",
+ NULL, NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Quad View Regions", "3D regions (the third one defines quad view settings, "
+ "the forth one is same as 'region_3d')");
prop = RNA_def_property(srna, "show_reconstruction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_RECONSTRUCTION);
@@ -2726,7 +2805,7 @@ static void rna_def_space_graph(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem mode_items[] = {
- {SIPO_MODE_ANIMATION, "FCURVES", ICON_IPO, "F-Curve Editor",
+ {SIPO_MODE_ANIMATION, "FCURVES", ICON_IPO, "F-Curve",
"Edit animation/keyframes displayed as 2D curves"},
{SIPO_MODE_DRIVERS, "DRIVERS", ICON_DRIVER, "Drivers", "Edit drivers"},
{0, NULL, 0, NULL, NULL}
@@ -2922,12 +3001,6 @@ static void rna_def_space_time(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Space Timeline Editor", "Timeline editor space data");
/* view settings */
- prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TIME_ONLYACTSEL);
- RNA_def_property_ui_text(prop, "Only Selected Channels",
- "Show keyframes for active Object and/or its selected bones only");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TIME_CFRA_NUM);
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
@@ -3303,7 +3376,7 @@ static void rna_def_space_node_path_api(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
- func = RNA_def_function(srna, "push", "rna_SpaceNodeEditor_path_push");
+ func = RNA_def_function(srna, "append", "rna_SpaceNodeEditor_path_append");
RNA_def_function_ui_description(func, "Append a node group tree to the path");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "Node tree to append to the node editor path");
@@ -3325,6 +3398,7 @@ static void rna_def_space_node(BlenderRNA *brna)
{SNODE_TEX_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit texture nodes from Object"},
{SNODE_TEX_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit texture nodes from World"},
{SNODE_TEX_BRUSH, "BRUSH", ICON_BRUSH_DATA, "Brush", "Edit texture nodes from Brush"},
+ {SNODE_TEX_LINESTYLE, "LINESTYLE", ICON_LINE_DATA, "Line Style", "Edit texture nodes from Line Style"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c
index 8a75aa2d227..d237dcffc96 100644
--- a/source/blender/makesrna/intern/rna_speaker.c
+++ b/source/blender/makesrna/intern/rna_speaker.c
@@ -65,15 +65,13 @@ static void rna_def_speaker(BlenderRNA *brna)
RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
-#if 0 /* This shouldn't be changed actually, hiding it! */
prop = RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_RELATIVE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Relative", "Whether the source is relative to the camera or not");
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
-#endif
prop = RNA_def_property(srna, "sound", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "sound");
RNA_def_property_struct_type(prop, "Sound");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -82,7 +80,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "volume_max", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "volume_max");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Maximum Volume", "Maximum volume, no matter how near the object is");
@@ -90,7 +87,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "volume_min", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "volume_min");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Minimum Volume", "Minimum volume, no matter how far away the object is");
@@ -98,7 +94,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "distance_max", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "distance_max");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Maximum Distance",
@@ -107,7 +102,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "distance_reference", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "distance_reference");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Reference Distance", "Reference distance at which volume is 100 %");
@@ -115,7 +109,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "attenuation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Attenuation", "How strong the distance affects volume, depending on distance model");
@@ -123,7 +116,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "cone_angle_outer", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "cone_angle_outer");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 360.0f);
RNA_def_property_ui_text(prop, "Outer Cone Angle",
@@ -133,7 +125,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "cone_angle_inner", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "cone_angle_inner");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 360.0f);
RNA_def_property_ui_text(prop, "Inner Cone Angle",
@@ -142,7 +133,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "cone_volume_outer", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "cone_volume_outer");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Outer Cone Volume", "Volume outside the outer cone");
@@ -150,7 +140,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "volume");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Volume", "How loud the sound is");
RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
@@ -158,7 +147,6 @@ static void rna_def_speaker(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "pitch");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound");
RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 0d327d6da0a..f098a659671 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -245,6 +245,9 @@ void rna_TextureSlot_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN
case ID_BR:
WM_main_add_notifier(NC_BRUSH, id);
break;
+ case ID_LS:
+ WM_main_add_notifier(NC_LINESTYLE, id);
+ break;
case ID_PA:
{
MTex *mtex = ptr->data;
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index 3a91796a727..695a3e0548e 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -69,17 +69,17 @@ static void clear_envmap(struct EnvMap *env, bContext *C)
}
}
-static void texture_evaluate(struct Tex *tex, float value[3], float color_r[4])
+static void texture_evaluate(struct Tex *tex, float value[3], float r_color[4])
{
TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
/* TODO(sergey): always use color management now. */
multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true);
- color_r[0] = texres.tr;
- color_r[1] = texres.tg;
- color_r[2] = texres.tb;
- color_r[3] = texres.tin;
+ r_color[0] = texres.tr;
+ r_color[1] = texres.tg;
+ r_color[2] = texres.tb;
+ r_color[3] = texres.tin;
}
#else
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 8cb82643b87..537ffe630a2 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -372,6 +372,17 @@ static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min
*max = max_ii(0, clip->tracking.stabilization.tot_track - 1);
}
+static void rna_tracking_resetIntrinsics(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieClip *clip = (MovieClip *)ptr->id.data;
+ MovieTracking *tracking = &clip->tracking;
+
+ if (tracking->camera.intrinsics) {
+ BKE_tracking_distortion_free(tracking->camera.intrinsics);
+ tracking->camera.intrinsics = NULL;
+ }
+}
+
static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -599,7 +610,7 @@ static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, cons
static void rna_trackingObject_remove(MovieTracking *tracking, ReportList *reports, PointerRNA *object_ptr)
{
MovieTrackingObject *object = object_ptr->data;
- if (BKE_tracking_object_delete(tracking, object) == FALSE) {
+ if (BKE_tracking_object_delete(tracking, object) == false) {
BKE_reportf(reports, RPT_ERROR, "MovieTracking '%s' cannot be removed", object->name);
return;
}
@@ -690,6 +701,45 @@ static void rna_trackingPlaneMarkers_delete_frame(MovieTrackingPlaneTrack *plane
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
}
+static MovieTrackingObject *find_object_for_reconstruction(MovieTracking *tracking,
+ MovieTrackingReconstruction *reconstruction)
+{
+ MovieTrackingObject *object;
+
+ for (object = tracking->objects.first; object; object = object->next) {
+ if (object->flag & TRACKING_OBJECT_CAMERA) {
+ if (&tracking->reconstruction == reconstruction) {
+ return object;
+ }
+ }
+ else if (&object->reconstruction == reconstruction) {
+ return object;
+ }
+ }
+
+ return NULL;
+}
+
+static MovieReconstructedCamera *rna_trackingCameras_find_frame(ID *id, MovieTrackingReconstruction *reconstruction, int framenr)
+{
+ MovieClip *clip = (MovieClip *) id;
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *object = find_object_for_reconstruction(tracking, reconstruction);
+ return BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
+}
+
+static void rna_trackingCameras_matrix_from_frame(ID *id, MovieTrackingReconstruction *reconstruction, int framenr, float matrix[16])
+{
+ float mat[4][4];
+
+ MovieClip *clip = (MovieClip *) id;
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *object = find_object_for_reconstruction(tracking, reconstruction);
+ BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
+
+ memcpy(matrix, mat, sizeof(float) * 16);
+}
+
#else
static EnumPropertyItem tracker_motion_model[] = {
@@ -930,6 +980,10 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking");
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+ prop = RNA_def_property(srna, "default_weight", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Weight", "Influence of newly created track on a final solution");
+
/* ** object tracking ** */
/* object distance */
@@ -947,6 +1001,13 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static EnumPropertyItem distortion_model_items[] = {
+ {TRACKING_DISTORTION_MODEL_POLYNOMIAL, "POLYNOMIAL", 0, "Polynomial", "Radial distortion model which fits common cameras"},
+ {TRACKING_DISTORTION_MODEL_DIVISION, "DIVISION", 0, "Divisions", "Division distortion model which "
+ "better represents wide-angle cameras"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem camera_units_items[] = {
{CAMERA_UNITS_PX, "PIXELS", 0, "px", "Use pixels for units of focal length"},
{CAMERA_UNITS_MM, "MILLIMETERS", 0, "mm", "Use millimeters for units of focal length"},
@@ -957,6 +1018,13 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_trackingCamera_path");
RNA_def_struct_ui_text(srna, "Movie tracking camera data", "Match-moving camera data for tracking");
+ /* Distortion model */
+ prop = RNA_def_property(srna, "distortion_model", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, distortion_model_items);
+ RNA_def_property_ui_text(prop, "Distortion Model", "Distortion model used for camera lenses");
+ RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_resetIntrinsics");
+
/* Sensor */
prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sensor_width");
@@ -1022,6 +1090,19 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "K3", "Third coefficient of third order polynomial radial distortion");
RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate");
+ /* Division distortion parameters */
+ prop = RNA_def_property(srna, "division_k1", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_range(prop, -10, 10, 0.1, 3);
+ RNA_def_property_ui_text(prop, "K1", "First coefficient of second order division distortion");
+ RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate");
+
+ prop = RNA_def_property(srna, "division_k2", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_range(prop, -10, 10, 0.1, 3);
+ RNA_def_property_ui_text(prop, "K2", "First coefficient of second order division distortion");
+ RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_tracking_flushUpdate");
+
/* pixel aspect */
prop = RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "pixel_aspect");
@@ -1125,7 +1206,7 @@ static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame",
"Frame number to find marker for", MINFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "exact", TRUE, "Exact",
+ RNA_def_boolean(func, "exact", true, "Exact",
"Get marker at exact frame number rather than get estimated marker");
parm = RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame");
RNA_def_function_return(func, parm);
@@ -1423,7 +1504,7 @@ static void rna_def_trackingPlaneMarkers(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame",
"Frame number to find marker for", MINFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "exact", TRUE, "Exact",
+ RNA_def_boolean(func, "exact", true, "Exact",
"Get plane marker at exact frame number rather than get estimated marker");
parm = RNA_def_pointer(func, "plane_marker", "MovieTrackingPlaneMarker", "", "Plane marker for specified frame");
RNA_def_function_return(func, parm);
@@ -1625,6 +1706,33 @@ static void rna_def_reconstructedCamera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Average Error", "Average error of reconstruction");
}
+static void rna_def_trackingReconstructedCameras(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ srna = RNA_def_struct(brna, "MovieTrackingReconstructedCameras", NULL);
+ RNA_def_struct_sdna(srna, "MovieTrackingReconstruction");
+ RNA_def_struct_ui_text(srna, "Reconstructed Cameras", "Collection of solved cameras");
+
+ func = RNA_def_function(srna, "find_frame", "rna_trackingCameras_find_frame");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Find a reconstructed camera for a give frame number");
+ RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to find camera for", MINFRAME, MAXFRAME);
+ parm = RNA_def_pointer(func, "camera", "MovieReconstructedCamera", "", "Camera for a given frame");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "matrix_from_frame", "rna_trackingCameras_matrix_from_frame");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Return interpolated camera matrix for a given frame");
+ RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to find camera for", MINFRAME, MAXFRAME);
+ parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, FLT_MIN, FLT_MAX, "Matrix",
+ "Interpolated camera matrix for a given frame", FLT_MIN, FLT_MAX);
+ RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */
+ RNA_def_function_output(func, parm);
+}
+
static void rna_def_trackingReconstruction(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1653,6 +1761,8 @@ static void rna_def_trackingReconstruction(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "MovieReconstructedCamera");
RNA_def_property_collection_sdna(prop, NULL, "cameras", "camnr");
RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras");
+ RNA_def_property_srna(prop, "MovieTrackingReconstructedCameras");
+
}
static void rna_def_trackingTracks(BlenderRNA *brna)
@@ -1911,6 +2021,7 @@ static void rna_def_tracking(BlenderRNA *brna)
rna_def_trackingObjectTracks(brna);
rna_def_trackingObjectPlaneTracks(brna);
rna_def_trackingStabilization(brna);
+ rna_def_trackingReconstructedCameras(brna);
rna_def_trackingReconstruction(brna);
rna_def_trackingObject(brna);
rna_def_trackingDopesheet(brna);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index ed526d00741..f14fadfa722 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -483,7 +483,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da
}
/* check if we have registered this uilist type before, and remove it */
- ult = WM_uilisttype_find(dummyult.idname, TRUE);
+ ult = WM_uilisttype_find(dummyult.idname, true);
if (ult && ult->ext.srna)
rna_UIList_unregister(bmain, ult->ext.srna);
@@ -708,7 +708,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
}
/* check if we have registered this menu type before, and remove it */
- mt = WM_menutype_find(dummymt.idname, TRUE);
+ mt = WM_menutype_find(dummymt.idname, true);
if (mt && mt->ext.srna)
rna_Menu_unregister(bmain, mt->ext.srna);
@@ -983,7 +983,7 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
RNA_def_property_string_default(prop, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
- RNA_define_verify_sdna(TRUE);
+ RNA_define_verify_sdna(true);
prop = RNA_def_property(srna, "bl_category", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->category");
@@ -1218,7 +1218,7 @@ static void rna_def_menu(BlenderRNA *brna)
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_define_verify_sdna(FALSE); /* not in sdna */
+ RNA_define_verify_sdna(false); /* not in sdna */
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "layout");
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index adabc1dd761..3cdff730b00 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -683,12 +683,16 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "template_preview", "uiTemplatePreview");
- RNA_def_function_ui_description(func, "Item. A preview window for materials, textures, lamps, etc");
+ RNA_def_function_ui_description(func, "Item. A preview window for materials, textures, lamps or worlds");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "id", "ID", "", "ID datablock");
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_boolean(func, "show_buttons", true, "", "Show preview buttons?");
RNA_def_pointer(func, "parent", "ID", "", "ID datablock");
RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot");
+ RNA_def_string(func, "preview_id", NULL, 0, "",
+ "Identifier of this preview widget, if not set the ID type will be used "
+ "(i.e. all previews of materials without explicit ID will have the same size...)");
func = RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping");
RNA_def_function_ui_description(func, "Item. A curve mapping widget used for e.g falloff curves for lamps");
@@ -733,7 +737,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_boolean(func, "value_slider", false, "", "Display the value slider to the right of the color wheel");
RNA_def_boolean(func, "lock", false, "", "Lock the color wheel display to value 1.0 regardless of actual color");
RNA_def_boolean(func, "lock_luminosity", false, "", "Keep the color at its original vector length");
- RNA_def_boolean(func, "cubic", true, "", "Cubic saturation for picking values close to white");
+ RNA_def_boolean(func, "cubic", false, "", "Cubic saturation for picking values close to white");
func = RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 704aff21c4d..7c101fb19be 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -540,7 +540,7 @@ static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, bool create)
static PointerRNA rna_Addon_preferences_get(PointerRNA *ptr)
{
bAddon *addon = (bAddon *)ptr->data;
- bAddonPrefType *apt = BKE_addon_pref_type_find(addon->module, TRUE);
+ bAddonPrefType *apt = BKE_addon_pref_type_find(addon->module, true);
if (apt) {
if (addon->prop == NULL) {
IDPropertyTemplate val = {0};
@@ -592,7 +592,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void
}
/* check if we have registered this header type before, and remove it */
- apt = BKE_addon_pref_type_find(dummyaddon.module, TRUE);
+ apt = BKE_addon_pref_type_find(dummyaddon.module, true);
if (apt) {
if (apt->ext.srna) {
rna_AddonPref_unregister(bmain, apt->ext.srna);
@@ -1292,7 +1292,7 @@ static void rna_def_userdef_theme_spaces_face(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
-static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, short incl_nurbs)
+static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, bool incl_nurbs, bool incl_lastsel, bool incl_vector)
{
PropertyRNA *prop;
@@ -1340,11 +1340,19 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, short incl_nurb
RNA_def_property_ui_text(prop, "Auto handle color", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "handle_vect", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_float_sdna(prop, NULL, "handle_vect");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Vector handle color", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ if (incl_vector) {
+ prop = RNA_def_property(srna, "handle_vect", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "handle_vect");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Vector handle color", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "handle_sel_vect", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "handle_sel_vect");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Vector handle selected color", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+ }
prop = RNA_def_property(srna, "handle_align", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "handle_align");
@@ -1364,19 +1372,13 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, short incl_nurb
RNA_def_property_ui_text(prop, "Auto handle selected color", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "handle_sel_vect", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_float_sdna(prop, NULL, "handle_sel_vect");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Vector handle selected color", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "handle_sel_align", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "handle_sel_align");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Align handle selected color", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- if (incl_nurbs == 0) {
+ if (incl_nurbs == false) {
/* assume that when nurbs are off, this is for 2D (i.e. anim) editors */
prop = RNA_def_property(srna, "handle_auto_clamped", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "handle_auto_clamped");
@@ -1391,11 +1393,13 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, short incl_nurb
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
- prop = RNA_def_property(srna, "lastsel_point", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_float_sdna(prop, NULL, "lastsel_point");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Last selected point", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ if (incl_lastsel) {
+ prop = RNA_def_property(srna, "lastsel_point", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "lastsel_point");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Last selected point", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+ }
}
static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
@@ -1442,6 +1446,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Camera", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "view_overlay", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "View Overlay", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "empty", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Empty", "");
@@ -1479,7 +1488,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
rna_def_userdef_theme_spaces_vertex(srna);
rna_def_userdef_theme_spaces_edge(srna);
rna_def_userdef_theme_spaces_face(srna);
- rna_def_userdef_theme_spaces_curves(srna, 1);
+ rna_def_userdef_theme_spaces_curves(srna, true, true, true);
prop = RNA_def_property(srna, "extra_edge_len", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
@@ -1623,7 +1632,7 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
rna_def_userdef_theme_spaces_vertex(srna);
- rna_def_userdef_theme_spaces_curves(srna, 0);
+ rna_def_userdef_theme_spaces_curves(srna, false, true, true);
prop = RNA_def_property(srna, "handle_vertex", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
@@ -2242,6 +2251,14 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Other Object UVs", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "cframe");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Current Frame", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ rna_def_userdef_theme_spaces_curves(srna, false, false, false);
}
static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
@@ -2754,6 +2771,8 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Strips Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ rna_def_userdef_theme_spaces_curves(srna, false, false, false);
}
static void rna_def_userdef_themes(BlenderRNA *brna)
@@ -3634,7 +3653,8 @@ static void rna_def_userdef_system(BlenderRNA *brna)
};
static EnumPropertyItem color_picker_types[] = {
- {USER_CP_CIRCLE, "CIRCLE", 0, "Circle", "A circular Hue/Saturation color wheel, with Value slider"},
+ {USER_CP_CIRCLE_HSV, "CIRCLE_HSV", 0, "Circle (HSV)", "A circular Hue/Saturation color wheel, with Value slider"},
+ {USER_CP_CIRCLE_HSL, "CIRCLE_HSL", 0, "Circle (HSL)", "A circular Hue/Saturation color wheel, with Lightness slider"},
{USER_CP_SQUARE_SV, "SQUARE_SV", 0, "Square (SV + H)", "A square showing Saturation/Value, with Hue slider"},
{USER_CP_SQUARE_HS, "SQUARE_HS", 0, "Square (HS + V)", "A square showing Hue/Saturation, with Value slider"},
{USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"},
@@ -3893,12 +3913,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "screencast_fps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "scrcastfps");
- RNA_def_property_range(prop, 10, 50);
+ RNA_def_property_range(prop, 10, 100);
RNA_def_property_ui_text(prop, "FPS", "Frame rate for the screencast to be played back");
prop = RNA_def_property(srna, "screencast_wait_time", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "scrcastwait");
- RNA_def_property_range(prop, 50, 1000);
+ RNA_def_property_range(prop, 10, 1000);
RNA_def_property_ui_text(prop, "Wait Timer (ms)",
"Time in milliseconds between each frame recorded for screencast");
@@ -3947,19 +3967,25 @@ static void rna_def_userdef_input(BlenderRNA *brna)
{0, "RIGHT", 0, "Right", "Use Right Mouse Button for selection"},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem view_rotation_items[] = {
{0, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport"},
{USER_TRACKBALL, "TRACKBALL", 0, "Trackball", "Use trackball style rotation in the viewport"},
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem ndof_view_navigation_items[] = {
+ {0, "FREE", 0, "Free", "Use full 6 degrees of freedom by default"},
+ {NDOF_MODE_ORBIT, "ORBIT", 0, "Orbit", "Orbit about the view center by default"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem ndof_view_rotation_items[] = {
{NDOF_TURNTABLE, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport"},
{0, "TRACKBALL", 0, "Trackball", "Use trackball style rotation in the viewport"},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem view_zoom_styles[] = {
{USER_ZOOM_CONT, "CONTINUE", 0, "Continue", "Old style zoom, continues while moving mouse up or down"},
{USER_ZOOM_DOLLY, "DOLLY", 0, "Dolly", "Zoom in and out based on vertical mouse movement"},
@@ -4039,17 +4065,17 @@ static void rna_def_userdef_input(BlenderRNA *brna)
/* 3D mouse settings */
/* global options */
prop = RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.25f, 40.0f);
+ RNA_def_property_range(prop, 0.01f, 40.0f);
RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse for panning");
prop = RNA_def_property(srna, "ndof_orbit_sensitivity", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.25f, 40.0f);
+ RNA_def_property_range(prop, 0.01f, 40.0f);
RNA_def_property_ui_text(prop, "Orbit Sensitivity", "Overall sensitivity of the 3D Mouse for orbiting");
- prop = RNA_def_property(srna, "ndof_zoom_updown", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_UPDOWN);
- RNA_def_property_ui_text(prop, "Zoom = Up/Down",
- "Zoom using up/down on the device (otherwise forward/backward)");
+ prop = RNA_def_property(srna, "ndof_pan_yz_swap_axis", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PAN_YZ_SWAP_AXIS);
+ RNA_def_property_ui_text(prop, "Y/Z Swap Axis",
+ "Pan using up/down on the device (otherwise forward/backward)");
prop = RNA_def_property(srna, "ndof_zoom_invert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_INVERT);
@@ -4062,40 +4088,45 @@ static void rna_def_userdef_input(BlenderRNA *brna)
/* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/
/* 3D view */
+ prop = RNA_def_property(srna, "ndof_view_navigate_method", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "ndof_flag");
+ RNA_def_property_enum_items(prop, ndof_view_navigation_items);
+ RNA_def_property_ui_text(prop, "NDOF View Navigate", "Navigation style in the viewport");
+
prop = RNA_def_property(srna, "ndof_view_rotate_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "ndof_flag");
RNA_def_property_enum_items(prop, ndof_view_rotation_items);
RNA_def_property_ui_text(prop, "NDOF View Rotation", "Rotation style in the viewport");
- /* 3D view: roll */
- prop = RNA_def_property(srna, "ndof_roll_invert_axis", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROLL_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert roll Axis", "Invert roll axis");
+ /* 3D view: yaw */
+ prop = RNA_def_property(srna, "ndof_rotx_invert_axis", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTX_INVERT_AXIS);
+ RNA_def_property_ui_text(prop, "Invert Pitch (X) Axis", "");
- /* 3D view: tilt */
- prop = RNA_def_property(srna, "ndof_tilt_invert_axis", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_TILT_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert tilt Axis", "Invert tilt axis");
+ /* 3D view: pitch */
+ prop = RNA_def_property(srna, "ndof_roty_invert_axis", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTY_INVERT_AXIS);
+ RNA_def_property_ui_text(prop, "Invert Yaw (Y) Axis", "");
- /* 3D view: rotate */
- prop = RNA_def_property(srna, "ndof_rotate_invert_axis", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTATE_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert rotation Axis", "Invert rotation axis");
+ /* 3D view: roll */
+ prop = RNA_def_property(srna, "ndof_rotz_invert_axis", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTZ_INVERT_AXIS);
+ RNA_def_property_ui_text(prop, "Invert Roll (Z) Axis", "");
/* 3D view: pan x */
prop = RNA_def_property(srna, "ndof_panx_invert_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANX_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert x Axis", "Invert x axis");
+ RNA_def_property_ui_text(prop, "Invert X Axis", "");
/* 3D view: pan y */
prop = RNA_def_property(srna, "ndof_pany_invert_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANY_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert y Axis", "Invert y axis");
+ RNA_def_property_ui_text(prop, "Invert Y Axis", "");
/* 3D view: pan z */
prop = RNA_def_property(srna, "ndof_panz_invert_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANZ_INVERT_AXIS);
- RNA_def_property_ui_text(prop, "Invert z Axis", "Invert z axis");
+ RNA_def_property_ui_text(prop, "Invert Z Axis", "");
/* 3D view: fly */
prop = RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index ff9469550d9..f24f94282b6 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -48,9 +48,9 @@ static int rna_VectorFont_filepath_editable(PointerRNA *ptr)
{
VFont *vfont = ptr->id.data;
if (BKE_vfont_is_builtin(vfont)) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void rna_VectorFont_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 3cad1df83f4..23b6d1e41ae 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -519,7 +519,7 @@ static PointerRNA rna_Operator_properties_get(PointerRNA *ptr)
static PointerRNA rna_OperatorMacro_properties_get(PointerRNA *ptr)
{
wmOperatorTypeMacro *otmacro = (wmOperatorTypeMacro *)ptr->data;
- wmOperatorType *ot = WM_operatortype_find(otmacro->idname, TRUE);
+ wmOperatorType *ot = WM_operatortype_find(otmacro->idname, true);
return rna_pointer_inherit_refine(ptr, ot->srna, otmacro->properties);
}
@@ -862,7 +862,7 @@ static int rna_wmClipboard_length(PointerRNA *UNUSED(ptr))
static void rna_wmClipboard_set(PointerRNA *UNUSED(ptr), const char *value)
{
- WM_clipboard_text_set((void *) value, FALSE);
+ WM_clipboard_text_set((void *) value, false);
}
#ifdef WITH_PYTHON
@@ -1157,7 +1157,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
/* check if we have registered this operator type before, and remove it */
{
- wmOperatorType *ot = WM_operatortype_find(dummyot.idname, TRUE);
+ wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true);
if (ot && ot->ext.srna)
rna_Operator_unregister(bmain, ot->ext.srna);
}
@@ -1249,7 +1249,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
/* check if we have registered this operator type before, and remove it */
{
- wmOperatorType *ot = WM_operatortype_find(dummyot.idname, TRUE);
+ wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true);
if (ot && ot->ext.srna)
rna_Operator_unregister(bmain, ot->ext.srna);
}
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index ea13cff442a..9b288903aa2 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -235,7 +235,7 @@ static void rna_KeyMap_item_remove(wmKeyMap *km, ReportList *reports, PointerRNA
{
wmKeyMapItem *kmi = kmi_ptr->data;
- if (WM_keymap_remove_item(km, kmi) == FALSE) {
+ if (WM_keymap_remove_item(km, kmi) == false) {
BKE_reportf(reports, RPT_ERROR, "KeyMapItem '%s' cannot be removed from '%s'", kmi->idname, km->idname);
return;
}
@@ -272,7 +272,7 @@ static void rna_KeyMap_remove(wmKeyConfig *keyconfig, ReportList *reports, Point
{
wmKeyMap *keymap = keymap_ptr->data;
- if (WM_keymap_remove(keyconfig, keymap) == FALSE) {
+ if (WM_keymap_remove(keyconfig, keymap) == false) {
BKE_reportf(reports, RPT_ERROR, "KeyConfig '%s' cannot be removed", keymap->idname);
return;
}
@@ -284,7 +284,7 @@ static void rna_KeyConfig_remove(wmWindowManager *wm, ReportList *reports, Point
{
wmKeyConfig *keyconf = keyconf_ptr->data;
- if (WM_keyconfig_remove(wm, keyconf) == FALSE) {
+ if (WM_keyconfig_remove(wm, keyconf) == false) {
BKE_reportf(reports, RPT_ERROR, "KeyConfig '%s' cannot be removed", keyconf->idname);
return;
}
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner.py b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
index 8b4b10c490e..8b4b10c490e 100755..100644
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
index 17ea5f9b0bd..17ea5f9b0bd 100755..100644
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
diff --git a/source/blender/makesrna/rna_cleanup/rna_update.sh b/source/blender/makesrna/rna_cleanup/rna_update.sh
index e3119191cb2..e3119191cb2 100755..100644
--- a/source/blender/makesrna/rna_cleanup/rna_update.sh
+++ b/source/blender/makesrna/rna_cleanup/rna_update.sh
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 7b43f9899b8..b841356709e 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -133,15 +133,6 @@ if(WITH_MOD_OCEANSIM)
add_definitions(-DWITH_OCEANSIM)
endif()
-if(WITH_GAMEENGINE)
- # for MOD_navmesh.c
- add_definitions(-DWITH_GAMEENGINE)
- list(APPEND INC
- ../gpu
- ../../../extern/recastnavigation
- )
-endif()
-
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index d2c44cd1281..0a4a6140c02 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -39,9 +39,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BLI_ghash.h"
-#include "BLI_edgehash.h"
#include "DNA_curve_types.h"
#include "DNA_meshdata_types.h"
@@ -51,9 +49,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_displist.h"
#include "BKE_curve.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "MOD_util.h"
@@ -65,6 +61,12 @@
#include <stdlib.h>
#include <string.h>
+/* Due to cyclic dependencies it's possible that curve used for
+ * deformation here is not evaluated at the time of evaluating
+ * this modifier.
+ */
+#define CYCLIC_DEPENDENCY_WORKAROUND
+
static void initData(ModifierData *md)
{
ArrayModifierData *amd = (ArrayModifierData *) md;
@@ -185,7 +187,7 @@ static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
}
/* above loops over all, so set all to dirty, if this is somehow
* setting valid values, this line can be removed - campbell */
- bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
+ bm->elem_index_dirty |= BM_ALL;
(*index_map_length) = i;
index_map = MEM_callocN(sizeof(int) * (*index_map_length), "index_map");
@@ -322,7 +324,7 @@ static void merge_first_last(BMesh *bm,
}
static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
- Object *ob, DerivedMesh *dm,
+ Scene *scene, Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
DerivedMesh *result;
@@ -377,7 +379,13 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
Curve *cu = amd->curve_ob->data;
if (cu) {
- if (amd->curve_ob->curve_cache->path) {
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+ if (amd->curve_ob->curve_cache == NULL) {
+ BKE_displist_make_curveTypes(scene, amd->curve_ob, false);
+ }
+#endif
+
+ if (amd->curve_ob->curve_cache && amd->curve_ob->curve_cache->path) {
float scale = mat4_to_scale(amd->curve_ob->obmat);
length = scale * amd->curve_ob->curve_cache->path->totdist;
}
@@ -516,7 +524,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
/* start capping */
if (start_cap || end_cap) {
- BM_mesh_elem_hflag_enable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_enable_all(bm, BM_VERT, BM_ELEM_TAG, false);
if (start_cap) {
float startoffset[4][4];
@@ -575,7 +583,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *result;
ArrayModifierData *amd = (ArrayModifierData *) md;
- result = arrayModifier_doArray(amd, ob, dm, flag);
+ result = arrayModifier_doArray(amd, md->scene, ob, dm, flag);
return result;
}
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index e5e7e004bbf..fc65990df20 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -41,16 +41,12 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
#include "BKE_modifier.h"
-#include "BKE_mesh.h"
#include "MOD_util.h"
#include "bmesh.h"
#include "bmesh_tools.h"
-#include "MEM_guardedalloc.h"
-
-
static void initData(ModifierData *md)
{
BevelModifierData *bmd = (BevelModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
index 3607c946be3..99016a0a41b 100644
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ b/source/blender/modifiers/intern/MOD_boolean_util.c
@@ -27,18 +27,16 @@
* \ingroup modifiers
*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
-#include "BLI_polyfill2d.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_material.h"
@@ -91,6 +89,41 @@ static void DM_loop_interp_from_poly(DerivedMesh *source_dm,
source_poly->totloop, target_loop_index);
}
+typedef struct DMArrays {
+ MVert *mvert;
+ MEdge *medge;
+ MLoop *mloop;
+ MPoly *mpoly;
+ bool mvert_allocated;
+ bool medge_allocated;
+ bool mloop_allocated;
+ bool mpoly_allocated;
+} DMArrays;
+
+static void dm_arrays_get(DerivedMesh *dm, DMArrays *arrays)
+{
+ arrays->mvert = DM_get_vert_array(dm, &arrays->mvert_allocated);
+ arrays->medge = DM_get_edge_array(dm, &arrays->medge_allocated);
+ arrays->mloop = DM_get_loop_array(dm, &arrays->mloop_allocated);
+ arrays->mpoly = DM_get_poly_array(dm, &arrays->mpoly_allocated);
+}
+
+static void dm_arrays_free(DMArrays *arrays)
+{
+ if (arrays->mvert_allocated) {
+ MEM_freeN(arrays->mvert);
+ }
+ if (arrays->medge_allocated) {
+ MEM_freeN(arrays->medge);
+ }
+ if (arrays->mloop_allocated) {
+ MEM_freeN(arrays->mloop);
+ }
+ if (arrays->mpoly_allocated) {
+ MEM_freeN(arrays->mpoly);
+ }
+}
+
/* **** Importer from derived mesh to Carve **** */
typedef struct ImportMeshData {
@@ -351,6 +384,11 @@ static void exporter_InitGeomArrays(ExportMeshData *export_data,
allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops,
CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPUV));
+ allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops,
+ CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPCOL));
+ allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops,
+ CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPUV));
+
/* Merge custom data layers from operands.
*
* Will only create custom data layers for all the layers which appears in
@@ -457,7 +495,7 @@ static void setMPolyMaterial(ExportMeshData *export_data,
* otherwise fallback to first material (material with index=0).
*/
if (!BLI_ghash_haskey(material_hash, orig_mat)) {
- int a, mat_nr;;
+ int a, mat_nr;
mat_nr = 0;
for (a = 0; a < export_data->ob_left->totcol; a++) {
@@ -521,10 +559,6 @@ static void exporter_SetPoly(ExportMeshData *export_data,
mpoly->loopstart = start_loop;
mpoly->totloop = num_loops;
- if (which_orig_mesh == CARVE_MESH_RIGHT) {
- which_orig_mesh = CARVE_MESH_RIGHT;
- }
-
/* Interpolate data for poly loops. */
{
MVert *source_mverts = which_mvert(export_data, which_orig_mesh);
@@ -635,25 +669,30 @@ static int operation_from_optype(int int_op_type)
return operation;
}
-static void prepare_import_data(Object *object, DerivedMesh *dm, ImportMeshData *import_data)
+static void prepare_import_data(Object *object,
+ DerivedMesh *dm,
+ const DMArrays *dm_arrays,
+ ImportMeshData *import_data)
{
import_data->dm = dm;
copy_m4_m4(import_data->obmat, object->obmat);
- import_data->mvert = dm->getVertArray(dm);
- import_data->medge = dm->getEdgeArray(dm);
- import_data->mloop = dm->getLoopArray(dm);
- import_data->mpoly = dm->getPolyArray(dm);
+ import_data->mvert = dm_arrays->mvert;
+ import_data->medge = dm_arrays->medge;
+ import_data->mloop = dm_arrays->mloop;
+ import_data->mpoly = dm_arrays->mpoly;
}
-static struct CarveMeshDescr *carve_mesh_from_dm(Object *object, DerivedMesh *dm)
+static struct CarveMeshDescr *carve_mesh_from_dm(Object *object,
+ DerivedMesh *dm,
+ const DMArrays *dm_arrays)
{
ImportMeshData import_data;
- prepare_import_data(object, dm, &import_data);
+ prepare_import_data(object, dm, dm_arrays, &import_data);
return carve_addMesh(&import_data, &MeshImporter);
}
-static void prepare_export_data(Object *object_left, DerivedMesh *dm_left,
- Object *object_right, DerivedMesh *dm_right,
+static void prepare_export_data(Object *object_left, DerivedMesh *dm_left, const DMArrays *dm_left_arrays,
+ Object *object_right, DerivedMesh *dm_right, const DMArrays *dm_right_arrays,
ExportMeshData *export_data)
{
float object_right_imat[4][4];
@@ -666,12 +705,12 @@ static void prepare_export_data(Object *object_left, DerivedMesh *dm_left,
export_data->dm_left = dm_left;
export_data->dm_right = dm_right;
- export_data->mvert_left = dm_left->getVertArray(dm_left);
- export_data->mloop_left = dm_left->getLoopArray(dm_left);
- export_data->mpoly_left = dm_left->getPolyArray(dm_left);
- export_data->mvert_right = dm_right->getVertArray(dm_right);
- export_data->mloop_right = dm_right->getLoopArray(dm_right);
- export_data->mpoly_right = dm_right->getPolyArray(dm_right);
+ export_data->mvert_left = dm_left_arrays->mvert;
+ export_data->mloop_left = dm_left_arrays->mloop;
+ export_data->mpoly_left = dm_left_arrays->mpoly;
+ export_data->mvert_right = dm_right_arrays->mvert;
+ export_data->mloop_right = dm_right_arrays->mloop;
+ export_data->mpoly_right = dm_right_arrays->mpoly;
export_data->material_hash = BLI_ghash_ptr_new("CSG_mat gh");
@@ -692,6 +731,7 @@ DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob,
DerivedMesh *output_dm = NULL;
int operation;
bool result;
+ DMArrays dm_left_arrays, dm_right_arrays;
if (dm == NULL || dm_select == NULL) {
return NULL;
@@ -702,8 +742,11 @@ DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob,
return NULL;
}
- left = carve_mesh_from_dm(ob_select, dm_select);
- right = carve_mesh_from_dm(ob, dm);
+ dm_arrays_get(dm_select, &dm_left_arrays);
+ dm_arrays_get(dm, &dm_right_arrays);
+
+ left = carve_mesh_from_dm(ob_select, dm_select, &dm_left_arrays);
+ right = carve_mesh_from_dm(ob, dm, &dm_right_arrays);
result = carve_performBooleanOperation(left, right, operation, &output);
@@ -713,7 +756,9 @@ DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob,
if (result) {
ExportMeshData export_data;
- prepare_export_data(ob_select, dm_select, ob, dm, &export_data);
+ prepare_export_data(ob_select, dm_select, &dm_left_arrays,
+ ob, dm, &dm_right_arrays,
+ &export_data);
carve_exportMesh(output, &MeshExporter, &export_data);
output_dm = export_data.dm;
@@ -725,5 +770,8 @@ DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob,
carve_deleteMesh(output);
}
+ dm_arrays_free(&dm_left_arrays);
+ dm_arrays_free(&dm_right_arrays);
+
return output_dm;
}
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index ab9c15f88db..f6ade2bf303 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -46,7 +46,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index 76a0ed59d06..ec077631c85 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -38,7 +38,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_deform.h"
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 1f24662960a..8f6c533ae4c 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -33,7 +33,6 @@
*/
-#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_meshdata_types.h"
@@ -47,7 +46,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 760fa8ffbe8..fbc72cef0e8 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -39,7 +39,6 @@
#include "DNA_object_types.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
@@ -120,7 +119,7 @@ static void deformVerts(ModifierData *md, Object *ob,
/* silly that defaxis and curve_deform_verts are off by 1
* but leave for now to save having to call do_versions */
- curve_deform_verts(cmd->object, ob, derivedData, vertexCos, numVerts,
+ curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
cmd->name, cmd->defaxis - 1);
}
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 54f2e688f31..a23873fcd8a 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -36,9 +36,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index df72d31596c..838ceb5cfe0 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -32,8 +32,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index aef6a12e8ff..127972a2e40 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -37,18 +37,17 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "BLI_utildefines.h"
#include "BLI_kdtree.h"
#include "BLI_rand.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
-#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
@@ -150,7 +149,7 @@ static void createFacepa(ExplodeModifierData *emd,
tree = BLI_kdtree_new(totpart);
for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
psys_particle_on_emitter(psmd, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, NULL, NULL, NULL, NULL, NULL);
- BLI_kdtree_insert(tree, p, co, NULL);
+ BLI_kdtree_insert(tree, p, co);
}
BLI_kdtree_balance(tree);
@@ -165,7 +164,7 @@ static void createFacepa(ExplodeModifierData *emd,
else
mul_v3_fl(center, 1.0f / 3.0f);
- p = BLI_kdtree_find_nearest(tree, center, NULL, NULL);
+ p = BLI_kdtree_find_nearest(tree, center, NULL);
v1 = vertpa[fa->v1];
v2 = vertpa[fa->v2];
@@ -801,7 +800,7 @@ static DerivedMesh *explodeMesh(ExplodeModifierData *emd,
float rot[4];
float cfra;
/* float timestep; */
- int *facepa = emd->facepa;
+ const int *facepa = emd->facepa;
int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
int i, v, u;
unsigned int ed_v1, ed_v2, mindex = 0;
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index e7eb5d64b9d..77fbb482f8b 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -45,12 +45,9 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_threads.h"
-#include "BKE_main.h"
#include "BKE_fluidsim.h" /* ensure definitions here match */
#include "BKE_cdderivedmesh.h"
-#include "BKE_mesh.h"
#include "BKE_global.h" /* G.main->name only */
#include "MOD_fluidsim_util.h"
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 31aad533727..c89bc8c1d41 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -33,13 +33,11 @@
*/
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_action.h"
#include "BKE_cdderivedmesh.h"
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 7b5b73e0f6d..d3bd05baa6d 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -34,7 +34,6 @@
#include "MEM_guardedalloc.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_particle.h"
@@ -138,24 +137,6 @@ static void deleteLaplacianSystem(LaplacianSystem *sys)
MEM_SAFE_FREE(sys);
}
-static float cotan_weight(const float v1[3], const float v2[3], const float v3[3])
-{
- float a[3], b[3], c[3], clen;
-
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
-
- clen = len_v3(c);
-
- if (clen > FLT_EPSILON) {
- return dot_v3v3(a, b) / clen;
- }
- else {
- return 0.0f;
- }
-}
-
static void createFaceRingMap(
const int mvert_tot, const MFace *mface, const int mface_tot,
MeshElemMap **r_map, int **r_indices)
@@ -306,9 +287,9 @@ static void initLaplacianMatrix(LaplacianSystem *sys)
if (has_4_vert) {
- w2 = (cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2)) / 2.0f;
- w3 = (cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3)) / 2.0f;
- w4 = (cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1)) / 2.0f;
+ w2 = (cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2)) / 2.0f;
+ w3 = (cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3)) / 2.0f;
+ w4 = (cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1)) / 2.0f;
sys->delta[idv1][0] -= v4[0] * w4;
sys->delta[idv1][1] -= v4[1] * w4;
@@ -321,8 +302,8 @@ static void initLaplacianMatrix(LaplacianSystem *sys)
nlMatrixAdd(idv1, idv4, -w4);
}
else {
- w2 = cotan_weight(v3, v1, v2);
- w3 = cotan_weight(v2, v3, v1);
+ w2 = cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1);
w4 = 0.0f;
}
@@ -537,6 +518,8 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
}
else if (sys->has_solution) {
+ nlMakeCurrent(sys->context);
+
nlBegin(NL_SYSTEM);
nlBegin(NL_MATRIX);
@@ -753,27 +736,27 @@ static void LaplacianDeformModifier_do(
}
}
else {
- if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
- if (isValidVertexGroup(lmd, ob, dm)) {
- filevertexCos = MEM_mallocN(sizeof(float[3]) * numVerts, "TempDeformCoordinates");
- memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
- MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
- initSystem(lmd, ob, dm, filevertexCos, numVerts);
- sys = lmd->cache_system;
- MEM_SAFE_FREE(filevertexCos);
- laplacianDeformPreview(sys, vertexCos);
- }
+ if (!isValidVertexGroup(lmd, ob, dm)) {
+ modifier_setError(&lmd->modifier, "Vertex group '%s' is not valid", lmd->anchor_grp_name);
+ lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
+ }
+ else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
+ filevertexCos = MEM_mallocN(sizeof(float[3]) * numVerts, "TempDeformCoordinates");
+ memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
+ MEM_SAFE_FREE(lmd->vertexco);
+ lmd->total_verts = 0;
+ initSystem(lmd, ob, dm, filevertexCos, numVerts);
+ sys = lmd->cache_system;
+ MEM_SAFE_FREE(filevertexCos);
+ laplacianDeformPreview(sys, vertexCos);
}
else {
- if (isValidVertexGroup(lmd, ob, dm)) {
- initSystem(lmd, ob, dm, vertexCos, numVerts);
- sys = lmd->cache_system;
- laplacianDeformPreview(sys, vertexCos);
- }
+ initSystem(lmd, ob, dm, vertexCos, numVerts);
+ sys = lmd->cache_system;
+ laplacianDeformPreview(sys, vertexCos);
}
}
- if (sys->is_matrix_computed && !sys->has_solution) {
+ if (sys && sys->is_matrix_computed && !sys->has_solution) {
modifier_setError(&lmd->modifier, "The system did not find a solution");
}
}
@@ -806,7 +789,7 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
tlmd->vertexco = MEM_dupallocN(lmd->vertexco);
- tlmd->cache_system = MEM_dupallocN(lmd->cache_system);
+ tlmd->cache_system = NULL;
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 130013af75b..9ba0bfc7ce9 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -34,18 +34,12 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "MEM_guardedalloc.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
-#include "BKE_displist.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
-#include "BKE_particle.h"
-#include "BKE_editmesh.h"
#include "MOD_modifiertypes.h"
#include "MOD_util.h"
@@ -88,7 +82,6 @@ static CustomDataMask required_data_mask(Object *ob, ModifierData *md);
static bool is_disabled(ModifierData *md, int useRenderParams);
static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4);
static float compute_volume(float (*vertexCos)[3], MFace *mfaces, int numFaces);
-static float cotan_weight(float *v1, float *v2, float *v3);
static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
static void copy_data(ModifierData *md, ModifierData *target);
static void delete_laplacian_system(LaplacianSystem *sys);
@@ -204,22 +197,6 @@ static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4)
return areaq / 2.0f;
}
-static float cotan_weight(float *v1, float *v2, float *v3)
-{
- float a[3], b[3], c[3], clen;
-
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
-
- clen = len_v3(c);
-
- if (clen == 0.0f)
- return 0.0f;
-
- return dot_v3v3(a, b) / clen;
-}
-
static float compute_volume(float (*vertexCos)[3], MFace *mfaces, int numFaces)
{
float vol = 0.0f;
@@ -367,17 +344,17 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
v3 = sys->vertexCos[idv3];
v4 = sys->vertexCos[idv4];
- w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
- w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
- w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
+ w2 = cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3);
+ w4 = cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1);
sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f;
}
}
else {
- w1 = cotan_weight(v1, v2, v3) / 2.0f;
- w2 = cotan_weight(v2, v3, v1) / 2.0f;
- w3 = cotan_weight(v3, v1, v2) / 2.0f;
+ w1 = cotangent_tri_weight_v3(v1, v2, v3) / 2.0f;
+ w2 = cotangent_tri_weight_v3(v2, v3, v1) / 2.0f;
+ w3 = cotangent_tri_weight_v3(v3, v1, v2) / 2.0f;
sys->fweights[i][0] = sys->fweights[i][0] + w1;
sys->fweights[i][1] = sys->fweights[i][1] + w2;
@@ -430,9 +407,9 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
v3 = sys->vertexCos[idv3];
v4 = sys->vertexCos[idv4];
- w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
- w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
- w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
+ w2 = cotangent_tri_weight_v3(v4, v1, v2) + cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1) + cotangent_tri_weight_v3(v4, v1, v3);
+ w4 = cotangent_tri_weight_v3(v2, v4, v1) + cotangent_tri_weight_v3(v3, v4, v1);
w2 = w2 / 4.0f;
w3 = w3 / 4.0f;
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index f3672287d70..7f21376ef48 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -37,7 +37,6 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
-#include "BLI_string.h"
#include "BLI_ghash.h"
#include "DNA_armature_types.h"
@@ -47,7 +46,6 @@
#include "BKE_action.h" /* BKE_pose_channel_find_name */
#include "BKE_cdderivedmesh.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
@@ -150,7 +148,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
Object *oba = mmd->ob_arm;
bPoseChannel *pchan;
bDeformGroup *def;
- char *bone_select_array;
+ bool *bone_select_array;
int bone_select_tot = 0;
const int defbase_tot = BLI_countlist(&ob->defbase);
@@ -167,11 +165,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
pchan = BKE_pose_channel_find_name(oba->pose, def->name);
if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- bone_select_array[i] = TRUE;
+ bone_select_array[i] = true;
bone_select_tot++;
}
else {
- bone_select_array[i] = FALSE;
+ bone_select_array[i] = false;
}
}
@@ -194,7 +192,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (dw->def_nr < defbase_tot) {
if (bone_select_array[dw->def_nr]) {
if (dw->weight != 0.0f) {
- found = TRUE;
+ found = true;
break;
}
}
@@ -263,12 +261,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
for (i = 0; i < maxPolys; i++) {
MPoly *mp = &mpoly[i];
MLoop *ml = mloop + mp->loopstart;
- int ok = TRUE;
+ bool ok = true;
int j;
for (j = 0; j < mp->totloop; j++, ml++) {
if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) {
- ok = FALSE;
+ ok = false;
break;
}
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 1897454e132..ac0363f8673 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -30,7 +30,6 @@
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
-#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
#include "BLI_math.h"
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.c b/source/blender/modifiers/intern/MOD_meshcache_util.c
index 10560a85a3f..c263c4810e4 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.c
@@ -27,12 +27,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
-#include "MEM_guardedalloc.h"
-
#include "MOD_meshcache_util.h"
void MOD_meshcache_calc_range(const float frame, const char interp,
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 61dcc1fbb9d..959bbdcbca9 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -32,9 +32,9 @@
* \ingroup modifiers
*/
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -43,7 +43,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
@@ -130,7 +129,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
}
}
-static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec)
+static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3])
{
MDefCell *cell;
MDefInfluence *inf;
@@ -187,12 +186,10 @@ static void meshdeformModifier_do(
float (*vertexCos)[3], int numVerts)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
- struct Mesh *me = (mmd->object) ? mmd->object->data : NULL;
- BMEditMesh *em = me ? me->edit_btmesh : NULL;
DerivedMesh *tmpdm, *cagedm;
MDeformVert *dvert = NULL;
MDefInfluence *influences;
- int *offsets;
+ const int *offsets;
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3];
int a, b, totvert, totcagevert, defgrp_index;
@@ -201,8 +198,18 @@ static void meshdeformModifier_do(
if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc))
return;
- /* get cage derivedmesh */
- if (em) {
+ /* Get cage derivedmesh.
+ *
+ * Only do this is the target object is in edit mode by itself, meaning
+ * we don't allow linked edit meshes here.
+ * This is because editbmesh_get_derived_cage_and_final() might easily
+ * conflict with the thread which evaluates object which is in the edit
+ * mode for this mesh.
+ *
+ * We'll support this case once granular dependency graph is landed.
+ */
+ if (mmd->object == md->scene->obedit) {
+ BMEditMesh *em = BKE_editmesh_from_object(mmd->object);
tmpdm = editbmesh_get_derived_cage_and_final(md->scene, mmd->object, em, &cagedm, 0);
if (tmpdm)
tmpdm->release(tmpdm);
@@ -262,7 +269,7 @@ static void meshdeformModifier_do(
return;
}
- cagecos = MEM_callocN(sizeof(*cagecos) * totcagevert, "meshdeformModifier vertCos");
+ cagecos = MEM_mallocN(sizeof(*cagecos) * totcagevert, "meshdeformModifier vertCos");
/* setup deformation data */
cagedm->getVertCos(cagedm, cagecos);
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 7f8fb851668..5cece9d349f 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -39,7 +39,6 @@
#include "BLI_math.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
@@ -272,7 +271,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
MDeformVert *dvert = (MDeformVert *) CustomData_get_layer(&result->vertData, CD_MDEFORMVERT) + maxVerts;
int *flip_map = NULL, flip_map_len = 0;
- flip_map = defgroup_flip_map(ob, &flip_map_len, FALSE);
+ flip_map = defgroup_flip_map(ob, &flip_map_len, false);
if (flip_map) {
for (i = 0; i < maxVerts; dvert++, i++) {
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index e5d9a9dae0e..a324702a6ae 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -29,22 +29,17 @@
* \ingroup modifiers
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_customdata_types.h"
#include "DNA_object_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_math_inline.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_global.h"
#include "BKE_modifier.h"
#include "BKE_ocean.h"
@@ -64,7 +59,7 @@ static void clear_cache_data(struct OceanModifierData *omd)
{
BKE_free_ocean_cache(omd->oceancache);
omd->oceancache = NULL;
- omd->cached = FALSE;
+ omd->cached = false;
}
/* keep in sync with init_ocean_modifier_bake(), object_modifier.c */
@@ -74,7 +69,7 @@ static void init_ocean_modifier(struct OceanModifierData *omd)
if (!omd || !omd->ocean) return;
- do_heightfield = TRUE;
+ do_heightfield = true;
do_chop = (omd->chop_amount > 0);
do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
@@ -442,7 +437,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
omd->refresh = 0;
/* do ocean simulation */
- if (omd->cached == TRUE) {
+ if (omd->cached == true) {
if (!omd->oceancache) init_cache_data(ob, omd);
BKE_simulate_ocean_cache(omd->oceancache, md->scene->r.cfra);
}
@@ -495,7 +490,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
const float u = OCEAN_CO(size_co_inv, co[0]);
const float v = OCEAN_CO(size_co_inv, co[1]);
- if (omd->oceancache && omd->cached == TRUE) {
+ if (omd->oceancache && omd->cached == true) {
BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
foam = ocr.foam;
CLAMP(foam, 0.0f, 1.0f);
@@ -523,7 +518,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
const float u = OCEAN_CO(size_co_inv, mv->co[0]);
const float v = OCEAN_CO(size_co_inv, mv->co[1]);
- if (omd->oceancache && omd->cached == TRUE)
+ if (omd->oceancache && omd->cached == true)
BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
else
BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index b8f590c0e96..7aa81d6a003 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -80,11 +80,11 @@ static bool isDisabled(ModifierData *md, int useRenderParams)
ModifierData *ob_md;
if (!pimd->ob)
- return TRUE;
+ return true;
psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
if (psys == NULL)
- return TRUE;
+ return true;
/* If the psys modifier is disabled we cannot use its data.
* First look up the psys modifier from the object, then check if it is enabled.
@@ -99,14 +99,14 @@ static bool isDisabled(ModifierData *md, int useRenderParams)
else required_mode = eModifierMode_Realtime;
if (!modifier_isEnabled(md->scene, ob_md, required_mode))
- return TRUE;
+ return true;
break;
}
}
}
- return FALSE;
+ return false;
}
@@ -260,11 +260,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
- float min_r[3], max_r[3];
- INIT_MINMAX(min_r, max_r);
- dm->getMinMax(dm, min_r, max_r);
- min_co = min_r[track];
- max_co = max_r[track];
+ float min[3], max[3];
+ INIT_MINMAX(min, max);
+ dm->getMinMax(dm, min, max);
+ min_co = min[track];
+ max_co = max[track];
}
result = CDDM_from_template(dm, maxvert, 0, 0, maxloop, maxpoly);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 8e72c49740f..a41fbb03462 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -41,10 +41,8 @@
#include "BKE_cdderivedmesh.h"
-#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
-#include "BKE_scene.h"
#include "MOD_util.h"
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index 8f0db9f8ebf..6d76dc51ac7 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -32,7 +32,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_mesh.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 9e5b4fad439..ff7cc01232b 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -190,7 +190,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
unsigned int vc_tot_linked = 0;
short other_axis_1, other_axis_2;
- float *tmpf1, *tmpf2;
+ const float *tmpf1, *tmpf2;
unsigned int edge_offset;
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index fef4c7ccedb..45725d1c453 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -32,22 +32,18 @@
* \ingroup modifiers
*/
-
#include "BLI_math.h"
#include "DNA_key_types.h"
#include "BLI_utildefines.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_key.h"
#include "BKE_particle.h"
#include "MOD_modifiertypes.h"
-#include "MEM_guardedalloc.h"
-
static void deformVerts(ModifierData *md, Object *ob,
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3],
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index fdc5578c049..ccba2097264 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -37,11 +37,9 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_lattice.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
#include "BKE_shrinkwrap.h"
@@ -51,6 +49,8 @@
#include "MOD_util.h"
+#define BEND_EPS 0.000001f
+
/* Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1]
* The amount of clamp is saved on dcut */
static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3])
@@ -122,15 +122,15 @@ static void simpleDeform_bend(const float factor, const float dcut[3], float r_c
float x = r_co[0], y = r_co[1], z = r_co[2];
float theta, sint, cost;
+ BLI_assert(!(fabsf(factor) < BEND_EPS));
+
theta = x * factor;
sint = sinf(theta);
cost = cosf(theta);
- if (fabsf(factor) > 1e-7f) {
- r_co[0] = -(y - 1.0f / factor) * sint;
- r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
- r_co[2] = z;
- }
+ r_co[0] = -(y - 1.0f / factor) * sint;
+ r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
+ r_co[2] = z;
{
r_co[0] += cost * dcut[0];
@@ -196,8 +196,6 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
smd_factor = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
}
- modifier_get_vgroup(ob, dm, smd->vgroup_name, &dvert, &vgroup);
-
switch (smd->mode) {
case MOD_SIMPLEDEFORM_MODE_TWIST: simpleDeform_callback = simpleDeform_twist; break;
case MOD_SIMPLEDEFORM_MODE_BEND: simpleDeform_callback = simpleDeform_bend; break;
@@ -207,6 +205,14 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
return; /* No simpledeform mode? */
}
+ if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
+ if (fabsf(smd_factor) < BEND_EPS) {
+ return;
+ }
+ }
+
+ modifier_get_vgroup(ob, dm, smd->vgroup_name, &dvert, &vgroup);
+
for (i = 0; i < numVerts; i++) {
float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index ca25d785da9..019eb54a9ee 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -59,7 +59,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_modifier_types.h"
@@ -67,10 +66,8 @@
#include "BLI_utildefines.h"
#include "BLI_array.h"
#include "BLI_heap.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_stack.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
@@ -111,9 +108,9 @@ typedef struct Frame {
} merge[4];
/* For hull frames, whether each vertex is detached or not */
- int inside_hull[4];
+ bool inside_hull[4];
/* Whether any part of the frame (corner or edge) is detached */
- int detached;
+ bool detached;
} Frame;
#define MAX_SKIN_NODE_FRAMES 2
@@ -174,34 +171,35 @@ static bool is_quad_symmetric(BMVert *quad[4],
}
/* Returns true if the quad crosses the plane of symmetry, false otherwise */
-static int quad_crosses_symmetry_plane(BMVert *quad[4],
- const SkinModifierData *smd)
+static bool quad_crosses_symmetry_plane(BMVert *quad[4],
+ const SkinModifierData *smd)
{
int axis;
for (axis = 0; axis < 3; axis++) {
if (smd->symmetry_axes & (1 << axis)) {
- int i, left = FALSE, right = FALSE;
+ bool left = false, right = false;
+ int i;
for (i = 0; i < 4; i++) {
if (quad[i]->co[axis] < 0.0f)
- left = TRUE;
+ left = true;
else if (quad[i]->co[axis] > 0.0f)
- right = TRUE;
+ right = true;
if (left && right)
- return TRUE;
+ return true;
}
}
}
- return FALSE;
+ return false;
}
/* Returns true if the frame is filled by precisely two faces (and
* outputs those faces to fill_faces), otherwise returns false. */
-static int skin_frame_find_contained_faces(const Frame *frame,
- BMFace *fill_faces[2])
+static bool skin_frame_find_contained_faces(const Frame *frame,
+ BMFace *fill_faces[2])
{
BMEdge *diag;
@@ -213,11 +211,11 @@ static int skin_frame_find_contained_faces(const Frame *frame,
if (diag)
return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]);
else
- return FALSE;
+ return false;
}
-/* Returns TRUE if hull is successfully built, FALSE otherwise */
-static int build_hull(SkinOutput *so, Frame **frames, int totframe)
+/* Returns true if hull is successfully built, false otherwise */
+static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
{
BMesh *bm = so->bm;
BMOperator op;
@@ -228,7 +226,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
BMEdge *e;
int i, j;
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
for (i = 0; i < totframe; i++) {
for (j = 0; j < 4; j++) {
@@ -246,7 +244,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
if (BMO_error_occurred(bm)) {
BMO_op_finish(bm, &op);
- return FALSE;
+ return false;
}
/* Apply face attributes to hull output */
@@ -264,8 +262,8 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
if (!frame->detached) {
for (j = 0; j < 4; j++) {
if (frame->verts[j] == v) {
- frame->inside_hull[j] = TRUE;
- frame->detached = TRUE;
+ frame->inside_hull[j] = true;
+ frame->detached = true;
break;
}
}
@@ -283,7 +281,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
!BM_edge_exists(frame->verts[2], frame->verts[3]) ||
!BM_edge_exists(frame->verts[3], frame->verts[0])))
{
- frame->detached = TRUE;
+ frame->detached = true;
}
}
@@ -304,7 +302,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
BM_elem_flag_enable(fill_faces[1], BM_ELEM_TAG);
}
else
- frame->detached = TRUE;
+ frame->detached = true;
}
}
@@ -324,9 +322,9 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
BMO_op_finish(bm, &op);
- BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_ONLYTAGGED);
+ BM_mesh_delete_hflag_tagged(bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
- return TRUE;
+ return true;
}
/* Returns the average frame side length (frames are rectangular, so
@@ -660,7 +658,7 @@ static void build_emats_stack(BLI_Stack *stack, int *visited_e, EMat *emat,
return;
/* Mark edge as visited */
- visited_e[e] = TRUE;
+ visited_e[e] = true;
/* Process edge */
@@ -751,12 +749,15 @@ static EMat *build_edge_mats(const MVertSkin *vs,
* having any special cases for dealing with sharing a frame between
* two hulls.) */
static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
- const MEdge *e, int *degree)
+ const MEdge *e, const int *degree)
{
+ /* prevent memory errors [#38003] */
+#define NUM_SUBDIVISIONS_MAX 128
+
const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
- float edge_len, avg[2];
- int v1_branch = degree[e->v1] > 2;
- int v2_branch = degree[e->v2] > 2;
+ float avg_radius;
+ const bool v1_branch = degree[e->v1] > 2;
+ const bool v2_branch = degree[e->v2] > 2;
int num_subdivisions;
/* If either end is a branch node marked 'loose', don't subdivide
@@ -770,15 +771,23 @@ static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
return 0;
}
- edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
-
- avg[0] = half_v2(evs[0]->radius);
- avg[1] = half_v2(evs[1]->radius);
+ avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
- if (avg[0] + avg[1] == 0.0f)
+ if (avg_radius != 0.0f) {
+ /* possible (but unlikely) that we overflow INT_MAX */
+ float num_subdivisions_fl;
+ const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
+ num_subdivisions_fl = (edge_len / avg_radius);
+ if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
+ num_subdivisions = (int)num_subdivisions_fl;
+ }
+ else {
+ num_subdivisions = NUM_SUBDIVISIONS_MAX;
+ }
+ }
+ else {
num_subdivisions = 0;
- else
- num_subdivisions = (int)((float)edge_len / (avg[0] + avg[1]));
+ }
/* If both ends are branch nodes, two intermediate nodes are
* required */
@@ -786,6 +795,8 @@ static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
num_subdivisions = 2;
return num_subdivisions;
+
+#undef NUM_SUBDIVISIONS_MAX
}
/* Take a DerivedMesh and subdivide its edges to keep skin nodes
@@ -1023,7 +1034,7 @@ static int isect_ray_poly(const float ray_start[3],
BMVert *v, *v_first = NULL, *v_prev = NULL;
BMIter iter;
float best_dist = FLT_MAX;
- int hit = 0;
+ bool hit = false;
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
if (!v_first)
@@ -1036,7 +1047,7 @@ static int isect_ray_poly(const float ray_start[3],
v_first->co, v_prev->co, v->co,
&dist, NULL);
if (curhit && dist < best_dist) {
- hit = TRUE;
+ hit = true;
best_dist = dist;
}
}
@@ -1091,15 +1102,16 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
/* Find the new face */
f = NULL;
BM_ITER_ELEM (vf, &iter, v_safe, BM_FACES_OF_VERT) {
- int wrong_face = FALSE;
+ bool wrong_face = false;
for (i = 0; i < orig_len; i++) {
- if (orig_verts[i] == v_merge)
+ if (orig_verts[i] == v_merge) {
orig_verts[i] = NULL;
+ }
else if (orig_verts[i] &&
!BM_vert_in_face(vf, orig_verts[i]))
{
- wrong_face = TRUE;
+ wrong_face = true;
break;
}
}
@@ -1215,7 +1227,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
BLI_assert(split_face->len >= 3);
/* Extrude the split face */
- BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
BM_elem_flag_enable(split_face, BM_ELEM_TAG);
BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"extrude_discrete_faces faces=%hf", BM_ELEM_TAG);
@@ -1238,7 +1250,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
* face is a triangle */
longest_edge = BM_face_find_longest_loop(split_face)->e;
- BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, false);
BM_elem_flag_enable(longest_edge, BM_ELEM_TAG);
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
@@ -1365,7 +1377,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
heap = BLI_heap_new();
- BM_mesh_elem_hflag_disable_all(so->bm, BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(so->bm, BM_FACE, BM_ELEM_TAG, false);
/* Build heap */
BM_ITER_MESH (e, &iter, so->bm, BM_EDGES_OF_MESH) {
@@ -1430,7 +1442,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
BLI_heap_free(heap, NULL);
- BM_mesh_delete_hflag_context(so->bm, BM_ELEM_TAG, DEL_ONLYTAGGED);
+ BM_mesh_delete_hflag_tagged(so->bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
}
@@ -1599,7 +1611,7 @@ static void skin_smooth_hulls(BMesh *bm, SkinNode *skin_nodes,
return;
/* Mark all frame vertices */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
for (i = 0; i < totvert; i++) {
for (j = 0; j < skin_nodes[i].totframe; j++) {
Frame *frame = &skin_nodes[i].frames[j];
@@ -1649,12 +1661,13 @@ static void skin_smooth_hulls(BMesh *bm, SkinNode *skin_nodes,
BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
}
-/* Returns TRUE if all hulls are successfully built, FALSE otherwise */
-static int skin_output_branch_hulls(SkinOutput *so, SkinNode *skin_nodes,
- int totvert, const MeshElemMap *emap,
- const MEdge *medge)
+/* Returns true if all hulls are successfully built, false otherwise */
+static bool skin_output_branch_hulls(SkinOutput *so, SkinNode *skin_nodes,
+ int totvert, const MeshElemMap *emap,
+ const MEdge *medge)
{
- int result = TRUE, v;
+ bool result = true;
+ int v;
for (v = 0; v < totvert; v++) {
SkinNode *sn = &skin_nodes[v];
@@ -1668,7 +1681,7 @@ static int skin_output_branch_hulls(SkinOutput *so, SkinNode *skin_nodes,
emap, medge,
&tothullframe);
if (!build_hull(so, hull_frames, tothullframe))
- result = FALSE;
+ result = false;
MEM_freeN(hull_frames);
}
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index eb8c62cfd89..d1ad8f1fcfc 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -37,7 +37,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 83b53e208c0..c212c13e396 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -37,7 +37,6 @@
#include "BLI_utildefines.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
@@ -538,13 +537,13 @@ static DerivedMesh *applyModifier(
LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) &&
((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0)))
{
- vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
+ vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], face_nors[i]) * angle;
}
else {
vert_angles[vidx] += angle;
}
#else
- vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
+ vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], face_nors[i]) * angle;
#endif
/* --- end non-angle-calc section --- */
@@ -720,7 +719,7 @@ static DerivedMesh *applyModifier(
CustomData_copy_data(&dm->loopData, &result->loopData, k1, (int)(numLoops * 2 + j + 2), 1);
CustomData_copy_data(&dm->loopData, &result->loopData, k2, (int)(numLoops * 2 + j + 3), 1);
- if (flip == FALSE) {
+ if (flip == false) {
ml[j].v = ed->v1;
ml[j++].e = eidx;
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 0cc9b8bb77b..386d6d985fb 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -34,7 +34,6 @@
#include "DNA_curve_types.h"
#include "DNA_image_types.h"
-#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 8ded9847c2a..2ff93efdb86 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -38,10 +38,8 @@
#include "DNA_meshdata_types.h"
#include "DNA_camera_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_uvproject.h"
#include "BLI_utildefines.h"
@@ -232,7 +230,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
numVerts = dm->getNumVerts(dm);
- coords = MEM_callocN(sizeof(*coords) * numVerts,
+ coords = MEM_mallocN(sizeof(*coords) * numVerts,
"uvprojectModifier_do coords");
dm->getVertCos(dm, coords);
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index 4640a36909b..f5ff30e35d9 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -31,7 +31,6 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_action.h" /* BKE_pose_channel_find_name */
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 93be31bcad7..f6714e79401 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -34,7 +34,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
@@ -253,7 +252,7 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
break;
case eWarp_Falloff_Root:
- fac = (float)sqrt(fac);
+ fac = sqrtf(fac);
break;
case eWarp_Falloff_Linear:
/* pass */
@@ -262,7 +261,7 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
fac = 1.0f;
break;
case eWarp_Falloff_Sphere:
- fac = (float)sqrt(2 * fac - fac * fac);
+ fac = sqrtf(2 * fac - fac * fac);
break;
}
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 1a81b1fdf4c..47e4c502a90 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -40,13 +40,11 @@
#include "DNA_object_types.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_library.h"
-#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 348b0361464..12ecae8ad4f 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -94,10 +94,10 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm
fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
break;
case MOD_WVG_MAPPING_ROOT:
- fac = (float)sqrt(fac);
+ fac = sqrtf(fac);
break;
case MOD_WVG_MAPPING_SPHERE:
- fac = (float)sqrt(2 * fac - fac * fac);
+ fac = sqrtf(2 * fac - fac * fac);
break;
case MOD_WVG_MAPPING_RANDOM:
fac = BLI_rng_get_float(rng) * fac;
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index a9062c31e66..f36abcceae0 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -30,8 +30,6 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_listbase.h"
#include "BLI_rand.h"
@@ -45,7 +43,6 @@
#include "BKE_colortools.h" /* CurveMapping. */
#include "BKE_deform.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index b4be0f75f81..bdc1099d682 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -30,10 +30,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_listbase.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -41,7 +39,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
@@ -380,7 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
/* Update (add to) vgroup.
* XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
*/
- weightvg_update_vg(dvert, defgrp_index, dw1, numIdx, indices, org_w, TRUE, -FLT_MAX, FALSE, 0.0f);
+ weightvg_update_vg(dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f);
/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 8115cdaa640..f5ae8561300 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -32,7 +32,6 @@
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_rand.h"
#include "DNA_mesh_types.h"
@@ -43,7 +42,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_shrinkwrap.h" /* For SpaceTransform stuff. */
#include "BKE_texture.h" /* Texture masking. */
@@ -465,7 +463,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
DerivedMesh *target_dm = obr->derivedFinal;
- short free_target_dm = FALSE;
+ bool free_target_dm = false;
if (!target_dm) {
if (ELEM3(obr->type, OB_CURVE, OB_SURF, OB_FONT))
target_dm = CDDM_from_curve(obr);
@@ -476,7 +474,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
else
target_dm = CDDM_from_mesh(me);
}
- free_target_dm = TRUE;
+ free_target_dm = true;
}
/* We must check that we do have a valid target_dm! */
@@ -521,7 +519,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
/* Update vgroup. Note we never add nor remove vertices from vgroup here. */
- weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, FALSE, 0.0f, FALSE, 0.0f);
+ weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f);
/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 3ebd9bd38fd..76986583ef5 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -20,8 +20,8 @@
*/
/** \file blender/modifiers/intern/MOD_wireframe.c
-* \ingroup modifiers
-*/
+ * \ingroup modifiers
+ */
#include "MEM_guardedalloc.h"
@@ -80,7 +80,7 @@ static DerivedMesh *WireframeModifier_do( WireframeModifierData *wmd, Object *ob
DerivedMesh *result;
BMesh *bm;
- const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);;
+ const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
bm = DM_to_bmesh(dm, true);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 16671e84da0..754a3c11d78 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -56,6 +56,7 @@ set(SRC
composite/nodes/node_composite_colorbalance.c
composite/nodes/node_composite_common.c
composite/nodes/node_composite_composite.c
+ composite/nodes/node_composite_cornerpin.c
composite/nodes/node_composite_crop.c
composite/nodes/node_composite_curves.c
composite/nodes/node_composite_despeckle.c
@@ -199,6 +200,7 @@ set(SRC
shader/nodes/node_shader_tex_wave.c
shader/nodes/node_shader_volume_scatter.c
shader/nodes/node_shader_volume_absorption.c
+ shader/nodes/node_shader_uvmap.c
shader/node_shader_tree.c
shader/node_shader_util.c
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index 78265154125..ad5f35b8faa 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -136,6 +136,7 @@ void register_node_type_cmp_switch(void);
void register_node_type_cmp_pixelate(void);
void register_node_type_cmp_trackpos(void);
void register_node_type_cmp_planetrackdeform(void);
+void register_node_type_cmp_cornerpin(void);
void node_cmp_rlayers_force_hidden_passes(struct bNode *node);
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 0f388a890a4..91b103da0e2 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -111,6 +111,7 @@ void register_node_type_sh_bsdf_hair(void);
void register_node_type_sh_subsurface_scattering(void);
void register_node_type_sh_mix_shader(void);
void register_node_type_sh_add_shader(void);
+void register_node_type_sh_uvmap(void);
void register_node_type_sh_output_lamp(void);
void register_node_type_sh_output_material(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index f7f7118822f..434e737772d 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -119,6 +119,7 @@ DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TE
DefNode( ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" )
DefNode( ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
DefNode( ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
+DefNode( ShaderNode, SH_NODE_UVMAP, def_sh_uvmap, "UVMAP", UVMap, "UV Map", "" )
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
@@ -204,6 +205,7 @@ DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYIN
DefNode( CompositorNode, CMP_NODE_TRACKPOS, def_cmp_trackpos, "TRACKPOS", TrackPos, "Track Position", "" )
DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXELATE", Pixelate, "Pixelate", "" )
DefNode( CompositorNode, CMP_NODE_PLANETRACKDEFORM,def_cmp_planetrackdeform,"PLANETRACKDEFORM",PlaneTrackDeform,"Plane Track Deform","" )
+DefNode( CompositorNode, CMP_NODE_CORNERPIN, 0, "CORNERPIN", CornerPin, "Corner Pin", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index f3a99d9184e..cd69cf4982d 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -32,20 +32,16 @@
#include <stdio.h>
-#include "DNA_anim_types.h"
#include "DNA_color_types.h"
#include "DNA_scene_types.h"
#include "DNA_node_types.h"
#include "BLI_listbase.h"
-#include "BLI_threads.h"
#include "BLF_translation.h"
-#include "BKE_animsys.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -72,10 +68,6 @@ static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED(
*r_from = NULL;
*r_id = &scene->id;
*r_ntree = scene->nodetree;
-
- /* update output sockets based on available layers */
- ntreeCompositForceHidden(scene->nodetree);
-
}
static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c
index 69f912346f6..36c12693bdf 100644
--- a/source/blender/nodes/composite/nodes/node_composite_common.c
+++ b/source/blender/nodes/composite/nodes/node_composite_common.c
@@ -58,7 +58,7 @@ void register_node_type_cmp_group(void)
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 400);
+ node_type_size(&ntype, 140, 60, 400);
node_type_label(&ntype, node_group_label);
node_type_update(&ntype, NULL, node_group_verify);
diff --git a/source/blender/nodes/composite/nodes/node_composite_cornerpin.c b/source/blender/nodes/composite/nodes/node_composite_cornerpin.c
new file mode 100644
index 00000000000..9758e32da3f
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_cornerpin.c
@@ -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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_cornerpin.c
+ * \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+static bNodeSocketTemplate inputs[] = {
+ { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Upper Left"), 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Upper Right"), 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Lower Left"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Lower Right"), 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate outputs[] = {
+ { SOCK_RGBA, 0, N_("Image")},
+ { SOCK_FLOAT, 0, N_("Plane")},
+ { -1, 0, "" }
+};
+
+void register_node_type_cmp_cornerpin(void)
+{
+ static bNodeType ntype;
+
+ cmp_node_type_base(&ntype, CMP_NODE_CORNERPIN, "Corner Pin", NODE_CLASS_DISTORT, 0);
+ node_type_socket_templates(&ntype, inputs, outputs);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index f87cf9da90b..659e582dc1d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -397,7 +397,7 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node)
set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
-
+
set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index 952ec15f2aa..76101409ba7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -129,7 +129,7 @@ bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, con
else
BKE_imformat_defaults(&sockdata->format);
/* use node data format by default */
- sockdata->use_node_format = TRUE;
+ sockdata->use_node_format = true;
nimf->active_input = BLI_findindex(&node->inputs, sock);
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 0ed6530cbaa..ae834f9e7cc 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -36,17 +36,11 @@
#include "DNA_node_types.h"
#include "BLI_listbase.h"
-#include "BLI_math.h"
-#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
-#include "BKE_global.h"
-#include "BKE_idprop.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
#include "BKE_node.h"
#include "RNA_access.h"
@@ -94,10 +88,10 @@ int node_group_poll_instance(bNode *node, bNodeTree *nodetree)
if (grouptree)
return nodeGroupPoll(nodetree, grouptree);
else
- return TRUE; /* without a linked node tree, group node is always ok */
+ return true; /* without a linked node tree, group node is always ok */
}
else
- return FALSE;
+ return false;
}
int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)
@@ -384,7 +378,7 @@ void node_group_input_verify(bNodeTree *ntree, bNode *node, ID *id)
static void node_group_input_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = node->outputs.last;
- bNodeLink *link;
+ bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links from the extension socket
* so they can be recreated after verification.
@@ -393,26 +387,37 @@ static void node_group_input_update(bNodeTree *ntree, bNode *node)
/* find links from the extension socket and store them */
BLI_listbase_clear(&tmplinks);
- for (link = ntree->links.first; link; link = link->next) {
+ for (link = ntree->links.first; link; link = linknext) {
+ linknext = link->next;
if (nodeLinkIsHidden(link))
continue;
+
if (link->fromsock == extsock) {
bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
*tlink = *link;
BLI_addtail(&tmplinks, tlink);
+
+ nodeRemLink(ntree, link);
}
}
- if (tmplinks.first) {
- bNodeSocket *gsock, *newsock;
+ /* find valid link to expose */
+ exposelink = NULL;
+ for (link = tmplinks.first; link; link = link->next) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- bNodeLink *exposelink = tmplinks.first;
+ if (link->tosock->type != SOCK_CUSTOM) {
+ exposelink = link;
+ break;
+ }
+ }
+
+ if (exposelink) {
+ bNodeSocket *gsock, *newsock;
- /* XXX what if connecting virtual to virtual socket?? */
gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
node_group_input_verify(ntree, node, (ID *)ntree);
@@ -423,8 +428,9 @@ static void node_group_input_update(bNodeTree *ntree, bNode *node)
nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
}
- BLI_freelistN(&tmplinks);
}
+
+ BLI_freelistN(&tmplinks);
}
void register_node_type_group_input(void)
@@ -471,7 +477,7 @@ void node_group_output_verify(bNodeTree *ntree, bNode *node, ID *id)
static void node_group_output_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = node->inputs.last;
- bNodeLink *link;
+ bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links to the extension socket
* so they can be recreated after verification.
@@ -480,24 +486,36 @@ static void node_group_output_update(bNodeTree *ntree, bNode *node)
/* find links to the extension socket and store them */
BLI_listbase_clear(&tmplinks);
- for (link = ntree->links.first; link; link = link->next) {
+ for (link = ntree->links.first; link; link = linknext) {
+ linknext = link->next;
if (nodeLinkIsHidden(link))
continue;
+
if (link->tosock == extsock) {
bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
*tlink = *link;
BLI_addtail(&tmplinks, tlink);
+
+ nodeRemLink(ntree, link);
}
}
- if (tmplinks.first) {
- bNodeSocket *gsock, *newsock;
+ /* find valid link to expose */
+ exposelink = NULL;
+ for (link = tmplinks.first; link; link = link->next) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- bNodeLink *exposelink = tmplinks.first;
+ if (link->fromsock->type != SOCK_CUSTOM) {
+ exposelink = link;
+ break;
+ }
+ }
+
+ if (exposelink) {
+ bNodeSocket *gsock, *newsock;
/* XXX what if connecting virtual to virtual socket?? */
gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
@@ -509,9 +527,9 @@ static void node_group_output_update(bNodeTree *ntree, bNode *node)
for (link = tmplinks.first; link; link = link->next) {
nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
}
-
- BLI_freelistN(&tmplinks);
}
+
+ BLI_freelistN(&tmplinks);
}
void register_node_type_group_output(void)
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 37018b3a98d..0e5f72c831b 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -33,7 +33,6 @@
#include "DNA_node_types.h"
#include "BLI_listbase.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_global.h"
@@ -265,7 +264,7 @@ bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
for (nts = lb->first; nts; nts = nts->next) {
if (!nts->used) {
- nts->used = TRUE;
+ nts->used = true;
break;
}
}
@@ -273,7 +272,7 @@ bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
if (!nts) {
nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
nts->stack = MEM_dupallocN(exec->stack);
- nts->used = TRUE;
+ nts->used = true;
BLI_addtail(lb, nts);
}
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index 4101c6c4c4d..a0023d02295 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -72,7 +72,7 @@ typedef struct bNodeTreeExec {
typedef struct bNodeThreadStack {
struct bNodeThreadStack *next, *prev;
struct bNodeStack *stack;
- int used;
+ bool used;
} bNodeThreadStack;
int node_exec_socket_use_stack(struct bNodeSocket *sock);
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index b30658fa2be..2ac1a2c85f3 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -39,7 +39,6 @@
#include "BLI_string.h"
#include "BKE_node.h"
-#include "BKE_idprop.h"
#include "RNA_access.h"
#include "RNA_define.h"
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 3997d9cbcac..cc8249b0f57 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -32,7 +32,6 @@
#include <limits.h>
#include <string.h>
-#include "DNA_action_types.h"
#include "DNA_node_types.h"
#include "BLI_listbase.h"
@@ -81,6 +80,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNode
return NULL; /* unused return */
}
+
/**** Labels ****/
void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
@@ -111,45 +111,140 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m
BLI_strncpy(label, IFACE_(name), maxlen);
}
+
+/**** Internal Links (mute and disconnect) ****/
+
+/* common datatype priorities, works for compositor, shader and texture nodes alike
+ * defines priority of datatype connection based on output type (to):
+ * < 0 : never connect these types
+ * >= 0 : priority of connection (higher values chosen first)
+ */
+static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to)
+{
+ switch (to) {
+ case SOCK_RGBA:
+ switch (from) {
+ case SOCK_RGBA: return 4;
+ case SOCK_FLOAT: return 3;
+ case SOCK_INT: return 2;
+ case SOCK_BOOLEAN: return 1;
+ default: return -1;
+ }
+ case SOCK_VECTOR:
+ switch (from) {
+ case SOCK_VECTOR: return 4;
+ case SOCK_FLOAT: return 3;
+ case SOCK_INT: return 2;
+ case SOCK_BOOLEAN: return 1;
+ default: return -1;
+ }
+ case SOCK_FLOAT:
+ switch (from) {
+ case SOCK_FLOAT: return 5;
+ case SOCK_INT: return 4;
+ case SOCK_BOOLEAN: return 3;
+ case SOCK_RGBA: return 2;
+ case SOCK_VECTOR: return 1;
+ default: return -1;
+ }
+ case SOCK_INT:
+ switch (from) {
+ case SOCK_INT: return 5;
+ case SOCK_FLOAT: return 4;
+ case SOCK_BOOLEAN: return 3;
+ case SOCK_RGBA: return 2;
+ case SOCK_VECTOR: return 1;
+ default: return -1;
+ }
+ case SOCK_BOOLEAN:
+ switch (from) {
+ case SOCK_BOOLEAN: return 5;
+ case SOCK_INT: return 4;
+ case SOCK_FLOAT: return 3;
+ case SOCK_RGBA: return 2;
+ case SOCK_VECTOR: return 1;
+ default: return -1;
+ }
+ case SOCK_SHADER:
+ switch (from) {
+ case SOCK_SHADER: return 1;
+ default: return -1;
+ }
+ case SOCK_STRING:
+ switch (from) {
+ case SOCK_STRING: return 1;
+ default: return -1;
+ }
+ default: return -1;
+ }
+}
+
+/* select a suitable input socket for an output */
+static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
+{
+ bNodeSocket *selected = NULL, *input;
+ int i;
+ int sel_priority = -1;
+ bool sel_is_linked = false;
+
+ for (input = node->inputs.first, i = 0; input; input = input->next, ++i) {
+ int priority = node_datatype_priority(input->type, output->type);
+ bool is_linked = (input->link != NULL);
+ bool preferred;
+
+ if (nodeSocketIsHidden(input) || /* ignore hidden sockets */
+ input->flag & SOCK_NO_INTERNAL_LINK || /* ignore if input is not allowed for internal connections */
+ priority < 0 || /* ignore incompatible types */
+ priority < sel_priority) /* ignore if we already found a higher priority input */
+ {
+ continue;
+ }
+
+ /* determine if this input is preferred over the currently selected */
+ preferred = (priority > sel_priority) || /* prefer higher datatype priority */
+ (is_linked && !sel_is_linked); /* prefer linked over unlinked */
+
+ if (preferred) {
+ selected = input;
+ sel_is_linked = is_linked;
+ sel_priority = priority;
+ }
+ }
+
+ return selected;
+}
+
void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
{
bNodeLink *link;
- bNodeSocket *output, *input, *selected;
-
+ bNodeSocket *output, *input;
+
/* sanity check */
if (!ntree)
return;
-
+
/* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
for (output = node->outputs.first; output; output = output->next)
output->link = NULL;
for (link = ntree->links.first; link; link = link->next) {
+ if (nodeLinkIsHidden(link))
+ continue;
+
output = link->fromsock;
if (link->fromnode != node || output->link)
continue;
+ if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK)
+ continue;
output->link = link; /* not really used, just for tagging handled sockets */
/* look for suitable input */
- selected = NULL;
- for (input = node->inputs.first; input; input = input->next) {
- /* only use if same type */
- if (input->type == output->type) {
- if (!selected) {
- selected = input;
- }
- else {
- /* linked inputs preferred */
- if (input->link && !selected->link)
- selected = input;
- }
- }
- }
+ input = select_internal_link_input(node, output);
- if (selected) {
+ if (input) {
bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
ilink->fromnode = node;
- ilink->fromsock = selected;
+ ilink->fromsock = input;
ilink->tonode = node;
ilink->tosock = output;
/* internal link is always valid */
@@ -163,6 +258,9 @@ void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
output->link = NULL;
}
+
+/**** Default value RNA access ****/
+
float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock)
{
PointerRNA ptr;
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 2186eb7c226..53f97e0d36c 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -79,7 +79,7 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT;
- if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
+ if (!BKE_scene_use_new_shading_nodes(scene) || snode->shaderfrom == SNODE_SHADER_OBJECT) {
if (ob) {
*r_from = &ob->id;
if (ob->type == OB_LAMP) {
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 8e83140733a..b00d96de935 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -54,7 +54,7 @@ void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, shor
void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
{
- float *from = ns->vec;
+ const float *from = ns->vec;
if (type_in == SOCK_FLOAT) {
if (ns->sockettype == SOCK_FLOAT)
@@ -228,22 +228,23 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs, sh
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
GPUNodeStack gpuin[MAX_SOCKET + 1], gpuout[MAX_SOCKET + 1];
- int do_it;
+ bool do_it;
stack = exec->stack;
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
node = nodeexec->node;
- do_it = FALSE;
+ do_it = false;
/* for groups, only execute outputs for edited group */
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
if (node->typeinfo->compatibility & compatibility)
if (do_outputs && (node->flag & NODE_DO_OUTPUT))
- do_it = TRUE;
+ do_it = true;
+ }
+ else {
+ do_it = true;
}
- else
- do_it = TRUE;
if (do_it) {
if (node->typeinfo->gpufunc) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c
index fb10efe1569..3ce01ce03bf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.c
@@ -61,7 +61,7 @@ void register_node_type_sh_bump(void)
sh_node_type_base(&ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_bump_in, sh_node_bump_out);
- node_type_storage(&ntype, "BumpNode", node_free_standard_storage, node_copy_standard_storage);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, gpu_shader_bump);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c
index d1ff30ef7d1..231af7e7d37 100644
--- a/source/blender/nodes/shader/nodes/node_shader_camera.c
+++ b/source/blender/nodes/shader/nodes/node_shader_camera.c
@@ -64,7 +64,7 @@ void register_node_type_sh_camera(void)
sh_node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, NULL, sh_node_camera_out);
- node_type_storage(&ntype, "node_camera", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_camera);
node_type_gpu(&ntype, gpu_shader_camera);
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index 3f03bb45d8f..7ff60ac716a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -218,7 +218,7 @@ static int gpu_group_execute(GPUMaterial *mat, bNode *node, bNodeExecData *execd
#if 0 /* XXX NODE_GROUP_EDIT is deprecated, depends on node space */
ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT));
#else
- ntreeExecGPUNodes(exec, mat, 0, NODE_NEW_SHADING|NODE_OLD_SHADING);
+ ntreeExecGPUNodes(exec, mat, 0, NODE_NEW_SHADING | NODE_OLD_SHADING);
#endif
group_gpu_move_outputs(node, out, exec->stack);
@@ -243,7 +243,7 @@ void register_node_type_sh_group(void)
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 400);
+ node_type_size(&ntype, 140, 60, 400);
node_type_label(&ntype, node_group_label);
node_type_update(&ntype, NULL, node_group_verify);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 94b667c5f6d..5e067e6c630 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -101,13 +101,15 @@ static bNodeSocketTemplate sh_node_curve_rgb_out[] = {
static void node_shader_exec_curve_rgb(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
+ float fac;
/* stack order input: vec */
/* stack order output: vec */
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
curvemapping_evaluateRGBF(node->storage, out[0]->vec, vec);
- if (in[0]->vec[0] != 1.0f) {
- interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, *in[0]->vec);
+ if (fac != 1.0f) {
+ interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, fac);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
index e4f0e6eb80e..6fe6a33010a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
@@ -48,21 +48,21 @@ static bNodeSocketTemplate sh_node_hue_sat_out[] = {
};
/* note: it would be possible to use CMP version for both nodes */
-static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *sat, float *val, float *in, float *fac)
+static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat, float val, float in[4], float fac)
{
- if (*fac != 0.0f && (*hue != 0.5f || *sat != 1.0f || *val != 1.0f)) {
- float col[3], hsv[3], mfac = 1.0f - *fac;
+ if (fac != 0.0f && (hue != 0.5f || sat != 1.0f || val != 1.0f)) {
+ float col[3], hsv[3], mfac = 1.0f - fac;
rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
- hsv[0] += (*hue - 0.5f);
+ hsv[0] += (hue - 0.5f);
if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
- hsv[1] *= *sat;
- hsv[2] *= *val;
+ hsv[1] *= sat;
+ hsv[2] *= val;
hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col + 1, col + 2);
- out[0] = mfac * in[0] + *fac * col[0];
- out[1] = mfac * in[1] + *fac * col[1];
- out[2] = mfac * in[2] + *fac * col[2];
+ out[0] = mfac * in[0] + fac * col[0];
+ out[1] = mfac * in[1] + fac * col[1];
+ out[2] = mfac * in[2] + fac * col[2];
}
else {
copy_v4_v4(out, in);
@@ -70,8 +70,15 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *s
}
static void node_shader_exec_hue_sat(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
-{
- do_hue_sat_fac(node, out[0]->vec, in[0]->vec, in[1]->vec, in[2]->vec, in[4]->vec, in[3]->vec);
+{
+ float hue, sat, val, fac;
+ float col[4];
+ nodestack_get_vec(&hue, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&sat, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&val, SOCK_FLOAT, in[2]);
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[3]);
+ nodestack_get_vec(col, SOCK_RGBA, in[4]);
+ do_hue_sat_fac(node, out[0]->vec, hue, sat, val, col, fac);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c
index 6e0dbf6b87e..27450ba0fe6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_invert.c
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.c
@@ -49,22 +49,20 @@ static bNodeSocketTemplate sh_node_invert_out[] = {
static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
bNodeStack **out)
{
- float col[3], facm;
+ float col[3], icol[3], fac;
- col[0] = 1.0f - in[1]->vec[0];
- col[1] = 1.0f - in[1]->vec[1];
- col[2] = 1.0f - in[1]->vec[2];
+ nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(col, SOCK_VECTOR, in[1]);
- /* if fac, blend result against original input */
- if (in[0]->vec[0] < 1.0f) {
- facm = 1.0f - in[0]->vec[0];
-
- col[0] = in[0]->vec[0] * col[0] + (facm * in[1]->vec[0]);
- col[1] = in[0]->vec[0] * col[1] + (facm * in[1]->vec[1]);
- col[2] = in[0]->vec[0] * col[2] + (facm * in[1]->vec[2]);
- }
+ icol[0] = 1.0f - col[0];
+ icol[1] = 1.0f - col[1];
+ icol[2] = 1.0f - col[2];
- copy_v3_v3(out[0]->vec, col);
+ /* if fac, blend result against original input */
+ if (fac < 1.0f)
+ interp_v3_v3v3(out[0]->vec, col, icol, fac);
+ else
+ copy_v3_v3(out[0]->vec, icol);
}
static int gpu_shader_invert(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.c b/source/blender/nodes/shader/nodes/node_shader_light_path.c
index 9d769b284b1..023c6ea02a9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_path.c
+++ b/source/blender/nodes/shader/nodes/node_shader_light_path.c
@@ -39,6 +39,7 @@ static bNodeSocketTemplate sh_node_light_path_out[] = {
{ SOCK_FLOAT, 0, N_("Is Transmission Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 0, N_("Ray Length"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 0, N_("Ray Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Transparent Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
index 820e0f479be..79d66495ad7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -186,7 +186,7 @@ static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *nod
if (node->type == SH_NODE_MATERIAL_EXT) {
/* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside
* a node tree :( */
- copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diff);
+ copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diffshad);
copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec);
copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 49a7de47fc3..d5ba8231cce 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -47,64 +47,69 @@ static bNodeSocketTemplate sh_node_math_out[] = {
static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
+ float a, b, r = 0.0f;
+
+ nodestack_get_vec(&a, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&b, SOCK_FLOAT, in[1]);
+
switch (node->custom1) {
case 0: /* Add */
- out[0]->vec[0] = in[0]->vec[0] + in[1]->vec[0];
+ r = a + b;
break;
case 1: /* Subtract */
- out[0]->vec[0] = in[0]->vec[0] - in[1]->vec[0];
+ r = a - b;
break;
case 2: /* Multiply */
- out[0]->vec[0] = in[0]->vec[0] * in[1]->vec[0];
+ r = a * b;
break;
case 3: /* Divide */
{
- if (in[1]->vec[0] == 0) /* We don't want to divide by zero. */
- out[0]->vec[0] = 0.0;
+ if (b == 0) /* We don't want to divide by zero. */
+ r = 0.0;
else
- out[0]->vec[0] = in[0]->vec[0] / in[1]->vec[0];
+ r = a / b;
break;
}
case 4: /* Sine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = sin(in[0]->vec[0]);
+ r = sin(a);
else
- out[0]->vec[0] = sin(in[1]->vec[0]);
+ r = sin(b);
break;
}
case 5: /* Cosine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = cos(in[0]->vec[0]);
+ r = cos(a);
else
- out[0]->vec[0] = cos(in[1]->vec[0]);
+ r = cos(b);
break;
}
case 6: /* Tangent */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = tan(in[0]->vec[0]);
+ r = tan(a);
else
- out[0]->vec[0] = tan(in[1]->vec[0]);
+ r = tan(b);
break;
}
case 7: /* Arc-Sine */
{
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 (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
- out[0]->vec[0] = asin(in[0]->vec[0]);
+ if (a <= 1 && a >= -1)
+ r = asin(a);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
else {
/* Can't do the impossible... */
- if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
- out[0]->vec[0] = asin(in[1]->vec[0]);
+ if (b <= 1 && b >= -1)
+ r = asin(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
break;
}
@@ -112,43 +117,43 @@ 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 (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
- out[0]->vec[0] = acos(in[0]->vec[0]);
+ if (a <= 1 && a >= -1)
+ r = acos(a);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
else {
/* Can't do the impossible... */
- if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
- out[0]->vec[0] = acos(in[1]->vec[0]);
+ if (b <= 1 && b >= -1)
+ r = acos(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
}
break;
}
case 9: /* Arc-Tangent */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = atan(in[0]->vec[0]);
+ r = atan(a);
else
- out[0]->vec[0] = atan(in[1]->vec[0]);
+ r = atan(b);
break;
}
case 10: /* Power */
{
/* Only raise negative numbers by full integers */
- if (in[0]->vec[0] >= 0) {
- out[0]->vec[0] = pow(in[0]->vec[0], in[1]->vec[0]);
+ if (a >= 0) {
+ r = pow(a, b);
}
else {
- float y_mod_1 = fabsf(fmodf(in[1]->vec[0], 1.0f));
+ float y_mod_1 = fabsf(fmodf(b, 1.0f));
/* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
- out[0]->vec[0] = powf(in[0]->vec[0], floorf(in[1]->vec[0] + 0.5f));
+ r = powf(a, floorf(b + 0.5f));
}
else {
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
}
}
@@ -157,61 +162,68 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
case 11: /* Logarithm */
{
/* Don't want any imaginary numbers... */
- if (in[0]->vec[0] > 0 && in[1]->vec[0] > 0)
- out[0]->vec[0] = log(in[0]->vec[0]) / log(in[1]->vec[0]);
+ if (a > 0 && b > 0)
+ r = log(a) / log(b);
else
- out[0]->vec[0] = 0.0;
+ r = 0.0;
break;
}
case 12: /* Minimum */
{
- if (in[0]->vec[0] < in[1]->vec[0])
- out[0]->vec[0] = in[0]->vec[0];
+ if (a < b)
+ r = a;
else
- out[0]->vec[0] = in[1]->vec[0];
+ r = b;
break;
}
case 13: /* Maximum */
{
- if (in[0]->vec[0] > in[1]->vec[0])
- out[0]->vec[0] = in[0]->vec[0];
+ if (a > b)
+ r = a;
else
- out[0]->vec[0] = in[1]->vec[0];
+ r = b;
break;
}
case 14: /* Round */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0] = (in[0]->vec[0] < 0) ? (int)(in[0]->vec[0] - 0.5f) : (int)(in[0]->vec[0] + 0.5f);
+ r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f);
else
- out[0]->vec[0] = (in[1]->vec[0] < 0) ? (int)(in[1]->vec[0] - 0.5f) : (int)(in[1]->vec[0] + 0.5f);
+ r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f);
break;
}
case 15: /* Less Than */
{
- if (in[0]->vec[0] < in[1]->vec[0])
- out[0]->vec[0] = 1.0f;
+ if (a < b)
+ r = 1.0f;
else
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
break;
}
case 16: /* Greater Than */
{
- if (in[0]->vec[0] > in[1]->vec[0])
- out[0]->vec[0] = 1.0f;
+ if (a > b)
+ r = 1.0f;
else
- out[0]->vec[0] = 0.0f;
+ r = 0.0f;
break;
}
case 17: /* Modulo */
{
- if (in[1]->vec[0] == 0.0f)
- out[0]->vec[0] = 0.0f;
+ if (b == 0.0f)
+ r = 0.0f;
else
- out[0]->vec[0] = fmod(in[0]->vec[0], in[1]->vec[0]);
+ r = fmod(a, b);
+ break;
+ }
+ case 18: /* Absolute */
+ {
+ r = fabs(a);
break;
}
}
+
+ out[0]->vec[0] = r;
}
static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -219,7 +231,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
static const char *names[] = {"math_add", "math_subtract", "math_multiply",
"math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin",
"math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max",
- "math_round", "math_less_than", "math_greater_than", "math_modulo"};
+ "math_round", "math_less_than", "math_greater_than", "math_modulo", "math_absolute"};
switch (node->custom1) {
case 0:
@@ -272,7 +284,7 @@ void register_node_type_sh_math(void)
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out);
node_type_label(&ntype, node_math_label);
- node_type_storage(&ntype, "node_math", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_math);
node_type_gpu(&ntype, gpu_shader_math);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
index 2c515d587c0..b5b15397595 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
@@ -46,8 +46,11 @@ static bNodeSocketTemplate sh_node_sephsv_out[] = {
static void node_shader_exec_sephsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2],
- &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+
+ rgb_to_hsv(col[0], col[1], col[2],
+ &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
}
static int gpu_shader_sephsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -83,8 +86,12 @@ static bNodeSocketTemplate sh_node_combhsv_out[] = {
static void node_shader_exec_combhsv(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- hsv_to_rgb(in[0]->vec[0], in[1]->vec[0], in[2]->vec[0],
- &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
+ float h, s, v;
+ nodestack_get_vec(&h, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&s, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&v, SOCK_FLOAT, in[2]);
+
+ hsv_to_rgb(h, s, v, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
}
static int gpu_shader_combhsv(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
index a3cbd14a90f..006ba34c3f3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
@@ -46,9 +46,12 @@ static bNodeSocketTemplate sh_node_seprgb_out[] = {
static void node_shader_exec_seprgb(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- out[0]->vec[0] = in[0]->vec[0];
- out[1]->vec[0] = in[0]->vec[1];
- out[2]->vec[0] = in[0]->vec[2];
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+
+ out[0]->vec[0] = col[0];
+ out[1]->vec[0] = col[1];
+ out[2]->vec[0] = col[2];
}
static int gpu_shader_seprgb(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -85,9 +88,14 @@ static bNodeSocketTemplate sh_node_combrgb_out[] = {
static void node_shader_exec_combrgb(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
- out[0]->vec[0] = in[0]->vec[0];
- out[0]->vec[1] = in[1]->vec[0];
- out[0]->vec[2] = in[2]->vec[0];
+ float r, g, b;
+ nodestack_get_vec(&r, SOCK_FLOAT, in[0]);
+ nodestack_get_vec(&g, SOCK_FLOAT, in[1]);
+ nodestack_get_vec(&b, SOCK_FLOAT, in[2]);
+
+ out[0]->vec[0] = r;
+ out[0]->vec[1] = g;
+ out[0]->vec[2] = b;
}
static int gpu_shader_combrgb(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
index c884f2c3353..a4c995748d9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c
+++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
@@ -68,7 +68,7 @@ void register_node_type_sh_squeeze(void)
sh_node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING);
node_type_socket_templates(&ntype, sh_node_squeeze_in, sh_node_squeeze_out);
- node_type_storage(&ntype, "node_squeeze", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_squeeze);
node_type_gpu(&ntype, gpu_shader_squeeze);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index 8162b5b8a75..f75f6a654d1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -30,21 +30,21 @@
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_brick_in[] = {
- { SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE | SOCK_NO_INTERNAL_LINK},
{ SOCK_RGBA, 1, N_("Color1"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 1, N_("Color2"), 0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 1, N_("Mortar"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- { SOCK_FLOAT, 1, N_("Mortar Size"), 0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.125f},
- { SOCK_FLOAT, 1, N_("Bias"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Brick Width"), 0.5f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f},
- { SOCK_FLOAT, 1, N_("Row Height"), 0.25f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f},
+ { SOCK_RGBA, 1, N_("Mortar"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 1, N_("Mortar Size"), 0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.125f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 1, N_("Bias"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 1, N_("Brick Width"), 0.5f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 1, N_("Row Height"), 0.25f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_tex_brick_out[] = {
{ SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
index fb62d30a787..30e51c7cb7d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
@@ -33,13 +33,13 @@ static bNodeSocketTemplate sh_node_tex_checker_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ SOCK_RGBA, 1, N_("Color1"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 1, N_("Color2"), 0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
+ { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_tex_checker_out[] = {
{ SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 5e6471eab77..dcb3ef3c8a0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -37,7 +37,7 @@ static bNodeSocketTemplate sh_node_tex_environment_in[] = {
};
static bNodeSocketTemplate sh_node_tex_environment_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
index a077e57d318..e11591ab5ce 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
@@ -35,8 +35,8 @@ static bNodeSocketTemplate sh_node_tex_gradient_in[] = {
};
static bNodeSocketTemplate sh_node_tex_gradient_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 1b705e12daf..0a11ee4a9b6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -37,8 +37,8 @@ static bNodeSocketTemplate sh_node_tex_image_in[] = {
};
static bNodeSocketTemplate sh_node_tex_image_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Alpha"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Alpha"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
index dba198f55f4..de2daeb8ee1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
@@ -37,8 +37,8 @@ static bNodeSocketTemplate sh_node_tex_magic_in[] = {
};
static bNodeSocketTemplate sh_node_tex_magic_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
index 114fec71578..75566773ea2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
@@ -41,8 +41,8 @@ static bNodeSocketTemplate sh_node_tex_musgrave_in[] = {
};
static bNodeSocketTemplate sh_node_tex_musgrave_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
index dfb2aca2169..601a31dff00 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
@@ -38,8 +38,8 @@ static bNodeSocketTemplate sh_node_tex_noise_in[] = {
};
static bNodeSocketTemplate sh_node_tex_noise_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index 22061979b12..51cca0df851 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -35,7 +35,7 @@ static bNodeSocketTemplate sh_node_tex_sky_in[] = {
};
static bNodeSocketTemplate sh_node_tex_sky_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
index 3ee9268e198..5eba5f3f59d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
@@ -36,8 +36,8 @@ static bNodeSocketTemplate sh_node_tex_voronoi_in[] = {
};
static bNodeSocketTemplate sh_node_tex_voronoi_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
index e2c73a93b21..ef79aac0d32 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
@@ -39,8 +39,8 @@ static bNodeSocketTemplate sh_node_tex_wave_in[] = {
};
static bNodeSocketTemplate sh_node_tex_wave_out[] = {
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index f6cb243059d..d02d72563ba 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -42,9 +42,9 @@ static bNodeSocketTemplate sh_node_texture_in[] = {
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_texture_out[] = {
- { SOCK_FLOAT, 0, N_("Value")},
- { SOCK_RGBA, 0, N_("Color")},
- { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_FLOAT, 0, N_("Value"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_RGBA, 0, N_("Color"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_VECTOR, 0, N_("Normal"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
{ -1, 0, "" }
};
@@ -75,7 +75,7 @@ static void node_shader_exec_texture(void *data, int UNUSED(thread), bNode *node
retval = multitex_nodes((Tex *)node->id, vec, fp, fp + 3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
}
else if (in[0]->datatype == NS_OSA_VALUES) {
- float *fp = in[0]->data;
+ const float *fp = in[0]->data;
float dxt[3], dyt[3];
dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f;
@@ -125,7 +125,7 @@ static int gpu_shader_texture(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
Tex *tex = (Tex *)node->id;
if (tex && tex->type == TEX_IMAGE && tex->ima) {
- GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, FALSE);
+ GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false);
int ret = GPU_stack_link(mat, "texture_image", in, out, texlink);
if (ret) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.c b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
new file mode 100644
index 00000000000..fff1bc1df95
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.c
@@ -0,0 +1,58 @@
+/*
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+#include "DNA_customdata_types.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_uvmap_out[] = {
+ { SOCK_VECTOR, 0, N_("UV"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_shader_init_uvmap(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderUVMap *attr = MEM_callocN(sizeof(NodeShaderUVMap), "NodeShaderUVMap");
+ node->storage = attr;
+}
+
+/* node type definition */
+void register_node_type_sh_uvmap(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_UVMAP, "UV Map", NODE_CLASS_INPUT, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, NULL, sh_node_uvmap_out);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, node_shader_init_uvmap);
+ node_type_storage(&ntype, "NodeShaderUVMap", node_free_standard_storage, node_copy_standard_storage);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index 1e402b3728b..fa5d9b43ee7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -103,8 +103,10 @@ static void node_shader_exec_rgbtobw(void *UNUSED(data), int UNUSED(thread), bNo
{
/* stack order out: bw */
/* stack order in: col */
+ float col[3];
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
- out[0]->vec[0] = rgb_to_bw(in[0]->vec);
+ out[0]->vec[0] = rgb_to_bw(col);
}
static int gpu_shader_rgbtobw(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
index e3868627444..b40bf6bc71a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
@@ -147,7 +147,7 @@ void register_node_type_sh_vect_math(void)
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_vect_math_in, sh_node_vect_math_out);
node_type_label(&ntype, node_vect_math_label);
- node_type_storage(&ntype, "node_vect_math", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_vect_math);
node_type_gpu(&ntype, gpu_shader_vect_math);
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 5e863da9635..882c843f317 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -92,7 +92,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
}
}
}
- else {
+ else if (snode->texfrom == SNODE_TEX_BRUSH) {
struct Brush *brush = NULL;
if (ob && (ob->mode & OB_MODE_SCULPT))
@@ -109,6 +109,17 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
}
}
}
+ else if (snode->texfrom == SNODE_TEX_LINESTYLE) {
+ FreestyleLineStyle *linestyle = CTX_data_linestyle_from_scene(scene);
+ if (linestyle) {
+ *r_from = (ID *)linestyle;
+ tx = give_current_linestyle_texture(linestyle);
+ if (tx) {
+ *r_id = &tx->id;
+ *r_ntree = tx->nodetree;
+ }
+ }
+ }
}
static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
@@ -318,6 +329,7 @@ int ntreeTexExecTree(
data.osatex = osatex;
data.target = texres;
data.do_preview = preview;
+ data.do_manage = (shi) ? shi->do_manage : 0;
data.thread = thread;
data.which_output = which_output;
data.cfra = cfra;
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index a8117b7b333..e01b7ec49f1 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -70,7 +70,7 @@ static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, sh
dg->fn(out, params, dg->node, dg->in, thread);
if (dg->cdata->do_preview)
- tex_do_preview(dg->preview, params->previewco, out);
+ tex_do_preview(dg->preview, params->previewco, out, dg->cdata->do_manage);
}
}
@@ -127,13 +127,13 @@ void params_from_cdata(TexParams *out, TexCallData *in)
out->mtex = in->mtex;
}
-void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4])
+void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4], bool do_manage)
{
if (preview) {
int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize;
int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize;
- BKE_node_preview_set_pixel(preview, col, xs, ys, 0); /* 0 = no color management */
+ BKE_node_preview_set_pixel(preview, col, xs, ys, do_manage);
}
}
diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h
index b81ea51ddff..eb81bcd6949 100644
--- a/source/blender/nodes/texture/node_texture_util.h
+++ b/source/blender/nodes/texture/node_texture_util.h
@@ -84,7 +84,8 @@ typedef struct TexCallData {
float *dxt, *dyt;
int osatex;
- char do_preview;
+ bool do_preview;
+ bool do_manage;
short thread;
short which_output;
int cfra;
@@ -126,7 +127,7 @@ void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread);
float tex_input_value(bNodeStack *in, TexParams *params, short thread);
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data);
-void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4]);
+void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4], bool do_manage);
void params_from_cdata(TexParams *out, TexCallData *in);
diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c
index 7e65c472eef..914f1ef5110 100644
--- a/source/blender/nodes/texture/nodes/node_texture_common.c
+++ b/source/blender/nodes/texture/nodes/node_texture_common.c
@@ -172,7 +172,7 @@ void register_node_type_tex_group(void)
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 400);
+ node_type_size(&ntype, 140, 60, 400);
node_type_label(&ntype, node_group_label);
node_type_update(&ntype, NULL, node_group_verify);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
diff --git a/source/blender/nodes/texture/nodes/node_texture_coord.c b/source/blender/nodes/texture/nodes/node_texture_coord.c
index 1b742b4c8fd..5221d456b88 100644
--- a/source/blender/nodes/texture/nodes/node_texture_coord.c
+++ b/source/blender/nodes/texture/nodes/node_texture_coord.c
@@ -54,7 +54,7 @@ void register_node_type_tex_coord(void)
tex_node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, outputs);
- node_type_storage(&ntype, "node_coord", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_distance.c b/source/blender/nodes/texture/nodes/node_texture_distance.c
index 97d2d8f2caf..76a5b79c7a9 100644
--- a/source/blender/nodes/texture/nodes/node_texture_distance.c
+++ b/source/blender/nodes/texture/nodes/node_texture_distance.c
@@ -67,7 +67,7 @@ void register_node_type_tex_distance(void)
tex_node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
- node_type_storage(&ntype, "node_distance", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index 6c348d33b88..9b13589f3e1 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -52,7 +52,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
float xoff, yoff;
int px, py;
- float *result;
+ const float *result;
xsize = ibuf->x / 2;
ysize = ibuf->y / 2;
diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c
index 8d69d79d847..4765ee5f02a 100644
--- a/source/blender/nodes/texture/nodes/node_texture_math.c
+++ b/source/blender/nodes/texture/nodes/node_texture_math.c
@@ -174,7 +174,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
- case 17: /* Modulo */
+ case 17: /* Modulo */
{
if (in1 == 0.0f)
*out = 0.0f;
@@ -182,6 +182,13 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = fmod(in0, in1);
break;
}
+
+ case 18: /* Absolute */
+ {
+ *out = fabs(in0);
+ break;
+ }
+
default:
{
BLI_assert(0);
@@ -202,7 +209,7 @@ void register_node_type_tex_math(void)
tex_node_type_base(&ntype, TEX_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_label(&ntype, node_math_label);
- node_type_storage(&ntype, "node_math", NULL, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c
index 37e527f611a..57165a8cb09 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -54,7 +54,7 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
tex_input_rgba(&target->tr, in[1], &params, cdata->thread);
else
tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
- tex_do_preview(execdata->preview, params.co, &target->tr);
+ tex_do_preview(execdata->preview, params.co, &target->tr, cdata->do_manage);
}
else {
/* 0 means don't care, so just use first */
@@ -65,7 +65,7 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
target->tin = (target->tr + target->tg + target->tb) / 3.0f;
- target->talpha = TRUE;
+ target->talpha = true;
if (target->nor) {
if (in[1] && in[1]->hasinput)
@@ -84,7 +84,7 @@ static void unique_name(bNode *node)
int new_len = 0;
int suffix;
bNode *i;
- char *name = tno->name;
+ const char *name = tno->name;
new_name[0] = '\0';
i = node;
diff --git a/source/blender/nodes/texture/nodes/node_texture_viewer.c b/source/blender/nodes/texture/nodes/node_texture_viewer.c
index 5d84a673199..4168e7a16e7 100644
--- a/source/blender/nodes/texture/nodes/node_texture_viewer.c
+++ b/source/blender/nodes/texture/nodes/node_texture_viewer.c
@@ -52,7 +52,7 @@ static void exec(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecD
params_from_cdata(&params, cdata);
tex_input_rgba(col, in[0], &params, cdata->thread);
- tex_do_preview(execdata->preview, params.previewco, col);
+ tex_do_preview(execdata->preview, params.previewco, col, cdata->do_manage);
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index eef2e147736..9c9b69186ab 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -503,7 +503,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
{
/* can't convert from these */
PyErr_Format(PyExc_NotImplementedError,
- "This arguments mapping subtype %d is not supported", slot->slot_subtype);
+ "This arguments mapping subtype %d is not supported", slot->slot_subtype.map);
return -1;
}
}
@@ -768,7 +768,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
/* temp code, strip off '.out' while we keep this convention */
{
char slot_name_strip[MAX_SLOTNAME];
- char *ch = strchr(slot->slot_name, '.'); /* can't fail! */
+ const char *ch = strchr(slot->slot_name, '.'); /* can't fail! */
int tot = ch - slot->slot_name;
BLI_assert(ch != NULL);
memcpy(slot_name_strip, slot->slot_name, tot);
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 47aff885885..c2b496f914b 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -176,9 +176,7 @@ static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED
BM_elem_index_set(self->ele, param); /* set_dirty! */
/* when setting the index assume its set invalid */
- if (self->ele->head.htype & (BM_VERT | BM_EDGE | BM_FACE)) {
- self->bm->elem_index_dirty |= self->ele->head.htype;
- }
+ self->bm->elem_index_dirty |= self->ele->head.htype;
return 0;
}
@@ -2264,11 +2262,9 @@ static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
index++;
}
- if (htype & (BM_VERT | BM_EDGE | BM_FACE)) {
- /* since this isn't the normal vert/edge/face loops,
- * we're setting dirty values here. so tag as dirty. */
- bm->elem_index_dirty |= htype;
- }
+ /* since this isn't the normal vert/edge/face loops,
+ * we're setting dirty values here. so tag as dirty. */
+ bm->elem_index_dirty |= htype;
break;
}
@@ -2336,12 +2332,12 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec
BMElem *ele;
int *elem_idx;
- int *elem_map_idx;
+ unsigned int *elem_map_idx;
int (*elem_idx_compare_by_keys)(const void *, const void *);
- int *vert_idx = NULL;
- int *edge_idx = NULL;
- int *face_idx = NULL;
+ unsigned int *vert_idx = NULL;
+ unsigned int *edge_idx = NULL;
+ unsigned int *face_idx = NULL;
int i;
BMesh *bm = self->bm;
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 4fbfbd88c05..dfb3ae75df4 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -33,7 +33,6 @@
#include <Python.h>
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BLI_math_vector.h"
#include "bmesh.h"
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 7edbf724ed7..3512dc76cef 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -367,9 +367,9 @@ PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin)
#define MLOOPCOL_FROM_CAPSULE(color_capsule) \
((MLoopCol *)PyCapsule_GetPointer(color_capsule, NULL))
-static void mloopcol_to_float(const MLoopCol *mloopcol, float col_r[3])
+static void mloopcol_to_float(const MLoopCol *mloopcol, float r_col[3])
{
- rgb_uchar_to_float(col_r, (unsigned char *)&mloopcol->r);
+ rgb_uchar_to_float(r_col, (unsigned char *)&mloopcol->r);
}
static void mloopcol_from_float(MLoopCol *mloopcol, const float col[3])
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index 1906fc8c90e..b8e04a0cab8 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -43,9 +43,7 @@
#include "bmesh_py_types.h"
#include "bmesh_py_types_select.h"
-#include "BKE_editmesh.h"
-#include "DNA_mesh_types.h"
#include "../generic/py_capi_utils.h"
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index cf61d87efa5..2790dc08242 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -428,7 +428,7 @@ static PyObject *Buffer_slice(Buffer *self, int begin, int end)
if (begin < 0) begin = 0;
if (end > self->dimensions[0]) end = self->dimensions[0];
if (begin > end) begin = end;
-
+
list = PyList_New(end - begin);
for (count = begin; count < end; count++) {
@@ -2334,7 +2334,7 @@ PyObject *BPyInit_bgles2(void)
static PyObject *Method_ShaderSource(PyObject *UNUSED(self), PyObject *args)
{
unsigned int shader;
- char *source;
+ const char *source;
if (!PyArg_ParseTuple(args, "Is", &shader, &source))
return NULL;
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 768c5506b8c..655542e320a 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -146,7 +146,7 @@ PyDoc_STRVAR(py_blf_draw_doc,
);
static PyObject *py_blf_draw(PyObject *UNUSED(self), PyObject *args)
{
- char *text;
+ const char *text;
int text_length;
int fontid;
@@ -172,7 +172,7 @@ PyDoc_STRVAR(py_blf_dimensions_doc,
);
static PyObject *py_blf_dimensions(PyObject *UNUSED(self), PyObject *args)
{
- char *text;
+ const char *text;
float r_width, r_height;
PyObject *ret;
int fontid;
@@ -356,7 +356,7 @@ PyDoc_STRVAR(py_blf_load_doc,
);
static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
{
- char *filename;
+ const char *filename;
if (!PyArg_ParseTuple(args, "s:blf.load", &filename))
return NULL;
@@ -374,7 +374,7 @@ PyDoc_STRVAR(py_blf_unload_doc,
);
static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args)
{
- char *filename;
+ const char *filename;
if (!PyArg_ParseTuple(args, "s:blf.unload", &filename))
return NULL;
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index af41c3b426b..2d19fdb87b3 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -47,6 +47,8 @@
#include "BKE_text.h" /* txt_to_buf */
#include "BKE_main.h"
+#include "py_capi_utils.h"
+
#include "bpy_internal_import.h" /* own include */
static Main *bpy_import_main = NULL;
@@ -133,6 +135,7 @@ void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
bool bpy_text_compile(Text *text)
{
char fn_dummy[FILE_MAX];
+ PyObject *fn_dummy_py;
char *buf;
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
@@ -140,10 +143,14 @@ bool bpy_text_compile(Text *text)
/* if previously compiled, free the object */
free_compiled_text(text);
+ fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
+
buf = txt_to_buf(text);
- text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input);
+ text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
MEM_freeN(buf);
+ Py_DECREF(fn_dummy_py);
+
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
@@ -226,7 +233,7 @@ PyObject *bpy_text_reimport(PyObject *module, int *found)
{
Text *text;
const char *name;
- char *filepath;
+ const char *filepath;
//XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main;
Main *maggie = bpy_import_main;
@@ -265,7 +272,7 @@ PyObject *bpy_text_reimport(PyObject *module, int *found)
static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
PyObject *exception, *err, *tb;
- char *name;
+ const char *name;
int found = 0;
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
int level = 0; /* relative imports */
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 938a4cc8049..dcdda2c440e 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -29,7 +29,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "idprop_py_api.h"
@@ -599,7 +598,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
switch (prop->subtype) {
case IDP_FLOAT:
{
- float *array = (float *)IDP_Array(prop);
+ const float *array = (float *)IDP_Array(prop);
for (i = 0; i < prop->len; i++) {
PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i]));
}
@@ -607,7 +606,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
}
case IDP_DOUBLE:
{
- double *array = (double *)IDP_Array(prop);
+ const double *array = (double *)IDP_Array(prop);
for (i = 0; i < prop->len; i++) {
PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i]));
}
@@ -615,7 +614,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
}
case IDP_INT:
{
- int *array = (int *)IDP_Array(prop);
+ const int *array = (int *)IDP_Array(prop);
for (i = 0; i < prop->len; i++) {
PyList_SET_ITEM(seq, i, PyLong_FromLong(array[i]));
}
@@ -847,7 +846,7 @@ static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value)
}
/* XXX, possible one is inside the other */
- IDP_MergeGroup(self->prop, other->prop, TRUE);
+ IDP_MergeGroup(self->prop, other->prop, true);
}
else if (PyDict_Check(value)) {
while (PyDict_Next(value, &i, &pkey, &pval)) {
@@ -881,7 +880,7 @@ static PyObject *BPy_IDGroup_clear(BPy_IDProperty *self)
static PyObject *BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args)
{
IDProperty *idprop;
- char *key;
+ const char *key;
PyObject *def = Py_None;
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
@@ -1158,7 +1157,7 @@ static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end)
switch (prop->subtype) {
case IDP_FLOAT:
{
- float *array = (float *)IDP_Array(prop);
+ const float *array = (float *)IDP_Array(prop);
for (count = begin; count < end; count++) {
PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(array[count]));
}
@@ -1166,7 +1165,7 @@ static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end)
}
case IDP_DOUBLE:
{
- double *array = (double *)IDP_Array(prop);
+ const double *array = (double *)IDP_Array(prop);
for (count = begin; count < end; count++) {
PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(array[count]));
}
@@ -1174,7 +1173,7 @@ static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end)
}
case IDP_INT:
{
- int *array = (int *)IDP_Array(prop);
+ const int *array = (int *)IDP_Array(prop);
for (count = begin; count < end; count++) {
PyTuple_SET_ITEM(tuple, count - begin, PyLong_FromLong(array[count]));
}
@@ -1550,7 +1549,7 @@ void IDP_spit(IDProperty *prop)
{
if (prop) {
PyGILState_STATE gilstate;
- int use_gil = TRUE; /* !PyC_IsInterpreterActive(); */
+ bool use_gil = true; /* !PyC_IsInterpreterActive(); */
PyObject *ret_dict;
PyObject *ret_str;
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index a37933d027e..33ff63a9a28 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -284,7 +284,7 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
{
Py_ssize_t i;
PyObject *item = o;
- char *attr;
+ const char *attr;
va_list vargs;
@@ -647,7 +647,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
va_start(vargs, n);
for (i = 0; i * 2 < n; i++) {
- char *format = va_arg(vargs, char *);
+ const char *format = va_arg(vargs, char *);
void *ptr = va_arg(vargs, void *);
ret = PyObject_CallFunction(calcsize, (char *)"s", format);
@@ -704,7 +704,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
/* now get the values back */
va_start(vargs, n);
for (i = 0; i * 2 < n; i++) {
- char *format = va_arg(vargs, char *);
+ const char *format = va_arg(vargs, char *);
void *ptr = va_arg(vargs, void *);
PyObject *item;
@@ -762,6 +762,9 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
PyGILState_Release(gilstate);
}
+ else {
+ fprintf(stderr, "%s: '%s' missing\n", __func__, filepath);
+ }
}
/* generic function to avoid depending on RNA */
@@ -901,19 +904,3 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
return ret;
}
-
-/* compat only */
-#if PY_VERSION_HEX < 0x03030200
-int
-_PyLong_AsInt(PyObject *obj)
-{
- int overflow;
- long result = PyLong_AsLongAndOverflow(obj, &overflow);
- if (overflow || result > INT_MAX || result < INT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "Python int too large to convert to C int");
- return -1;
- }
- return (int)result;
-}
-#endif
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 27dd1bba6d6..0afc4dd98d9 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -73,8 +73,4 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int
int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix);
PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag);
-#if PY_VERSION_HEX < 0x03030200
-int _PyLong_AsInt(PyObject *obj);
-#endif
-
#endif /* __PY_CAPI_UTILS_H__ */
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index aa4b8117e3a..89104821cb0 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -144,8 +144,8 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py
static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- char *type;
- char *subdir = NULL;
+ const char *type;
+ const char *subdir = NULL;
int folder_id;
static const char *kwlist[] = {"type", "subdir", NULL};
@@ -189,7 +189,7 @@ PyDoc_STRVAR(bpy_resource_path_doc,
);
static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- char *type;
+ const char *type;
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
static const char *kwlist[] = {"type", "major", "minor", NULL};
int folder_id;
@@ -212,6 +212,50 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return PyUnicode_DecodeFSDefault(path ? path : "");
}
+PyDoc_STRVAR(bpy_escape_identifier_doc,
+".. function:: escape_identifier(string)\n"
+"\n"
+" Simple string escaping function used for animation paths.\n"
+"\n"
+" :arg string: text\n"
+" :type string: string\n"
+" :return: The escaped string.\n"
+" :rtype: string\n"
+);
+static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
+{
+ const char *value_str;
+ Py_ssize_t value_str_len;
+
+ char *value_escape_str;
+ Py_ssize_t value_escape_str_len;
+ PyObject *value_escape;
+ size_t size;
+
+ value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
+
+ if (value_str == NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string");
+ return NULL;
+ }
+
+ size = (value_str_len * 2) + 1;
+ value_escape_str = PyMem_MALLOC(size);
+ value_escape_str_len = BLI_strescape(value_escape_str, value_str, size);
+
+ if (value_escape_str_len == value_str_len) {
+ Py_INCREF(value);
+ value_escape = value;
+ }
+ else {
+ value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
+ }
+
+ PyMem_FREE(value_escape_str);
+
+ return value_escape;
+}
+
static PyMethodDef meth_bpy_script_paths =
{"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
static PyMethodDef meth_bpy_blend_paths =
@@ -220,7 +264,8 @@ static PyMethodDef meth_bpy_user_resource =
{"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS | METH_KEYWORDS, NULL};
static PyMethodDef meth_bpy_resource_path =
{"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS | METH_KEYWORDS, bpy_resource_path_doc};
-
+static PyMethodDef meth_bpy_escape_identifier =
+ {"escape_identifier", (PyCFunction)bpy_escape_identifier, METH_O, bpy_escape_identifier_doc};
static PyObject *bpy_import_test(const char *modname)
{
@@ -307,6 +352,7 @@ void BPy_init_modules(void)
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
PyModule_AddObject(mod, meth_bpy_resource_path.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
+ PyModule_AddObject(mod, meth_bpy_escape_identifier.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
/* register funcs (bpy_rna.c) */
PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));
diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c
index f5dc2942e63..f43b67cf42f 100644
--- a/source/blender/python/intern/bpy_app_build_options.c
+++ b/source/blender/python/intern/bpy_app_build_options.c
@@ -25,7 +25,6 @@
*/
#include <Python.h>
-#include "BLI_utildefines.h"
#include "bpy_app_build_options.h"
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index f8725d61167..b3be5a819fb 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -174,7 +174,7 @@ static PyObject *py_cb_array[BLI_CB_EVT_TOT] = {NULL};
static PyObject *make_app_cb_info(void)
{
PyObject *app_cb_info;
- int pos = 0;
+ int pos;
app_cb_info = PyStructSequence_New(&BlenderAppCbType);
if (app_cb_info == NULL) {
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 7141db7352a..b51de01103c 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -186,7 +186,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
/* get the py expression to be evaluated */
expr = driver->expression;
- if ((expr == NULL) || (expr[0] == '\0'))
+ if (expr[0] == '\0')
return 0.0f;
if (!(G.f & G_SCRIPT_AUTOEXEC)) {
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 78cce6e98fc..acaa644d3d0 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -37,13 +37,16 @@
#include <Python.h>
+#ifdef WIN32
+# include "BLI_math_base.h" /* finite */
+#endif
+
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
-#include "BLI_math_base.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
@@ -58,7 +61,6 @@
#include "bpy_traceback.h"
#include "bpy_intern_string.h"
-#include "DNA_space_types.h"
#include "DNA_text_types.h"
#include "BKE_context.h"
@@ -260,11 +262,7 @@ void BPY_python_start(int argc, const char **argv)
* an error, this is highly annoying, another stumbling block for devs,
* so use a more relaxed error handler and enforce utf-8 since the rest of
* blender is utf-8 too - campbell */
-
- /* XXX, update: this is unreliable! 'PYTHONIOENCODING' is ignored in MS-Windows
- * when dynamically linked, see: [#31555] for details.
- * Python doesn't expose a good way to set this. */
- BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape");
+ Py_SetStandardStreamEncoding("utf-8", "surrogateescape");
/* Update, Py3.3 resolves attempting to parse non-existing header */
#if 0
@@ -280,24 +278,6 @@ void BPY_python_start(int argc, const char **argv)
Py_Initialize();
- /* THIS IS BAD: see http://bugs.python.org/issue16129 */
- /* this clobbers the stdout on exit (no 'MEM_printmemlist_stats') */
-#if 0
- /* until python provides a reliable way to set the env var */
- PyRun_SimpleString("import sys, io\n"
- "sys.__backup_stdio__ = sys.__stdout__, sys.__stderr__\n" /* else we loose the FD's [#32720] */
- "sys.__stdout__ = sys.stdout = io.TextIOWrapper(io.open(sys.stdout.fileno(), 'wb', -1), "
- "encoding='utf-8', errors='surrogateescape', newline='\\n', line_buffering=True)\n"
- "sys.__stderr__ = sys.stderr = io.TextIOWrapper(io.open(sys.stderr.fileno(), 'wb', -1), "
- "encoding='utf-8', errors='surrogateescape', newline='\\n', line_buffering=True)\n");
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
-#endif
- /* end the baddness */
-
-
// PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */
/* sigh, why do python guys not have a (char **) version anymore? */
{
@@ -468,12 +448,17 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text,
bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
- char *buf = txt_to_buf(text);
+ char *buf;
+ PyObject *fn_dummy_py;
- text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input);
+ fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
+ buf = txt_to_buf(text);
+ text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
MEM_freeN(buf);
+ Py_DECREF(fn_dummy_py);
+
if (PyErr_Occurred()) {
if (do_jump) {
python_script_error_jump_text(text);
@@ -501,15 +486,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text,
* incompatible'.
* So now we load the script file data to a buffer */
{
- char *pystring;
+ const char *pystring = "with open(__file__, 'r') as f: exec(f.read())";
fclose(fp);
- pystring = MEM_mallocN(strlen(fn) + 37, "pystring");
- pystring[0] = '\0';
- sprintf(pystring, "f=open(r'%s');exec(f.read());f.close()", fn);
py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
- MEM_freeN(pystring);
}
#else
py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 7e84070e930..3d7d08024c7 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -38,7 +38,6 @@
#include "BLI_string.h"
#include "BLI_linklist.h"
#include "BLI_path_util.h"
-#include "BLI_listbase.h"
#include "BLO_readfile.h"
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index e867aa00958..2c526601fcd 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -65,10 +65,10 @@
static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
{
wmOperatorType *ot;
- char *opname;
+ const char *opname;
PyObject *context_dict = NULL; /* optional args */
PyObject *context_dict_back;
- char *context_str = NULL;
+ const char *context_str = NULL;
PyObject *ret;
int context = WM_OP_EXEC_DEFAULT;
@@ -139,8 +139,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
PointerRNA ptr;
int operator_ret = OPERATOR_CANCELLED;
- char *opname;
- char *context_str = NULL;
+ const char *opname;
+ const char *context_str = NULL;
PyObject *kw = NULL; /* optional args */
PyObject *context_dict = NULL; /* optional args */
PyObject *context_dict_back;
@@ -310,7 +310,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
wmOperatorType *ot;
PointerRNA ptr;
- char *opname;
+ const char *opname;
PyObject *kw = NULL; /* optional args */
int all_args = 1;
int macro_args = 1;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index efee9b13d58..11e27ca3e3c 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -163,7 +163,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
PointerRNA ptr_otmacro;
StructRNA *srna;
- char *opname;
+ const char *opname;
const char *macroname;
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 3888e1b7ecd..6e36680ec4a 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1881,7 +1881,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -1967,7 +1967,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2062,7 +2062,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2154,7 +2154,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2259,9 +2259,9 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
- char *pyunit = NULL;
+ const char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2365,9 +2365,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
- char *pyunit = NULL;
+ const char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2468,7 +2468,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- char *pysubtype = NULL;
+ const char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
PyObject *get_cb = NULL;
@@ -2542,8 +2542,8 @@ BPY_PROPDEF_OPTIONS_ENUM_DOC
" For dynamic values a callback can be passed which returns a list in\n"
" the same format as the static list.\n"
" This function must take 2 arguments (self, context)\n"
-" WARNING: Do not use generators here (they will work the first time, but will lead to empty values\n"
-" in some unload/reload scenarii)!\n"
+" WARNING: There is a known bug with using a callback,\n"
+" Python must keep a reference to the strings returned or Blender will crash.\n"
" :type items: sequence of string tuples or a function\n"
BPY_PROPDEF_UPDATE_DOC
);
@@ -2847,7 +2847,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
else {
static const char *kwlist[] = {"attr", NULL};
- char *id = NULL;
+ const char *id = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
"s:RemoveProperty",
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 23308bf997d..38a0f74f009 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -73,8 +73,6 @@
#include "BKE_report.h"
#include "BKE_idprop.h"
-#include "BKE_animsys.h"
-#include "BKE_fcurve.h"
#include "../generic/idprop_py_api.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
@@ -1920,7 +1918,6 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
error_prefix, RNA_struct_identifier(ptr->type),
RNA_property_identifier(prop));
return -1;
- break;
}
}
@@ -2172,7 +2169,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
PointerRNA *r_ptr
)
{
- char *keyname;
+ const char *keyname;
/* first validate the args, all we know is that they are a tuple */
if (PyTuple_GET_SIZE(key) != 2) {
@@ -4884,7 +4881,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
break;
case PROP_STRING:
{
- char *data_ch;
+ const char *data_ch;
PyObject *value_coerce = NULL;
const int subtype = RNA_property_subtype(prop);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 3320043aeb5..ed51ba5bd1f 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -168,8 +168,13 @@ static int pyrna_struct_keyframe_parse(
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
/* flag may be null (no option currently for remove keyframes e.g.). */
- if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1))
- return -1;
+ if (options) {
+ if (pyoptions && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1)) {
+ return -1;
+ }
+
+ *options |= INSERTKEY_NO_USERPREF;
+ }
return 0; /* success */
}
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index bb40a21eed9..033f8a3f3ec 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -30,12 +30,12 @@
#include "RNA_types.h"
-#include "BLI_utildefines.h"
-
#include "bpy_rna.h"
#include "BKE_global.h"
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#define USE_MATHUTILS
@@ -83,7 +83,7 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
for (i = 0; i < seq_size; i++) {
Py_ssize_t item_seq_size;
PyObject *item;
- int ok = 1;
+ bool ok = true;
item = PySequence_GetItem(seq, i);
if (item == NULL) {
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index 9aefe5a733f..87c3a6eb4ef 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -182,8 +182,8 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
void *handle;
PyObject *cls;
PyObject *cb_func, *cb_args;
- char *cb_regiontype_str;
- char *cb_event_str;
+ const char *cb_regiontype_str;
+ const char *cb_event_str;
int cb_event;
int cb_regiontype;
StructRNA *srna;
@@ -248,7 +248,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar
void *handle;
void *customdata;
StructRNA *srna;
- char *cb_regiontype_str;
+ const char *cb_regiontype_str;
int cb_regiontype;
if (PyTuple_GET_SIZE(args) < 2) {
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 81d12e9d9a6..bff778b9c9e 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -31,7 +31,9 @@
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
-#include "BLI_string.h"
+#ifdef WIN32
+# include "BLI_string.h" /* BLI_strcasecmp */
+#endif
#include "bpy_traceback.h"
@@ -40,10 +42,12 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce)
return PyBytes_AS_STRING((*coerce = PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename)));
}
-/* copied from pythonrun.c, 3.3.0 */
+/* copied from pythonrun.c, 3.4.0 */
+_Py_static_string(PyId_string, "<string>");
+
static int
-parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
- int *lineno, int *offset, const char **text)
+parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
+ int *lineno, int *offset, PyObject **text)
{
long hold;
PyObject *v;
@@ -54,6 +58,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
_Py_IDENTIFIER(text);
*message = NULL;
+ *filename = NULL;
/* new style errors. `err' is an instance */
*message = _PyObject_GetAttrId(err, &PyId_msg);
@@ -65,13 +70,13 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
goto finally;
if (v == Py_None) {
Py_DECREF(v);
- *filename = NULL;
+ *filename = _PyUnicode_FromId(&PyId_string);
+ if (*filename == NULL)
+ goto finally;
+ Py_INCREF(*filename);
}
else {
- *filename = _PyUnicode_AsString(v);
- Py_DECREF(v);
- if (!*filename)
- goto finally;
+ *filename = v;
}
v = _PyObject_GetAttrId(err, &PyId_lineno);
@@ -105,15 +110,13 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
*text = NULL;
}
else {
- *text = _PyUnicode_AsString(v);
- Py_DECREF(v);
- if (!*text)
- goto finally;
+ *text = v;
}
return 1;
finally:
Py_XDECREF(*message);
+ Py_XDECREF(*filename);
return 0;
}
/* end copied function! */
@@ -137,9 +140,10 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
if (value) { /* should always be true */
PyObject *message;
- const char *filename, *text;
+ PyObject *filename_py, *text_py;
- if (parse_syntax_error(value, &message, &filename, lineno, offset, &text)) {
+ if (parse_syntax_error(value, &message, &filename_py, lineno, offset, &text_py)) {
+ const char *filename = _PyUnicode_AsString(filename_py);
/* python adds a '/', prefix, so check for both */
if ((BLI_path_cmp(filename, filepath) == 0) ||
((filename[0] == '\\' || filename[0] == '/') && BLI_path_cmp(filename + 1, filepath) == 0))
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index b0b0f346944..93183a4f320 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -86,7 +86,7 @@ short BPy_errors_to_report(ReportList *reports)
{
PyObject *pystring;
PyObject *pystring_format = NULL; /* workaround, see below */
- char *cstring;
+ const char *cstring;
const char *filename;
int lineno;
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index b007e123cfc..d19696aa230 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -27,8 +27,8 @@
#ifndef __BPY_UTIL_H__
#define __BPY_UTIL_H__
-#if PY_VERSION_HEX < 0x03030000
-# error "Python 3.3 or greater is required, you'll need to update your python."
+#if PY_VERSION_HEX < 0x03040000
+# error "Python 3.4 or greater is required, you'll need to update your python."
#endif
struct EnumPropertyItem;
diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c
index 5dcf67e5417..26e3bde57a3 100644
--- a/source/blender/python/intern/gpu.c
+++ b/source/blender/python/intern/gpu.c
@@ -42,8 +42,6 @@
#include "DNA_scene_types.h"
#include "DNA_image_types.h"
#include "DNA_material_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_object_types.h"
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index aa035aa05a6..6129bb869f5 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -42,6 +42,7 @@ typedef enum eMatrixAccess_t {
MAT_ACCESS_COL
} eMatrixAccess_t;
+static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix);
static PyObject *Matrix_copy(MatrixObject *self);
static PyObject *Matrix_deepcopy(MatrixObject *self, PyObject *args);
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value);
@@ -550,7 +551,9 @@ PyDoc_STRVAR(C_Matrix_Translation_doc,
);
static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value)
{
- float mat[4][4] = MAT4_UNITY;
+ float mat[4][4];
+
+ unit_m4(mat);
if (mathutils_array_parse(mat[3], 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1)
return NULL;
@@ -621,7 +624,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
for (x = 0; x < vec_size; x++) {
norm += tvec[x] * tvec[x];
}
- norm = (float) sqrt(norm);
+ norm = sqrtf(norm);
for (x = 0; x < vec_size; x++) {
tvec[x] /= norm;
}
@@ -742,7 +745,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
for (x = 0; x < vec_size; x++) {
norm += tvec[x] * tvec[x];
}
- norm = (float) sqrt(norm);
+ norm = sqrtf(norm);
for (x = 0; x < vec_size; x++) {
tvec[x] /= norm;
}
@@ -881,8 +884,17 @@ void matrix_as_3x3(float mat[3][3], MatrixObject *self)
copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2));
}
+static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
+{
+ BLI_assert((mat_dst->num_col == mat_src->num_col) &&
+ (mat_dst->num_row == mat_src->num_row));
+ BLI_assert(mat_dst != mat_src);
+
+ memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row));
+}
+
/* assumes rowsize == colsize is checked and the read callback has run */
-static float matrix_determinant_internal(MatrixObject *self)
+static float matrix_determinant_internal(const MatrixObject *self)
{
if (self->num_col == 2) {
return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1),
@@ -898,6 +910,58 @@ static float matrix_determinant_internal(MatrixObject *self)
}
}
+/**
+ * \param r_mat can be from ``self->matrix`` or not. */
+static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
+{
+ float det;
+
+ det = matrix_determinant_internal(self);
+
+ if (det != 0.0f) {
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ int x, y, z;
+
+ /* calculate the classical adjoint */
+ switch (self->num_col) {
+ case 2:
+ {
+ adjoint_m2_m2((float (*)[2])mat, (float (*)[2])self->matrix);
+ break;
+ }
+ case 3:
+ {
+ adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix);
+ break;
+ }
+ case 4:
+ {
+ adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix);
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
+ /* divide by determinate */
+ for (x = 0; x < (self->num_col * self->num_row); x++) {
+ mat[x] /= det;
+ }
+ /* set values */
+ z = 0;
+ for (x = 0; x < self->num_col; x++) {
+ for (y = 0; y < self->num_row; y++) {
+ r_mat[MATRIX_ITEM_INDEX(self, y, x)] = mat[z];
+ z++;
+ }
+ }
+
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
/*-----------------------------METHODS----------------------------*/
PyDoc_STRVAR(Matrix_to_quaternion_doc,
@@ -1013,7 +1077,7 @@ PyDoc_STRVAR(Matrix_resize_4x4_doc,
);
static PyObject *Matrix_resize_4x4(MatrixObject *self)
{
- float mat[4][4] = MAT4_UNITY;
+ float mat[4][4];
int col;
if (self->wrapped == Py_WRAP) {
@@ -1029,7 +1093,7 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
return NULL;
}
- self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * 16));
+ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * (MATRIX_MAX_DIM * MATRIX_MAX_DIM)));
if (self->matrix == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Matrix.resize_4x4(): "
@@ -1037,6 +1101,8 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
return NULL;
}
+ unit_m4(mat);
+
for (col = 0; col < self->num_col; col++) {
memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float));
}
@@ -1163,79 +1229,104 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
}
/*---------------------------matrix.invert() ---------------------*/
+
+/* re-usable checks for invert */
+static bool matrix_invert_is_compat(const MatrixObject *self)
+{
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "only square matrices are supported");
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, bool check_type)
+{
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ return true;
+ case 1:
+ if (check_type) {
+ const MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
+ if (!MatrixObject_Check(fallback)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix.invert: "
+ "expects a matrix argument or nothing");
+ return false;
+ }
+
+ if ((self->num_col != fallback->num_col) ||
+ (self->num_row != fallback->num_row))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix.invert: "
+ "matrix argument has different dimensions");
+ return false;
+ }
+ }
+
+ return true;
+ default:
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "takes at most one argument");
+ return false;
+ }
+}
+
+static void matrix_invert_raise_degenerate(void)
+{
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "matrix does not have an inverse");
+}
+
PyDoc_STRVAR(Matrix_invert_doc,
-".. method:: invert()\n"
+".. method:: invert(fallback=None)\n"
"\n"
" Set the matrix to its inverse.\n"
"\n"
-" .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n"
+" :arg fallback: Set the matrix to this value when the inverse can't be calculated\n"
+" (instead of raising a :exc:`ValueError` exception).\n"
+" :type fallback: :class:`Matrix`\n"
"\n"
" .. seealso:: <http://en.wikipedia.org/wiki/Inverse_matrix>\n"
);
-static PyObject *Matrix_invert(MatrixObject *self)
+static PyObject *Matrix_invert(MatrixObject *self, PyObject *args)
{
-
- int x, y, z = 0;
- float det = 0.0f;
- float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
-
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.invert(ed): "
- "only square matrices are supported");
+ if (matrix_invert_is_compat(self) == false) {
return NULL;
}
- /* calculate the determinant */
- det = matrix_determinant_internal(self);
+ if (matrix_invert_args_check(self, args, true) == false) {
+ return NULL;
+ }
- if (det != 0) {
- /* calculate the classical adjoint */
- switch (self->num_col) {
- case 2:
- {
- adjoint_m2_m2((float (*)[2])mat, (float (*)[2])self->matrix);
- break;
- }
- case 3:
- {
- adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix);
- break;
- }
- case 4:
- {
- adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix);
- break;
- }
- default:
- PyErr_Format(PyExc_ValueError,
- "Matrix invert(ed): size (%d) unsupported",
- (int)self->num_col);
+ if (matrix_invert_internal(self, self->matrix)) {
+ /* pass */
+ }
+ else {
+ if (PyTuple_GET_SIZE(args) == 1) {
+ MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
+
+ if (BaseMath_ReadCallback(fallback) == -1)
return NULL;
- }
- /* divide by determinate */
- for (x = 0; x < (self->num_col * self->num_row); x++) {
- mat[x] /= det;
- }
- /* set values */
- for (x = 0; x < self->num_col; x++) {
- for (y = 0; y < self->num_row; y++) {
- MATRIX_ITEM(self, y, x) = mat[z];
- z++;
+
+ if (self != fallback) {
+ matrix_copy(self, fallback);
}
}
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.invert(ed): "
- "matrix does not have an inverse");
- return NULL;
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
}
(void)BaseMath_WriteCallback(self);
@@ -1243,18 +1334,68 @@ static PyObject *Matrix_invert(MatrixObject *self)
}
PyDoc_STRVAR(Matrix_inverted_doc,
-".. method:: inverted()\n"
+".. method:: inverted(fallback=None)\n"
"\n"
" Return an inverted copy of the matrix.\n"
"\n"
-" :return: the inverted matrix.\n"
+" :arg fallback: return this value when the inverse can't be calculated\n"
+" (instead of raising a :exc:`ValueError` exception).\n"
+" :type fallback: any\n"
+" :return: the inverted matrix or fallback when given.\n"
" :rtype: :class:`Matrix`\n"
-"\n"
-" .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n"
);
-static PyObject *Matrix_inverted(MatrixObject *self)
+static PyObject *Matrix_inverted(MatrixObject *self, PyObject *args)
{
- return matrix__apply_to_copy((PyNoArgsFunction)Matrix_invert, self);
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ if (matrix_invert_args_check(self, args, false) == false) {
+ return NULL;
+ }
+
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
+
+ if (matrix_invert_internal(self, mat)) {
+ /* pass */
+ }
+ else {
+ if (PyTuple_GET_SIZE(args) == 1) {
+ PyObject *fallback = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
+ }
+
+ return Matrix_copy_notest(self, mat);
+}
+
+static PyObject *Matrix_inverted_noargs(MatrixObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
+
+ if (matrix_invert_internal(self, self->matrix)) {
+ /* pass */
+ }
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
/*---------------------------matrix.adjugate() ---------------------*/
@@ -1633,6 +1774,12 @@ static PyObject *Matrix_identity(MatrixObject *self)
}
/*---------------------------Matrix.copy() ------------------*/
+
+static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix)
+{
+ return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
+}
+
PyDoc_STRVAR(Matrix_copy_doc,
".. method:: copy()\n"
"\n"
@@ -1646,7 +1793,7 @@ static PyObject *Matrix_copy(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Matrix_CreatePyObject((float (*))self->matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
+ return Matrix_copy_notest(self, self->matrix);
}
static PyObject *Matrix_deepcopy(MatrixObject *self, PyObject *args)
{
@@ -1811,7 +1958,7 @@ static PyObject *Matrix_item_col(MatrixObject *self, int col)
static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
{
int col;
- float vec[4];
+ float vec[MATRIX_MAX_DIM];
if (BaseMath_ReadCallback(self) == -1)
return -1;
@@ -1836,7 +1983,7 @@ static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
{
int row;
- float vec[4];
+ float vec[MATRIX_MAX_DIM];
if (BaseMath_ReadCallback(self) == -1)
return -1;
@@ -1904,7 +2051,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
else {
const int size = end - begin;
int row, col;
- float mat[16];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
float vec[4];
if (PySequence_Fast_GET_SIZE(value_fast) != size) {
@@ -1946,7 +2093,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
*------------------------obj + obj------------------------------*/
static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
{
- float mat[16];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject *)m1;
@@ -1978,7 +2125,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
* subtraction */
static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
{
- float mat[16];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
MatrixObject *mat1 = NULL, *mat2 = NULL;
mat1 = (MatrixObject *)m1;
@@ -2010,7 +2157,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
* multiplication */
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
- float tmat[16];
+ float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_NEW, Py_TYPE(mat));
}
@@ -2035,10 +2182,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
if (mat1 && mat2) {
/* MATRIX * MATRIX */
- float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
int col, row, item;
@@ -2071,7 +2215,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
/* MATRIX * VECTOR */
if (VectorObject_Check(m2)) {
VectorObject *vec2 = (VectorObject *)m2;
- float tvec[4];
+ float tvec[MATRIX_MAX_DIM];
if (BaseMath_ReadCallback(vec2) == -1)
return NULL;
if (column_vector_multiplication(tvec, vec2, mat1) == -1) {
@@ -2205,7 +2349,7 @@ static PyNumberMethods Matrix_NumMethods = {
(unaryfunc) 0, /*tp_positive*/
(unaryfunc) 0, /*tp_absolute*/
(inquiry) 0, /*tp_bool*/
- (unaryfunc) Matrix_inverted, /*nb_invert*/
+ (unaryfunc) Matrix_inverted_noargs, /*nb_invert*/
NULL, /*nb_lshift*/
(binaryfunc)0, /*nb_rshift*/
NULL, /*nb_and*/
@@ -2413,8 +2557,8 @@ static struct PyMethodDef Matrix_methods[] = {
{"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
{"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
{"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
- {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc},
- {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc},
+ {"invert", (PyCFunction) Matrix_invert, METH_VARARGS, Matrix_invert_doc},
+ {"inverted", (PyCFunction) Matrix_inverted, METH_VARARGS, Matrix_inverted_doc},
{"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
{"adjugated", (PyCFunction) Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc},
{"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 19246978cbf..a719691d5d4 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -800,6 +800,36 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
}
+PyDoc_STRVAR(Vector_orthogonal_doc,
+".. method:: orthogonal()\n"
+"\n"
+" Return a perpendicular vector.\n"
+"\n"
+" :return: a new vector 90 degrees from this vector.\n"
+" :rtype: :class:`Vector`\n"
+"\n"
+" .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n"
+);
+static PyObject *Vector_orthogonal(VectorObject *self)
+{
+ float vec[3];
+
+ if (self->size != 3) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.orthogonal(): "
+ "Vector must be 3D");
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ortho_v3_v3(vec, self->vec);
+
+ return Vector_CreatePyObject(vec, self->size, Py_NEW, Py_TYPE(self));
+}
+
+
/*
* Vector.reflect(mirror): return a reflected vector on the mirror normal
* vec - ((2 * DotVecs(vec, mirror)) * mirror)
@@ -915,13 +945,13 @@ static PyObject *Vector_dot(VectorObject *self, PyObject *value)
}
PyDoc_STRVAR(Vector_angle_doc,
-".. function:: angle(other, fallback)\n"
+".. function:: angle(other, fallback=None)\n"
"\n"
" Return the angle between two vectors.\n"
"\n"
" :arg other: another vector to compare the angle with\n"
" :type other: :class:`Vector`\n"
-" :arg fallback: return this value when the angle cant be calculated\n"
+" :arg fallback: return this value when the angle can't be calculated\n"
" (zero length vector)\n"
" :type fallback: any\n"
" :return: angle in radians or fallback when given\n"
@@ -985,7 +1015,7 @@ PyDoc_STRVAR(Vector_angle_signed_doc,
"\n"
" :arg other: another vector to compare the angle with\n"
" :type other: :class:`Vector`\n"
-" :arg fallback: return this value when the angle cant be calculated\n"
+" :arg fallback: return this value when the angle can't be calculated\n"
" (zero length vector)\n"
" :type fallback: any\n"
" :return: angle in radians or fallback when given\n"
@@ -1168,6 +1198,95 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self));
}
+PyDoc_STRVAR(Vector_slerp_doc,
+".. function:: slerp(other, factor, fallback=None)\n"
+"\n"
+" Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
+"\n"
+" :arg other: value to interpolate with.\n"
+" :type other: :class:`Vector`\n"
+" :arg factor: The interpolation value typically in [0.0, 1.0].\n"
+" :type factor: float\n"
+" :arg fallback: return this value when the vector can't be calculated\n"
+" (zero length vector or direct opposites)\n"
+" :type fallback: any\n"
+" :return: The interpolated vector.\n"
+" :rtype: :class:`Vector`\n"
+);
+static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
+{
+ const int size = self->size;
+ PyObject *value = NULL;
+ float fac, cosom, w[2];
+ float self_vec[3], other_vec[3], ret_vec[3];
+ float self_len_sq, other_len_sq;
+ int x;
+ PyObject *fallback = NULL;
+
+ if (!PyArg_ParseTuple(args, "Of|O:slerp", &value, &fac, &fallback))
+ return NULL;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (self->size > 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector must be 2D or 3D");
+ return NULL;
+ }
+
+ if (mathutils_array_parse(other_vec, size, size, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
+
+ self_len_sq = normalize_vn_vn(self_vec, self->vec, size);
+ other_len_sq = normalize_vn(other_vec, size);
+
+ /* use fallbacks for zero length vectors */
+ if (UNLIKELY((self_len_sq < FLT_EPSILON) ||
+ (other_len_sq < FLT_EPSILON)))
+ {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "zero length vectors unsupported");
+ return NULL;
+ }
+ }
+
+ /* We have sane state, execute slerp */
+ cosom = (float)dot_vn_vn(self_vec, other_vec, size);
+
+ /* direct opposite, can't slerp */
+ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "opposite vectors unsupported");
+ return NULL;
+ }
+ }
+
+ interp_dot_slerp(fac, cosom, w);
+
+ for (x = 0; x < size; x++) {
+ ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
+ }
+
+ return Vector_CreatePyObject(ret_vec, size, Py_NEW, Py_TYPE(self));
+}
+
PyDoc_STRVAR(Vector_rotate_doc,
".. function:: rotate(other)\n"
"\n"
@@ -1858,17 +1977,6 @@ static PyObject *Vector_neg(VectorObject *self)
return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self));
}
-/*------------------------vec_magnitude_nosqrt (internal) - for comparing only */
-static double vec_magnitude_nosqrt(const float *data, int size)
-{
- /* return (double)sqrt(dot);*/
- /* warning, line above removed because we are not using the length,
- * rather the comparing the sizes and for this we do not need the sqrt
- * for the actual length, the dot must be sqrt'd */
- return dot_vn_vn(data, data, size);
-}
-
-
/*------------------------tp_richcmpr
* returns -1 exception, 0 false, 1 true */
static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
@@ -1903,15 +2011,15 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
switch (comparison_type) {
case Py_LT:
- lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
- lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
if (lenA < lenB) {
result = 1;
}
break;
case Py_LE:
- lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
- lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
if (lenA < lenB) {
result = 1;
}
@@ -1926,15 +2034,15 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
break;
case Py_GT:
- lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
- lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
if (lenA > lenB) {
result = 1;
}
break;
case Py_GE:
- lenA = vec_magnitude_nosqrt(vecA->vec, vecA->size);
- lenB = vec_magnitude_nosqrt(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
if (lenA > lenB) {
result = 1;
}
@@ -2768,6 +2876,7 @@ static struct PyMethodDef Vector_methods[] = {
{"resize_4d", (PyCFunction) Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
{"to_tuple", (PyCFunction) Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
{"to_track_quat", (PyCFunction) Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
+ {"orthogonal", (PyCFunction) Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
/* operation between 2 or more types */
{"reflect", (PyCFunction) Vector_reflect, METH_O, Vector_reflect_doc},
@@ -2778,6 +2887,7 @@ static struct PyMethodDef Vector_methods[] = {
{"rotation_difference", (PyCFunction) Vector_rotation_difference, METH_O, Vector_rotation_difference_doc},
{"project", (PyCFunction) Vector_project, METH_O, Vector_project_doc},
{"lerp", (PyCFunction) Vector_lerp, METH_VARARGS, Vector_lerp_doc},
+ {"slerp", (PyCFunction) Vector_slerp, METH_VARARGS, Vector_slerp_doc},
{"rotate", (PyCFunction) Vector_rotate, METH_O, Vector_rotate_doc},
{"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 4cf6520e583..0500b2afb18 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -269,7 +269,7 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
{
PyObject *ret;
VectorObject *vec_a, *vec_b;
- float *v_a, *v_b;
+ const float *v_a, *v_b;
float rad_a, rad_b;
float v_ab[2];
float dist;
@@ -1516,7 +1516,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
ret = PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
+ PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height));
return ret;
}
diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c
index d48ab803740..0833d522a60 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.c
+++ b/source/blender/python/mathutils/mathutils_kdtree.c
@@ -161,7 +161,7 @@ static PyObject *py_kdtree_insert(PyKDTree *self, PyObject *args, PyObject *kwar
return NULL;
}
- BLI_kdtree_insert(self->obj, index, co, NULL);
+ BLI_kdtree_insert(self->obj, index, co);
self->count++;
Py_RETURN_NONE;
@@ -213,7 +213,7 @@ static PyObject *py_kdtree_find(PyKDTree *self, PyObject *args, PyObject *kwargs
nearest.index = -1;
- BLI_kdtree_find_nearest(self->obj, co, NULL, &nearest);
+ BLI_kdtree_find_nearest(self->obj, co, &nearest);
return kdtree_nearest_to_py_and_check(&nearest);
}
@@ -261,7 +261,7 @@ static PyObject *py_kdtree_find_n(PyKDTree *self, PyObject *args, PyObject *kwar
nearest = MEM_mallocN(sizeof(KDTreeNearest) * n, __func__);
- found = BLI_kdtree_find_nearest_n(self->obj, co, NULL, nearest, n);
+ found = BLI_kdtree_find_nearest_n(self->obj, co, nearest, n);
py_list = PyList_New(found);
@@ -316,7 +316,7 @@ static PyObject *py_kdtree_find_range(PyKDTree *self, PyObject *args, PyObject *
return NULL;
}
- found = BLI_kdtree_range_search(self->obj, co, NULL, &nearest, radius);
+ found = BLI_kdtree_range_search(self->obj, co, &nearest, radius);
py_list = PyList_New(found);
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 61bc2b60861..8dfa7904300 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -36,13 +36,10 @@
#include "structseq.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_noise.h"
#include "BLI_utildefines.h"
-#include "MEM_guardedalloc.h"
-
#include "DNA_texture_types.h"
#include "mathutils.h"
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
index 51a9f128f94..9318c896d7c 100644
--- a/source/blender/quicktime/apple/qtkit_import.m
+++ b/source/blender/quicktime/apple/qtkit_import.m
@@ -66,7 +66,7 @@ typedef struct _QuicktimeMovie {
void quicktime_init(void)
{
- G.have_quicktime = TRUE;
+ G.have_quicktime = true;
}
void quicktime_exit(void)
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index db23cd97b74..8e326e770fc 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -48,16 +48,15 @@ set(SRC
intern/raytrace/rayobject_octree.cpp
intern/raytrace/rayobject_raycounter.cpp
intern/raytrace/rayobject_svbvh.cpp
- intern/raytrace/rayobject_blibvh.cpp
intern/raytrace/rayobject_instance.cpp
intern/raytrace/rayobject_qbvh.cpp
intern/raytrace/rayobject_rtbuild.cpp
intern/raytrace/rayobject_vbvh.cpp
intern/source/bake.c
+ intern/source/bake_api.c
intern/source/convertblender.c
intern/source/envmap.c
intern/source/external_engine.c
- intern/source/gammaCorrectionTables.c
intern/source/imagetexture.c
intern/source/initrender.c
intern/source/multires_bake.c
@@ -84,12 +83,12 @@ set(SRC
intern/source/zbuf.c
extern/include/RE_engine.h
+ extern/include/RE_bake.h
extern/include/RE_multires_bake.h
extern/include/RE_pipeline.h
extern/include/RE_render_ext.h
extern/include/RE_shader_ext.h
intern/include/envmap.h
- intern/include/gammaCorrectionTables.h
intern/include/initrender.h
intern/include/occlusion.h
intern/include/pixelblending.h
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
new file mode 100644
index 00000000000..d59819c8ef4
--- /dev/null
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -0,0 +1,105 @@
+/*
+ * ***** 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) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file RE_bake.h
+ * \ingroup render
+ */
+
+#ifndef __RE_BAKE_H__
+#define __RE_BAKE_H__
+
+struct Render;
+struct Mesh;
+
+typedef struct BakeImage {
+ struct Image *image;
+ int width;
+ int height;
+ int offset;
+} BakeImage;
+
+typedef struct BakeImages {
+ BakeImage *data; /* all the images of an object */
+ int *lookup; /* lookup table from Material to BakeImage */
+ int size;
+} BakeImages;
+
+typedef struct BakePixel {
+ int primitive_id;
+ float uv[2];
+ float du_dx, du_dy;
+ float dv_dx, dv_dy;
+} BakePixel;
+
+typedef struct BakeHighPolyData {
+ struct BakePixel *pixel_array;
+ struct Object *ob;
+ struct ModifierData *tri_mod;
+ struct Mesh *me;
+ char restrict_flag;
+ float mat_lowtohigh[4][4];
+} BakeHighPolyData;
+
+/* external_engine.c */
+bool RE_bake_has_engine(struct Render *re);
+
+bool RE_bake_engine(
+ struct Render *re, struct Object *object, const BakePixel pixel_array[],
+ const int num_pixels, const int depth, const ScenePassType pass_type, float result[]);
+
+/* bake.c */
+int RE_pass_depth(const ScenePassType pass_type);
+bool RE_bake_internal(
+ struct Render *re, struct Object *object, const BakePixel pixel_array[],
+ const int num_pixels, const int depth, const ScenePassType pass_type, float result[]);
+
+void RE_bake_pixels_populate_from_objects(
+ struct Mesh *me_low, BakePixel pixel_array_from[],
+ BakeHighPolyData highpoly[], const int tot_highpoly, const int num_pixels,
+ const float cage_extrusion);
+
+void RE_bake_pixels_populate(
+ struct Mesh *me, struct BakePixel *pixel_array,
+ const int num_pixels, const struct BakeImages *bake_images);
+
+void RE_bake_mask_fill(const BakePixel pixel_array[], const int num_pixels, char *mask);
+
+void RE_bake_margin(struct ImBuf *ibuf, char *mask, const int margin);
+
+void RE_bake_normal_world_to_object(
+ const BakePixel pixel_array[], const int num_pixels, const int depth, float result[],
+ struct Object *ob, const BakeNormalSwizzle normal_swizzle[3]);
+void RE_bake_normal_world_to_tangent(
+ const BakePixel pixel_array[], const int num_pixels, const int depth, float result[],
+ struct Mesh *me, const BakeNormalSwizzle normal_swizzle[3]);
+void RE_bake_normal_world_to_world(
+ const BakePixel pixel_array[], const int num_pixels, const int depth, float result[],
+ const BakeNormalSwizzle normal_swizzle[3]);
+
+void RE_bake_ibuf_clear(struct BakeImages *bake_images, const bool is_tangent);
+
+#endif /* __RE_BAKE_H__ */
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index bd976e6c14a..2c6492b5c5a 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -35,6 +35,7 @@
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "RNA_types.h"
+#include "RE_bake.h"
struct bNode;
struct bNodeTree;
@@ -47,6 +48,7 @@ struct RenderLayer;
struct RenderResult;
struct ReportList;
struct Scene;
+struct BakePixel;
/* External Engine */
@@ -85,6 +87,7 @@ typedef struct RenderEngineType {
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
void (*render)(struct RenderEngine *engine, struct Scene *scene);
+ void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result);
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
@@ -153,6 +156,7 @@ RenderEngineType *RE_engines_find(const char *idname);
void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
struct RenderData *RE_engine_get_render_data(struct Render *re);
+void RE_bake_engine_set_engine_parameters(struct Render *re, struct Main *bmain, struct Scene *scene);
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 7251ba7a66d..031d6b5a51a 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -224,8 +224,11 @@ void RE_init_threadcount(Render *re);
void RE_TileProcessor(struct Render *re);
/* only RE_NewRender() needed, main Blender render calls */
-void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay_override, int frame, const short write_still);
-void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay_override, int sfra, int efra, int tfra);
+void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene,
+ struct SceneRenderLayer *srl, struct Object *camera_override,
+ unsigned int lay_override, int frame, const bool write_still);
+void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override,
+ unsigned int lay_override, int sfra, int efra, int tfra);
#ifdef WITH_FREESTYLE
void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene, int render);
#endif
@@ -236,12 +239,12 @@ void RE_SetReports(struct Render *re, struct ReportList *reports);
/* main preview render call */
void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene);
-int RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
-int RE_WriteRenderResult(struct ReportList *reports, RenderResult *rr, const char *filename, int compress);
-struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty);
+bool RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
+bool RE_WriteRenderResult(struct ReportList *reports, RenderResult *rr, const char *filename, int compress);
+struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty);
extern const float default_envmap_layout[];
-int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]);
+bool RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]);
/* do a full sample buffer compo */
void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce, struct bNodeTree *ntree);
@@ -254,6 +257,7 @@ void RE_stats_draw_cb (struct Render *re, void *handle, void (*f)(void *handle,
void RE_progress_cb (struct Render *re, void *handle, void (*f)(void *handle, float));
void RE_draw_lock_cb (struct Render *re, void *handle, void (*f)(void *handle, int));
void RE_test_break_cb (struct Render *re, void *handle, int (*f)(void *handle));
+void RE_current_scene_update_cb(struct Render *re, void *handle, void (*f)(void *handle, struct Scene *scene));
/* should move to kernel once... still unsure on how/where */
float RE_filter_value(int type, float x);
@@ -285,6 +289,7 @@ void RE_DataBase_GetView(struct Render *re, float mat[4][4]);
void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
struct Scene *RE_GetScene(struct Render *re);
+bool RE_force_single_renderlayer(struct Scene *scene);
bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports);
bool RE_allow_render_generic_object(struct Object *ob);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 57e52a9316b..da847d235f2 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -50,9 +50,10 @@ typedef struct ShadeResult {
float col[4];
float alpha, mist, z;
float emit[3];
- float diff[3]; /* no ramps, shadow, etc */
- float spec[3];
- float shad[4]; /* shad[3] is shadow intensity */
+ float diff[3]; /* diffuse with no ramps, shadow, etc */
+ float diffshad[3]; /* diffuse with shadow */
+ float spec[3]; /* specular with shadow */
+ float shad[4]; /* shad[3] is shadow intensity */
float ao[3];
float env[3];
float indirect[3];
@@ -80,7 +81,7 @@ struct ShadeInputCopy {
short osatex;
float vn[3], vno[3]; /* actual render normal, and a copy to restore it */
float n1[3], n2[3], n3[3]; /* vertex normals, corrected */
- int mode; /* base material mode (OR-ed result of entire node tree) */
+ int mode, mode2; /* base material mode (OR-ed result of entire node tree) */
};
typedef struct ShadeInputUV {
@@ -112,7 +113,7 @@ typedef struct ShadeInput {
short osatex;
float vn[3], vno[3]; /* actual render normal, and a copy to restore it */
float n1[3], n2[3], n3[3]; /* vertex normals, corrected */
- int mode; /* base material mode (OR-ed result of entire node tree) */
+ int mode, mode2; /* base material mode (OR-ed result of entire node tree) */
/* internal face coordinates */
float u, v, dx_u, dx_v, dy_u, dy_v;
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 69706ecc933..1f11cdc6729 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -40,7 +40,7 @@ struct Object;
void free_sample_tables(Render *re);
void make_sample_tables(Render *re);
-void RE_parts_init(Render *re, int do_crop);
+void RE_parts_init(Render *re, bool do_crop);
void RE_parts_free(Render *re);
void RE_parts_clamp(Render *re);
diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h
index 3607e66a237..9c0835af56f 100644
--- a/source/blender/render/intern/include/rayintersection.h
+++ b/source/blender/render/intern/include/rayintersection.h
@@ -121,7 +121,7 @@ typedef struct Isect {
/* arbitrary, but can't use e.g. FLT_MAX because of precision issues */
#define RE_RAYTRACE_MAXDIST 1e15f
-#define RE_RAYTRACE_EPSILON 0.0f
+#define RE_RAYTRACE_EPSILON -FLT_EPSILON
#ifdef __cplusplus
}
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h
index e9514b8585e..63135d01c23 100644
--- a/source/blender/render/intern/include/rayobject.h
+++ b/source/blender/render/intern/include/rayobject.h
@@ -59,7 +59,6 @@ RayObject *RE_rayobject_octree_create(int ocres, int size);
RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob);
RayObject *RE_rayobject_empty_create(void);
-RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */
RayObject *RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */
RayObject *RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_svbvh.c */
RayObject *RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_qbvh.c */
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 61b39a59b0b..457f1377e9b 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -57,7 +57,7 @@ struct RenderResult *render_result_new(struct Render *re,
struct RenderResult *render_result_new_full_sample(struct Render *re,
struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers);
-struct RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty);
+struct RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty);
/* Merge */
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index b9e06d3e6f7..eeb0544cf73 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -108,8 +108,9 @@ typedef struct RenderPart {
rcti disprect; /* part coordinates within total picture */
int rectx, recty; /* the size */
+ int nr; /* nr is partnr */
short crop, status; /* crop is amount of pixels we crop, for filter */
- short sample, nr; /* sample can be used by zbuffers, nr is partnr */
+ short sample; /* sample can be used by zbuffers */
short thread; /* thread id */
char *clipflag; /* clipflags for part zbuffering */
@@ -255,6 +256,8 @@ struct Render
void *dch;
void (*display_update)(void *handle, RenderResult *rr, volatile rcti *rect);
void *duh;
+ void (*current_scene_update)(void *handle, struct Scene *scene);
+ void *suh;
void (*stats_draw)(void *handle, RenderStats *ri);
void *sdh;
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 891505dd3a8..da45a2bfead 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -33,6 +33,10 @@
#ifndef __RENDERDATABASE_H__
#define __RENDERDATABASE_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct Object;
struct VlakRen;
struct VertRen;
@@ -92,7 +96,7 @@ void free_renderdata_tables(struct Render *re);
void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
-void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets);
+void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), bool do_pano, float xoffs, bool do_buckets);
int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]);
/* functions are not exported... so wrong names */
@@ -159,6 +163,9 @@ void area_lamp_vectors(struct LampRen *lar);
void init_render_world(Render *re);
void RE_Database_FromScene_Vectors(Render *re, struct Main *bmain, struct Scene *sce, unsigned int lay);
+#ifdef __cplusplus
+}
+#endif
#endif /* __RENDERDATABASE_H__ */
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 0e0337d6e0e..ff5004fd7f0 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -35,7 +35,7 @@
#define BRICONT \
texres->tin= (texres->tin-0.5f) * tex->contrast+tex->bright-0.5f; \
- if(!(tex->flag & TEX_NO_CLAMP)) { \
+ if (!(tex->flag & TEX_NO_CLAMP)) { \
if (texres->tin < 0.0f) texres->tin= 0.0f; \
else if (texres->tin > 1.0f) texres->tin= 1.0f; \
} \
@@ -44,7 +44,7 @@
texres->tr= tex->rfac*((texres->tr-0.5f)*tex->contrast+tex->bright-0.5f); \
texres->tg= tex->gfac*((texres->tg-0.5f)*tex->contrast+tex->bright-0.5f); \
texres->tb= tex->bfac*((texres->tb-0.5f)*tex->contrast+tex->bright-0.5f); \
- if(!(tex->flag & TEX_NO_CLAMP)) { \
+ if (!(tex->flag & TEX_NO_CLAMP)) { \
if (texres->tr < 0.0f) texres->tr= 0.0f; \
if (texres->tg < 0.0f) texres->tg= 0.0f; \
if (texres->tb < 0.0f) texres->tb= 0.0f; \
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index 9e639501fdd..de6b9139363 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -43,6 +43,7 @@
#include "rayobject.h"
#include "raycounter.h"
#include "render_types.h"
+#include "renderdatabase.h"
/* RayFace
*
@@ -118,7 +119,7 @@ MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRe
if (is->mode == RE_RAY_MIRROR)
return !(vlr->mat->mode & MA_ONLYCAST);
else
- return (is->lay & obi->lay);
+ return (vlr->mat->mode2 & MA_CASTSHADOW) && (is->lay & obi->lay);
}
MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
@@ -326,15 +327,33 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i
if (dist < 0.1f && is->orig.ob == face->ob) {
VlakRen *a = (VlakRen *)is->orig.face;
VlakRen *b = (VlakRen *)face->face;
+ ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr;
+
+ VertRen **va, **vb;
+ int *org_idx_a, *org_idx_b;
+ int i, j;
+ bool is_neighbor = false;
+
+ /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available
+ * (autosmooth only, currently). */
+ for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) {
+ org_idx_a = RE_vertren_get_origindex(obr, *va, false);
+ for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) {
+ if (*va == *vb) {
+ is_neighbor = true;
+ }
+ else if (org_idx_a) {
+ org_idx_b = RE_vertren_get_origindex(obr, *vb, 0);
+ if (org_idx_b && *org_idx_a == *org_idx_b) {
+ is_neighbor = true;
+ }
+ }
+ }
+ }
- /* so there's a shared edge or vertex, let's intersect ray with
- * face itself, if that's true we can safely return 1, otherwise
- * we assume the intersection is invalid, 0 */
- if (a->v1 == b->v1 || a->v2 == b->v1 || a->v3 == b->v1 || a->v4 == b->v1 ||
- a->v1 == b->v2 || a->v2 == b->v2 || a->v3 == b->v2 || a->v4 == b->v2 ||
- a->v1 == b->v3 || a->v2 == b->v3 || a->v3 == b->v3 || a->v4 == b->v3 ||
- (b->v4 && (a->v1 == b->v4 || a->v2 == b->v4 || a->v3 == b->v4 || a->v4 == b->v4)))
- {
+ /* So there's a shared edge or vertex, let's intersect ray with self, if that's true
+ * we can safely return 1, otherwise we assume the intersection is invalid, 0 */
+ if (is_neighbor) {
/* create RayFace from original face, transformed if necessary */
RayFace origface;
ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
diff --git a/source/blender/render/intern/raytrace/rayobject_blibvh.cpp b/source/blender/render/intern/raytrace/rayobject_blibvh.cpp
deleted file mode 100644
index 18e8ba6cd14..00000000000
--- a/source/blender/render/intern/raytrace/rayobject_blibvh.cpp
+++ /dev/null
@@ -1,169 +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) 2009 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): André Pinto.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/render/intern/raytrace/rayobject_blibvh.cpp
- * \ingroup render
- */
-
-#include <assert.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_kdopbvh.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-
-#include "rayintersection.h"
-#include "rayobject.h"
-
-static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec);
-static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob);
-static void RE_rayobject_blibvh_done(RayObject *o);
-static void RE_rayobject_blibvh_free(RayObject *o);
-static void RE_rayobject_blibvh_bb(RayObject *o, float min[3], float max[3]);
-
-static float RE_rayobject_blibvh_cost(RayObject *UNUSED(o))
-{
- //TODO calculate the expected cost to raycast on this structure
- return 1.0;
-}
-
-static void RE_rayobject_blibvh_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint),
- float *UNUSED(min), float *UNUSED(max))
-{
- return;
-}
-
-static RayObjectAPI bvh_api =
-{
- RE_rayobject_blibvh_intersect,
- RE_rayobject_blibvh_add,
- RE_rayobject_blibvh_done,
- RE_rayobject_blibvh_free,
- RE_rayobject_blibvh_bb,
- RE_rayobject_blibvh_cost,
- RE_rayobject_blibvh_hint_bb
-};
-
-typedef struct BVHObject {
- RayObject rayobj;
- RayObject **leafs, **next_leaf;
- BVHTree *bvh;
- float bb[2][3];
-} BVHObject;
-
-RayObject *RE_rayobject_blibvh_create(int size)
-{
- BVHObject *obj = (BVHObject *)MEM_callocN(sizeof(BVHObject), "BVHObject");
- assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */
-
- obj->rayobj.api = &bvh_api;
- obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6);
- obj->next_leaf = obj->leafs = (RayObject **)MEM_callocN(size * sizeof(RayObject *), "BVHObject leafs");
-
- INIT_MINMAX(obj->bb[0], obj->bb[1]);
- return RE_rayobject_unalignRayAPI((RayObject *) obj);
-}
-
-struct BVHCallbackUserData {
- Isect *isec;
- RayObject **leafs;
-};
-
-static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit)
-{
- struct BVHCallbackUserData *data = (struct BVHCallbackUserData *)userdata;
- Isect *isec = data->isec;
- RayObject *face = data->leafs[index];
-
- if (RE_rayobject_intersect(face, isec)) {
- hit->index = index;
-
- if (isec->mode == RE_RAY_SHADOW)
- hit->dist = 0;
- else
- hit->dist = isec->dist;
- }
-}
-
-static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec)
-{
- BVHObject *obj = (BVHObject *)o;
- BVHTreeRayHit hit;
- float dir[3];
- struct BVHCallbackUserData data;
- data.isec = isec;
- data.leafs = obj->leafs;
-
- copy_v3_v3(dir, isec->dir);
-
- hit.index = 0;
- hit.dist = isec->dist;
-
- return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, (void *)&data);
-}
-
-static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob)
-{
- BVHObject *obj = (BVHObject *)o;
- float min_max[6];
- INIT_MINMAX(min_max, min_max + 3);
- RE_rayobject_merge_bb(ob, min_max, min_max + 3);
-
- DO_MIN(min_max, obj->bb[0]);
- DO_MAX(min_max + 3, obj->bb[1]);
-
- BLI_bvhtree_insert(obj->bvh, obj->next_leaf - obj->leafs, min_max, 2);
- *(obj->next_leaf++) = ob;
-}
-
-static void RE_rayobject_blibvh_done(RayObject *o)
-{
- BVHObject *obj = (BVHObject *)o;
- BLI_bvhtree_balance(obj->bvh);
-}
-
-static void RE_rayobject_blibvh_free(RayObject *o)
-{
- BVHObject *obj = (BVHObject *)o;
-
- if (obj->bvh)
- BLI_bvhtree_free(obj->bvh);
-
- if (obj->leafs)
- MEM_freeN(obj->leafs);
-
- MEM_freeN(obj);
-}
-
-static void RE_rayobject_blibvh_bb(RayObject *o, float min[3], float max[3])
-{
- BVHObject *obj = (BVHObject *)o;
- DO_MIN(obj->bb[0], min);
- DO_MAX(obj->bb[1], max);
-}
-
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index 6182d066f68..24804b8c0ad 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -380,7 +380,7 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa
x = ocx1; y = ocy1;
lambda = MIN2(lambda_x, lambda_y);
- while (TRUE) {
+ while (true) {
if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) {
/* pass*/
@@ -1004,7 +1004,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
/* this loop has been constructed to make sure the first and last node of ray
* are always included, even when dda_lambda==1.0f or larger */
- while (TRUE) {
+ while (true) {
no = ocread(oc, xo, yo, zo);
if (no) {
diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h
index 5cb48f7e145..e25538cd584 100644
--- a/source/blender/render/intern/raytrace/reorganize.h
+++ b/source/blender/render/intern/raytrace/reorganize.h
@@ -287,6 +287,10 @@ static float bvh_refit(Node *node)
#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */
#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE
+#define CUT_SIZE_IS_VALID(cut_size) ((cut_size) < MAX_CUT_SIZE && (cut_size) >= 0)
+#define CUT_SIZE_INVALID -1
+
+
struct OVBVHNode {
float bb[6];
@@ -300,6 +304,7 @@ struct OVBVHNode {
float cut_cost[MAX_CUT_SIZE];
float get_cost(int cutsize)
{
+ assert(CUT_SIZE_IS_VALID(cutsize - 1));
return cut_cost[cutsize - 1];
}
@@ -310,6 +315,7 @@ struct OVBVHNode {
int cut_size[MAX_CUT_SIZE];
int get_cut_size(int parent_cut_size)
{
+ assert(CUT_SIZE_IS_VALID(parent_cut_size - 1));
return cut_size[parent_cut_size - 1];
}
@@ -343,9 +349,9 @@ struct OVBVHNode {
{
if (RE_rayobject_isAligned(this->child)) {
//Calc new childs
- {
+ if (this->best_cutsize != CUT_SIZE_INVALID) {
OVBVHNode **cut = &(this->child);
- set_cut(best_cutsize, &cut);
+ set_cut(this->best_cutsize, &cut);
*cut = NULL;
}
@@ -468,12 +474,17 @@ struct VBVH_optimalPackSIMD {
}
}
}
- assert(node->cut_cost[0] != INFINITY);
+
+ if (node->cut_cost[0] == INFINITY) {
+ node->best_cutsize = CUT_SIZE_INVALID;
+ }
}
else {
node->cut_cost[0] = 1.0f;
for (int i = 1; i < MAX_CUT_SIZE; i++)
node->cut_cost[i] = INFINITY;
+
+ /* node->best_cutsize can remain unset here */
}
}
diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h
index a3ef166e6b2..292b93c445f 100644
--- a/source/blender/render/intern/raytrace/svbvh.h
+++ b/source/blender/render/intern/raytrace/svbvh.h
@@ -36,7 +36,6 @@
#include "bvh.h"
#include "BLI_memarena.h"
-#include <stdio.h>
#include <algorithm>
struct SVBVHNode {
@@ -214,7 +213,7 @@ struct Reorganize_SVBVH {
~Reorganize_SVBVH()
{
-#ifdef DEBUG
+#if 0
{
printf("%f childs per node\n", childs_per_node / nodes);
printf("%d childs BB are useless\n", useless_bb);
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 977c30ff20a..f2793a9bc5b 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -34,7 +34,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -55,6 +54,8 @@
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
+#include "RE_bake.h"
+
/* local include */
#include "rayintersection.h"
#include "rayobject.h"
@@ -373,7 +374,7 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist,
bs->vcol->b = col[2];
}
else {
- char *imcol = (char *)(bs->rect + bs->rectx * y + x);
+ const char *imcol = (char *)(bs->rect + bs->rectx * y + x);
copy_v4_v4_char((char *)imcol, (char *)col);
}
}
@@ -936,8 +937,8 @@ void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max)
{
int i;
- float *current_displacement = displacement;
- char *current_mask = mask;
+ const float *current_displacement = displacement;
+ const char *current_mask = mask;
float max_distance;
max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
@@ -981,6 +982,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
int a, vdone = false, result = BAKE_RESULT_OK;
bool use_mask = false;
bool use_displacement_buffer = false;
+ bool do_manage = BKE_scene_check_color_management_enabled(re->scene);
re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
@@ -1040,6 +1042,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
}
handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
handles[a].ssamp.shi[0].thread = a;
+ handles[a].ssamp.shi[0].do_manage = do_manage;
handles[a].ssamp.tot = 1;
handles[a].type = type;
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
new file mode 100644
index 00000000000..258208eeec6
--- /dev/null
+++ b/source/blender/render/intern/source/bake_api.c
@@ -0,0 +1,867 @@
+/*
+ * ***** 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.
+ *
+ * Contributors:
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/bake_api.c
+ * \ingroup render
+ *
+ * \brief The API itself is simple. Blender sends a populated array of BakePixels to the renderer, and gets back an
+ * array of floats with the result.
+ *
+ * \section bake_api Development Notes for External Engines
+ *
+ * The Bake API is fully implemented with Python rna functions. The operator expects/call a function:
+ *
+ * ``def bake(scene, object, pass_type, pixel_array, num_pixels, depth, result)``
+ * - scene: current scene (Python object)
+ * - object: object to render (Python object)
+ * - pass_type: pass to render (string, e.g., "COMBINED", "AO", "NORMAL", ...)
+ * - pixel_array: list of primitive ids and barycentric coordinates to bake(Python object, see bake_pixel)
+ * - num_pixels: size of pixel_array, number of pixels to bake (int)
+ * - depth: depth of pixels to return (int, assuming always 4 now)
+ * - result: array to be populated by the engine (float array, PyLong_AsVoidPtr)
+ *
+ * \note Normals are expected to be in World Space and in the +X, +Y, +Z orientation.
+ *
+ * \subsection bake_pixel BakePixel data structure
+ *
+ * pixel_array is a Python object storing BakePixel elements:
+ *
+ * <pre>
+ * struct BakePixel {
+ * int primitive_id;
+ * float uv[2];
+ * float du_dx, du_dy;
+ * float dv_dx, dv_dy;
+ * };
+ * </pre>
+ *
+ * In python you have access to:
+ * - ``primitive_id``, ``uv``, ``du_dx``, ``du_dy``, ``next``
+ * - ``next()`` is a function that returns the next #BakePixel in the array.
+ *
+ * \note Pixels that should not be baked have ``primitive_id == -1``
+ *
+ * For a complete implementation example look at the Cycles Bake commit.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "DNA_mesh_types.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_image.h"
+#include "BKE_node.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "RE_bake.h"
+
+/* local include */
+#include "render_types.h"
+#include "zbuf.h"
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+typedef struct BakeDataZSpan {
+ BakePixel *pixel_array;
+ int primitive_id;
+ BakeImage *bk_image;
+ ZSpan *zspan;
+ float du_dx, du_dy;
+ float dv_dx, dv_dy;
+} BakeDataZSpan;
+
+/**
+ * struct wrapping up tangent space data
+ */
+typedef struct TSpace {
+ float tangent[3];
+ float sign;
+} TSpace;
+
+typedef struct TriTessFace {
+ const MVert *mverts[3];
+ const TSpace *tspace[3];
+ float normal[3]; /* for flat faces */
+ bool is_smooth;
+} TriTessFace;
+
+static void store_bake_pixel(void *handle, int x, int y, float u, float v)
+{
+ BakeDataZSpan *bd = (BakeDataZSpan *)handle;
+ BakePixel *pixel;
+
+ const int width = bd->bk_image->width;
+ const int offset = bd->bk_image->offset;
+ const int i = offset + y * width + x;
+
+ pixel = &bd->pixel_array[i];
+ pixel->primitive_id = bd->primitive_id;
+
+ copy_v2_fl2(pixel->uv, u, v);
+
+ pixel->du_dx = bd->du_dx;
+ pixel->du_dy = bd->du_dy;
+ pixel->dv_dx = bd->dv_dx;
+ pixel->dv_dy = bd->dv_dy;
+}
+
+void RE_bake_mask_fill(const BakePixel pixel_array[], const int num_pixels, char *mask)
+{
+ int i;
+ if (!mask)
+ return;
+
+ /* only extend to pixels outside the mask area */
+ for (i = 0; i < num_pixels; i++) {
+ if (pixel_array[i].primitive_id != -1) {
+ mask[i] = FILTER_MASK_USED;
+ }
+ }
+}
+
+void RE_bake_margin(ImBuf *ibuf, char *mask, const int margin)
+{
+ /* margin */
+ IMB_filter_extend(ibuf, mask, margin);
+
+ if (ibuf->planes != R_IMF_PLANES_RGBA)
+ /* clear alpha added by filtering */
+ IMB_rectfill_alpha(ibuf, 1.0f);
+}
+
+/**
+ * This function returns the coordinate and normal of a barycentric u,v for a face defined by the primitive_id index.
+ */
+static void calc_point_from_barycentric(
+ TriTessFace *triangles, int primitive_id, float u, float v, float cage_extrusion,
+ float r_co[3], float r_dir[3])
+{
+ float data[3][3];
+ float coord[3];
+ float dir[3];
+ float cage[3];
+
+ TriTessFace *triangle = &triangles[primitive_id];
+
+ copy_v3_v3(data[0], triangle->mverts[0]->co);
+ copy_v3_v3(data[1], triangle->mverts[1]->co);
+ copy_v3_v3(data[2], triangle->mverts[2]->co);
+
+ interp_barycentric_tri_v3(data, u, v, coord);
+
+ normal_short_to_float_v3(data[0], triangle->mverts[0]->no);
+ normal_short_to_float_v3(data[1], triangle->mverts[1]->no);
+ normal_short_to_float_v3(data[2], triangle->mverts[2]->no);
+
+ interp_barycentric_tri_v3(data, u, v, dir);
+ normalize_v3_v3(cage, dir);
+ mul_v3_fl(cage, cage_extrusion);
+
+ add_v3_v3(coord, cage);
+
+ normalize_v3_v3(dir, dir);
+ mul_v3_fl(dir, -1.0f);
+
+ copy_v3_v3(r_co, coord);
+ copy_v3_v3(r_dir, dir);
+}
+
+/**
+ * This function returns the barycentric u,v of a face for a coordinate. The face is defined by its index.
+ */
+static void calc_barycentric_from_point(
+ TriTessFace *triangles, const int index, const float co[3],
+ int *r_primitive_id, float r_uv[2])
+{
+ TriTessFace *triangle = &triangles[index];
+ resolve_tri_uv_v3(r_uv, co,
+ triangle->mverts[0]->co,
+ triangle->mverts[1]->co,
+ triangle->mverts[2]->co);
+ *r_primitive_id = index;
+}
+
+/**
+ * This function populates pixel_array and returns TRUE if things are correct
+ */
+static bool cast_ray_highpoly(
+ BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakeHighPolyData *highpoly,
+ float const co_low[3], const float dir[3], const int pixel_id, const int tot_highpoly,
+ const float du_dx, const float du_dy, const float dv_dx, const float dv_dy)
+{
+ int i;
+ int primitive_id = -1;
+ float uv[2];
+ int hit_mesh = -1;
+ float hit_distance = FLT_MAX;
+
+ BVHTreeRayHit *hits;
+ hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays");
+
+ for (i = 0; i < tot_highpoly; i++) {
+ float co_high[3];
+ hits[i].index = -1;
+ /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */
+ hits[i].dist = 10000.0f;
+
+ copy_v3_v3(co_high, co_low);
+
+ /* transform the ray from the lowpoly to the highpoly space */
+ mul_m4_v3(highpoly[i].mat_lowtohigh, co_high);
+
+ /* cast ray */
+ BLI_bvhtree_ray_cast(treeData[i].tree, co_high, dir, 0.0f, &hits[i], treeData[i].raycast_callback, &treeData[i]);
+
+ if (hits[i].index != -1) {
+ /* cull backface */
+ const float dot = dot_v3v3(dir, hits[i].no);
+ if (dot < 0.0f) {
+ if (hits[i].dist < hit_distance) {
+ hit_mesh = i;
+ hit_distance = hits[i].dist;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < tot_highpoly; i++) {
+ if (hit_mesh == i) {
+ calc_barycentric_from_point(triangles[i], hits[i].index, hits[i].co, &primitive_id, uv);
+ highpoly[i].pixel_array[pixel_id].primitive_id = primitive_id;
+ copy_v2_v2(highpoly[i].pixel_array[pixel_id].uv, uv);
+
+ /* the differentials are relative to the UV/image space, so the highpoly differentials
+ * are the same as the low poly differentials */
+ highpoly[i].pixel_array[pixel_id].du_dx = du_dx;
+ highpoly[i].pixel_array[pixel_id].du_dy = du_dy;
+ highpoly[i].pixel_array[pixel_id].dv_dx = dv_dx;
+ highpoly[i].pixel_array[pixel_id].dv_dy = dv_dy;
+ }
+ else {
+ highpoly[i].pixel_array[pixel_id].primitive_id = -1;
+ }
+ }
+
+ MEM_freeN(hits);
+ return hit_mesh != -1;
+}
+
+/**
+ * This function populates an array of verts for the triangles of a mesh
+ * Tangent and Normals are also stored
+ */
+static void mesh_calc_tri_tessface(
+ TriTessFace *triangles, Mesh *me, bool tangent, DerivedMesh *dm)
+{
+ int i;
+ int p_id;
+ MFace *mface;
+ MVert *mvert;
+ TSpace *tspace;
+ float *precomputed_normals;
+ bool calculate_normal;
+
+ mface = CustomData_get_layer(&me->fdata, CD_MFACE);
+ mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
+
+ if (tangent) {
+ DM_ensure_normals(dm);
+ DM_add_tangent_layer(dm);
+
+ precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ calculate_normal = precomputed_normals ? false : true;
+
+ //mface = dm->getTessFaceArray(dm);
+ //mvert = dm->getVertArray(dm);
+
+ tspace = dm->getTessFaceDataArray(dm, CD_TANGENT);
+ BLI_assert(tspace);
+ }
+
+ p_id = -1;
+ for (i = 0; i < me->totface; i++) {
+ MFace *mf = &mface[i];
+ TSpace *ts = &tspace[i * 4];
+
+ p_id++;
+
+ triangles[p_id].mverts[0] = &mvert[mf->v1];
+ triangles[p_id].mverts[1] = &mvert[mf->v2];
+ triangles[p_id].mverts[2] = &mvert[mf->v3];
+ triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0;
+
+ if (tangent) {
+ triangles[p_id].tspace[0] = &ts[0];
+ triangles[p_id].tspace[1] = &ts[1];
+ triangles[p_id].tspace[2] = &ts[2];
+
+ if (calculate_normal) {
+ if (mf->v4 != 0) {
+ normal_quad_v3(triangles[p_id].normal,
+ mvert[mf->v1].co,
+ mvert[mf->v2].co,
+ mvert[mf->v3].co,
+ mvert[mf->v4].co);
+ }
+ else {
+ normal_tri_v3(triangles[p_id].normal,
+ triangles[p_id].mverts[0]->co,
+ triangles[p_id].mverts[1]->co,
+ triangles[p_id].mverts[2]->co);
+ }
+ }
+ else {
+ copy_v3_v3(triangles[p_id].normal, &precomputed_normals[3 * i]);
+ }
+ }
+
+ /* 4 vertices in the face */
+ if (mf->v4 != 0) {
+ p_id++;
+
+ triangles[p_id].mverts[0] = &mvert[mf->v1];
+ triangles[p_id].mverts[1] = &mvert[mf->v3];
+ triangles[p_id].mverts[2] = &mvert[mf->v4];
+ triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0;
+
+ if (tangent) {
+ triangles[p_id].tspace[0] = &ts[0];
+ triangles[p_id].tspace[1] = &ts[2];
+ triangles[p_id].tspace[2] = &ts[3];
+
+ /* same normal as the other "triangle" */
+ copy_v3_v3(triangles[p_id].normal, triangles[p_id - 1].normal);
+ }
+ }
+ }
+
+ BLI_assert(p_id < me->totface * 2);
+}
+
+void RE_bake_pixels_populate_from_objects(
+ struct Mesh *me_low, BakePixel pixel_array_from[],
+ BakeHighPolyData highpoly[], const int tot_highpoly, const int num_pixels,
+ const float cage_extrusion)
+{
+ int i;
+ int primitive_id;
+ float u, v;
+
+ DerivedMesh **dm_highpoly;
+ BVHTreeFromMesh *treeData;
+
+ /* Note: all coordinates are in local space */
+ TriTessFace *tris_low;
+ TriTessFace **tris_high;
+
+ /* assume all lowpoly tessfaces can be quads */
+ tris_low = MEM_callocN(sizeof(TriTessFace) * (me_low->totface * 2), "MVerts Lowpoly Mesh");
+ tris_high = MEM_callocN(sizeof(TriTessFace *) * tot_highpoly, "MVerts Highpoly Mesh Array");
+
+ /* assume all highpoly tessfaces are triangles */
+ dm_highpoly = MEM_callocN(sizeof(DerivedMesh *) * tot_highpoly, "Highpoly Derived Meshes");
+ treeData = MEM_callocN(sizeof(BVHTreeFromMesh) * tot_highpoly, "Highpoly BVH Trees");
+
+ mesh_calc_tri_tessface(tris_low, me_low, false, NULL);
+
+ for (i = 0; i < tot_highpoly; i++) {
+ tris_high[i] = MEM_callocN(sizeof(TriTessFace) * highpoly[i].me->totface, "MVerts Highpoly Mesh");
+ mesh_calc_tri_tessface(tris_high[i], highpoly[i].me, false, NULL);
+
+ dm_highpoly[i] = CDDM_from_mesh(highpoly[i].me);
+
+ /* Create a bvh-tree for each highpoly object */
+ bvhtree_from_mesh_faces(&treeData[i], dm_highpoly[i], 0.0, 2, 6);
+
+ if (&treeData[i].tree == NULL) {
+ printf("Baking: Out of memory\n");
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < num_pixels; i++) {
+ float co[3];
+ float dir[3];
+
+ primitive_id = pixel_array_from[i].primitive_id;
+
+ if (primitive_id == -1) {
+ int j;
+ for (j = 0; j < tot_highpoly; j++) {
+ highpoly[j].pixel_array[i].primitive_id = -1;
+ }
+ continue;
+ }
+
+ u = pixel_array_from[i].uv[0];
+ v = pixel_array_from[i].uv[1];
+
+ /* calculate from low poly mesh cage */
+ calc_point_from_barycentric(tris_low, primitive_id, u, v, cage_extrusion, co, dir);
+
+ /* cast ray */
+ if (!cast_ray_highpoly(treeData, tris_high, highpoly, co, dir, i, tot_highpoly,
+ pixel_array_from[i].du_dx, pixel_array_from[i].du_dy,
+ pixel_array_from[i].dv_dx, pixel_array_from[i].dv_dy)) {
+ /* if it fails mask out the original pixel array */
+ pixel_array_from[i].primitive_id = -1;
+ }
+ }
+
+
+ /* garbage collection */
+cleanup:
+ for (i = 0; i < tot_highpoly; i++) {
+ free_bvhtree_from_mesh(&treeData[i]);
+ dm_highpoly[i]->release(dm_highpoly[i]);
+ MEM_freeN(tris_high[i]);
+ }
+
+ MEM_freeN(tris_low);
+ MEM_freeN(tris_high);
+ MEM_freeN(treeData);
+ MEM_freeN(dm_highpoly);
+}
+
+static void bake_differentials(BakeDataZSpan *bd, const float *uv1, const float *uv2, const float *uv3)
+{
+ float A;
+
+ /* assumes dPdu = P1 - P3 and dPdv = P2 - P3 */
+ A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]);
+
+ if (fabsf(A) > FLT_EPSILON) {
+ A = 0.5f / A;
+
+ bd->du_dx = (uv2[1] - uv3[1]) * A;
+ bd->dv_dx = (uv3[1] - uv1[1]) * A;
+
+ bd->du_dy = (uv3[0] - uv2[0]) * A;
+ bd->dv_dy = (uv1[0] - uv3[0]) * A;
+ }
+ else {
+ bd->du_dx = bd->du_dy = 0.0f;
+ bd->dv_dx = bd->dv_dy = 0.0f;
+ }
+}
+
+void RE_bake_pixels_populate(
+ Mesh *me, BakePixel pixel_array[],
+ const int num_pixels, const BakeImages *bake_images)
+{
+ BakeDataZSpan bd;
+ int i, a;
+ int p_id;
+
+ MTFace *mtface;
+ MFace *mface;
+
+ /* we can't bake in edit mode */
+ if (me->edit_btmesh)
+ return;
+
+ bd.pixel_array = pixel_array;
+ bd.zspan = MEM_callocN(sizeof(ZSpan) * bake_images->size, "bake zspan");
+
+ /* initialize all pixel arrays so we know which ones are 'blank' */
+ for (i = 0; i < num_pixels; i++) {
+ pixel_array[i].primitive_id = -1;
+ }
+
+ for (i = 0; i < bake_images->size; i++) {
+ zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height, R.clipcrop);
+ }
+
+ mtface = CustomData_get_layer(&me->fdata, CD_MTFACE);
+ mface = CustomData_get_layer(&me->fdata, CD_MFACE);
+
+ if (mtface == NULL)
+ return;
+
+ p_id = -1;
+ for (i = 0; i < me->totface; i++) {
+ float vec[4][2];
+ MTFace *mtf = &mtface[i];
+ MFace *mf = &mface[i];
+ int mat_nr = mf->mat_nr;
+ int image_id = bake_images->lookup[mat_nr];
+
+ bd.bk_image = &bake_images->data[image_id];
+ bd.primitive_id = ++p_id;
+
+ for (a = 0; a < 4; a++) {
+ /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
+ * where a pixel gets in between 2 faces or the middle of a quad,
+ * camera aligned quads also have this problem but they are less common.
+ * Add a small offset to the UVs, fixes bug #18685 - Campbell */
+ vec[a][0] = mtf->uv[a][0] * (float)bd.bk_image->width - (0.5f + 0.001f);
+ vec[a][1] = mtf->uv[a][1] * (float)bd.bk_image->height - (0.5f + 0.002f);
+ }
+
+ bake_differentials(&bd, vec[0], vec[1], vec[2]);
+ zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel);
+
+ /* 4 vertices in the face */
+ if (mf->v4 != 0) {
+ bd.primitive_id = ++p_id;
+
+ bake_differentials(&bd, vec[0], vec[2], vec[3]);
+ zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[2], vec[3], store_bake_pixel);
+ }
+ }
+
+ for (i = 0; i < bake_images->size; i++) {
+ zbuf_free_span(&bd.zspan[i]);
+ }
+ MEM_freeN(bd.zspan);
+}
+
+/* ******************** NORMALS ************************ */
+
+/**
+ * convert a normalized normal to the -1.0 1.0 range
+ * the input is expected to be POS_X, POS_Y, POS_Z
+ */
+static void normal_uncompress(float out[3], const float in[3])
+{
+ int i;
+ for (i = 0; i < 3; i++)
+ out[i] = 2.0f * in[i] - 1.0f;
+}
+
+static void normal_compress(float out[3], const float in[3], const BakeNormalSwizzle normal_swizzle[3])
+{
+ const int swizzle_index[6] = {
+ 0, /* R_BAKE_POSX */
+ 1, /* R_BAKE_POSY */
+ 2, /* R_BAKE_POSZ */
+ 0, /* R_BAKE_NEGX */
+ 1, /* R_BAKE_NEGY */
+ 2, /* R_BAKE_NEGZ */
+ };
+ const float swizzle_sign[6] = {
+ +1.0f, /* R_BAKE_POSX */
+ +1.0f, /* R_BAKE_POSY */
+ +1.0f, /* R_BAKE_POSZ */
+ -1.0f, /* R_BAKE_NEGX */
+ -1.0f, /* R_BAKE_NEGY */
+ -1.0f, /* R_BAKE_NEGZ */
+ };
+
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ int index;
+ float sign;
+
+ sign = swizzle_sign[normal_swizzle[i]];
+ index = swizzle_index[normal_swizzle[i]];
+
+ /*
+ * There is a small 1e-5f bias for precision issues. otherwise
+ * we randomly get 127 or 128 for neutral colors in tangent maps.
+ * we choose 128 because it is the convention flat color. *
+ */
+
+ out[i] = sign * in[index] / 2.0f + 0.5f + 1e-5f;
+ }
+}
+
+/**
+ * This function converts an object space normal map to a tangent space normal map for a given low poly mesh
+ */
+void RE_bake_normal_world_to_tangent(
+ const BakePixel pixel_array[], const int num_pixels, const int depth,
+ float result[], Mesh *me, const BakeNormalSwizzle normal_swizzle[3])
+{
+ int i;
+
+ TriTessFace *triangles;
+
+ DerivedMesh *dm = CDDM_from_mesh(me);
+
+ triangles = MEM_callocN(sizeof(TriTessFace) * (me->totface * 2), "MVerts Mesh");
+ mesh_calc_tri_tessface(triangles, me, true, dm);
+
+ BLI_assert(num_pixels >= 3);
+
+ for (i = 0; i < num_pixels; i++) {
+ TriTessFace *triangle;
+ float tangents[3][3];
+ float normals[3][3];
+ float signs[3];
+ int j;
+
+ float tangent[3];
+ float normal[3];
+ float binormal[3];
+ float sign;
+ float u, v, w;
+
+ float tsm[3][3]; /* tangent space matrix */
+ float itsm[3][3];
+
+ int offset;
+ float nor[3]; /* texture normal */
+
+ bool is_smooth;
+
+ int primitive_id = pixel_array[i].primitive_id;
+
+ offset = i * depth;
+
+ if (primitive_id == -1) {
+ copy_v3_fl3(&result[offset], 0.5f, 0.5f, 1.0f);
+ continue;
+ }
+
+ triangle = &triangles[primitive_id];
+ is_smooth = triangle->is_smooth;
+
+ for (j = 0; j < 3; j++) {
+ const TSpace *ts;
+
+ if (is_smooth)
+ normal_short_to_float_v3(normals[j], triangle->mverts[j]->no);
+ else
+ normal[j] = triangle->normal[j];
+
+ ts = triangle->tspace[j];
+ copy_v3_v3(tangents[j], ts->tangent);
+ signs[j] = ts->sign;
+ }
+
+ u = pixel_array[i].uv[0];
+ v = pixel_array[i].uv[1];
+ w = 1.0f - u - v;
+
+ /* normal */
+ if (is_smooth)
+ interp_barycentric_tri_v3(normals, u, v, normal);
+
+ /* tangent */
+ interp_barycentric_tri_v3(tangents, u, v, tangent);
+
+ /* sign */
+ /* The sign is the same at all face vertices for any non degenerate face.
+ * Just in case we clamp the interpolated value though. */
+ sign = (signs[0] * u + signs[1] * v + signs[2] * w) < 0 ? (-1.0f) : 1.0f;
+
+ /* binormal */
+ /* B = sign * cross(N, T) */
+ cross_v3_v3v3(binormal, normal, tangent);
+ mul_v3_fl(binormal, sign);
+
+ /* populate tangent space matrix */
+ copy_v3_v3(tsm[0], tangent);
+ copy_v3_v3(tsm[1], binormal);
+ copy_v3_v3(tsm[2], normal);
+
+ /* texture values */
+ normal_uncompress(nor, &result[offset]);
+
+ invert_m3_m3(itsm, tsm);
+ mul_m3_v3(itsm, nor);
+ normalize_v3(nor);
+
+ /* save back the values */
+ normal_compress(&result[offset], nor, normal_swizzle);
+ }
+
+ /* garbage collection */
+ MEM_freeN(triangles);
+
+ if (dm)
+ dm->release(dm);
+}
+
+void RE_bake_normal_world_to_object(
+ const BakePixel pixel_array[], const int num_pixels, const int depth,
+ float result[], struct Object *ob, const BakeNormalSwizzle normal_swizzle[3])
+{
+ int i;
+ float iobmat[4][4];
+
+ invert_m4_m4(iobmat, ob->obmat);
+
+ for (i = 0; i < num_pixels; i++) {
+ int offset;
+ float nor[3];
+
+ if (pixel_array[i].primitive_id == -1)
+ continue;
+
+ offset = i * depth;
+ normal_uncompress(nor, &result[offset]);
+
+ mul_m4_v3(iobmat, nor);
+ normalize_v3(nor);
+
+ /* save back the values */
+ normal_compress(&result[offset], nor, normal_swizzle);
+ }
+}
+
+void RE_bake_normal_world_to_world(
+ const BakePixel pixel_array[], const int num_pixels, const int depth,
+ float result[], const BakeNormalSwizzle normal_swizzle[3])
+{
+ int i;
+
+ for (i = 0; i < num_pixels; i++) {
+ int offset;
+ float nor[3];
+
+ if (pixel_array[i].primitive_id == -1)
+ continue;
+
+ offset = i * depth;
+ normal_uncompress(nor, &result[offset]);
+
+ /* save back the values */
+ normal_compress(&result[offset], nor, normal_swizzle);
+ }
+}
+
+void RE_bake_ibuf_clear(BakeImages *bake_images, const bool is_tangent)
+{
+ ImBuf *ibuf;
+ void *lock;
+ Image *image;
+ int i;
+
+ const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
+ const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+
+ for (i = 0; i < bake_images->size; i ++) {
+ image = bake_images->data[i].image;
+
+ ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+ BLI_assert(ibuf);
+
+ if (is_tangent)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+}
+
+/* ************************************************************* */
+
+/**
+ * not the real UV, but the internal per-face UV instead
+ * I'm using it to test if everything is correct */
+static bool bake_uv(const BakePixel pixel_array[], const int num_pixels, const int depth, float result[])
+{
+ int i;
+
+ for (i=0; i < num_pixels; i++) {
+ int offset = i * depth;
+ copy_v2_v2(&result[offset], pixel_array[i].uv);
+ }
+
+ return true;
+}
+
+bool RE_bake_internal(
+ Render *UNUSED(re), Object *UNUSED(object), const BakePixel pixel_array[],
+ const int num_pixels, const int depth, const ScenePassType pass_type, float result[])
+{
+ switch (pass_type) {
+ case SCE_PASS_UV:
+ {
+ return bake_uv(pixel_array, num_pixels, depth, result);
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+int RE_pass_depth(const ScenePassType pass_type)
+{
+ /* IMB_buffer_byte_from_float assumes 4 channels
+ * making it work for now - XXX */
+ return 4;
+
+ switch (pass_type) {
+ case SCE_PASS_Z:
+ case SCE_PASS_AO:
+ case SCE_PASS_MIST:
+ {
+ return 1;
+ }
+ case SCE_PASS_UV:
+ {
+ return 2;
+ }
+ case SCE_PASS_RGBA:
+ {
+ return 4;
+ }
+ case SCE_PASS_COMBINED:
+ case SCE_PASS_DIFFUSE:
+ case SCE_PASS_SPEC:
+ case SCE_PASS_SHADOW:
+ case SCE_PASS_REFLECT:
+ case SCE_PASS_NORMAL:
+ case SCE_PASS_VECTOR:
+ case SCE_PASS_REFRACT:
+ case SCE_PASS_INDEXOB: /* XXX double check */
+ case SCE_PASS_INDIRECT:
+ case SCE_PASS_RAYHITS: /* XXX double check */
+ case SCE_PASS_EMIT:
+ case SCE_PASS_ENVIRONMENT:
+ case SCE_PASS_INDEXMA:
+ case SCE_PASS_DIFFUSE_DIRECT:
+ case SCE_PASS_DIFFUSE_INDIRECT:
+ case SCE_PASS_DIFFUSE_COLOR:
+ case SCE_PASS_GLOSSY_DIRECT:
+ case SCE_PASS_GLOSSY_INDIRECT:
+ case SCE_PASS_GLOSSY_COLOR:
+ case SCE_PASS_TRANSM_DIRECT:
+ case SCE_PASS_TRANSM_INDIRECT:
+ case SCE_PASS_TRANSM_COLOR:
+ case SCE_PASS_SUBSURFACE_DIRECT:
+ case SCE_PASS_SUBSURFACE_INDIRECT:
+ case SCE_PASS_SUBSURFACE_COLOR:
+ default:
+ {
+ return 3;
+ }
+ }
+}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 4fee36f832b..3ee05d6f1f4 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -39,56 +39,39 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_rand.h"
-#include "BLI_task.h"
#include "BLI_memarena.h"
-#include "BLI_linklist.h"
#ifdef WITH_FREESTYLE
# include "BLI_edgehash.h"
#endif
#include "BLF_translation.h"
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
#include "DNA_material_types.h"
#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_image_types.h"
-#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_meta_types.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
#include "BKE_anim.h"
-#include "BKE_armature.h"
-#include "BKE_action.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_colortools.h"
-#include "BKE_constraint.h"
#include "BKE_displist.h"
-#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_group.h"
#include "BKE_key.h"
-#include "BKE_ipo.h"
#include "BKE_image.h"
#include "BKE_lattice.h"
-#include "BKE_library.h"
#include "BKE_material.h"
#include "BKE_main.h"
#include "BKE_mball.h"
@@ -98,10 +81,7 @@
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "BKE_subsurf.h"
-#include "BKE_texture.h"
-#include "BKE_world.h"
#include "PIL_time.h"
#include "IMB_imbuf_types.h"
@@ -398,23 +378,25 @@ static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[
}
}
-static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangent, int do_nmap_tangent)
+static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, bool do_vertex_normal, bool do_tangent, bool do_nmap_tangent)
{
int a;
/* clear all vertex normals */
- for (a=0; a<obr->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(obr, a);
- ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
+ if (do_vertex_normal) {
+ for (a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
+ ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
+ }
}
/* calculate cos of angles and point-masses, use as weight factor to
* add face normal to vertex */
for (a=0; a<obr->totvlak; a++) {
VlakRen *vlr= RE_findOrAddVlak(obr, a);
- if (vlr->flag & ME_SMOOTH) {
+ if (do_vertex_normal && vlr->flag & ME_SMOOTH) {
float *n4= (vlr->v4)? vlr->v4->n: NULL;
- float *c4= (vlr->v4)? vlr->v4->co: NULL;
+ const float *c4= (vlr->v4)? vlr->v4->co: NULL;
accumulate_vertex_normals(vlr->v1->n, vlr->v2->n, vlr->v3->n, n4,
vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co, c4);
@@ -430,7 +412,7 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
for (a=0; a<obr->totvlak; a++) {
VlakRen *vlr= RE_findOrAddVlak(obr, a);
- if ((vlr->flag & ME_SMOOTH)==0) {
+ if (do_vertex_normal && (vlr->flag & ME_SMOOTH)==0) {
if (is_zero_v3(vlr->v1->n)) copy_v3_v3(vlr->v1->n, vlr->n);
if (is_zero_v3(vlr->v2->n)) copy_v3_v3(vlr->v2->n, vlr->n);
if (is_zero_v3(vlr->v3->n)) copy_v3_v3(vlr->v3->n, vlr->n);
@@ -456,7 +438,7 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
}
/* normal mapping tangent with mikktspace */
- if (do_nmap_tangent != FALSE) {
+ if (do_nmap_tangent != false) {
SRenderMeshToTangent mesh2tangent;
SMikkTSpaceContext sContext;
SMikkTSpaceInterface sInterface;
@@ -494,163 +476,153 @@ typedef struct ASface {
VertRen *nver[4];
} ASface;
-static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
+static int as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
{
ASface *asf;
- int a;
-
- if (v1 == NULL) return;
-
- if (asv->faces.first==NULL) {
- asf= MEM_callocN(sizeof(ASface), "asface");
- BLI_addtail(&asv->faces, asf);
- }
-
- asf= asv->faces.last;
- for (a=0; a<4; a++) {
- if (asf->vlr[a]==NULL) {
- asf->vlr[a]= vlr;
- asv->totface++;
- break;
+ int a = -1;
+
+ if (v1 == NULL)
+ return a;
+
+ asf = asv->faces.last;
+ if (asf) {
+ for (a = 0; a < 4 && asf->vlr[a]; a++) {
}
}
-
+ else {
+ a = 4;
+ }
+
/* new face struct */
- if (a==4) {
- asf= MEM_callocN(sizeof(ASface), "asface");
+ if (a == 4) {
+ a = 0;
+ asf = MEM_callocN(sizeof(ASface), "asface");
BLI_addtail(&asv->faces, asf);
- asf->vlr[0]= vlr;
- asv->totface++;
}
+
+ asf->vlr[a] = vlr;
+ asv->totface++;
+
+ return a;
}
-static int as_testvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float thresh)
+static VertRen *as_findvertex_lnor(VlakRen *vlr, VertRen *ver, ASvert *asv, const float lnor[3])
{
- /* return 1: vertex needs a copy */
+ /* return when new vertex already was made, or existing one is OK */
ASface *asf;
- float inp;
int a;
-
- if (vlr == NULL) return 0;
-
- asf= asv->faces.first;
- while (asf) {
- for (a=0; a<4; a++) {
- if (asf->vlr[a] && asf->vlr[a]!=vlr) {
- inp = fabsf(dot_v3v3(vlr->n, asf->vlr[a]->n));
- if (inp < thresh) return 1;
- }
- }
- asf= asf->next;
+
+ /* First face, we can use existing vert and assign it current lnor! */
+ if (asv->totface == 1) {
+ copy_v3_v3(ver->n, lnor);
+ return ver;
}
-
- return 0;
-}
-static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float thresh)
-{
- /* return when new vertex already was made */
- ASface *asf;
- float inp;
- int a;
-
- asf= asv->faces.first;
+ /* In case existing ver has same normal as current lnor, we can simply use it! */
+ if (equals_v3v3(lnor, ver->n)) {
+ return ver;
+ }
+
+ asf = asv->faces.first;
while (asf) {
- for (a=0; a<4; a++) {
- if (asf->vlr[a] && asf->vlr[a]!=vlr) {
+ for (a = 0; a < 4; a++) {
+ if (asf->vlr[a] && asf->vlr[a] != vlr) {
/* this face already made a copy for this vertex! */
if (asf->nver[a]) {
- inp = fabsf(dot_v3v3(vlr->n, asf->vlr[a]->n));
- if (inp >= thresh) {
+ if (equals_v3v3(lnor, asf->nver[a]->n)) {
return asf->nver[a];
}
}
}
}
- asf= asf->next;
+ asf = asf->next;
}
-
+
return NULL;
}
+static void as_addvert_lnor(ObjectRen *obr, ASvert *asv, VertRen *ver, VlakRen *vlr, const short _lnor[3])
+{
+ VertRen *v1;
+ ASface *asf;
+ int asf_idx;
+ float lnor[3];
+
+ normal_short_to_float_v3(lnor, _lnor);
+
+ asf_idx = as_addvert(asv, ver, vlr);
+ if (asf_idx < 0) {
+ return;
+ }
+ asf = asv->faces.last;
+
+ /* already made a new vertex within threshold? */
+ v1 = as_findvertex_lnor(vlr, ver, asv, lnor);
+ if (v1 == NULL) {
+ /* make a new vertex */
+ v1 = RE_vertren_copy(obr, ver);
+ copy_v3_v3(v1->n, lnor);
+ }
+ if (v1 != ver) {
+ asf->nver[asf_idx] = v1;
+ if (vlr->v1 == ver) vlr->v1 = v1;
+ if (vlr->v2 == ver) vlr->v2 = v1;
+ if (vlr->v3 == ver) vlr->v3 = v1;
+ if (vlr->v4 == ver) vlr->v4 = v1;
+ }
+}
+
/* note; autosmooth happens in object space still, after applying autosmooth we rotate */
/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
-static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr)
+static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], short (*lnors)[4][3])
{
- ASvert *asv, *asverts;
- ASface *asf;
- VertRen *ver, *v1;
+ ASvert *asverts;
+ VertRen *ver;
VlakRen *vlr;
- float thresh;
- int a, b, totvert;
-
- if (obr->totvert==0) return;
- asverts= MEM_callocN(sizeof(ASvert)*obr->totvert, "all smooth verts");
-
- thresh= cosf(DEG2RADF((0.5f + (float)degr)));
-
- /* step zero: give faces normals of original mesh, if this is provided */
-
-
- /* step one: construct listbase of all vertices and pointers to faces */
- for (a=0; a<obr->totvlak; a++) {
- vlr= RE_findOrAddVlak(obr, a);
- /* skip wire faces */
- if (vlr->v2 != vlr->v3) {
- as_addvert(asverts+vlr->v1->index, vlr->v1, vlr);
- as_addvert(asverts+vlr->v2->index, vlr->v2, vlr);
- as_addvert(asverts+vlr->v3->index, vlr->v3, vlr);
- if (vlr->v4)
- as_addvert(asverts+vlr->v4->index, vlr->v4, vlr);
- }
- }
-
- totvert= obr->totvert;
- /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
- for (a=0, asv=asverts; a<totvert; a++, asv++) {
- if (asv->totface > 1) {
- ver= RE_findOrAddVert(obr, a);
+ int a, totvert;
- asf= asv->faces.first;
- while (asf) {
- for (b=0; b<4; b++) {
-
- /* is there a reason to make a new vertex? */
- vlr= asf->vlr[b];
- if ( as_testvertex(vlr, ver, asv, thresh) ) {
-
- /* already made a new vertex within threshold? */
- v1= as_findvertex(vlr, ver, asv, thresh);
- if (v1==NULL) {
- /* make a new vertex */
- v1= RE_vertren_copy(obr, ver);
- }
- asf->nver[b]= v1;
- if (vlr->v1==ver) vlr->v1= v1;
- if (vlr->v2==ver) vlr->v2= v1;
- if (vlr->v3==ver) vlr->v3= v1;
- if (vlr->v4==ver) vlr->v4= v1;
- }
- }
- asf= asf->next;
+ if (obr->totvert == 0)
+ return;
+
+ totvert = obr->totvert;
+ asverts = MEM_callocN(sizeof(ASvert) * totvert, "all smooth verts");
+
+ if (lnors) {
+ /* We construct listbase of all vertices and pointers to faces, and add new verts when needed
+ * (i.e. when existing ones do not share the same (loop)normal).
+ */
+ for (a = 0; a < obr->totvlak; a++, lnors++) {
+ vlr = RE_findOrAddVlak(obr, a);
+ /* skip wire faces */
+ if (vlr->v2 != vlr->v3) {
+ as_addvert_lnor(obr, asverts+vlr->v1->index, vlr->v1, vlr, (const short*)lnors[0][0]);
+ as_addvert_lnor(obr, asverts+vlr->v2->index, vlr->v2, vlr, (const short*)lnors[0][1]);
+ as_addvert_lnor(obr, asverts+vlr->v3->index, vlr->v3, vlr, (const short*)lnors[0][2]);
+ if (vlr->v4)
+ as_addvert_lnor(obr, asverts+vlr->v4->index, vlr->v4, vlr, (const short*)lnors[0][3]);
}
}
}
-
+
/* free */
- for (a=0; a<totvert; a++) {
+ for (a = 0; a < totvert; a++) {
BLI_freelistN(&asverts[a].faces);
}
MEM_freeN(asverts);
-
+
/* rotate vertices and calculate normal of faces */
- for (a=0; a<obr->totvert; a++) {
- ver= RE_findOrAddVert(obr, a);
+ for (a = 0; a < obr->totvert; a++) {
+ ver = RE_findOrAddVert(obr, a);
mul_m4_v3(mat, ver->co);
+ if (lnors) {
+ mul_mat3_m4_v3(mat, ver->n);
+ negate_v3(ver->n);
+ normalize_v3(ver->n);
+ }
}
- for (a=0; a<obr->totvlak; a++) {
- vlr= RE_findOrAddVlak(obr, a);
-
+ for (a = 0; a < obr->totvlak; a++) {
+ vlr = RE_findOrAddVlak(obr, a);
+
/* skip wire faces */
if (vlr->v2 != vlr->v3) {
if (vlr->v4)
@@ -1328,11 +1300,12 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
float pa_time, pa_birthtime, pa_dietime;
float random, simplify[2], pa_co[3];
const float cfra= BKE_scene_frame_get(re->scene);
- int i, a, k, max_k=0, totpart, do_simplify = FALSE, do_surfacecache = FALSE, use_duplimat = FALSE;
+ int i, a, k, max_k=0, totpart;
+ bool do_simplify = false, do_surfacecache = false, use_duplimat = false;
int totchild=0, step_nbr;
int seed, path_nbr=0, orco1=0, num;
int totface;
- char **uv_name = NULL;
+ const char **uv_name = NULL;
const int *index_mf_to_mpoly = NULL;
const int *index_mp_to_orig = NULL;
@@ -1350,7 +1323,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
return 1;
- if ((re->r.scemode & R_VIEWPORT_PREVIEW) && psys->edit)
+ if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
/* 2. start initializing things */
@@ -1460,7 +1433,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (psys->flag & PSYS_USE_IMAT) {
/* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */
mul_m4_m4m4(duplimat, ob->obmat, psys->imat);
- use_duplimat = TRUE;
+ use_duplimat = true;
}
/* 2.6 setup strand rendering */
@@ -1510,10 +1483,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
svert= strandbuf->vert;
if (re->r.mode & R_SPEED)
- do_surfacecache = TRUE;
+ do_surfacecache = true;
else if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
if (ma->amb != 0.0f)
- do_surfacecache = TRUE;
+ do_surfacecache = true;
totface= psmd->dm->getNumTessFaces(psmd->dm);
index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
@@ -1579,8 +1552,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
pa_size = pa->size;
- r_tilt = 2.0f*(PSYS_FRAND(a) - 0.5f);
- r_length = PSYS_FRAND(a+1);
+ r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f);
+ r_length = psys_frand(psys, a+1);
if (path_nbr) {
cache = psys->pathcache[a];
@@ -1604,8 +1577,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
- r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
+ r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
num = cpa->num;
@@ -1898,7 +1871,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
if (path_nbr && (ma->mode_l & MA_TANGENT_STR)==0)
- calc_vertexnormals(re, obr, 0, 0);
+ calc_vertexnormals(re, obr, 1, 0, 0);
return 1;
}
@@ -2008,7 +1981,7 @@ static short test_for_displace(Render *re, Object *ob)
return 0;
}
-static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3])
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale)
{
MTFace *tface;
short texco= shi->mat->texco;
@@ -2021,15 +1994,6 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
/* vertex normal is used for textures type 'col' and 'var' */
copy_v3_v3(shi->vn, vr->n);
- if (mat)
- mul_m4_v3(mat, shi->co);
-
- if (imat) {
- shi->vn[0] = dot_v3v3(imat[0], vr->n);
- shi->vn[1] = dot_v3v3(imat[1], vr->n);
- shi->vn[2] = dot_v3v3(imat[2], vr->n);
- }
-
if (texco & TEXCO_UV) {
shi->totuv= 0;
shi->actuv= obr->actmtface;
@@ -2061,7 +2025,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
/* not (yet?) */
}
if (texco & TEXCO_STRESS) {
- float *s= RE_vertren_get_stress(obr, vr, 0);
+ const float *s= RE_vertren_get_stress(obr, vr, 0);
if (s) {
shi->stress= *s;
@@ -2082,9 +2046,6 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
displace[0]= shi->displace[0] * scale[0];
displace[1]= shi->displace[1] * scale[1];
displace[2]= shi->displace[2] * scale[2];
-
- if (mat)
- mul_m3_v3(imat, displace);
/* 0.5 could become button once? */
vr->co[0] += displace[0];
@@ -2107,7 +2068,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
return;
}
-static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3])
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale)
{
ShadeInput shi;
@@ -2136,17 +2097,17 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
/* Displace the verts, flag is set when done */
if (!vlr->v1->flag)
- displace_render_vert(re, obr, &shi, vlr->v1, 0, scale, mat, imat);
+ displace_render_vert(re, obr, &shi, vlr->v1, 0, scale);
if (!vlr->v2->flag)
- displace_render_vert(re, obr, &shi, vlr->v2, 1, scale, mat, imat);
+ displace_render_vert(re, obr, &shi, vlr->v2, 1, scale);
if (!vlr->v3->flag)
- displace_render_vert(re, obr, &shi, vlr->v3, 2, scale, mat, imat);
+ displace_render_vert(re, obr, &shi, vlr->v3, 2, scale);
if (vlr->v4) {
if (!vlr->v4->flag)
- displace_render_vert(re, obr, &shi, vlr->v4, 3, scale, mat, imat);
+ displace_render_vert(re, obr, &shi, vlr->v4, 3, scale);
/* closest in displace value. This will help smooth edges. */
if (fabsf(vlr->v1->accum - vlr->v3->accum) > fabsf(vlr->v2->accum - vlr->v4->accum)) vlr->flag |= R_DIVIDE_24;
@@ -2162,7 +2123,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
}
}
-static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3])
+static void displace(Render *re, ObjectRen *obr)
{
VertRen *vr;
VlakRen *vlr;
@@ -2187,11 +2148,11 @@ static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float i
for (i=0; i<obr->totvlak; i++) {
vlr=RE_findOrAddVlak(obr, i);
- displace_render_face(re, obr, vlr, scale, mat, imat);
+ displace_render_face(re, obr, vlr, scale);
}
/* Recalc vertex normals */
- calc_vertexnormals(re, obr, 0, 0);
+ calc_vertexnormals(re, obr, 1, 0, 0);
}
/* ------------------------------------------------------------------------- */
@@ -2587,7 +2548,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
}
/* Normals */
- calc_vertexnormals(re, obr, 0, 0);
+ calc_vertexnormals(re, obr, 1, 0, 0);
}
}
@@ -2601,7 +2562,8 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
DispList *dl;
Material **matar;
float *orco=NULL, mat[4][4];
- int a, totmat, need_orco=0;
+ int a, totmat;
+ bool need_orco = false;
DerivedMesh *dm= NULL;
cu= ob->data;
@@ -2630,7 +2592,7 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
if (need_orco) {
orco = get_object_orco(re, ob);
if (!orco) {
- orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1);
+ orco= BKE_displist_make_orco(re->scene, ob, dm, true, true);
if (orco) {
set_object_orco(re, ob, orco);
}
@@ -2675,13 +2637,14 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
float *data, *fp, *orco=NULL;
float n[3], mat[4][4], nmat[4][4];
int nr, startvert, a, b;
- int need_orco=0, totmat;
+ bool need_orco = false;
+ int totmat;
cu= ob->data;
if (ob->type==OB_FONT && cu->str==NULL) return;
else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return;
- BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, 0, 1);
+ BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, false, true);
dl= disp.first;
if (dl==NULL) return;
@@ -2708,7 +2671,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
if (need_orco) {
orco = get_object_orco(re, ob);
if (!orco) {
- orco = BKE_displist_make_orco(re->scene, ob, dm, 1, 1);
+ orco = BKE_displist_make_orco(re->scene, ob, dm, true, true);
if (orco) {
set_object_orco(re, ob, orco);
}
@@ -2732,7 +2695,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
/* pass */
}
else if (dl->type==DL_INDEX3) {
- unsigned int *index;
+ const unsigned int *index;
startvert= obr->totvert;
data= dl->verts;
@@ -3103,7 +3066,7 @@ static EdgeHash *make_freestyle_edge_mark_hash(Mesh *me, DerivedMesh *dm)
FreestyleEdge *fed;
MEdge *medge;
int totedge, a;
- int *index;
+ const int *index;
medge = dm->getEdgeArray(dm);
totedge = dm->getNumEdges(dm);
@@ -3152,10 +3115,12 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco = NULL;
- int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
+ short (*loop_nors)[4][3] = NULL;
+ bool need_orco = false, need_stress = false, need_nmap_tangent = false, need_tangent = false, need_origindex = false;
int a, a1, ok, vertofs;
- int end, do_autosmooth = FALSE, totvert = 0;
- int use_original_normals = FALSE;
+ int end, totvert = 0;
+ bool do_autosmooth = false, do_displace = false;
+ bool use_original_normals = false;
int recalc_normals = 0; /* false by default */
int negative_scale;
#ifdef WITH_FREESTYLE
@@ -3204,18 +3169,19 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
need_nmap_tangent= 1;
}
-
- /* origindex currently only used when baking to vertex colors */
- if (re->flag & R_BAKING && re->r.bake_flag & R_BAKE_VCOL)
- need_origindex= 1;
- /* check autosmooth and displacement, we then have to skip only-verts optimize */
- do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
- if (do_autosmooth)
- timeoffset= 0;
- if (test_for_displace(re, ob ) )
- timeoffset= 0;
-
+ /* check autosmooth and displacement, we then have to skip only-verts optimize
+ * Note: not sure what we want to give higher priority, currently do_displace
+ * takes precedence over do_autosmooth.
+ */
+ do_displace = test_for_displace(re, ob);
+ do_autosmooth = ((me->flag & ME_AUTOSMOOTH) != 0) && !do_displace;
+ if (do_autosmooth || do_displace)
+ timeoffset = 0;
+
+ /* origindex currently used when using autosmooth, or baking to vertex colors. */
+ need_origindex = (do_autosmooth || ((re->flag & R_BAKING) && (re->r.bake_flag & R_BAKE_VCOL)));
+
mask= CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL;
if (!timeoffset)
if (need_orco)
@@ -3247,7 +3213,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* attempt to autsmooth on original mesh, only without subsurf */
if (do_autosmooth && me->totvert==totvert && me->totface==dm->getNumTessFaces(dm))
- use_original_normals= TRUE;
+ use_original_normals= true;
ma= give_render_material(re, ob, 1);
@@ -3271,7 +3237,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
for (a=0; a<totvert; a++, mvert++) {
ver= RE_findOrAddVert(obr, obr->totvert++);
copy_v3_v3(ver->co, mvert->co);
- if (do_autosmooth == FALSE) { /* autosmooth on original unrotated data to prevent differences between frames */
+ if (do_autosmooth == false) { /* autosmooth on original unrotated data to prevent differences between frames */
normal_short_to_float_v3(ver->n, mvert->no);
mul_m4_v3(mat, ver->co);
mul_transposed_m3_v3(imat, ver->n);
@@ -3298,6 +3264,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
if (!timeoffset) {
+ short (*lnp)[4][3] = NULL;
#ifdef WITH_FREESTYLE
EdgeHash *edge_hash;
@@ -3346,6 +3313,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (ok) {
end= dm->getNumTessFaces(dm);
mface= dm->getTessFaceArray(dm);
+ if (!loop_nors && do_autosmooth &&
+ (dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL) != NULL))
+ {
+ lnp = loop_nors = MEM_mallocN(sizeof(*loop_nors) * end, __func__);
+ }
#ifdef WITH_FREESTYLE
index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
@@ -3357,7 +3329,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if ( mface->mat_nr==a1 ) {
float len;
- int reverse_verts = (negative_scale != 0 && do_autosmooth == FALSE);
+ bool reverse_verts = (negative_scale != 0 && do_autosmooth == false);
int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3};
v1= reverse_verts==0 ? mface->v1 : mface->v3;
v2= mface->v2;
@@ -3423,7 +3395,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn= 0, mcn= 0, mtng=0, vindex;
+ int index, mtfn= 0, mcn= 0, mtng=0, mln = 0, vindex;
char *name;
int nr_verts = v4!=0 ? 4 : 3;
@@ -3456,6 +3428,21 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
normalize_v3(ftang+vindex*4);
}
}
+ mtng++;
+ }
+ else if (layer->type == CD_TESSLOOPNORMAL && mln < 1) {
+ if (loop_nors) {
+ const short (*lnors)[4][3] = (const short (*)[4][3])layer->data;
+ for (vindex = 0; vindex < 4; vindex++) {
+ //print_v3("lnors[a][rev_tab[vindex]]", lnors[a][rev_tab[vindex]]);
+ copy_v3_v3_short((short *)lnp[0][vindex], lnors[a][rev_tab[vindex]]);
+ /* If we copy loop normals, we are doing autosmooth, so we are still
+ * in object space, no need to multiply with mat!
+ */
+ }
+ lnp++;
+ }
+ mln++;
}
}
@@ -3538,24 +3525,22 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (need_stress)
calc_edge_stress(re, obr, me);
- if (test_for_displace(re, ob ) ) {
- recalc_normals= 1;
- calc_vertexnormals(re, obr, 0, 0);
- if (do_autosmooth)
- do_displacement(re, obr, mat, imat);
- else
- do_displacement(re, obr, NULL, NULL);
+ if (do_displace) {
+ calc_vertexnormals(re, obr, 1, 0, 0);
+ displace(re, obr);
+ recalc_normals = 0; /* Already computed by displace! */
}
-
- if (do_autosmooth) {
- recalc_normals= 1;
- autosmooth(re, obr, mat, me->smoothresh);
+ else if (do_autosmooth) {
+ recalc_normals = (loop_nors == NULL); /* Should never happen, but better be safe than sorry. */
+ autosmooth(re, obr, mat, loop_nors);
}
if (recalc_normals!=0 || need_tangent!=0)
- calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
+ calc_vertexnormals(re, obr, recalc_normals, need_tangent, need_nmap_tangent);
}
+ MEM_SAFE_FREE(loop_nors);
+
dm->release(dm);
}
@@ -3927,7 +3912,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
return go;
}
-static bool is_object_hidden(Render *re, Object *ob)
+static bool is_object_restricted(Render *re, Object *ob)
{
if (re->r.scemode & R_VIEWPORT_PREVIEW)
return (ob->restrictflag & OB_RESTRICT_VIEW) != 0;
@@ -3935,6 +3920,22 @@ static bool is_object_hidden(Render *re, Object *ob)
return (ob->restrictflag & OB_RESTRICT_RENDER) != 0;
}
+static bool is_object_hidden(Render *re, Object *ob)
+{
+ if (is_object_restricted(re, ob))
+ return true;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW) {
+ /* Mesh deform cages and so on mess up the preview. To avoid the problem,
+ * viewport doesn't show mesh object if its draw type is bounding box or wireframe.
+ */
+ return ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE);
+ }
+ else {
+ return false;
+ }
+}
+
/* layflag: allows material group to ignore layerflag */
static void add_lightgroup(Render *re, Group *group, int exclusive)
{
@@ -3975,7 +3976,7 @@ static void set_material_lightgroups(Render *re)
Material *ma;
/* not for preview render */
- if (re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))
+ if (re->scene->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))
return;
for (group= re->main->group.first; group; group=group->id.next)
@@ -4354,7 +4355,7 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
* I will look at means to have autosmooth enabled for all object types
* and have it as general postprocess, like displace */
if (ob->type!=OB_MESH && test_for_displace(re, ob))
- do_displacement(re, obr, NULL, NULL);
+ displace(re, obr);
if (!timeoffset) {
/* phong normal interpolation can cause error in tracing
@@ -4783,7 +4784,7 @@ void RE_Database_Free(Render *re)
free_strand_surface(re);
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
- re->i.convertdone = FALSE;
+ re->i.convertdone = false;
re->bakebuf= NULL;
@@ -4800,6 +4801,9 @@ void RE_Database_Free(Render *re)
static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob)
{
+ if (is_object_hidden(re, ob))
+ return 0;
+
/* override not showing object when duplis are used with particles */
if (ob->transflag & OB_DUPLIPARTS) {
/* pass */ /* let particle system(s) handle showing vs. not showing */
@@ -4973,7 +4977,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
lay= (timeoffset)? renderlay & vectorlay: renderlay;
/* if the object has been restricted from rendering in the outliner, ignore it */
- if (is_object_hidden(re, ob)) continue;
+ if (is_object_restricted(re, ob)) continue;
/* OB_DONE means the object itself got duplicated, so was already converted */
if (ob->flag & OB_DONE) {
@@ -4989,19 +4993,21 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
else if ((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->lay)) ) {
if ((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
DupliObject *dob;
- ListBase *lb;
+ ListBase *duplilist;
+ DupliApplyData *duplilist_apply_data = NULL;
+ int i;
/* create list of duplis generated by this object, particle
* system need to have render settings set for dupli particles */
dupli_render_particle_set(re, ob, timeoffset, 0, 1);
- lb= object_duplilist(re->eval_ctx, re->scene, ob);
+ duplilist = object_duplilist(re->eval_ctx, re->scene, ob);
+ duplilist_apply_data = duplilist_apply_matrix(duplilist);
dupli_render_particle_set(re, ob, timeoffset, 0, 0);
- for (dob= lb->first; dob; dob= dob->next) {
+ for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
+ DupliExtraData *dob_extra = &duplilist_apply_data->extra[i];
Object *obd= dob->ob;
- float omat[4][4];
-
- copy_m4_m4(omat, obd->obmat);
+
copy_m4_m4(obd->obmat, dob->mat);
/* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
@@ -5034,7 +5040,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], 0, mat, ob->lay);
/* fill in instance variables for texturing */
- set_dupli_tex_mat(re, obi, dob, omat);
+ set_dupli_tex_mat(re, obi, dob, dob_extra->obmat);
if (dob->type != OB_DUPLIGROUP) {
copy_v3_v3(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0];
@@ -5060,7 +5066,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
mul_m4_m4m4(mat, re->viewmat, dob->mat);
obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay);
- set_dupli_tex_mat(re, obi, dob, omat);
+ set_dupli_tex_mat(re, obi, dob, dob_extra->obmat);
if (dob->type != OB_DUPLIGROUP) {
copy_v3_v3(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0];
@@ -5076,7 +5082,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
if (obi==NULL)
/* can't instance, just create the object */
- init_render_object(re, obd, ob, dob, omat, timeoffset);
+ init_render_object(re, obd, ob, dob, dob_extra->obmat, timeoffset);
if (dob->type != OB_DUPLIGROUP) {
obd->flag |= OB_DONE;
@@ -5084,13 +5090,16 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
}
}
else
- init_render_object(re, obd, ob, dob, omat, timeoffset);
-
- copy_m4_m4(obd->obmat, omat);
+ init_render_object(re, obd, ob, dob, dob_extra->obmat, timeoffset);
if (re->test_break(re->tbh)) break;
}
- free_object_duplilist(lb);
+
+ if (duplilist_apply_data) {
+ duplilist_restore_matrix(duplilist, duplilist_apply_data);
+ duplilist_free_apply_data(duplilist_apply_data);
+ }
+ free_object_duplilist(duplilist);
if (allow_render_object(re, ob, nolamps, onlyselected, actob))
init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
@@ -5142,7 +5151,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
re->lampren.first= re->lampren.last= NULL;
slurph_opt= 0;
- re->i.partsdone = FALSE; /* signal now in use for previewrender */
+ re->i.partsdone = false; /* signal now in use for previewrender */
/* in localview, lamps are using normal layers, objects only local bits */
if (re->lay & 0xFF000000)
@@ -5259,7 +5268,7 @@ void RE_Database_Preprocess(Render *re)
volume_precache(re);
}
- re->i.convertdone = TRUE;
+ re->i.convertdone = true;
if (re->test_break(re->tbh))
RE_Database_Free(re);
@@ -5714,7 +5723,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
/* free dbase and make the future one */
strandsurface= re->strandsurface;
memset(&re->strandsurface, 0, sizeof(ListBase));
- re->i.convertdone = TRUE;
+ re->i.convertdone = true;
RE_Database_Free(re);
re->strandsurface= strandsurface;
@@ -5730,7 +5739,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
/* free dbase and make the real one */
strandsurface= re->strandsurface;
memset(&re->strandsurface, 0, sizeof(ListBase));
- re->i.convertdone = TRUE;
+ re->i.convertdone = true;
RE_Database_Free(re);
re->strandsurface= strandsurface;
@@ -5843,7 +5852,9 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
re->lay= lay;
/* renderdata setup and exceptions */
- re->r= scene->r;
+ BLI_freelistN(&re->r.layers);
+ re->r = scene->r;
+ BLI_duplicatelist(&re->r.layers, &scene->r.layers);
RE_init_threadcount(re);
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 311ec1efc6b..28b29261e4e 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -31,7 +31,6 @@
#include <string.h>
/* external modules: */
-#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -50,14 +49,10 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_image.h" /* BKE_imbuf_write */
#include "BKE_texture.h"
-
-
-
/* this module */
#include "render_types.h"
#include "renderpipeline.h"
@@ -172,6 +167,8 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->duh = re->duh;
envre->test_break = re->test_break;
envre->tbh = re->tbh;
+ envre->current_scene_update = re->current_scene_update;
+ envre->suh = re->suh;
/* and for the evil stuff; copy the database... */
envre->totvlak = re->totvlak;
@@ -321,6 +318,10 @@ void env_rotate_scene(Render *re, float mat[4][4], int do_rotate)
mul_m4_v3(tmat, har->co);
}
+
+ /* imat_ren is needed for correct texture coordinates */
+ mul_m4_m4m4(obr->ob->imat_ren, re->viewmat, obr->ob->obmat);
+ invert_m4(obr->ob->imat_ren);
}
for (go = re->lights.first; go; go = go->next) {
@@ -532,7 +533,8 @@ static void render_envmap(Render *re, EnvMap *env)
void make_envmaps(Render *re)
{
Tex *tex;
- int do_init = FALSE, depth = 0, trace;
+ bool do_init = false;
+ int depth = 0, trace;
if (!(re->r.mode & R_ENVMAP)) return;
@@ -586,7 +588,7 @@ void make_envmaps(Render *re)
if (env->ok == 0 && depth == 0) env->recalc = 1;
if (env->ok == 0) {
- do_init = TRUE;
+ do_init = true;
render_envmap(re, env);
if (depth == env->depth) env->recalc = 0;
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 5255e574c41..e8751210540 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -57,6 +57,7 @@
#include "RE_engine.h"
#include "RE_pipeline.h"
+#include "RE_bake.h"
#include "initrender.h"
#include "render_types.h"
@@ -67,7 +68,7 @@
static RenderEngineType internal_render_type = {
NULL, NULL,
"BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL,
- NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}
};
@@ -76,7 +77,7 @@ static RenderEngineType internal_render_type = {
static RenderEngineType internal_game_type = {
NULL, NULL,
"BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME,
- NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}
};
@@ -131,7 +132,7 @@ bool RE_engine_is_external(Render *re)
RenderEngine *RE_engine_create(RenderEngineType *type)
{
- return RE_engine_create_ex(type, FALSE);
+ return RE_engine_create_ex(type, false);
}
RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport)
@@ -402,6 +403,84 @@ RenderData *RE_engine_get_render_data(Render *re)
return &re->r;
}
+/* Bake */
+void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene)
+{
+ re->scene = scene;
+ re->main = bmain;
+ re->r = scene->r;
+
+ /* prevent crash when freeing the scene
+ but it potentially leaves unfreed memory blocks
+ not sure how to fix this yet -- dfelinto */
+ re->r.layers.first = re->r.layers.last = NULL;
+}
+
+bool RE_bake_has_engine(Render *re)
+{
+ RenderEngineType *type = RE_engines_find(re->r.engine);
+ return (bool)(type->bake);
+}
+
+bool RE_bake_engine(
+ Render *re, Object *object, const BakePixel pixel_array[],
+ const int num_pixels, const int depth,
+ const ScenePassType pass_type, float result[])
+{
+ RenderEngineType *type = RE_engines_find(re->r.engine);
+ RenderEngine *engine;
+ int persistent_data = re->r.mode & R_PERSISTENT_DATA;
+
+ /* set render info */
+ re->i.cfra = re->scene->r.cfra;
+ BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name) - 2);
+ re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0;
+
+ /* render */
+ engine = re->engine;
+
+ if (!engine) {
+ engine = RE_engine_create(type);
+ re->engine = engine;
+ }
+
+ engine->flag |= RE_ENGINE_RENDERING;
+
+ /* TODO: actually link to a parent which shouldn't happen */
+ engine->re = re;
+
+ engine->resolution_x = re->winx;
+ engine->resolution_y = re->winy;
+
+ RE_parts_init(re, false);
+ engine->tile_x = re->partx;
+ engine->tile_y = re->party;
+
+ /* update is only called so we create the engine.session */
+ if (type->update)
+ type->update(engine, re->main, re->scene);
+
+ if (type->bake)
+ type->bake(engine, re->scene, object, pass_type, pixel_array, num_pixels, depth, result);
+
+ engine->tile_x = 0;
+ engine->tile_y = 0;
+ engine->flag &= ~RE_ENGINE_RENDERING;
+
+ /* re->engine becomes zero if user changed active render engine during render */
+ if (!persistent_data || !re->engine) {
+ RE_engine_free(engine);
+ re->engine = NULL;
+ }
+
+ RE_parts_free(re);
+
+ if (BKE_reports_contain(re->reports, RPT_ERROR))
+ G.is_break = true;
+
+ return true;
+}
+
/* Render */
static bool render_layer_exclude_animated(Scene *scene, SceneRenderLayer *srl)
@@ -524,7 +603,7 @@ int RE_engine_render(Render *re, int do_all)
engine->resolution_x = re->winx;
engine->resolution_y = re->winy;
- RE_parts_init(re, FALSE);
+ RE_parts_init(re, false);
engine->tile_x = re->partx;
engine->tile_y = re->party;
@@ -563,7 +642,7 @@ int RE_engine_render(Render *re, int do_all)
RE_parts_free(re);
if (BKE_reports_contain(re->reports, RPT_ERROR))
- G.is_break = TRUE;
+ G.is_break = true;
return 1;
}
diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c
deleted file mode 100644
index 8efdf472232..00000000000
--- a/source/blender/render/intern/source/gammaCorrectionTables.c
+++ /dev/null
@@ -1,140 +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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/render/intern/source/gammaCorrectionTables.c
- * \ingroup render
- */
-
-
-#include "gammaCorrectionTables.h"
-#include <stdlib.h>
-#include <math.h>
-
-/* WARNING; optimized, cannot be used to do gamma(invgamma()) and expect */
-/* result remain identical (ton) */
-
-/* gamma is only used here for correcting adding colors or alpha */
-// #define RE_DEFAULT_GAMMA 2.0 // UNUSED
-
-/* This 400 is sort of based on the number of intensity levels needed for */
-/* the typical dynamic range of a medium, in this case CRTs. (Foley) */
-/* (Actually, it says the number should be between 400 and 535.) */
-#define RE_GAMMA_TABLE_SIZE 400
-
-/* These indicate the status of the gamma lookup table --------------------- */
-
-static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
-static float gamfactor_table[RE_GAMMA_TABLE_SIZE];
-static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1];
-static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE];
-static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1];
-static float color_step;
-static float inv_color_step;
-static float valid_gamma;
-static float valid_inv_gamma;
-
-/* ------------------------------------------------------------------------- */
-
-float gammaCorrect(float c)
-{
- int i;
- float res = 0.0;
-
- i = floor(c * inv_color_step);
- /* Clip to range [0,1]: outside, just do the complete calculation. */
- /* We may have some performance problems here. Stretching up the LUT */
- /* may help solve that, by exchanging LUT size for the interpolation. */
- /* Negative colors are explicitly handled. */
- if (i < 0) res = -pow(abs(c), valid_gamma);
- else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
- else res = gamma_range_table[i] +
- ( (c - color_domain_table[i]) * gamfactor_table[i]);
-
- return res;
-} /* end of float gammaCorrect(float col) */
-
-/* ------------------------------------------------------------------------- */
-
-float invGammaCorrect(float col)
-{
- int i;
- float res = 0.0;
-
- i = floor(col*inv_color_step);
- /* Negative colors are explicitly handled. */
- if (i < 0) res = -pow(abs(col), valid_inv_gamma);
- else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
- else res = inv_gamma_range_table[i] +
- ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
-
- return res;
-} /* end of float invGammaCorrect(float col) */
-
-
-/* ------------------------------------------------------------------------- */
-
-void makeGammaTables(float gamma)
-{
- /* we need two tables: one forward, one backward */
- int i;
-
- valid_gamma = gamma;
- valid_inv_gamma = 1.0f / gamma;
- color_step = 1.0 / RE_GAMMA_TABLE_SIZE;
- inv_color_step = (float) RE_GAMMA_TABLE_SIZE;
-
- /* We could squeeze out the two range tables to gain some memory. */
- for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) {
- color_domain_table[i] = i * color_step;
- gamma_range_table[i] = pow(color_domain_table[i],
- valid_gamma);
- inv_gamma_range_table[i] = pow(color_domain_table[i],
- valid_inv_gamma);
- }
-
- /* The end of the table should match 1.0 carefully. In order to avoid */
- /* rounding errors, we just set this explicitly. The last segment may */
- /* have a different length than the other segments, but our */
- /* interpolation is insensitive to that. */
- color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
- gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
- inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
-
- /* To speed up calculations, we make these calc factor tables. They are */
- /* multiplication factors used in scaling the interpolation. */
- for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) {
- gamfactor_table[i] = inv_color_step * (gamma_range_table[i + 1] - gamma_range_table[i]);
- inv_gamfactor_table[i] = inv_color_step * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]);
- }
-
-} /* end of void makeGammaTables(float gamma) */
-
-
-
-/* ------------------------------------------------------------------------- */
-
-/* eof */
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 716c4b8af65..7d4b70cea15 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -38,8 +38,6 @@
#include <io.h>
#endif
-#include "MEM_guardedalloc.h"
-
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -52,11 +50,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_image.h"
-#include "BKE_texture.h"
-#include "BKE_library.h"
#include "RE_render_ext.h"
@@ -82,21 +77,21 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
if (ibuf->rect_float) {
if (ibuf->channels==4) {
- float *fp= ibuf->rect_float + 4*ofs;
+ const float *fp= ibuf->rect_float + 4*ofs;
copy_v4_v4(col, fp);
}
else if (ibuf->channels==3) {
- float *fp= ibuf->rect_float + 3*ofs;
+ const float *fp= ibuf->rect_float + 3*ofs;
copy_v3_v3(col, fp);
col[3]= 1.0f;
}
else {
- float *fp= ibuf->rect_float + ofs;
+ const float *fp= ibuf->rect_float + ofs;
col[0]= col[1]= col[2]= col[3]= *fp;
}
}
else {
- char *rect = (char *)( ibuf->rect+ ofs);
+ const char *rect = (char *)( ibuf->rect+ ofs);
col[0] = ((float)rect[0])*(1.0f/255.0f);
col[1] = ((float)rect[1])*(1.0f/255.0f);
@@ -227,7 +222,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (ima) {
if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
- texres->talpha = TRUE;
+ texres->talpha = true;
}
}
}
@@ -727,7 +722,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf
}
}
else {
- char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
+ const char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
col[0] = rect[0] * inv_alpha_fac;
col[1] = rect[1] * inv_alpha_fac;
@@ -1536,7 +1531,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (ima) {
if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
- texres->talpha = TRUE;
+ texres->talpha = true;
}
}
}
@@ -1909,7 +1904,7 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu
if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
ibuf->rect+= (ibuf->x*ibuf->y);
- texres.talpha = TRUE; /* boxsample expects to be initialized */
+ texres.talpha = true; /* boxsample expects to be initialized */
boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
copy_v4_v4(result, &texres.tr);
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 2fb723faa12..5fd4747f19b 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -44,23 +44,12 @@
#include "BLI_utildefines.h"
#include "DNA_camera_types.h"
-#include "DNA_group_types.h"
#include "DNA_image_types.h"
-#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_camera.h"
-#include "BKE_global.h"
-#include "BKE_material.h"
-#include "BKE_object.h"
-#include "BKE_image.h"
-#include "BKE_ipo.h"
-#include "BKE_key.h"
-#include "BKE_action.h"
-#include "BKE_writeavi.h"
-#include "BKE_scene.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -92,10 +81,10 @@ static void init_render_jit(Render *re)
if (lastjit != re->r.osa || last_mblur_jit != re->r.mblur_samples) {
memset(jit, 0, sizeof(jit));
- BLI_jitter_init(jit[0], re->r.osa);
+ BLI_jitter_init(jit, re->r.osa);
memset(mblur_jit, 0, sizeof(mblur_jit));
- BLI_jitter_init(mblur_jit[0], re->r.mblur_samples);
+ BLI_jitter_init(mblur_jit, re->r.mblur_samples);
}
lastjit = re->r.osa;
@@ -545,7 +534,7 @@ void RE_parts_clamp(Render *re)
re->party = max_ii(1, min_ii(re->r.tiley, re->recty));
}
-void RE_parts_init(Render *re, int do_crop)
+void RE_parts_init(Render *re, bool do_crop)
{
int nr, xd, yd, partx, party, xparts, yparts;
int xminb, xmaxb, yminb, ymaxb;
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index be6d0111819..4ac1593d1bb 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -42,7 +42,6 @@
#include "BLI_threads.h"
#include "BKE_ccg.h"
-#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_multires.h"
@@ -76,7 +75,7 @@ typedef struct {
MFace *mface;
MTFace *mtface;
float *pvtangent;
- float *precomputed_normals;
+ const float *precomputed_normals;
int w, h;
int face_index;
int i0, i1, i2;
@@ -137,7 +136,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],
}
else {
float nor[3];
- float *p0, *p1, *p2;
+ const float *p0, *p1, *p2;
const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
p0 = data->mvert[indices[0]].co;
@@ -145,7 +144,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],
p2 = data->mvert[indices[2]].co;
if (iGetNrVerts == 4) {
- float *p3 = data->mvert[indices[3]].co;
+ const float *p3 = data->mvert[indices[3]].co;
normal_quad_v3(nor, p0, p1, p2, p3);
}
else {
@@ -156,7 +155,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],
}
}
else {
- short *no = data->mvert[indices[vert_index]].no;
+ const short *no = data->mvert[indices[vert_index]].no;
normal_short_to_float_v3(norm, no);
normalize_v3(norm);
@@ -181,8 +180,8 @@ static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResol
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
{
float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
- float *st0, *st1, *st2;
- float *tang0, *tang1, *tang2;
+ const float *st0, *st1, *st2;
+ const float *tang0, *tang1, *tang2;
float no0[3], no1[3], no2[3];
float fUV[2], from_tang[3][3], to_tang[3][3];
float u, v, w, sign;
@@ -200,7 +199,7 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
multiresbake_get_normal(data, no1, data->face_index, i1);
multiresbake_get_normal(data, no2, data->face_index, i2);
- resolve_tri_uv(fUV, st, st0, st1, st2);
+ resolve_tri_uv_v2(fUV, st, st0, st1, st2);
u = fUV[0];
v = fUV[1];
@@ -432,7 +431,7 @@ static void *do_multires_bake_thread(void *data_v)
bkr->baked_faces++;
if (bkr->do_update)
- *bkr->do_update = TRUE;
+ *bkr->do_update = true;
if (bkr->progress)
*bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / handle->queue->tot_face) / bkr->tot_obj;
@@ -451,7 +450,7 @@ static void init_ccgdm_arrays(DerivedMesh *dm)
CCGElem **grid_data;
CCGKey key;
int grid_size;
- int *grid_offset;
+ const int *grid_offset;
grid_size = dm->getGridSize(dm);
grid_data = dm->getGridData(dm);
@@ -463,7 +462,7 @@ static void init_ccgdm_arrays(DerivedMesh *dm)
(void) grid_offset;
}
-static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData,
+static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_tangent, MPassKnownData passKnownData,
MInitBakeData initBakeData, MFreeBakeData freeBakeData, MultiresBakeResult *result)
{
DerivedMesh *dm = bkr->lores_dm;
@@ -478,7 +477,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_ta
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getTessFaceArray(dm);
MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
- float *precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const float *precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
float *pvtangent = NULL;
ListBase threads;
@@ -772,10 +771,10 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
if (mface.v4) {
st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else
- resolve_tri_uv(uv, st, st0, st1, st2);
+ resolve_tri_uv_v2(uv, st, st0, st1, st2);
CLAMP(uv[0], 0.0f, 1.0f);
CLAMP(uv[1], 0.0f, 1.0f);
@@ -868,10 +867,10 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
if (mface.v4) {
st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else
- resolve_tri_uv(uv, st, st0, st1, st2);
+ resolve_tri_uv_v2(uv, st, st0, st1, st2);
CLAMP(uv[0], 0.0f, 1.0f);
CLAMP(uv[1], 0.0f, 1.0f);
@@ -937,7 +936,7 @@ static void build_permutation_table(unsigned short permutation[], unsigned short
for (i = 0; i < number_of_rays; i++) {
const unsigned int nr_entries_left = number_of_rays - i;
- unsigned short rnd = is_first_perm_table != FALSE ? get_ao_random1(i) : get_ao_random2(i);
+ unsigned short rnd = is_first_perm_table != false ? get_ao_random1(i) : get_ao_random2(i);
const unsigned short entry = rnd % nr_entries_left;
/* pull entry */
@@ -1072,7 +1071,7 @@ static void build_coordinate_frame(float axisX[3], float axisY[3], const float a
}
}
-/* return FALSE if nothing was hit and TRUE otherwise */
+/* return false if nothing was hit and true otherwise */
static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3])
{
Isect isect = {{0}};
@@ -1112,10 +1111,10 @@ static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void
if (mface.v4) {
st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else
- resolve_tri_uv(uv, st, st0, st1, st2);
+ resolve_tri_uv_v2(uv, st, st0, st1, st2);
CLAMP(uv[0], 0.0f, 1.0f);
CLAMP(uv[1], 0.0f, 1.0f);
@@ -1234,14 +1233,14 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
switch (bkr->mode) {
case RE_BAKE_NORMALS:
- do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, free_normal_data, result);
+ do_multires_bake(bkr, ima, true, apply_tangmat_callback, init_normal_data, free_normal_data, result);
break;
case RE_BAKE_DISPLACEMENT:
case RE_BAKE_DERIVATIVE:
- do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, free_heights_data, result);
+ do_multires_bake(bkr, ima, false, apply_heights_callback, init_heights_data, free_heights_data, result);
break;
case RE_BAKE_AO:
- do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, free_ao_data, result);
+ do_multires_bake(bkr, ima, false, apply_ao_callback, init_ao_data, free_ao_data, result);
break;
}
}
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 91c9143f5a3..dd0b1f89da7 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -39,14 +39,12 @@
#include "DNA_material_types.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_memarena.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
-#include "BKE_global.h"
#include "BKE_scene.h"
@@ -1176,7 +1174,7 @@ static void sample_occ_surface(ShadeInput *shi)
{
StrandRen *strand = shi->strand;
StrandSurface *mesh = strand->buffer->surface;
- int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
+ const int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
float w[4], *co1, *co2, *co3, *co4;
if (mesh && mesh->face && mesh->co && mesh->ao && index) {
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 1501c04a650..232f9db1c65 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -35,7 +35,6 @@
#include <stdlib.h>
#include <stddef.h>
-#include "DNA_group_types.h"
#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -80,7 +79,6 @@
#include "RE_pipeline.h"
#ifdef WITH_FREESTYLE
-# include "BKE_library.h"
# include "FRS_freestyle.h"
#endif
@@ -144,9 +142,10 @@ static int thread_break(void *UNUSED(arg))
/* default callbacks, set in each new render */
static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr)) {}
static void result_rcti_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) {}
+static void current_scene_nothing(void *UNUSED(arg), Scene *UNUSED(scene)) {}
static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs)) {}
static void float_nothing(void *UNUSED(arg), float UNUSED(val)) {}
-static int default_break(void *UNUSED(arg)) { return G.is_break == TRUE; }
+static int default_break(void *UNUSED(arg)) { return G.is_break == true; }
static void stats_background(void *UNUSED(arg), RenderStats *rs)
{
@@ -211,7 +210,7 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
}
}
-RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty)
+RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
{
return render_result_new_from_exr(exrhandle, colorspace, predivide, rectx, recty);
}
@@ -230,7 +229,7 @@ static int render_scene_needs_vector(Render *re)
{
SceneRenderLayer *srl;
- for (srl = re->scene->r.layers.first; srl; srl = srl->next)
+ for (srl = re->r.layers.first; srl; srl = srl->next)
if (!(srl->layflag & SCE_LAY_DISABLE))
if (srl->passflag & SCE_PASS_VECTOR)
return 1;
@@ -395,6 +394,7 @@ void RE_InitRenderCB(Render *re)
re->display_init = result_nothing;
re->display_clear = result_nothing;
re->display_update = result_rcti_nothing;
+ re->current_scene_update = current_scene_nothing;
re->progress = float_nothing;
re->test_break = default_break;
if (G.background)
@@ -412,6 +412,8 @@ void RE_FreeRender(Render *re)
RE_engine_free(re->engine);
BLI_rw_mutex_end(&re->resultmutex);
+
+ BLI_freelistN(&re->r.layers);
/* main dbase can already be invalid now, some database-free code checks it */
re->main = NULL;
@@ -504,10 +506,14 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
{
bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
- re->ok = TRUE; /* maybe flag */
+ re->ok = true; /* maybe flag */
re->i.starttime = PIL_check_seconds_timer();
- re->r = *rd; /* hardcopy */
+
+ /* copy render data and render layers for thread safety */
+ BLI_freelistN(&re->r.layers);
+ re->r = *rd;
+ BLI_duplicatelist(&re->r.layers, &rd->layers);
if (source) {
/* reuse border flags from source renderer */
@@ -582,7 +588,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
}
if (srl) {
- int index = BLI_findindex(&re->r.layers, srl);
+ int index = BLI_findindex(&rd->layers, srl);
if (index != -1) {
re->r.actlay = index;
re->r.scemode |= R_SINGLE_LAYER;
@@ -602,7 +608,17 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->result = NULL;
}
else if (re->result) {
- if (re->result->rectx == re->rectx && re->result->recty == re->recty) {
+ SceneRenderLayer *actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
+ RenderLayer *rl;
+ bool have_layer = false;
+
+ for (rl = re->result->layers.first; rl; rl = rl->next)
+ if (STREQ(rl->name, actsrl->name))
+ have_layer = true;
+
+ if (re->result->rectx == re->rectx && re->result->recty == re->recty &&
+ have_layer)
+ {
/* keep render result, this avoids flickering black tiles
* when the preview changes */
}
@@ -649,6 +665,10 @@ static void render_update_anim_renderdata(Render *re, RenderData *rd)
/* freestyle */
re->r.line_thickness_mode = rd->line_thickness_mode;
re->r.unit_line_thickness = rd->unit_line_thickness;
+
+ /* render layers */
+ BLI_freelistN(&re->r.layers);
+ BLI_duplicatelist(&re->r.layers, &rd->layers);
}
void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
@@ -719,6 +739,11 @@ void RE_display_update_cb(Render *re, void *handle, void (*f)(void *handle, Rend
re->display_update = f;
re->duh = handle;
}
+void RE_current_scene_update_cb(Render *re, void *handle, void (*f)(void *handle, Scene *scene))
+{
+ re->current_scene_update = f;
+ re->suh = handle;
+}
void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))
{
re->stats_draw = f;
@@ -780,6 +805,14 @@ static void *do_part_thread(void *pa_v)
else
pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM, RR_ALL_LAYERS);
+ /* Copy EXR tile settings, so pipeline knows whether this is a result
+ * for Save Buffers enabled rendering.
+ *
+ * TODO(sergey): This actually duplicates logic with external engine, so
+ * worth looking into more generic solution.
+ */
+ pa->result->do_exr_tile = R.result->do_exr_tile;
+
if (R.sss_points)
zbufshade_sss_tile(pa);
else if (R.osa)
@@ -1005,7 +1038,7 @@ static void threaded_tile_processor(Render *re)
/* warning; no return here without closing exr file */
- RE_parts_init(re, TRUE);
+ RE_parts_init(re, true);
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
@@ -1162,6 +1195,8 @@ static void do_render_3d(Render *re)
{
int cfra_backup;
+ re->current_scene_update(re->suh, re->scene);
+
/* try external */
if (RE_engine_render(re, 0))
return;
@@ -1273,7 +1308,7 @@ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float bl
/* called by blur loop, accumulate renderlayers */
-static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, int key_alpha)
+static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, bool key_alpha)
{
RenderLayer *rl, *rl1;
RenderPass *rpass, *rpass1;
@@ -1317,7 +1352,7 @@ static void do_render_blur_3d(Render *re)
blurfac = 1.0f / (float)(re->r.mblur_samples - blur);
- merge_renderresult_blur(rres, re->result, blurfac, FALSE);
+ merge_renderresult_blur(rres, re->result, blurfac, false);
if (re->test_break(re->tbh)) break;
}
@@ -1478,7 +1513,7 @@ static void do_render_fields_blur_3d(Render *re)
/* also check for camera here */
if (camera == NULL) {
BKE_report(re->reports, RPT_ERROR, "Cannot render, no camera");
- G.is_break = TRUE;
+ G.is_break = true;
return;
}
@@ -1567,6 +1602,8 @@ static void render_scene(Render *re, Scene *sce, int cfra)
resc->tbh = re->tbh;
resc->stats_draw = re->stats_draw;
resc->sdh = re->sdh;
+ resc->current_scene_update = re->current_scene_update;
+ resc->suh = re->suh;
do_render_fields_blur_3d(resc);
}
@@ -1578,7 +1615,7 @@ static int composite_needs_render(Scene *sce, int this_scene)
bNode *node;
if (ntree == NULL) return 1;
- if (sce->use_nodes == FALSE) return 1;
+ if (sce->use_nodes == false) return 1;
if ((sce->r.scemode & R_DOCOMP) == 0) return 1;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1940,7 +1977,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
ntreeCompositTagRender(re->scene);
ntreeCompositTagAnimated(ntree);
- ntreeCompositExecTree(re->scene, ntree, &re->r, TRUE, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
+ ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
}
/* ensure we get either composited result or the active layer */
@@ -2014,7 +2051,7 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)
bNode *node;
/* default start situation */
- G.is_break = FALSE;
+ G.is_break = false;
re->main = bmain;
re->scene = sce;
@@ -2136,7 +2173,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
if (re->r.scemode & R_FULL_SAMPLE)
do_merge_fullsample(re, ntree);
else {
- ntreeCompositExecTree(re->scene, ntree, &re->r, TRUE, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
+ ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
}
ntree->stats_draw = NULL;
@@ -2238,7 +2275,7 @@ static void do_render_seq(Render *re)
if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */
Editing *ed = re->scene->ed;
if (ed)
- BKE_sequencer_free_imbuf(re->scene, &ed->seqbase, TRUE);
+ BKE_sequencer_free_imbuf(re->scene, &ed->seqbase, true);
}
IMB_freeImBuf(ibuf);
}
@@ -2267,6 +2304,8 @@ static void do_render_seq(Render *re)
/* main loop: doing sequence + fields + blur + 3d render + compositing */
static void do_render_all_options(Render *re)
{
+ re->current_scene_update(re->suh, re->scene);
+
BKE_scene_camera_switch_update(re->scene);
re->i.starttime = PIL_check_seconds_timer();
@@ -2305,6 +2344,20 @@ static void do_render_all_options(Render *re)
}
}
+bool RE_force_single_renderlayer(Scene *scene)
+{
+ int scemode = check_mode_full_sample(&scene->r);
+ if (scemode & R_SINGLE_LAYER) {
+ SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+ /* force layer to be enabled */
+ if (srl->layflag & SCE_LAY_DISABLE) {
+ srl->layflag &= ~SCE_LAY_DISABLE;
+ return true;
+ }
+ }
+ return false;
+}
+
static bool check_valid_compositing_camera(Scene *scene, Object *camera_override)
{
if (scene->r.scemode & R_DOCOMP && scene->use_nodes) {
@@ -2366,24 +2419,24 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList
return true;
}
-static int node_tree_has_composite_output(bNodeTree *ntree)
+static bool node_tree_has_composite_output(bNodeTree *ntree)
{
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) {
- return TRUE;
+ return true;
}
else if (node->type == NODE_GROUP) {
if (node->id) {
if (node_tree_has_composite_output((bNodeTree *)node->id)) {
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
static int check_composite_output(Scene *scene)
@@ -2466,14 +2519,8 @@ bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *
}
#endif
}
-
- /* layer flag tests */
- if (scemode & R_SINGLE_LAYER) {
- srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
- /* force layer to be enabled */
- srl->layflag &= ~SCE_LAY_DISABLE;
- }
+ /* layer flag tests */
for (srl = scene->r.layers.first; srl; srl = srl->next)
if (!(srl->layflag & SCE_LAY_DISABLE))
break;
@@ -2598,10 +2645,11 @@ void RE_SetReports(Render *re, ReportList *reports)
}
/* general Blender frame render call */
-void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, Object *camera_override, unsigned int lay_override, int frame, const short write_still)
+void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, Object *camera_override,
+ unsigned int lay_override, int frame, const bool write_still)
{
/* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */
- G.is_rendering = TRUE;
+ G.is_rendering = true;
scene->r.cfra = frame;
@@ -2619,7 +2667,8 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
}
else {
char name[FILE_MAX];
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
/* reports only used for Movie */
do_write_image_or_movie(re, bmain, scene, NULL, name);
@@ -2632,7 +2681,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
/* UGLY WARNING */
- G.is_rendering = FALSE;
+ G.is_rendering = false;
}
#ifdef WITH_FREESTYLE
@@ -2667,7 +2716,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect");
ibuf->mall |= IB_rect;
RE_AcquiredResultGet32(re, &rres, ibuf->rect);
- do_free = TRUE;
+ do_free = true;
}
@@ -2691,7 +2740,8 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
if (name_override)
BLI_strncpy(name, name_override, sizeof(name));
else
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
if (re->result) {
@@ -2754,7 +2804,8 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
}
/* saves images to disk */
-void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay_override, int sfra, int efra, int tfra)
+void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override,
+ unsigned int lay_override, int sfra, int efra, int tfra)
{
bMovieHandle *mh = BKE_movie_handle_get(scene->r.im_format.imtype);
int cfrao = scene->r.cfra;
@@ -2766,7 +2817,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
/* is also set by caller renderwin.c */
- G.is_rendering = TRUE;
+ G.is_rendering = true;
re->flag |= R_ANIMATION;
@@ -2788,7 +2839,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
}
if (!mh->start_movie(scene, &re->r, width, height, re->reports))
- G.is_break = TRUE;
+ G.is_break = true;
}
if (mh->get_next_frame) {
@@ -2804,16 +2855,16 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (re->test_break(re->tbh) == 0) {
if (!do_write_image_or_movie(re, bmain, scene, mh, NULL))
- G.is_break = TRUE;
+ G.is_break = true;
}
- if (G.is_break == FALSE) {
+ if (G.is_break == false) {
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
}
}
else {
if (re->test_break(re->tbh)) {
- G.is_break = TRUE;
+ G.is_break = true;
}
}
}
@@ -2847,7 +2898,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* Touch/NoOverwrite options are only valid for image's */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if (scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
@@ -2872,12 +2924,12 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (re->test_break(re->tbh) == 0) {
if (!G.is_break)
if (!do_write_image_or_movie(re, bmain, scene, mh, NULL))
- G.is_break = TRUE;
+ G.is_break = true;
}
else
- G.is_break = TRUE;
+ G.is_break = true;
- if (G.is_break == TRUE) {
+ if (G.is_break == true) {
/* remove touched file */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) {
@@ -2888,7 +2940,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
break;
}
- if (G.is_break == FALSE) {
+ if (G.is_break == false) {
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
}
}
@@ -2908,7 +2960,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
/* UGLY WARNING */
- G.is_rendering = FALSE;
+ G.is_rendering = false;
}
void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
@@ -2940,10 +2992,11 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
/* note; repeated win/disprect calc... solve that nicer, also in compo */
/* only the temp file! */
-int RE_ReadRenderResult(Scene *scene, Scene *scenode)
+bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
{
Render *re;
- int winx, winy, success;
+ int winx, winy;
+ bool success;
rcti disprect;
/* calculate actual render result and display size */
@@ -3041,7 +3094,7 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, const c
const float default_envmap_layout[] = { 0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1 };
-int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, const char imtype, float layout[12])
+bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, const char imtype, float layout[12])
{
ImageFormatData imf;
ImBuf *ibuf = NULL;
@@ -3092,11 +3145,11 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
IMB_freeImBuf(ibuf);
if (ok) {
- return TRUE;
+ return true;
}
else {
BKE_report(reports, RPT_ERROR, "Error writing environment map");
- return FALSE;
+ return false;
}
}
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 66fd2209881..460a6814f07 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -35,14 +35,11 @@
#include <string.h>
/* global includes */
-#include "BLI_math.h"
-#include "BLI_rand.h"
/* own includes */
#include "render_types.h"
#include "renderpipeline.h"
#include "pixelblending.h"
-#include "gammaCorrectionTables.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index feaf68a8c4a..09a6a6374be 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -39,7 +39,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "DNA_camera_types.h"
#include "DNA_group_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
@@ -47,11 +46,7 @@
#include "DNA_texture_types.h"
#include "DNA_lamp_types.h"
-#include "BKE_colortools.h"
-#include "BKE_image.h"
-#include "BKE_global.h"
#include "BKE_material.h"
-#include "BKE_texture.h"
/* own module */
@@ -517,14 +512,14 @@ void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const
if (blend<0.0f) skyflag= 0;
- blend= fabs(blend);
+ blend = fabsf(blend);
}
else if (R.wrld.skytype & WO_SKYPAPER) {
blend= 0.5f + 0.5f * view[1];
}
else {
/* the fraction of how far we are above the bottom of the screen */
- blend= fabs(0.5f + view[1]);
+ blend = fabsf(0.5f + view[1]);
}
copy_v3_v3(hor, &R.wrld.horr);
@@ -567,7 +562,7 @@ void shadeSunView(float col_r[3], const float view[3])
GroupObject *go;
LampRen *lar;
float sview[3];
- int do_init = TRUE;
+ bool do_init = true;
for (go=R.lights.first; go; go= go->next) {
lar= go->lampren;
@@ -582,11 +577,11 @@ void shadeSunView(float col_r[3], const float view[3])
if (sview[2] < 0.0f)
sview[2] = 0.0f;
normalize_v3(sview);
- do_init = FALSE;
+ do_init = false;
}
GetSkyXYZRadiancef(lar->sunsky, sview, colorxyz);
- xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2],
+ xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2],
lar->sunsky->sky_colorspace);
ramp_blend(lar->sunsky->skyblendtype, col_r, lar->sunsky->skyblendfac, sun_collector);
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index ce87888b6a0..799f7fa2f2e 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -43,10 +43,8 @@
#include "BLF_translation.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
-#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
@@ -350,7 +348,7 @@ void free_pointdensities(Render *re)
typedef struct PointDensityRangeData {
float *density;
float squared_radius;
- float *point_data;
+ const float *point_data;
float *vec;
float softness;
short falloff_type;
@@ -503,7 +501,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
case TEX_PD_COLOR_PARTAGE:
if (pd->coba) {
if (do_colorband(pd->coba, age, col)) {
- texres->talpha = TRUE;
+ texres->talpha = true;
copy_v3_v3(&texres->tr, col);
texres->tin *= col[3];
texres->ta = texres->tin;
@@ -516,7 +514,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
if (pd->coba) {
if (do_colorband(pd->coba, speed, col)) {
- texres->talpha = TRUE;
+ texres->talpha = true;
copy_v3_v3(&texres->tr, col);
texres->tin *= col[3];
texres->ta = texres->tin;
@@ -525,7 +523,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
break;
}
case TEX_PD_COLOR_PARTVEL:
- texres->talpha = TRUE;
+ texres->talpha = true;
mul_v3_fl(vec, pd->speed_scale);
copy_v3_v3(&texres->tr, vec);
texres->ta = texres->tin;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 6807af0abc9..7e56d93f23b 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -41,15 +41,13 @@
#include "DNA_lamp_types.h"
#include "BLI_blenlib.h"
-#include "BLI_cpu.h"
-#include "BLI_jitter.h"
+#include "BLI_system.h"
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
-#include "BKE_global.h"
#include "BKE_node.h"
@@ -120,8 +118,6 @@ RayObject *RE_rayobject_create(int type, int size, int octree_resolution)
if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres
res = RE_rayobject_octree_create(octree_resolution, size);
- else if (type == R_RAYSTRUCTURE_BLIBVH)
- res = RE_rayobject_blibvh_create(size);
else if (type == R_RAYSTRUCTURE_VBVH)
res = RE_rayobject_vbvh_create(size);
else if (type == R_RAYSTRUCTURE_SIMD_SVBVH)
@@ -479,9 +475,9 @@ static void shade_ray_set_derivative(ShadeInput *shi)
t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
}
else {
- float *v1= shi->v1->co;
- float *v2= shi->v2->co;
- float *v3= shi->v3->co;
+ const float *v1= shi->v1->co;
+ const float *v2= shi->v2->co;
+ const float *v3= shi->v3->co;
/* same as above */
t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
@@ -563,6 +559,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
/* raytrace likes to separate the spec color */
sub_v3_v3v3(shr->diff, shr->combined, shr->spec);
+ copy_v3_v3(shr->diffshad, shr->diff);
}
}
@@ -749,7 +746,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
shi.lay= origshi->lay;
shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
shi.combinedflag= 0xFFFFFF; /* ray trace does all options */
- //shi.do_preview = FALSE; // memset above, so don't need this
+ //shi.do_preview = false; // memset above, so don't need this
shi.light_override= origshi->light_override;
shi.mat_override= origshi->mat_override;
@@ -1205,13 +1202,13 @@ static QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int t
for (qsa=re->qmcsamplers[thread].first; qsa; qsa=qsa->next) {
if (qsa->type == type && qsa->tot == tot && !qsa->used) {
- qsa->used = TRUE;
+ qsa->used = true;
return qsa;
}
}
qsa= QMC_initSampler(type, tot);
- qsa->used = TRUE;
+ qsa->used = true;
BLI_addtail(&re->qmcsamplers[thread], qsa);
return qsa;
@@ -1672,18 +1669,6 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
/* aolight: function to create random unit sphere vectors for total random sampling */
-static void RandomSpherical(RNG *rng, float v[3])
-{
- float r;
- v[2] = 2.f*BLI_rng_get_float(rng)-1.f;
- if ((r = 1.f - v[2]*v[2])>0.f) {
- float a = 6.283185307f*BLI_rng_get_float(rng);
- r = sqrt(r);
- v[0] = r * cosf(a);
- v[1] = r * sinf(a);
- }
- else v[2] = 1.f;
-}
/* calc distributed spherical energy */
static void DS_energy(float *sphere, int tot, float vec[3])
@@ -1729,7 +1714,7 @@ void init_ao_sphere(World *wrld)
/* init */
fp= wrld->aosphere;
for (a=0; a<tot; a++, fp+= 3) {
- RandomSpherical(rng, fp);
+ BLI_rng_get_float_unit_v3(rng, fp);
}
while (iter--) {
@@ -1780,7 +1765,7 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, in
vec= sphere;
for (a=0; a<tot; a++, vec+=3) {
- RandomSpherical(rng, vec);
+ BLI_rng_get_float_unit_v3(rng, vec);
}
BLI_rng_free(rng);
@@ -2168,7 +2153,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
float adapt_thresh = lar->adapt_thresh;
int min_adapt_samples=4, max_samples = lar->ray_totsamp;
float start[3];
- int do_soft = TRUE, full_osa = FALSE, i;
+ bool do_soft = true, full_osa = false;
+ int i;
float min[3], max[3];
RayHint bb_hint;
@@ -2183,8 +2169,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
else
shadfac[3]= 1.0f;
- if (lar->ray_totsamp < 2) do_soft = FALSE;
- if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = TRUE;
+ if (lar->ray_totsamp < 2) do_soft = false;
+ if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = true;
if (full_osa) {
if (do_soft) max_samples = max_samples/R.osa + 1;
@@ -2340,7 +2326,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3],
static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec)
{
/* area soft shadow */
- float *jitlamp;
+ const float *jitlamp;
float fac=0.0f, div=0.0f, vec[3];
int a, j= -1, mask;
RayHint point_hint;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index b174748a050..40de1080634 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -36,18 +36,18 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
#include "BLI_threads.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
-#include "BKE_freestyle.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -471,7 +471,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
if (savebuffers) {
- rr->do_exr_tile = TRUE;
+ rr->do_exr_tile = true;
}
/* check renderdata for amount of layers */
@@ -481,10 +481,14 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
if (strcmp(srl->name, layername) != 0)
continue;
- if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay)
- continue;
- if (srl->layflag & SCE_LAY_DISABLE)
- continue;
+ if (re->r.scemode & R_SINGLE_LAYER) {
+ if (nr != re->r.actlay)
+ continue;
+ }
+ else {
+ if (srl->layflag & SCE_LAY_DISABLE)
+ continue;
+ }
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
@@ -585,6 +589,8 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
/* duplicate code... */
if (rr->do_exr_tile) {
+ rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba");
+
rl->exrhandle = IMB_exr_get_handle();
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
@@ -664,7 +670,7 @@ static void ml_addpass_cb(void *UNUSED(base), void *lay, const char *str, float
}
/* from imbuf, if a handle was returned we convert this to render result */
-RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty)
+RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
{
RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
RenderLayer *rl;
@@ -771,12 +777,12 @@ static char *make_pass_name(RenderPass *rpass, int chan)
/* filename already made absolute */
/* called from within UI, saves both rendered result as a file-read result */
-int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
+bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
{
RenderLayer *rl;
RenderPass *rpass;
void *exrhandle = IMB_exr_get_handle();
- int success;
+ bool success;
BLI_make_existing_file(filename);
@@ -819,12 +825,12 @@ int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *file
/* when the filename has no permissions, this can fail */
if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
IMB_exr_write_channels(exrhandle);
- success = TRUE;
+ success = true;
}
else {
/* TODO, get the error from openexr's exception */
BKE_report(reports, RPT_ERROR, "Error writing render result (see console)");
- success = FALSE;
+ success = false;
}
IMB_exr_close(exrhandle);
@@ -868,7 +874,7 @@ void render_result_single_layer_end(Render *re)
BLI_remlink(&re->result->layers, rl);
/* reconstruct render result layers */
- for (nr = 0, srl = re->scene->r.layers.first; srl; srl = srl->next, nr++) {
+ for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
if (nr == re->r.actlay) {
BLI_addtail(&re->result->layers, rl);
}
@@ -1001,7 +1007,7 @@ void render_result_exr_file_end(Render *re)
rl->exrhandle = NULL;
}
- rr->do_exr_tile = FALSE;
+ rr->do_exr_tile = false;
}
render_result_free_list(&re->fullresult, re->result);
@@ -1023,10 +1029,13 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample,
char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
BLI_split_file_part(G.main->name, fi, sizeof(fi));
- if (sample == 0)
- BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
- else
- BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
+ if (sample == 0) {
+ BLI_snprintf(name, sizeof(name), "%s_%s_%s_%d.exr", fi, scene->id.name + 2, layname, abs(getpid()));
+ }
+ else {
+ BLI_snprintf(name, sizeof(name), "%s_%s_%s%d_%d.exr", fi, scene->id.name + 2, layname, sample,
+ abs(getpid()));
+ }
BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
}
@@ -1036,7 +1045,7 @@ int render_result_exr_file_read(Render *re, int sample)
{
RenderLayer *rl;
char str[FILE_MAX];
- int success = TRUE;
+ bool success = true;
RE_FreeRenderResult(re->result);
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
@@ -1048,7 +1057,7 @@ int render_result_exr_file_read(Render *re, int sample)
if (!render_result_exr_file_read_path(re->result, rl, str)) {
printf("cannot read: %s\n", str);
- success = FALSE;
+ success = false;
}
}
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 2718d2090cd..597f93a2659 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -33,7 +33,6 @@
#include <string.h>
#include <math.h>
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_noise.h"
#include "BLI_rand.h"
@@ -43,7 +42,6 @@
#include "DNA_texture_types.h"
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
#include "DNA_image_types.h"
@@ -53,7 +51,6 @@
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
-#include "BKE_colortools.h"
#include "BKE_image.h"
#include "BKE_node.h"
@@ -64,10 +61,7 @@
#include "BKE_material.h"
#include "BKE_scene.h"
-#include "BKE_library.h"
#include "BKE_texture.h"
-#include "BKE_key.h"
-#include "BKE_ipo.h"
#include "MEM_guardedalloc.h"
@@ -643,10 +637,10 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres)
{
int rv = TEX_INT;
float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */
- float aw1 = fabs(tex->vn_w1);
- float aw2 = fabs(tex->vn_w2);
- float aw3 = fabs(tex->vn_w3);
- float aw4 = fabs(tex->vn_w4);
+ float aw1 = fabsf(tex->vn_w1);
+ float aw2 = fabsf(tex->vn_w2);
+ float aw3 = fabsf(tex->vn_w3);
+ float aw4 = fabsf(tex->vn_w4);
float sc = (aw1 + aw2 + aw3 + aw4);
if (sc!=0.f) sc = tex->ns_outscale/sc;
@@ -751,9 +745,9 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1
}
mul_mat3_m4_v3(R.viewinv, nor);
- x1= fabs(nor[0]);
- y1= fabs(nor[1]);
- z1= fabs(nor[2]);
+ x1 = fabsf(nor[0]);
+ y1 = fabsf(nor[1]);
+ z1 = fabsf(nor[2]);
if (z1>=x1 && z1>=y1) {
*adr1 = (x + 1.0f) / 2.0f;
@@ -844,9 +838,9 @@ static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, f
copy_v3_v3(nor, n);
if (ob) mul_mat3_m4_v3(ob->imat, nor);
- x1= fabs(nor[0]);
- y1= fabs(nor[1]);
- z1= fabs(nor[2]);
+ x1 = fabsf(nor[0]);
+ y1 = fabsf(nor[1]);
+ z1 = fabsf(nor[2]);
if (z1>=x1 && z1>=y1) {
*adr1 = (x + 1.0f) / 2.0f;
@@ -1103,7 +1097,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
float tmpvec[3];
int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
- texres->talpha = FALSE; /* is set when image texture returns alpha (considered premul) */
+ texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
if (tex->use_nodes && tex->nodetree) {
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
@@ -1200,7 +1194,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
if (tex->flag & TEX_COLORBAND) {
float col[4];
if (do_colorband(tex->coba, texres->tin, col)) {
- texres->talpha = TRUE;
+ texres->talpha = true;
texres->tr= col[0];
texres->tg= col[1];
texres->tb= col[2];
@@ -1326,7 +1320,7 @@ int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct Image
{
int use_nodes= tex->use_nodes, retval;
- tex->use_nodes = FALSE;
+ tex->use_nodes = false;
retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage);
tex->use_nodes= use_nodes;
@@ -1420,12 +1414,9 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
fact*= facg;
facm= 1.0f-fact;
- col= tex[0]+((1-tex[0])*facm);
- if (col < out[0]) in[0]= col; else in[0]= out[0];
- col= tex[1]+((1-tex[1])*facm);
- if (col < out[1]) in[1]= col; else in[1]= out[1];
- col= tex[2]+((1-tex[2])*facm);
- if (col < out[2]) in[2]= col; else in[2]= out[2];
+ in[0] = min_ff(out[0], tex[0])*fact + out[0]*facm;
+ in[1] = min_ff(out[1], tex[1])*fact + out[1]*facm;
+ in[2] = min_ff(out[2], tex[2])*fact + out[2]*facm;
break;
case MTEX_LIGHT:
@@ -1522,8 +1513,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
break;
case MTEX_DARK:
- col= fact*tex;
- if (col < out) in= col; else in= out;
+ in = min_ff(out, tex)*fact + out*facm;
break;
case MTEX_LIGHT:
@@ -1642,7 +1632,7 @@ static void texco_mapping(ShadeInput *shi, Tex *tex, MTex *mtex,
typedef struct CompatibleBump {
float nu[3], nv[3], nn[3];
float dudnu, dudnv, dvdnu, dvdnv;
- int nunvdone;
+ bool nunvdone;
} CompatibleBump;
static void compatible_bump_init(CompatibleBump *compat_bump)
@@ -1679,11 +1669,11 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s
compat_bump->nn[1] = -shi->vn[1];
compat_bump->nn[2] = -shi->vn[2];
ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
- compat_bump->nunvdone = TRUE;
+ compat_bump->nunvdone = true;
}
if (tf) {
- float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
+ const float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])};
const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
@@ -1733,7 +1723,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
/* render normal is negated */
negate_v3_v3(compat_bump->nn, shi->vn);
ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
- compat_bump->nunvdone = TRUE;
+ compat_bump->nunvdone = true;
}
/* two methods, either constant based on main image resolution,
@@ -1916,7 +1906,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
ntap_bump->fPrevMagnitude = 1.0f;
ntap_bump->iPrevBumpSpace = 0;
- ntap_bump->init_done = TRUE;
+ ntap_bump->init_done = true;
}
/* resolve image dimensions */
@@ -2142,10 +2132,10 @@ void do_material_tex(ShadeInput *shi, Render *re)
float *co = NULL, *dx = NULL, *dy = NULL;
float fact, facm, factt, facmm, stencilTin=1.0;
float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
- int tex_nr, rgbnor= 0, warp_done = FALSE;
- int use_compat_bump = FALSE, use_ntap_bump = FALSE;
- int found_nmapping = 0, found_deriv_map = 0;
- int iFirstTimeNMap=1;
+ int tex_nr, rgbnor= 0;
+ bool warp_done = false, use_compat_bump = false, use_ntap_bump = false;
+ bool found_nmapping = false, found_deriv_map = false;
+ bool iFirstTimeNMap = true;
compatible_bump_init(&compat_bump);
ntap_bump_init(&ntap_bump);
@@ -2165,25 +2155,25 @@ void do_material_tex(ShadeInput *shi, Render *re)
if (tex == NULL) continue;
found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
- use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP);
- use_ntap_bump = ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? TRUE : FALSE;
+ use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP) != 0;
+ use_ntap_bump = ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? true : false;
/* XXX texture node trees don't work for this yet */
if (tex->nodetree && tex->use_nodes) {
- use_compat_bump = FALSE;
- use_ntap_bump = FALSE;
+ use_compat_bump = false;
+ use_ntap_bump = false;
}
/* case displacement mapping */
if (shi->osatex == 0 && use_ntap_bump) {
- use_ntap_bump = FALSE;
- use_compat_bump = TRUE;
+ use_ntap_bump = false;
+ use_compat_bump = true;
}
/* case ocean */
if (tex->type == TEX_OCEAN) {
- use_ntap_bump = FALSE;
- use_compat_bump = FALSE;
+ use_ntap_bump = false;
+ use_compat_bump = false;
}
/* which coords */
@@ -2321,7 +2311,7 @@ void do_material_tex(ShadeInput *shi, Render *re)
/* texture output */
- if ( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+ if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
texres.tin = rgb_to_grayscale(&texres.tr);
rgbnor -= TEX_RGB;
}
@@ -2381,7 +2371,7 @@ void do_material_tex(ShadeInput *shi, Render *re)
warpvec[0]= mtex->warpfac*warpnor[0];
warpvec[1]= mtex->warpfac*warpnor[1];
warpvec[2]= mtex->warpfac*warpnor[2];
- warp_done = TRUE;
+ warp_done = true;
}
#if 0
if (mtex->texflag & MTEX_VIEWSPACE) {
@@ -2476,8 +2466,8 @@ void do_material_tex(ShadeInput *shi, Render *re)
if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
/* qdn: tangent space */
float B[3], tv[3];
- const float * no = iFirstTimeNMap!=0 ? shi->nmapnorm : shi->vn;
- iFirstTimeNMap=0;
+ const float *no = iFirstTimeNMap ? shi->nmapnorm : shi->vn;
+ iFirstTimeNMap = false;
cross_v3_v3v3(B, no, shi->nmaptang); /* bitangent */
mul_v3_fl(B, shi->nmaptang[3]);
/* transform norvec from tangent space to object surface in camera space */
@@ -2759,7 +2749,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_
/* texture output */
- if ( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+ if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
texres.tin = rgb_to_grayscale(&texres.tr);
rgbnor -= TEX_RGB;
}
@@ -3713,7 +3703,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const
/* for every uv map set coords and name */
for (i=0; i<layers; i++) {
if (layer_index >= 0) {
- float *uv1, *uv2, *uv3;
+ const float *uv1, *uv2, *uv3;
float l;
CustomData *data = &orcoDm->faceData;
MTFace *tface = (MTFace *) data->layers[layer_index+i].data;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index c3ca3ee4559..27bc449dce3 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -41,28 +41,16 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_jitter.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-
-
#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_group_types.h"
-#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_image.h"
#include "BKE_main.h"
-#include "BKE_node.h"
-#include "BKE_texture.h"
-#include "BKE_scene.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -349,7 +337,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
float *pass;
float fac, col[4];
intptr_t *rd= pa->rectdaps;
- int *rz= pa->rectz;
+ const int *rz= pa->rectz;
int x, y, sample, totsample, fullsample, od;
totsample= get_sample_layers(pa, rl, rlpp);
@@ -699,7 +687,8 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
float col[4];
- int sample, done = FALSE;
+ int sample;
+ bool done = false;
for (sample= 0; sample<totsample; sample++) {
float *pass= rlpp[sample]->rectf + od;
@@ -708,7 +697,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
if (done==0) {
shadeSkyPixel(col, x, y, pa->thread);
- done = TRUE;
+ done = true;
}
if (pass[3]==0.0f) {
@@ -763,10 +752,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
int sample;
for (sample=0; sample<totsample; sample++) {
- float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od;
+ const float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od;
float *rgbrect = rlpp[sample]->rectf + 4*od;
float rgb[3] = {0};
- int done = FALSE;
+ bool done = false;
for (go=R.lights.first; go; go= go->next) {
@@ -798,7 +787,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
if (done==0) {
copy_v3_v3(rgb, tmp_rgb);
- done = TRUE;
+ done = true;
}
else {
rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0];
@@ -1157,10 +1146,10 @@ static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *da
ZbufSolidData *sdata = (ZbufSolidData *)data;
ListBase *lb= sdata->psmlist;
intptr_t *rd= pa->rectdaps;
- int *ro= zspan->recto;
- int *rp= zspan->rectp;
- int *rz= zspan->rectz;
- int *rm= zspan->rectmask;
+ const int *ro= zspan->recto;
+ const int *rp= zspan->rectp;
+ const int *rz= zspan->rectz;
+ const int *rm= zspan->rectmask;
int x, y;
int mask= 1<<sample;
@@ -1363,8 +1352,8 @@ void zbufshade_tile(RenderPart *pa)
rr->renlay= rl;
if (rl->layflag & SCE_LAY_SOLID) {
- float *fcol= rl->rectf;
- int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
+ const float *fcol= rl->rectf;
+ const int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
int x, y, offs=0, seed;
/* we set per pixel a fixed seed, for random AO and shadow samples */
@@ -1910,9 +1899,9 @@ static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
for (b=1; b<har->flarec; b++) {
- fla.r= fabs(rc[0]);
- fla.g= fabs(rc[1]);
- fla.b= fabs(rc[2]);
+ fla.r = fabsf(rc[0]);
+ fla.g = fabsf(rc[1]);
+ fla.b = fabsf(rc[2]);
fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]);
fla.hard= 20.0f + fabsf(70.0f*rc[7]);
fla.tex= 0;
@@ -1962,7 +1951,7 @@ void add_halo_flare(Render *re)
/* for now, we get the first renderlayer in list with halos set */
for (rl= rr->layers.first; rl; rl= rl->next) {
- int do_draw = FALSE;
+ bool do_draw = false;
if ((rl->layflag & SCE_LAY_HALO) == 0)
continue;
@@ -1978,7 +1967,7 @@ void add_halo_flare(Render *re)
har= R.sortedhalos[a];
if (har->flarec && (har->lay & rl->lay)) {
- do_draw = TRUE;
+ do_draw = true;
renderflare(rr, rl->rectf, har);
}
}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 9a1ee91d1f0..6a3787289d8 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -66,16 +66,12 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_memarena.h"
#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_texture_types.h"
#include "BKE_customdata.h"
-#include "BKE_texture.h"
#include "BKE_DerivedMesh.h"
#include "RE_render_ext.h" /* externtex */
@@ -1234,13 +1230,13 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
/* -------------------------- operations on entire database ----------------------- */
/* ugly function for halos in panorama */
-static int panotestclip(Render *re, int do_pano, float v[4])
+static int panotestclip(Render *re, bool do_pano, float v[4])
{
/* part size (ensure we run RE_parts_clamp first) */
BLI_assert(re->partx == min_ii(re->r.tilex, re->rectx));
BLI_assert(re->party == min_ii(re->r.tiley, re->recty));
- if (do_pano == FALSE) {
+ if (do_pano == false) {
return testclip(v);
}
else {
@@ -1278,7 +1274,7 @@ static int panotestclip(Render *re, int do_pano, float v[4])
void project_renderdata(Render *re,
void (*projectfunc)(const float *, float mat[4][4], float *),
- int do_pano, float xoffs, int UNUSED(do_buckets))
+ bool do_pano, float xoffs, bool UNUSED(do_buckets))
{
ObjectRen *obr;
HaloRen *har = NULL;
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 0c3bf85cd24..9d337e542a1 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -141,7 +141,7 @@ static float *give_jitter_tab(int samp)
if (ctab[samp]==0) {
ctab[samp]= 1;
- BLI_jitter_init(jit[offset], samp*samp);
+ BLI_jitter_init((float (*)[2])jit[offset], samp*samp);
}
return jit[offset];
@@ -660,7 +660,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar)
if (vlr->mat!= ma) {
ma= vlr->mat;
ok= 1;
- if ((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
}
if (ok && (obi->lay & lay)) {
@@ -925,7 +925,7 @@ void freeshadowbuf(LampRen *lar)
}
else {
intptr_t *ztile= shsample->zbuf;
- char *ctile= shsample->cbuf;
+ const char *ctile= shsample->cbuf;
v= (shb->size*shb->size)/256;
for (b=0; b<v; b++, ztile++, ctile++)
@@ -949,7 +949,7 @@ static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int
{
/* return a 1 if fully compressed shadbuf-tile && z==const */
int ofs;
- char *ct;
+ const char *ct;
if (shsample->deepbuf)
return 0;
@@ -1614,7 +1614,7 @@ static void isb_bsp_split(ISBBranch *root, MemArena *mem)
static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample)
{
ISBBranch *bspn= root;
- float *zco= sample->zco;
+ const float *zco= sample->zco;
int i= 0;
/* debug counter, also used to check if something was filled in ever */
@@ -1702,7 +1702,7 @@ static int point_behind_strand(const float p[3], BSPFace *face)
rc[0]= pt[0]-p[0];
rc[1]= pt[1]-p[1];
- dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
+ dist= sqrtf(rc[0]*rc[0]+ rc[1]*rc[1]);
if (dist < face->radline) {
float zval= face->vec1[2] + lambda*face->rc[2];
@@ -2013,7 +2013,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
if (vlr->mat!= ma) {
ma= vlr->mat;
ok= 1;
- if ((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
if (ma->material_type == MA_TYPE_WIRE) ok= 0;
zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
}
@@ -2120,7 +2120,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v
/* clip We can test for -1.0/1.0 because of the properties of the
* coordinate transformations. */
- fac= fabs(hoco[3]);
+ fac = fabsf(hoco[3]);
if (hoco[0]<-fac || hoco[0]>fac)
return 0;
if (hoco[1]<-fac || hoco[1]>fac)
@@ -2574,7 +2574,7 @@ float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
if (y >= 0 && y < isbdata->recty) {
if (isbdata->shadfacs) {
- short *sp= isbdata->shadfacs + y*isbdata->rectx + x;
+ const short *sp= isbdata->shadfacs + y*isbdata->rectx + x;
return *sp>=4096?0.0f:1.0f - ((float)*sp)/4096.0f;
}
else {
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index bc9ba348c62..7aca6b9ac87 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -34,16 +34,12 @@
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "DNA_curve_types.h"
-#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
-#include "BKE_colortools.h"
#include "BKE_scene.h"
#include "BKE_node.h"
@@ -118,8 +114,10 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
madd_v3_v3fl(shr->combined, shr_t.combined, fac);
if (shi->passflag & SCE_PASS_SPEC)
madd_v3_v3fl(shr->spec, shr_t.spec, fac);
- if (shi->passflag & SCE_PASS_DIFFUSE)
+ if (shi->passflag & SCE_PASS_DIFFUSE) {
madd_v3_v3fl(shr->diff, shr_t.diff, fac);
+ madd_v3_v3fl(shr->diffshad, shr_t.diffshad, fac);
+ }
if (shi->passflag & SCE_PASS_SHADOW)
madd_v3_v3fl(shr->shad, shr_t.shad, fac);
@@ -274,6 +272,7 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen
shi->osatex = (shi->mat->texco & TEXCO_OSA);
shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */
+ shi->mode2 = shi->mat->mode2_l;
/* facenormal copy, can get flipped */
shi->flippednor = 0;
@@ -393,7 +392,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
if (mode & MA_STR_SURFDIFF) {
- float *surfnor = RE_strandren_get_surfnor(obr, strand, 0);
+ const float *surfnor = RE_strandren_get_surfnor(obr, strand, 0);
if (surfnor)
copy_v3_v3(shi->surfnor, surfnor);
@@ -409,7 +408,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
if (R.r.mode & R_SPEED) {
- float *speed;
+ const float *speed;
speed = RE_strandren_get_winspeed(shi->obi, strand, 0);
if (speed)
@@ -448,7 +447,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE))) {
MCol *mcol;
- float *uv;
+ const float *uv;
char *name;
int i;
@@ -460,7 +459,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
for (i = 0; (mcol = RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) {
ShadeInputCol *scol = &shi->col[i];
- char *cp = (char *)mcol;
+ const char *cp = (char *)mcol;
shi->totcol++;
scol->name = name;
@@ -883,7 +882,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if (shi->vlr->flag & R_SMOOTH) {
if (shi->osatex && (texco & (TEXCO_NORM | TEXCO_REFL)) ) {
- float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3;
+ const float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3;
dl = shi->dx_u + shi->dx_v;
shi->dxno[0] = dl * n3[0] - shi->dx_u * n1[0] - shi->dx_v * n2[0];
@@ -899,7 +898,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
/* calc tangents */
if (mode & (MA_TANGENT_V | MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
- float *tangent, *s1, *s2, *s3;
+ const float *tangent, *s1, *s2, *s3;
float tl, tu, tv;
if (shi->vlr->flag & R_SMOOTH) {
@@ -971,7 +970,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
if (mode & MA_STR_SURFDIFF) {
- float *surfnor = RE_vlakren_get_surfnor(obr, shi->vlr, 0);
+ const float *surfnor = RE_vlakren_get_surfnor(obr, shi->vlr, 0);
if (surfnor) {
copy_v3_v3(shi->surfnor, surfnor);
@@ -985,7 +984,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
if (R.r.mode & R_SPEED) {
- float *s1, *s2, *s3;
+ const float *s1, *s2, *s3;
s1 = RE_vertren_get_winspeed(obi, v1, 0);
s2 = RE_vertren_get_winspeed(obi, v2, 0);
@@ -1010,7 +1009,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if (texco & TEXCO_ORCO) {
if (v1->orco) {
- float *o1, *o2, *o3;
+ const float *o1, *o2, *o3;
o1 = v1->orco;
o2 = v2->orco;
@@ -1074,7 +1073,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
for (i = 0; (mcol = RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
ShadeInputCol *scol = &shi->col[i];
- char *cp1, *cp2, *cp3;
+ const char *cp1, *cp2, *cp3;
float a[3];
shi->totcol++;
@@ -1254,7 +1253,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
if (texco & TEXCO_STRESS) {
- float *s1, *s2, *s3;
+ const float *s1, *s2, *s3;
s1 = RE_vertren_get_stress(obr, v1, 0);
s2 = RE_vertren_get_stress(obr, v2, 0);
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 6cb34a67f45..cc781c863a0 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -181,7 +181,8 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
double a, b, c, disc, nray[3], npos[3];
double t0, t1 = 0.0f, t2= 0.0f, t3;
float p1[3], p2[3], ladist, maxz = 0.0f, maxy = 0.0f, haint;
- int cuts, do_clip = TRUE, use_yco = FALSE;
+ int cuts;
+ bool do_clip = true, use_yco = false;
*intens= 0.0f;
haint= lar->haint;
@@ -217,7 +218,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
/* rotate maxz */
if (shi->co[2]==0.0f) {
- do_clip = FALSE; /* for when halo at sky */
+ do_clip = false; /* for when halo at sky */
}
else {
p1[0]= shi->co[0]-lar->co[0];
@@ -229,7 +230,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2];
if (fabs(nray[2]) < FLT_EPSILON) {
- use_yco = TRUE;
+ use_yco = true;
}
}
@@ -285,7 +286,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
if (ok1==0 && ok2==0) return;
/* intersction point with -ladist, the bottom of the cone */
- if (use_yco == FALSE) {
+ if (use_yco == false) {
t3= ((double)(-ladist)-npos[2])/nray[2];
/* de we have to replace one of the intersection points? */
@@ -319,7 +320,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
/* calculate t0: is the maximum visible z (when halo is intersected by face) */
if (do_clip) {
- if (use_yco == FALSE) t0 = ((double)maxz - npos[2]) / nray[2];
+ if (use_yco == false) t0 = ((double)maxz - npos[2]) / nray[2];
else t0 = ((double)maxy - npos[1]) / nray[1];
if (t0 < t1) return;
@@ -937,6 +938,8 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
shr->diff[2] *= obcol[2];
if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3];
}
+
+ copy_v3_v3(shr->diffshad, shr->diff);
}
/* ramp for at end of shade */
@@ -1874,9 +1877,11 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
}
if (shi->combinedflag & SCE_PASS_SHADOW)
- copy_v3_v3(shr->combined, shr->shad); /* note, no ';' ! */
+ copy_v3_v3(shr->diffshad, shr->shad); /* note, no ';' ! */
else
- copy_v3_v3(shr->combined, shr->diff);
+ copy_v3_v3(shr->diffshad, shr->diff);
+
+ copy_v3_v3(shr->combined, shr->diffshad);
/* calculate shadow pass, we use a multiplication mask */
/* if diff = 0,0,0 it doesn't matter what the shadow pass is, so leave it as is */
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 09169259461..52d3815c4ad 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -61,11 +61,8 @@
#include "DNA_material_types.h"
-#include "BKE_colortools.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_material.h"
-#include "BKE_node.h"
#include "BKE_scene.h"
@@ -934,7 +931,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
if (!re->test_break(re->tbh)) {
SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData");
float ior= mat->sss_ior, cfac= mat->sss_colfac;
- float *radius= mat->sss_radius;
+ const float *radius = mat->sss_radius;
float fw= mat->sss_front, bw= mat->sss_back;
float error = mat->sss_error;
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index f2d4a7afd94..50343cfaa0b 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -79,7 +79,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
{
Material *ma;
StrandBuffer *strandbuf;
- float *simplify;
+ const float *simplify;
float p[4][3], data[4], cross[3], w, dx, dy, t;
int type;
@@ -216,8 +216,10 @@ static void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float
}
if (addpassflag & SCE_PASS_EMIT)
interpolate_vec3(shr1->emit, shr2->emit, t, negt, shr->emit);
- if (addpassflag & SCE_PASS_DIFFUSE)
+ if (addpassflag & SCE_PASS_DIFFUSE) {
interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff);
+ interpolate_vec3(shr1->diffshad, shr2->diffshad, t, negt, shr->diffshad);
+ }
if (addpassflag & SCE_PASS_SPEC)
interpolate_vec3(shr1->spec, shr2->spec, t, negt, shr->spec);
if (addpassflag & SCE_PASS_SHADOW)
@@ -860,7 +862,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
/* test if we should skip it */
ma = obr->strandbuf->ma;
- if (shadow && !(ma->mode & MA_SHADBUF))
+ if (shadow && (!(ma->mode2 & MA_CASTSHADOW) || !(ma->mode & MA_SHADBUF)))
continue;
else if (!shadow && (ma->mode & MA_ONLYCAST))
continue;
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index e812b99287c..71ef5b8f62f 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -28,7 +28,6 @@
#include "sunsky.h"
#include "BLI_math.h"
-#include "BKE_global.h"
/**
* These macros are defined for vector operations
@@ -109,8 +108,8 @@ static float AngleBetween(float thetav, float phiv, float theta, float phi)
* */
static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
{
- *theta = acos(toSun[2]);
- if (fabs(*theta) < 1e-5)
+ *theta = acosf(toSun[2]);
+ if (fabsf(*theta) < 1e-5f)
*phi = 0;
else
*phi = atan2(toSun[1], toSun[0]);
diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c
index 0d68c40be0f..bfd155eba62 100644
--- a/source/blender/render/intern/source/texture_ocean.c
+++ b/source/blender/render/intern/source/texture_ocean.c
@@ -83,7 +83,7 @@ int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres)
const float u = 0.5f + 0.5f * texvec[0];
const float v = 0.5f + 0.5f * texvec[1];
- if (omd->oceancache && omd->cached == TRUE) {
+ if (omd->oceancache && omd->cached == true) {
CLAMP(cfra, omd->bakestart, omd->bakeend);
cfra -= omd->bakestart; /* shift to 0 based */
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 6cf83d0508f..6135a8761bb 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -60,7 +60,6 @@
#include "volumetric.h"
#include "volume_precache.h"
-#include "BKE_global.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@@ -290,7 +289,7 @@ BLI_INLINE int lc_to_ms_I(int x, int y, int z, int *n)
static float total_ss_energy(Render *re, int do_test_break, VolumePrecache *vp)
{
int x, y, z;
- int *res = vp->res;
+ const int *res = vp->res;
float energy=0.f;
for (z=0; z < res[2]; z++) {
@@ -600,7 +599,7 @@ static void precache_launch_parts(Render *re, RayObject *tree, ShadeInput *shi,
float voxel[3];
int sizex, sizey, sizez;
float bbmin[3], bbmax[3];
- int *res;
+ const int *res;
int minx, maxx;
int miny, maxy;
int minz, maxz;
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 05d0eff311f..fe3af5b840e 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -29,15 +29,11 @@
* \ingroup render
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_voxel.h"
@@ -50,7 +46,6 @@
#include "DNA_lamp_types.h"
#include "DNA_meta_types.h"
-#include "BKE_global.h"
#include "render_types.h"
#include "pixelshading.h"
@@ -661,7 +656,7 @@ static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co
static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume)
{
float hitco[3], col[4] = {0.f, 0.f, 0.f, 0.f};
- float *startco, *endco;
+ const float *startco, *endco;
int trace_behind = 1;
const int ztransp = ((shi->depth == 0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP));
Isect is;
@@ -748,6 +743,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in
shr->alpha = col[3];
copy_v3_v3(shr->diff, shr->combined);
+ copy_v3_v3(shr->diffshad, shr->diff);
}
/* Traces a shadow through the object,
@@ -757,7 +753,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct
float hitco[3];
float tr[3] = {1.0, 1.0, 1.0};
Isect is = {{0}};
- float *startco, *endco;
+ const float *startco, *endco;
memset(shr, 0, sizeof(ShadeResult));
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index ed9d12edc83..d81fbf900d1 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -70,7 +70,7 @@
#include "texture.h"
#include "voxeldata.h"
-static int is_vd_res_ok(VoxelData *vd)
+static bool is_vd_res_ok(VoxelData *vd)
{
/* arbitrary large value so corrupt headers don't break */
const int min = 1, max = 100000;
@@ -90,7 +90,7 @@ static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame)
const size_t size = vd_resol_size(vd);
size_t offset = sizeof(VoxelDataHeader);
- if (is_vd_res_ok(vd) == FALSE)
+ if (is_vd_res_ok(vd) == false)
return 0;
vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset");
@@ -112,7 +112,7 @@ static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame)
size_t i;
char *data_c;
- if (is_vd_res_ok(vd) == FALSE)
+ if (is_vd_res_ok(vd) == false)
return 0;
vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset");
@@ -154,7 +154,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
ImageUser *tiuser = &tex->iuser;
ImageUser iuser = *(tiuser);
int x = 0, y = 0, z = 0;
- float *rf;
+ const float *rf;
if (!ima) return;
if (iuser.frames == 0) return;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index a8ccd1f362f..28849ed7686 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -49,7 +49,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_lamp_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
@@ -61,7 +60,6 @@
#include "RE_render_ext.h"
/* local includes */
-#include "gammaCorrectionTables.h"
#include "pixelblending.h"
#include "render_result.h"
#include "render_types.h"
@@ -314,7 +312,7 @@ static void zbuffillAc4(ZSpan *zspan, int obi, int zvlnr,
double zxd, zyd, zy0, zverg;
float x0, y0, z0;
float x1, y1, z1, x2, y2, z2, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int *rz, *rm, x, y;
int sn1, sn2, rectx, *rectzofs, *rectmaskofs, my0, my2, mask;
@@ -437,7 +435,7 @@ static void zbuffillAc4(ZSpan *zspan, int obi, int zvlnr,
static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], const float vec2[3])
{
APixstr *ap, *apn;
- int *rectz, *rectmask;
+ const int *rectz, *rectmask;
int start, end, x, y, oldx, oldy, ofs;
int dz, vergz, mask, maxtest=0;
float dx, dy;
@@ -1054,10 +1052,10 @@ static void zbuffillGLinv4(ZSpan *zspan, int obi, int zvlnr,
double zxd, zyd, zy0, zverg;
float x0, y0, z0;
float x1, y1, z1, x2, y2, z2, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int *rectoofs, *ro;
int *rectpofs, *rp;
- int *rectmaskofs, *rm;
+ const int *rectmaskofs, *rm;
int *rz, x, y;
int sn1, sn2, rectx, *rectzofs, my0, my2;
@@ -1177,10 +1175,10 @@ static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr,
double zxd, zyd, zy0, zverg;
float x0, y0, z0;
float x1, y1, z1, x2, y2, z2, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int *rectoofs, *ro;
int *rectpofs, *rp;
- int *rectmaskofs, *rm;
+ const int *rectmaskofs, *rm;
int *rz, x, y;
int sn1, sn2, rectx, *rectzofs, my0, my2;
@@ -1308,7 +1306,7 @@ static void zbuffillGL_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr),
double zxd, zyd, zy0, zverg;
float x0, y0, z0;
float x1, y1, z1, x2, y2, z2, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int *rz, *rz1, x, y;
int sn1, sn2, rectx, *rectzofs, *rectzofs1= NULL, my0, my2;
@@ -1416,7 +1414,7 @@ void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2,
{
float x0, y0, x1, y1, x2, y2, z0, z1, z2, z;
float u, v, uxd, uyd, vxd, vyd, uy0, vy0, zxd, zyd, zy0, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2;
/* init */
@@ -1516,7 +1514,7 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
{
float x0, y0, x1, y1, x2, y2, z0, z1, z2;
float u, v, uxd, uyd, vxd, vyd, uy0, vy0, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2;
/* init */
@@ -1832,7 +1830,9 @@ void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4])
void zbuf_make_winmat(Render *re, float winmat[4][4])
{
if (re->r.mode & R_PANORAMA) {
- float panomat[4][4]= MAT4_UNITY;
+ float panomat[4][4];
+
+ unit_m4(panomat);
panomat[0][0]= re->panoco;
panomat[0][2]= re->panosi;
@@ -2368,7 +2368,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in
if (vlr->mat!= ma) {
ma= vlr->mat;
ok= 1;
- if ((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
}
if (ok && (obi->lay & lay) && !(vlr->flag & R_HIDDEN)) {
@@ -2421,7 +2421,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in
if (sseg.buffer->ma!= ma) {
ma= sseg.buffer->ma;
ok= 1;
- if ((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
}
if (ok && (sseg.buffer->lay & lay)) {
@@ -2659,7 +2659,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
/* ******************** VECBLUR ACCUM BUF ************************* */
typedef struct DrawBufPixel {
- float *colpoin;
+ const float *colpoin;
float alpha;
} DrawBufPixel;
@@ -2670,7 +2670,7 @@ static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float
double zxd, zyd, zy0, zverg;
float x0, y0, z0;
float x1, y1, z1, x2, y2, z2, xx1;
- float *span1, *span2;
+ const float *span1, *span2;
float *rectzofs, *rz;
int x, y;
int sn1, sn2, rectx, my0, my2;
@@ -3067,7 +3067,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
/* has to become static, the init-jit calls a random-seed, screwing up texture noise node */
if (firsttime) {
firsttime= 0;
- BLI_jitter_init(jit[0], 256);
+ BLI_jitter_init(jit, 256);
}
memset(newrect, 0, sizeof(float)*xsize*ysize*4);
@@ -3349,7 +3349,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *
if (vlr->mat!=ma) {
ma= vlr->mat;
if (shadow)
- dofill= (ma->mode & MA_SHADBUF);
+ dofill= (ma->mode2 & MA_CASTSHADOW) && (ma->mode & MA_SHADBUF);
else
dofill= (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST));
}
@@ -3616,7 +3616,7 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
for (samp= 1; samp<R.osa; samp++, shr_t++) {
if (shr_t->combined[3] > 0.0f) {
- float *speed= shr_t->winspeed;
+ const float *speed= shr_t->winspeed;
if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
fp[0]= speed[0];
@@ -3632,7 +3632,7 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
break;
}
if (col) {
- float *fp= col+delta;
+ const float *fp= col+delta;
int samp;
for (samp= 1; samp<R.osa; samp++, fp+=delta) {
@@ -4008,7 +4008,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
if (R.osa > 16) { /* MAX_OSA */
printf("zbuffer_transp_shade: osa too large\n");
- G.is_break = TRUE;
+ G.is_break = true;
return NULL;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 2e04a833f72..49e06e9dda4 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -65,6 +65,7 @@ struct wmDrag;
struct ImBuf;
struct ImageFormatData;
struct ARegion;
+struct wmNDOFMotionData;
typedef struct wmJob wmJob;
@@ -91,6 +92,7 @@ struct wmWindow *WM_window_open (struct bContext *C, const struct rcti *rect);
int WM_window_pixels_x (struct wmWindow *win);
int WM_window_pixels_y (struct wmWindow *win);
+bool WM_window_is_fullscreen (struct wmWindow *win);
/* defines for 'type' WM_window_open_temp */
#define WM_WINDOW_RENDER 0
@@ -250,6 +252,7 @@ void WM_operator_properties_free(struct PointerRNA *ptr);
void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, short action, short flag, short display);
void WM_operator_properties_border(struct wmOperatorType *ot);
void WM_operator_properties_border_to_rcti(struct wmOperator *op, struct rcti *rect);
+void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect);
void WM_operator_properties_gesture_border(struct wmOperatorType *ot, bool extend);
void WM_operator_properties_mouse_select(struct wmOperatorType *ot);
void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, int cursor);
@@ -376,6 +379,7 @@ enum {
WM_JOB_TYPE_OBJECT_SIM_OCEAN,
WM_JOB_TYPE_OBJECT_SIM_FLUID,
WM_JOB_TYPE_OBJECT_BAKE_TEXTURE,
+ WM_JOB_TYPE_OBJECT_BAKE,
WM_JOB_TYPE_FILESEL_THUMBNAIL,
WM_JOB_TYPE_CLIP_BUILD_PROXY,
WM_JOB_TYPE_CLIP_TRACK_MARKERS,
@@ -436,6 +440,12 @@ bool write_crash_blend(void);
/* Lock the interface for any communication */
void WM_set_locked_interface(struct wmWindowManager *wm, bool lock);
+void WM_event_ndof_pan_get(const struct wmNDOFMotionData *ndof, float r_pan[3], const bool use_zoom);
+void WM_event_ndof_rotate_get(const struct wmNDOFMotionData *ndof, float r_rot[3]);
+
+float WM_event_ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
+void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4]);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 8bbdd7bd736..e73d599a643 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -132,7 +132,7 @@ struct ImBuf;
#define OPTYPE_PRESET 32 /* show preset menu */
#define OPTYPE_INTERNAL 64 /* some operators are mainly for internal use
* and don't make sense to be accessed from the
- * search menu, even if poll() returns TRUE.
+ * search menu, even if poll() returns true.
* currently only used for the search toolbox */
#define OPTYPE_LOCK_BYPASS 128 /* Allow operator to run when interface is locked */
@@ -169,7 +169,7 @@ enum {
#define KM_OSKEY2 128
/* KM_MOD_ flags for wmKeyMapItem and wmEvent.alt/shift/oskey/ctrl */
-/* note that KM_ANY and FALSE are used with these defines too */
+/* note that KM_ANY and false are used with these defines too */
#define KM_MOD_FIRST 1
#define KM_MOD_SECOND 2
@@ -481,14 +481,8 @@ typedef struct wmNDOFMotionData {
/* awfully similar to GHOST_TEventNDOFMotionData... */
/* Each component normally ranges from -1 to +1, but can exceed that.
* These use blender standard view coordinates, with positive rotations being CCW about the axis. */
- union {
- float tvec[3]; /* translation */
- struct { float tx, ty, tz; };
- };
- union {
- float rvec[3]; /* rotation: */
- struct { float rx, ry, rz; };
- };
+ float tvec[3]; /* translation */
+ float rvec[3]; /* rotation: */
/* axis = (rx,ry,rz).normalized */
/* amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] */
float dt; /* time since previous NDOF Motion event */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 3c7a7676a63..28bddb47778 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -47,7 +47,6 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 01cd1514a3a..6fd3b426142 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -277,7 +277,7 @@ int wm_cursor_arrow_move(wmWindow *win, wmEvent *event)
void WM_cursor_time(wmWindow *win, int nr)
{
/* 10 8x8 digits */
- static char number_bitmaps[10][8] = {
+ const char number_bitmaps[10][8] = {
{0, 56, 68, 68, 68, 68, 68, 56},
{0, 24, 16, 16, 16, 16, 16, 56},
{0, 60, 66, 32, 16, 8, 4, 126},
@@ -300,7 +300,7 @@ void WM_cursor_time(wmWindow *win, int nr)
/* print number bottom right justified */
for (idx = 3; nr && idx >= 0; idx--) {
- char *digit = number_bitmaps[nr % 10];
+ const char *digit = number_bitmaps[nr % 10];
int x = idx % 2;
int y = idx / 2;
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 0919b9ae5d0..0a06f2e12dd 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -41,13 +41,8 @@
#include "BIF_glutil.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
-#include "BKE_idprop.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
#include "BKE_screen.h"
-#include "BKE_global.h"
#include "BLF_translation.h"
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 258db003d5b..ba4e2415dda 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -46,8 +46,6 @@
#include "BIF_glutil.h"
#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_screen.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -743,10 +741,10 @@ static bool wm_draw_update_test_window(wmWindow *win)
for (ar = win->screen->regionbase.first; ar; ar = ar->next) {
if (ar->do_draw_overlay) {
wm_tag_redraw_overlay(win, ar);
- ar->do_draw_overlay = FALSE;
+ ar->do_draw_overlay = false;
}
if (ar->swinid && ar->do_draw)
- do_draw = TRUE;
+ do_draw = true;
}
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
@@ -754,7 +752,7 @@ static bool wm_draw_update_test_window(wmWindow *win)
wm_region_test_render_do_draw(win->screen, sa, ar);
if (ar->swinid && ar->do_draw)
- do_draw = TRUE;
+ do_draw = true;
}
}
@@ -824,13 +822,13 @@ void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar)
if (ar && win) {
if (wm_automatic_draw_method(win) != USER_DRAW_TRIPLE)
ED_region_tag_redraw(ar);
- win->screen->do_draw_paintcursor = TRUE;
+ win->screen->do_draw_paintcursor = true;
}
}
void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *ar)
{
- win->screen->do_draw_paintcursor = TRUE;
+ win->screen->do_draw_paintcursor = true;
wm_tag_redraw_overlay(win, ar);
}
@@ -883,9 +881,9 @@ void wm_draw_update(bContext *C)
else // if (drawmethod == USER_DRAW_TRIPLE)
wm_method_draw_triple(C, win);
- win->screen->do_draw_gesture = FALSE;
- win->screen->do_draw_paintcursor = FALSE;
- win->screen->do_draw_drag = FALSE;
+ win->screen->do_draw_gesture = false;
+ win->screen->do_draw_paintcursor = false;
+ win->screen->do_draw_drag = false;
wm_window_swap_buffers(win);
@@ -921,7 +919,7 @@ void wm_draw_region_clear(wmWindow *win, ARegion *ar)
if (ELEM(drawmethod, USER_DRAW_OVERLAP, USER_DRAW_OVERLAP_FLIP))
wm_flush_regions_down(win->screen, &ar->winrct);
- win->screen->do_draw = TRUE;
+ win->screen->do_draw = true;
}
void WM_redraw_windows(bContext *C)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index a3d84f8c096..927e29d23e4 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -51,7 +51,6 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
@@ -64,7 +63,6 @@
#include "ED_fileselect.h"
#include "ED_info.h"
-#include "ED_render.h"
#include "ED_screen.h"
#include "ED_view3d.h"
#include "ED_util.h"
@@ -289,7 +287,7 @@ void wm_event_do_notifiers(bContext *C)
{
if (note->category == NC_SCENE) {
if (note->data == ND_FRAME)
- do_anim = TRUE;
+ do_anim = true;
}
}
if (ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) {
@@ -302,7 +300,7 @@ void wm_event_do_notifiers(bContext *C)
/* XXX, quick frame changes can cause a crash if framechange and rendering
* collide (happens on slow scenes), BKE_scene_update_for_newframe can be called
* twice which can depgraph update the same object at once */
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == false) {
/* depsgraph gets called, might send more notifiers */
ED_update_for_newframe(CTX_data_main(C), win->screen->scene, 1);
@@ -365,7 +363,7 @@ void wm_event_do_notifiers(bContext *C)
}
/* XXX make lock in future, or separated derivedmesh users in scene */
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == false) {
/* depsgraph & animation: update tagged datablocks */
Main *bmain = CTX_data_main(C);
@@ -490,7 +488,7 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot)
/* sets up the new context and calls 'wm_operator_invoke()' with poll_only */
int WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context)
{
- return wm_operator_call_internal(C, ot, NULL, NULL, context, TRUE);
+ return wm_operator_call_internal(C, ot, NULL, NULL, context, true);
}
static void wm_operator_print(bContext *C, wmOperator *op)
@@ -541,7 +539,7 @@ void WM_event_print(const wmEvent *event)
event->keymap_idname, (void *)event);
if (ISNDOF(event->type)) {
- const wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ const wmNDOFMotionData *ndof = event->customdata;
if (event->type == NDOF_MOTION) {
printf(" ndof: rot: (%.4f %.4f %.4f),\n"
" tx: (%.4f %.4f %.4f),\n"
@@ -612,10 +610,10 @@ void WM_reportf(const bContext *C, ReportType type, const char *format, ...)
BLI_dynstr_free(ds);
}
-/* (caller_owns_reports == TRUE) when called from python */
-static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int caller_owns_reports)
+/* (caller_owns_reports == true) when called from python */
+static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool caller_owns_reports)
{
- if (caller_owns_reports == FALSE) { /* popup */
+ if (caller_owns_reports == false) { /* popup */
if (op->reports->list.first) {
/* FIXME, temp setting window, see other call to uiPupMenuReports for why */
wmWindow *win_prev = CTX_wm_window(C);
@@ -639,7 +637,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int cal
wm_operator_print(C, op);
}
- if (caller_owns_reports == FALSE) {
+ if (caller_owns_reports == false) {
BKE_reports_print(op->reports, RPT_DEBUG); /* print out reports to console. */
}
@@ -727,7 +725,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
* Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason
* why this was needed, but worth to note it in case something turns bad. (mont29) */
if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)/* && repeat == 0 */)
- wm_operator_reports(C, op, retval, FALSE);
+ wm_operator_reports(C, op, retval, false);
if (retval & OPERATOR_FINISHED) {
if (store) {
@@ -789,7 +787,7 @@ int WM_operator_repeat(bContext *C, wmOperator *op)
{
return wm_operator_exec(C, op, true, true);
}
-/* TRUE if WM_operator_repeat can run
+/* true if WM_operator_repeat can run
* simple check for now but may become more involved.
* To be sure the operator can run call WM_operator_poll(C, op->type) also, since this call
* checks if WM_operator_repeat() can run at all, not that it WILL run at any time. */
@@ -986,14 +984,14 @@ bool WM_operator_last_properties_store(wmOperator *op)
#else
-int WM_operator_last_properties_init(wmOperator *UNUSED(op))
+bool WM_operator_last_properties_init(wmOperator *UNUSED(op))
{
- return FALSE;
+ return false;
}
-int WM_operator_last_properties_store(wmOperator *UNUSED(op))
+bool WM_operator_last_properties_store(wmOperator *UNUSED(op))
{
- return FALSE;
+ return false;
}
#endif
@@ -1076,7 +1074,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event,
*/
if (ot->flag & OPTYPE_BLOCKING || (op->opm && op->opm->type->flag & OPTYPE_BLOCKING)) {
int bounds[4] = {-1, -1, -1, -1};
- int wrap;
+ bool wrap;
if (op->opm) {
wrap = (U.uiflag & USER_CONTINUOUS_MOUSE) &&
@@ -1091,7 +1089,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event,
if (wrap) {
ARegion *ar = CTX_wm_region(C);
if (ar && ar->regiontype == RGN_TYPE_HEADER) {
- wrap = FALSE;
+ wrap = false;
}
}
@@ -1268,7 +1266,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, short context, Poin
{
wmOperatorType *ot = WM_operatortype_find(opstring, 0);
if (ot)
- return wm_operator_call_internal(C, ot, properties, NULL, context, FALSE);
+ return wm_operator_call_internal(C, ot, properties, NULL, context, false);
return 0;
}
@@ -1309,7 +1307,7 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context,
wmWindowManager *wm = CTX_wm_manager(C);
if (!is_undo && wm) wm->op_undo_depth++;
- retval = wm_operator_call_internal(C, ot, properties, reports, context, FALSE);
+ retval = wm_operator_call_internal(C, ot, properties, reports, context, false);
if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
@@ -1580,7 +1578,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
wm->op_undo_depth--;
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED))
- wm_operator_reports(C, op, retval, FALSE);
+ wm_operator_reports(C, op, retval, false);
/* important to run 'wm_operator_finished' before NULLing the context members */
if (retval & OPERATOR_FINISHED) {
@@ -1625,7 +1623,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (ot) {
if (wm_operator_check_locked_interface(C, ot)) {
- retval = wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
+ retval = wm_operator_invoke(C, ot, event, properties, NULL, false);
}
}
}
@@ -1645,19 +1643,14 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
return WM_HANDLER_BREAK;
}
-/* fileselect handlers are only in the window queue, so it's save to switch screens or area types */
-static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event)
+/* fileselect handlers are only in the window queue, so it's safe to switch screens or area types */
+static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHandler *handler, int val)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile;
int action = WM_HANDLER_CONTINUE;
-
- if (event->type != EVT_FILESELECT)
- return action;
- if (handler->op != (wmOperator *)event->customdata)
- return action;
-
- switch (event->val) {
+
+ switch (val) {
case EVT_FILESELECT_OPEN:
case EVT_FILESELECT_FULL_OPEN:
{
@@ -1673,7 +1666,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
sa = handler->op_area;
}
- if (event->val == EVT_FILESELECT_OPEN) {
+ if (val == EVT_FILESELECT_OPEN) {
ED_area_newspace(C, sa, SPACE_FILE); /* 'sa' is modified in-place */
}
else {
@@ -1704,7 +1697,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
/* remlink now, for load file case before removing*/
BLI_remlink(handlers, handler);
- if (event->val != EVT_FILESELECT_EXTERNAL_CANCEL) {
+ if (val != EVT_FILESELECT_EXTERNAL_CANCEL) {
if (screen != handler->filescreen) {
ED_screen_full_prevspace(C, CTX_wm_area(C));
}
@@ -1717,7 +1710,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
/* needed for uiPupMenuReports */
- if (event->val == EVT_FILESELECT_EXEC) {
+ if (val == EVT_FILESELECT_EXEC) {
int retval;
if (handler->op->type->flag & OPTYPE_UNDO)
@@ -1794,6 +1787,18 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
return action;
}
+static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event)
+{
+ int action = WM_HANDLER_CONTINUE;
+
+ if (event->type != EVT_FILESELECT)
+ return action;
+ if (handler->op != (wmOperator *)event->customdata)
+ return action;
+
+ return wm_handler_fileselect_do(C, handlers, handler, event->val);
+}
+
static bool handler_boundbox_test(wmEventHandler *handler, wmEvent *event)
{
if (handler->bbwin) {
@@ -2011,12 +2016,15 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
* wasn't handled, the KM_RELEASE will become a KM_CLICK */
if (win && event->val == KM_PRESS) {
- win->eventstate->check_click = TRUE;
+ win->eventstate->check_click = true;
}
if (win && win->eventstate->prevtype == event->type) {
- if (event->val == KM_RELEASE && win->eventstate->prevval == KM_PRESS && win->eventstate->check_click == TRUE) {
+ if ((event->val == KM_RELEASE) &&
+ (win->eventstate->prevval == KM_PRESS) &&
+ (win->eventstate->check_click == true))
+ {
event->val = KM_CLICK;
if (G.debug & (G_DEBUG_HANDLERS)) {
@@ -2135,10 +2143,10 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
}
if (event->type == MOUSEMOVE)
- win->screen->do_draw_drag = TRUE;
+ win->screen->do_draw_drag = true;
else if (event->type == ESCKEY) {
BLI_freelistN(&wm->drags);
- win->screen->do_draw_drag = TRUE;
+ win->screen->do_draw_drag = true;
}
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
event->type = EVT_DROP;
@@ -2154,7 +2162,7 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
event->customdatafree = 1;
/* clear drop icon */
- win->screen->do_draw_drag = TRUE;
+ win->screen->do_draw_drag = true;
/* restore cursor (disabled, see wm_dragdrop.c) */
// WM_cursor_modal_restore(win);
@@ -2163,7 +2171,7 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
/* overlap fails otherwise */
if (win->screen->do_draw_drag)
if (win->drawmethod == USER_DRAW_OVERLAP)
- win->screen->do_draw = TRUE;
+ win->screen->do_draw = true;
}
@@ -2268,7 +2276,7 @@ void wm_event_do_handlers(bContext *C)
wm_paintcursor_test(C, event);
}
else if (event->type == NDOF_MOTION) {
- win->addmousemove = TRUE;
+ win->addmousemove = true;
}
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
@@ -2405,10 +2413,25 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
handlernext = handler->next;
if (handler->type == WM_HANDLER_FILESELECT) {
- if (handler->op)
- WM_operator_free(handler->op);
- BLI_remlink(&win->modalhandlers, handler);
- wm_event_free_handler(handler);
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa;
+
+ /* find the area with the file selector for this handler */
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = sa->spacedata.first;
+
+ if (sfile->op == handler->op) {
+ CTX_wm_area_set(C, sa);
+ wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL);
+ break;
+ }
+ }
+ }
+
+ /* if not found we stop the handler without changing the screen */
+ if (!sa)
+ wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
}
}
@@ -2851,33 +2874,17 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
{
wmNDOFMotionData *data = MEM_mallocN(sizeof(wmNDOFMotionData), "customdata NDOF");
- const float s = U.ndof_sensitivity;
+ const float ts = U.ndof_sensitivity;
const float rs = U.ndof_orbit_sensitivity;
- data->tx = s * ghost->tx;
-
- data->rx = rs * ghost->rx;
- data->ry = rs * ghost->ry;
- data->rz = rs * ghost->rz;
+ mul_v3_v3fl(data->tvec, &ghost->tx, ts);
+ mul_v3_v3fl(data->rvec, &ghost->rx, rs);
- if (U.ndof_flag & NDOF_ZOOM_UPDOWN) {
- /* rotate so Y is where Z was */
- data->ty = s * ghost->tz;
- data->tz = s * ghost->ty;
- /* maintain handed-ness? or just do what feels right? */
-
- /* should this affect rotation also?
- * initial guess is 'yes', but get user feedback immediately!
- */
-#if 0
- /* after turning this on, my guess becomes 'no' */
- data->ry = s * ghost->rz;
- data->rz = s * ghost->ry;
-#endif
- }
- else {
- data->ty = s * ghost->ty;
- data->tz = s * ghost->tz;
+ if (U.ndof_flag & NDOF_PAN_YZ_SWAP_AXIS) {
+ float t;
+ t = data->tvec[1];
+ data->tvec[1] = -data->tvec[2];
+ data->tvec[2] = t;
}
data->dt = ghost->dt;
@@ -3166,22 +3173,22 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
case LEFTSHIFTKEY: case RIGHTSHIFTKEY:
evt->shift = (event.val == KM_PRESS) ?
((evt->ctrl || evt->alt || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- FALSE;
+ false;
break;
case LEFTCTRLKEY: case RIGHTCTRLKEY:
evt->ctrl = (event.val == KM_PRESS) ?
((evt->shift || evt->alt || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- FALSE;
+ false;
break;
case LEFTALTKEY: case RIGHTALTKEY:
evt->alt = (event.val == KM_PRESS) ?
((evt->ctrl || evt->shift || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- FALSE;
+ false;
break;
case OSKEY:
evt->oskey = (event.val == KM_PRESS) ?
((evt->ctrl || evt->alt || evt->shift) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- FALSE;
+ false;
break;
default:
if (event.val == KM_PRESS && event.keymodifier == 0)
@@ -3215,7 +3222,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
/* check other modifiers because ms-windows uses these to bring up the task manager */
(event.shift == 0 && event.ctrl == 0 && event.alt == 0))
{
- G.is_break = TRUE;
+ G.is_break = true;
}
/* double click test - only for press */
@@ -3331,3 +3338,49 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock)
*/
BKE_spacedata_draw_locks(lock);
}
+
+
+/* -------------------------------------------------------------------- */
+/* NDOF */
+
+/** \name NDOF Utility Functions
+ * \{ */
+
+
+void WM_event_ndof_pan_get(const wmNDOFMotionData *ndof, float r_pan[3], const bool use_zoom)
+{
+ int z_flag = use_zoom ? NDOF_ZOOM_INVERT : NDOF_PANZ_INVERT_AXIS;
+ r_pan[0] = ndof->tvec[0] * ((U.ndof_flag & NDOF_PANX_INVERT_AXIS) ? -1.0f : 1.0f);
+ r_pan[1] = ndof->tvec[1] * ((U.ndof_flag & NDOF_PANY_INVERT_AXIS) ? -1.0f : 1.0f);
+ r_pan[2] = ndof->tvec[2] * ((U.ndof_flag & z_flag) ? -1.0f : 1.0f);
+}
+
+void WM_event_ndof_rotate_get(const wmNDOFMotionData *ndof, float r_rot[3])
+{
+ r_rot[0] = ndof->rvec[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
+ r_rot[1] = ndof->rvec[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
+ r_rot[2] = ndof->rvec[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
+}
+
+float WM_event_ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3])
+{
+ float angle;
+ angle = normalize_v3_v3(axis, ndof->rvec);
+
+ axis[0] = axis[0] * ((U.ndof_flag & NDOF_ROTX_INVERT_AXIS) ? -1.0f : 1.0f);
+ axis[1] = axis[1] * ((U.ndof_flag & NDOF_ROTY_INVERT_AXIS) ? -1.0f : 1.0f);
+ axis[2] = axis[2] * ((U.ndof_flag & NDOF_ROTZ_INVERT_AXIS) ? -1.0f : 1.0f);
+
+ return ndof->dt * angle;
+}
+
+void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
+{
+ float axis[3];
+ float angle;
+
+ angle = WM_event_ndof_to_axis_angle(ndof, axis);
+ axis_angle_to_quat(q, axis, angle);
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 6440c197d51..c47896655f9 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -46,10 +46,7 @@
# endif
# include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff
* because 'near' is disabled through BLI_windstuff */
-# include <process.h> /* getpid */
# include "BLI_winstuff.h"
-#else
-# include <unistd.h> /* getpid */
#endif
#include "MEM_guardedalloc.h"
@@ -60,10 +57,11 @@
#include "BLI_utildefines.h"
#include "BLI_threads.h"
#include "BLI_callbacks.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
#include "BLF_translation.h"
-#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@@ -71,22 +69,17 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "BKE_utildefines.h"
#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_font.h"
#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_multires.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_sound.h"
#include "BKE_screen.h"
-#include "BKE_texture.h"
-
#include "BLO_readfile.h"
#include "BLO_writefile.h"
@@ -99,9 +92,7 @@
#include "ED_datafiles.h"
#include "ED_fileselect.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_view3d.h"
#include "ED_util.h"
@@ -294,14 +285,12 @@ static void wm_init_userdef(bContext *C, const bool from_memory)
sound_init(CTX_data_main(C));
/* needed so loading a file from the command line respects user-pref [#26156] */
- if (U.flag & USER_FILENOUI) G.fileflags |= G_FILE_NO_UI;
- else G.fileflags &= ~G_FILE_NO_UI;
+ BKE_BIT_TEST_SET(G.fileflags, U.flag & USER_FILENOUI, G_FILE_NO_UI);
/* set the python auto-execute setting from user prefs */
/* enabled by default, unless explicitly enabled in the command line which overrides */
if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) {
- if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) G.f |= G_SCRIPT_AUTOEXEC;
- else G.f &= ~G_SCRIPT_AUTOEXEC;
+ BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC);
}
/* avoid re-saving for every small change to our prefs, allow overrides */
@@ -352,7 +341,7 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
}
else {
#if 0 /* historic stuff - no longer used */
- WM_cursor_wait(TRUE);
+ WM_cursor_wait(true);
if (is_foo_format(name)) {
read_foo(name);
@@ -364,7 +353,7 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
retval = BKE_READ_EXOTIC_FAIL_FORMAT;
}
#if 0
- WM_cursor_wait(FALSE);
+ WM_cursor_wait(false);
#endif
}
}
@@ -413,7 +402,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
ListBase wmbase;
/* assume automated tasks with background, don't write recent file list */
- const bool do_history = (G.background == FALSE) && (CTX_wm_manager(C)->op_undo_depth == 0);
+ const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
/* put aside screens to match with persistent windows later */
/* also exit screens and editors */
@@ -460,7 +449,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
ED_editors_init(C);
- DAG_on_visible_update(CTX_data_main(C), TRUE);
+ DAG_on_visible_update(CTX_data_main(C), true);
#ifdef WITH_PYTHON
/* run any texts that were loaded in and flagged as modules */
@@ -536,7 +525,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
char prefstr[FILE_MAX];
int success = 0;
- /* Indicates whether user prefereneces were really load from memory.
+ /* Indicates whether user preferences were really load from memory.
*
* This is used for versioning code, and for this we can not rely on from_memory
* passed via argument. This is because there might be configuration folder
@@ -578,9 +567,6 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
}
}
- /* prevent loading no UI */
- G.fileflags &= ~G_FILE_NO_UI;
-
/* put aside screens to match with persistent windows later */
wm_window_match_init(C, &wmbase);
@@ -617,7 +603,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
/* check new prefs only after startup.blend was finished */
if (!from_memory && BLI_exists(prefstr)) {
int done = BKE_read_file_userdef(prefstr, NULL);
- if (done) {
+ if (done != BKE_READ_FILE_FAIL) {
read_userdef_from_memory = false;
printf("Read new prefs: %s\n", prefstr);
}
@@ -650,7 +636,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
BKE_write_undo(C, "original"); /* save current state */
ED_editors_init(C);
- DAG_on_visible_update(CTX_data_main(C), TRUE);
+ DAG_on_visible_update(CTX_data_main(C), true);
#ifdef WITH_PYTHON
if (CTX_py_init_get(C)) {
@@ -671,7 +657,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
CTX_wm_window_set(C, NULL); /* exits queues */
}
- return TRUE;
+ return true;
}
int wm_history_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
@@ -689,6 +675,12 @@ int wm_homefile_read_exec(bContext *C, wmOperator *op)
if (!from_memory) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
+
+ /* This can be used when loading of a start-up file should only change
+ * the scene content but keep the blender UI as it is. */
+ wm_open_init_load_ui(op, true);
+ BKE_BIT_TEST_SET(G.fileflags, !RNA_boolean_get(op->ptr, "load_ui"), G_FILE_NO_UI);
+
if (RNA_property_is_set(op->ptr, prop)) {
RNA_property_string_get(op->ptr, prop, filepath_buf);
filepath = filepath_buf;
@@ -707,7 +699,7 @@ void wm_read_history(void)
char name[FILE_MAX];
LinkNode *l, *lines;
struct RecentFile *recent;
- char *line;
+ const char *line;
int num;
const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
@@ -823,11 +815,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt)
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out);
+ IB_rect, OB_SOLID, false, false, R_ADDSKY, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, FALSE, R_ADDSKY, err_out);
+ IB_rect, false, R_ADDSKY, err_out);
}
if (ibuf) {
@@ -955,11 +947,8 @@ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *
G.save_over = 1; /* disable untitled.blend convention */
}
- if (fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS;
- else G.fileflags &= ~G_FILE_COMPRESS;
-
- if (fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY;
- else G.fileflags &= ~G_FILE_AUTOPLAY;
+ BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_COMPRESS, G_FILE_COMPRESS);
+ BKE_BIT_TEST_SET(G.fileflags, fileflags & G_FILE_AUTOPLAY, G_FILE_AUTOPLAY);
/* prevent background mode scripts from clobbering history */
if (!G.background) {
@@ -1156,3 +1145,39 @@ void wm_autosave_read(bContext *C, ReportList *reports)
WM_file_read(C, filename, reports);
}
+
+/** \name Initialize WM_OT_open_xxx properties
+ *
+ * Check if load_ui was set by the caller.
+ * Fall back to user preference when file flags not specified.
+ *
+ * \{ */
+
+void wm_open_init_load_ui(wmOperator *op, bool use_prefs)
+{
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ bool value = use_prefs ?
+ ((U.flag & USER_FILENOUI) == 0) :
+ ((G.fileflags & G_FILE_NO_UI) == 0);
+
+ RNA_property_boolean_set(op->ptr, prop, value);
+ }
+}
+
+void wm_open_init_use_scripts(wmOperator *op, bool use_prefs)
+{
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ /* use G_SCRIPT_AUTOEXEC rather than the userpref because this means if
+ * the flag has been disabled from the command line, then opening
+ * from the menu wont enable this setting. */
+ bool value = use_prefs ?
+ ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) :
+ ((G.f & G_SCRIPT_AUTOEXEC) != 0);
+
+ RNA_property_boolean_set(op->ptr, prop, value);
+ }
+}
+
+/** \} */
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 49c2f2221a9..bc3d0c7005c 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -75,7 +75,7 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
gesture->event_type = event->type;
gesture->swinid = ar->swinid; /* means only in area-region context! */
- wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
if (ELEM5(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK,
WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE))
@@ -272,7 +272,7 @@ static void draw_filled_lasso_px_cb(int x, int y, void *user_data)
static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
{
- short *lasso = (short *)gt->customdata;
+ const short *lasso = (short *)gt->customdata;
const int tot = gt->points;
int (*moves)[2] = MEM_mallocN(sizeof(*moves) * (tot + 1), __func__);
int i;
@@ -286,7 +286,7 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
BLI_lasso_boundbox(&rect, (const int (*)[2])moves, tot);
- wm_subwindow_getrect(win, gt->swinid, &rect_win);
+ wm_subwindow_rect_get(win, gt->swinid, &rect_win);
BLI_rcti_translate(&rect, rect_win.xmin, rect_win.ymin);
BLI_rcti_isect(&rect_win, &rect, &rect);
BLI_rcti_translate(&rect, -rect_win.xmin, -rect_win.ymin);
@@ -323,7 +323,7 @@ static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled)
{
- short *lasso = (short *)gt->customdata;
+ const short *lasso = (short *)gt->customdata;
int i;
if (filled) {
@@ -440,7 +440,7 @@ void wm_gesture_tag_redraw(bContext *C)
ARegion *ar = CTX_wm_region(C);
if (screen)
- screen->do_draw_gesture = TRUE;
+ screen->do_draw_gesture = true;
wm_tag_redraw_overlay(win, ar);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index c3b0729dfe5..3b1b170f371 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -39,12 +39,10 @@
#endif
#include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
@@ -59,10 +57,7 @@
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "BKE_curve.h"
-#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -71,7 +66,6 @@
#include "BKE_report.h"
#include "BKE_addon.h"
-#include "BKE_packedFile.h"
#include "BKE_sequencer.h" /* free seq clipboard */
#include "BKE_material.h" /* clear_matcopybuf */
#include "BKE_tracking.h" /* free tracking clipboard */
@@ -162,6 +156,9 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
BLF_lang_init();
+ /* Enforce loading the UI for the initial homefile */
+ G.fileflags &= ~G_FILE_NO_UI;
+
/* get the default database, plus a wm */
wm_homefile_read(C, NULL, G.factory_startup, NULL);
@@ -539,5 +536,5 @@ void WM_exit(bContext *C)
}
#endif
- exit(G.is_break == TRUE);
+ exit(G.is_break == true);
}
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 4cf5813d080..74c504050ae 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -40,13 +40,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
-#include "BKE_idprop.h"
#include "BKE_global.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -82,7 +77,7 @@
* - it puts timer to sleep (or removes?)
*
*/
-
+
struct wmJob {
struct wmJob *next, *prev;
@@ -230,13 +225,13 @@ bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
if (wm_job->owner == owner) {
if (job_type == WM_JOB_TYPE_ANY || (wm_job->job_type == job_type)) {
if (wm_job->running || wm_job->suspended) {
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
float WM_jobs_progress(wmWindowManager *wm, void *owner)
@@ -305,7 +300,7 @@ void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *
if (wm_job->running) {
/* signal job to end */
- wm_job->stop = TRUE;
+ wm_job->stop = true;
}
}
@@ -333,7 +328,7 @@ static void *do_job_thread(void *job_v)
wmJob *wm_job = job_v;
wm_job->startjob(wm_job->run_customdata, &wm_job->stop, &wm_job->do_update, &wm_job->progress);
- wm_job->ready = TRUE;
+ wm_job->ready = true;
return NULL;
}
@@ -342,11 +337,11 @@ static void *do_job_thread(void *job_v)
static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
{
wmJob *wm_job;
- int suspend = FALSE;
+ bool suspend = false;
/* job added with suspend flag, we wait 1 timer step before activating it */
if (test->flag & WM_JOB_SUSPEND) {
- suspend = TRUE;
+ suspend = true;
test->flag &= ~WM_JOB_SUSPEND;
}
else {
@@ -367,11 +362,11 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
if (0 == (wm_job->flag & WM_JOB_EXCL_RENDER))
continue;
- suspend = TRUE;
+ suspend = true;
/* if this job has higher priority, stop others */
if (test->flag & WM_JOB_PRIORITY) {
- wm_job->stop = TRUE;
+ wm_job->stop = true;
// printf("job stopped: %s\n", wm_job->name);
}
}
@@ -388,7 +383,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
{
if (wm_job->running) {
/* signal job to end and restart */
- wm_job->stop = TRUE;
+ wm_job->stop = true;
// printf("job started a running job, ending... %s\n", wm_job->name);
}
else {
@@ -397,19 +392,19 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
wm_jobs_test_suspend_stop(wm, wm_job);
- if (wm_job->suspended == FALSE) {
+ if (wm_job->suspended == false) {
/* copy to ensure proper free in end */
wm_job->run_customdata = wm_job->customdata;
wm_job->run_free = wm_job->free;
wm_job->free = NULL;
wm_job->customdata = NULL;
- wm_job->running = TRUE;
+ wm_job->running = true;
if (wm_job->initjob)
wm_job->initjob(wm_job->run_customdata);
- wm_job->stop = FALSE;
- wm_job->ready = FALSE;
+ wm_job->stop = false;
+ wm_job->ready = false;
wm_job->progress = 0.0;
// printf("job started: %s\n", wm_job->name);
@@ -444,7 +439,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
{
if (wm_job->running) {
/* signal job to end */
- wm_job->stop = TRUE;
+ wm_job->stop = true;
wm_job_main_thread_yield(wm_job, true);
BLI_end_threads(&wm_job->threads);
@@ -508,7 +503,7 @@ void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
if (wm_job->running) {
- wm_job->stop = TRUE;
+ wm_job->stop = true;
}
}
}
@@ -573,7 +568,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
if (wm_job->flag & WM_JOB_PROGRESS)
WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
- wm_job->do_update = FALSE;
+ wm_job->do_update = false;
}
if (wm_job->ready) {
@@ -593,7 +588,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
PIL_check_seconds_timer() - wm_job->start_time);
}
- wm_job->running = FALSE;
+ wm_job->running = false;
wm_job_main_thread_yield(wm_job, true);
BLI_end_threads(&wm_job->threads);
wm_job->main_thread_mutex_ending = false;
@@ -654,9 +649,9 @@ bool WM_jobs_has_running(wmWindowManager *wm)
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
if (wm_job->running) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 1c2b3713d2b..f1370146086 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -44,11 +44,9 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_screen.h"
@@ -401,10 +399,10 @@ static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modif
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_ANY;
}
else {
- kmi->shift = (modifier & KM_SHIFT) ? KM_MOD_FIRST : ((modifier & KM_SHIFT2) ? KM_MOD_SECOND : FALSE);
- kmi->ctrl = (modifier & KM_CTRL) ? KM_MOD_FIRST : ((modifier & KM_CTRL2) ? KM_MOD_SECOND : FALSE);
- kmi->alt = (modifier & KM_ALT) ? KM_MOD_FIRST : ((modifier & KM_ALT2) ? KM_MOD_SECOND : FALSE);
- kmi->oskey = (modifier & KM_OSKEY) ? KM_MOD_FIRST : ((modifier & KM_OSKEY2) ? KM_MOD_SECOND : FALSE);
+ kmi->shift = (modifier & KM_SHIFT) ? KM_MOD_FIRST : ((modifier & KM_SHIFT2) ? KM_MOD_SECOND : false);
+ kmi->ctrl = (modifier & KM_CTRL) ? KM_MOD_FIRST : ((modifier & KM_CTRL2) ? KM_MOD_SECOND : false);
+ kmi->alt = (modifier & KM_ALT) ? KM_MOD_FIRST : ((modifier & KM_ALT2) ? KM_MOD_SECOND : false);
+ kmi->oskey = (modifier & KM_OSKEY) ? KM_MOD_FIRST : ((modifier & KM_OSKEY2) ? KM_MOD_SECOND : false);
}
}
@@ -1041,7 +1039,7 @@ static wmKeyMapItem *wm_keymap_item_find(
wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, is_hotkey, keymap_r);
if (!found && properties) {
- wmOperatorType *ot = WM_operatortype_find(opname, TRUE);
+ wmOperatorType *ot = WM_operatortype_find(opname, true);
if (ot) {
/* make a copy of the properties and set any unset props
* to their default values, so the ID property compare function succeeds */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index eece2b78fa7..6ac26d2231f 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -87,7 +87,6 @@
#include "ED_screen.h"
#include "ED_util.h"
-#include "ED_object.h"
#include "ED_view3d.h"
#include "GHOST_C-api.h"
@@ -351,7 +350,7 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds);
+ WM_cursor_grab_enable(win, wrap, false, bounds);
}
}
}
@@ -375,7 +374,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
{
wmOperatorType *ot;
- if (WM_operatortype_find(idname, TRUE)) {
+ if (WM_operatortype_find(idname, true)) {
printf("%s: macro error: operator %s exists\n", __func__, idname);
return NULL;
}
@@ -508,7 +507,7 @@ bool WM_operatortype_remove(const char *idname)
/* SOME_OT_op -> some.op */
void WM_operator_py_idname(char *to, const char *from)
{
- char *sep = strstr(from, "_OT_");
+ const char *sep = strstr(from, "_OT_");
if (sep) {
int ofs = (sep - from);
@@ -530,7 +529,7 @@ void WM_operator_py_idname(char *to, const char *from)
void WM_operator_bl_idname(char *to, const char *from)
{
if (from) {
- char *sep = strchr(from, '.');
+ const char *sep = strchr(from, '.');
if (sep) {
int ofs = (sep - from);
@@ -687,7 +686,7 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert
*/
/* don't get from the context store since this is normally set only for the UI and not usable elsewhere */
- ListBase lb = CTX_data_dir_get_ex(C, FALSE, TRUE, TRUE);
+ ListBase lb = CTX_data_dir_get_ex(C, false, true, true);
LinkData *link;
const char *member_found = NULL;
@@ -954,7 +953,7 @@ bool WM_operator_properties_default(PointerRNA *ptr, const bool do_update)
break;
}
default:
- if ((do_update == false) || (RNA_property_is_set(ptr, prop) == FALSE)) {
+ if ((do_update == false) || (RNA_property_is_set(ptr, prop) == false)) {
if (RNA_property_reset(ptr, prop, -1)) {
changed = true;
}
@@ -1025,9 +1024,9 @@ void WM_operator_view3d_unit_defaults(struct bContext *C, struct wmOperator *op)
PropertySubType pstype = RNA_property_subtype(prop);
if (pstype == PROP_DISTANCE) {
/* we don't support arrays yet */
- BLI_assert(RNA_property_array_check(prop) == FALSE);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* initialize */
- if (!RNA_property_is_set_ex(op->ptr, prop, FALSE)) {
+ if (!RNA_property_is_set_ex(op->ptr, prop, false)) {
const float value = RNA_property_float_get_default(op->ptr, prop) * dia;
RNA_property_float_set(op->ptr, prop, value);
}
@@ -1089,10 +1088,10 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
#if 0 /* ok, this isn't so easy... */
- uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
#endif
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
- 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
+ 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
@@ -1104,7 +1103,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
- event.customdatafree = FALSE;
+ event.customdatafree = false;
wm_event_add(win, &event);
return block;
@@ -1172,9 +1171,9 @@ bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFor
RNA_property_string_set(op->ptr, prop, filepath);
/* note, we could check for and update 'filename' here,
* but so far nothing needs this. */
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* default properties for fileselect */
@@ -1239,7 +1238,7 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type,
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
if (flag & WM_FILESEL_RELPATH)
- RNA_def_boolean(ot->srna, "relative_path", TRUE, "Relative Path", "Select the file relative to the blend file");
+ RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file");
prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
@@ -1305,6 +1304,13 @@ void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
rect->ymax = RNA_int_get(op->ptr, "ymax");
}
+void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
+{
+ rcti rect_i;
+ WM_operator_properties_border_to_rcti(op, &rect_i);
+ BLI_rctf_rcti_copy(rect, &rect_i);
+}
+
void WM_operator_properties_gesture_border(wmOperatorType *ot, bool extend)
{
RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
@@ -1351,7 +1357,7 @@ int WM_operator_winactive(bContext *C)
return 1;
}
-/* return FALSE, if the UI should be disabled */
+/* return false, if the UI should be disabled */
bool WM_operator_check_ui_enabled(const bContext *C, const char *idname)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1420,11 +1426,10 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
if (op == WM_operator_last_redo(C))
if (!WM_operator_check_ui_enabled(C, op->type->name))
- uiLayoutSetEnabled(layout, FALSE);
+ uiLayoutSetEnabled(layout, false);
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
- uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
}
}
@@ -1454,7 +1459,7 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
WM_operator_call_ex(C, data->op, true);
/* let execute handle freeing it */
- //data->free_op = FALSE;
+ //data->free_op = false;
//data->op = NULL;
/* in this case, wm_operator_ui_popup_cancel wont run */
@@ -1504,7 +1509,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
uiLayout *col;
uiBut *btn;
- col = uiLayoutColumn(layout, FALSE);
+ col = uiLayoutColumn(layout, false);
col_block = uiLayoutGetBlock(col);
/* Create OK button, the callback of which will execute op */
btn = uiDefBut(col_block, BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
@@ -1576,7 +1581,7 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
data->op = op;
data->width = width;
data->height = height;
- data->free_op = TRUE; /* if this runs and gets registered we may want not to free it */
+ data->free_op = true; /* if this runs and gets registered we may want not to free it */
uiPupBlockEx(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
return OPERATOR_RUNNING_MODAL;
}
@@ -1594,6 +1599,14 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
return OPERATOR_CANCELLED;
}
+ if (do_redo) {
+ if ((op->type->flag & OPTYPE_UNDO) == 0) {
+ BKE_reportf(op->reports, RPT_ERROR,
+ "Operator '%s' does not have undo enabled, incorrect invoke function", op->type->idname);
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* if we don't have global undo, we can't do undo push for automatic redo,
* so we require manual OK clicking in this popup */
if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
@@ -1636,7 +1649,7 @@ int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int h
data->op = op;
data->width = width;
data->height = height;
- data->free_op = TRUE; /* if this runs and gets registered we may want not to free it */
+ data->free_op = true; /* if this runs and gets registered we may want not to free it */
/* op is not executed until popup OK but is clicked */
uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
@@ -1755,7 +1768,7 @@ static int wm_resource_check_prev(void)
// if (res) printf("LOCAL: %s\n", res);
if (res) {
- return FALSE;
+ return false;
}
else {
return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
@@ -1768,23 +1781,22 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBut *but;
uiLayout *layout, *split, *col;
uiStyle *style = UI_GetStyle();
- struct RecentFile *recent;
+ const struct RecentFile *recent;
int i;
- MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE);
+ MenuType *mt = WM_menutype_find("USERPREF_MT_splash", true);
char url[96];
- char file[FILE_MAX];
#ifndef WITH_HEADLESS
extern char datatoc_splash_png[];
extern int datatoc_splash_png_size;
- ImBuf *ibuf = IMB_ibImageFromMemory((unsigned char *)datatoc_splash_png,
- datatoc_splash_png_size, IB_rect, NULL, "<splash screen>");
+ extern char datatoc_splash_2x_png[];
+ extern int datatoc_splash_2x_png_size;
+ ImBuf *ibuf;
#else
ImBuf *ibuf = NULL;
#endif
-
#ifdef WITH_BUILDINFO
int label_delta = 0;
int hash_width, date_width;
@@ -1802,18 +1814,48 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
date_width = (int)BLF_width(style->widgetlabel.uifont_id, date_buf, sizeof(date_buf)) + U.widget_unit;
#endif /* WITH_BUILDINFO */
+#ifndef WITH_HEADLESS
+ if (U.pixelsize == 2) {
+ ibuf = IMB_ibImageFromMemory((unsigned char *)datatoc_splash_2x_png,
+ datatoc_splash_2x_png_size, IB_rect, NULL, "<splash screen>");
+ }
+ else {
+ ibuf = IMB_ibImageFromMemory((unsigned char *)datatoc_splash_png,
+ datatoc_splash_png_size, IB_rect, NULL, "<splash screen>");
+ }
+#endif
+
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
/* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized
* with the OS when the splash shows, window clipping in this case gives
* ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
-
+
/* XXX splash scales with pixelsize, should become widget-units */
but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
uiButSetFunc(but, wm_block_splash_close, block, NULL);
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
-
+
+ /* label for 'a' bugfix releases, or 'Release Candidate 1'...
+ * avoids recreating splash for version updates */
+ if (0) {
+ /* placed after the version number in the image,
+ * placing y is tricky to match baseline */
+ int x = 260 - (2 * UI_DPI_WINDOW_FAC);
+ int y = 242 + (4 * UI_DPI_WINDOW_FAC);
+ int w = 240;
+
+ const char *version_suffix = "Release Candidate";
+
+ /* hack to have text draw 'text_sel' */
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but = uiDefBut(block, LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ /* XXX, set internal flag - UI_SELECT */
+ uiButSetFlag(but, 1);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+
#ifdef WITH_BUILDINFO
if (build_commit_timestamp != 0) {
uiDefBut(block, LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -1847,9 +1889,11 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBlockSetEmboss(block, UI_EMBOSSP);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
- split = uiLayoutSplit(layout, 0.0f, FALSE);
- col = uiLayoutColumn(split, FALSE);
+ split = uiLayoutSplit(layout, 0.0f, false);
+ 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");
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",
@@ -1859,8 +1903,6 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
"http://wiki.blender.org/index.php/Doc:2.6/Manual");
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
- uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
- "http://www.blender.org/community/user-community");
if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
STRINGIFY(BLENDER_VERSION_CHAR) "_release",
@@ -1873,7 +1915,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemStringO(col, IFACE_("Python API Reference"), ICON_URL, "WM_OT_url_open", "url", url);
uiItemL(col, "", ICON_NONE);
- col = uiLayoutColumn(split, FALSE);
+ col = uiLayoutColumn(split, false);
if (wm_resource_check_prev()) {
uiItemO(col, NULL, ICON_NEW, "WM_OT_copy_prev_settings");
@@ -1882,11 +1924,10 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemL(col, IFACE_("Recent"), ICON_NONE);
for (recent = G.recent_files.first, i = 0; (i < 5) && (recent); recent = recent->next, i++) {
- BLI_split_file_part(recent->filepath, file, sizeof(file));
- if (BLO_has_bfile_extension(file))
- uiItemStringO(col, BLI_path_basename(recent->filepath), ICON_FILE_BLEND, "WM_OT_open_mainfile", "filepath", recent->filepath);
- else
- uiItemStringO(col, BLI_path_basename(recent->filepath), ICON_FILE_BACKUP, "WM_OT_open_mainfile", "filepath", recent->filepath);
+ const char *filename = BLI_path_basename(recent->filepath);
+ uiItemStringO(col, filename,
+ BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
+ "WM_OT_open_mainfile", "filepath", recent->filepath);
}
uiItemS(col);
@@ -1929,7 +1970,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
+ but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
uiOperatorSearch_But(but);
/* fake button, it holds space for search items */
@@ -1942,7 +1983,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
- event.customdatafree = FALSE;
+ event.customdatafree = false;
wm_event_add(win, &event);
return block;
@@ -2128,6 +2169,11 @@ static void WM_OT_read_homefile(wmOperatorType *ot)
"Path to an alternative start-up file");
RNA_def_property_flag(prop, PROP_HIDDEN);
+ /* So scripts can use an alternative start-up file without the UI */
+ prop = RNA_def_boolean(ot->srna, "load_ui", true, "Load UI",
+ "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 */
}
@@ -2170,30 +2216,6 @@ struct FileRuntime {
bool is_untrusted;
};
-
-static void open_set_load_ui(wmOperator *op, bool use_prefs)
-{
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, use_prefs ?
- (U.flag & USER_FILENOUI) == 0 :
- (G.fileflags & G_FILE_NO_UI) == 0);
- }
-}
-
-static void open_set_use_scripts(wmOperator *op, bool use_prefs)
-{
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
- if (!RNA_property_is_set(op->ptr, prop)) {
- /* use G_SCRIPT_AUTOEXEC rather than the userpref because this means if
- * the flag has been disabled from the command line, then opening
- * from the menu wont enable this setting. */
- RNA_property_boolean_set(op->ptr, prop, use_prefs ?
- (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0 :
- (G.f & G_SCRIPT_AUTOEXEC) != 0);
- }
-}
-
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
const char *openname = G.main->name;
@@ -2213,8 +2235,8 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
}
RNA_string_set(op->ptr, "filepath", openname);
- open_set_load_ui(op, true);
- open_set_use_scripts(op, true);
+ wm_open_init_load_ui(op, true);
+ wm_open_init_use_scripts(op, true);
op->customdata = NULL;
WM_event_add_fileselect(C, op);
@@ -2230,8 +2252,8 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", filepath);
/* re-use last loaded setting so we can reload a file without changing */
- open_set_load_ui(op, false);
- open_set_use_scripts(op, false);
+ wm_open_init_load_ui(op, false);
+ wm_open_init_use_scripts(op, false);
if (RNA_boolean_get(op->ptr, "load_ui"))
G.fileflags &= ~G_FILE_NO_UI;
@@ -2353,6 +2375,7 @@ static void WM_OT_revert_mainfile(wmOperatorType *ot)
ot->name = "Revert";
ot->idname = "WM_OT_revert_mainfile";
ot->description = "Reload the saved file";
+ ot->invoke = WM_operator_confirm;
ot->exec = wm_revert_mainfile_exec;
ot->poll = wm_revert_mainfile_poll;
@@ -2416,6 +2439,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Main *mainl = NULL;
BlendHandle *bh;
+ Library *lib;
PropertyRNA *prop;
char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[BLO_GROUP_MAX];
int idcode, totfiles = 0;
@@ -2490,6 +2514,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* here appending/linking starts */
mainl = BLO_library_append_begin(bmain, &bh, libname);
+ lib = mainl->curlib;
+ BLI_assert(lib);
+
if (totfiles == 0) {
BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
}
@@ -2509,9 +2536,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* append, rather than linking */
if ((flag & FILE_LINK) == 0) {
- Library *lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
- if (lib) BKE_library_make_local(bmain, lib, true);
- else BLI_assert(!"cant find name of just added library!");
+ BLI_assert(BLI_findindex(&bmain->library, lib) != -1);
+ BKE_library_make_local(bmain, lib, true);
}
/* important we unset, otherwise these object wont
@@ -2553,7 +2579,7 @@ static void WM_OT_link_append(wmOperatorType *ot)
/* better not save _any_ settings for this operator */
/* properties */
prop = RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer");
@@ -2599,6 +2625,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
ot->name = "Recover Last Session";
ot->idname = "WM_OT_recover_last_session";
ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")";
+ ot->invoke = WM_operator_confirm;
ot->exec = wm_recover_last_session_exec;
}
@@ -2744,9 +2771,9 @@ static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
* we keep getting nitpicking bug reports about this - campbell */
BLI_ensure_extension(filepath, FILE_MAX, ".blend");
RNA_string_set(op->ptr, "filepath", filepath);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
static void WM_OT_save_as_mainfile(wmOperatorType *ot)
@@ -3016,7 +3043,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
rect->xmin = rect->xmax = event->x - sx;
@@ -3048,7 +3075,6 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
wm_gesture_end(C, op);
return OPERATOR_CANCELLED;
- break;
case GESTURE_MODAL_CANCEL:
wm_gesture_end(C, op);
@@ -3118,7 +3144,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
rect->xmin = event->x - sx;
rect->ymin = event->y - sy;
@@ -3217,7 +3243,7 @@ static void tweak_gesture_modal(bContext *C, const wmEvent *event)
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
- wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
rect->xmax = event->x - sx;
rect->ymax = event->y - sy;
@@ -3326,7 +3352,7 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op)
PointerRNA itemptr;
float loc[2];
int i;
- short *lasso = gesture->customdata;
+ const short *lasso = gesture->customdata;
/* operator storage as path. */
@@ -3357,7 +3383,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
wm_gesture_tag_redraw(C);
- wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->points == gesture->size) {
short *old_lasso = gesture->customdata;
@@ -3540,7 +3566,7 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
int sx, sy;
if (event->type == MOUSEMOVE) {
- wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
+ wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->mode == 0) {
rect->xmin = rect->xmax = event->x - sx;
@@ -3569,7 +3595,6 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
}
wm_gesture_end(C, op);
return OPERATOR_CANCELLED;
- break;
case GESTURE_MODAL_CANCEL:
wm_gesture_end(C, op);
@@ -3608,7 +3633,10 @@ void WM_OT_straightline_gesture(wmOperatorType *ot)
/* *********************** radial control ****************** */
-static const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200;
+#define WM_RADIAL_CONTROL_DISPLAY_SIZE 200
+#define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE 35
+#define WM_RADIAL_CONTROL_DISPLAY_WIDTH (WM_RADIAL_CONTROL_DISPLAY_SIZE - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE)
+#define WM_RADIAL_MAX_STR 6
typedef struct {
PropertyType type;
@@ -3639,7 +3667,7 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e
d[0] = rc->initial_value;
break;
case PROP_FACTOR:
- d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - rc->initial_value);
+ 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);
@@ -3743,7 +3771,14 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
{
RadialControl *rc = (RadialControl*)customdata;
ARegion *ar = CTX_wm_region(C);
- float r1 = 0.0f, r2 = 0.0f, tex_radius, alpha;
+ uiStyle *style = UI_GetStyle();
+ const uiFontStyle *fstyle = &style->widget;
+ const int fontid = fstyle->uifont_id;
+ short fstyle_points = fstyle->points;
+ char str[WM_RADIAL_MAX_STR];
+ short strdrawlen = 0;
+ float strwidth, strheight;
+ float r1 = 0.0f, r2 = 0.0f, rmin = 0.0, tex_radius, alpha;
float zoom[2], col[4] = {1, 1, 1, 0.5f};
switch (rc->subtype) {
@@ -3756,13 +3791,19 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
alpha = 0.75;
break;
case PROP_FACTOR:
- r1 = (1 - rc->current_value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ r1 = (1 - rc->current_value) * WM_RADIAL_CONTROL_DISPLAY_WIDTH + WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE;
r2 = tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ rmin = WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE;
alpha = rc->current_value / 2.0f + 0.5f;
+ BLI_snprintf(str, WM_RADIAL_MAX_STR, "%1.2f", rc->current_value);
+ strdrawlen = BLI_strlen_utf8(str);
break;
case PROP_ANGLE:
r1 = r2 = tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE;
alpha = 0.75;
+ rmin = WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE;
+ BLI_snprintf(str, WM_RADIAL_MAX_STR, "%3f", RAD2DEGF(rc->current_value));
+ strdrawlen = BLI_strlen_utf8(str);
break;
default:
tex_radius = WM_RADIAL_CONTROL_DISPLAY_SIZE; /* note, this is a dummy value */
@@ -3809,14 +3850,13 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
gpuPushMatrix();
/* draw original angle line */
-
gpuRotateAxis(rc->initial_value, 'Z');
- gpuDrawLinef(0, 0, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
+ gpuDrawLinef((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
/* draw new angle line */
gpuRotateAxis(rc->current_value - rc->initial_value, 'Z');
- gpuDrawLinef(0, 0, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
+ gpuDrawLinef((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
gpuPopMatrix();
}
@@ -3824,9 +3864,24 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
/* draw circles on top */
gpuDrawCircle(0, 0, r1, 40);
gpuDrawCircle(0, 0, r2, 40);
+
+ if (rmin > 0.0f)
+ gpuDrawCircle(0, 0, rmin, 40);
gpuImmediateUnformat();
+ BLF_size(fontid, 1.5 * fstyle_points, 1.0f / U.dpi);
+ BLF_width_and_height(fontid, str, strdrawlen, &strwidth, &strheight);
+ BLF_enable(fontid, BLF_SHADOW);
+ BLF_shadow(fontid, 3, 0.0f, 0.0f, 0.0f, 0.5f);
+ BLF_shadow_offset(fontid, 1, -1);
+
+ /* draw value */
+ BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f);
+ BLF_draw(fontid, str, strdrawlen);
+
+ BLF_disable(fontid, BLF_SHADOW);
+
glDisable(GL_BLEND);
GPU_aspect_disable(GPU_ASPECT_RASTER, GPU_RASTER_AA);
@@ -4091,7 +4146,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
delta[1] /= zoom[1];
}
- dist = sqrt(delta[0] * delta[0] + delta[1] * delta[1]);
+ dist = len_v2(delta);
/* calculate new value and apply snapping */
switch (rc->subtype) {
@@ -4102,7 +4157,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
if (snap) new_value = ((int)new_value + 5) / 10 * 10;
break;
case PROP_FACTOR:
- new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH;
if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
break;
case PROP_ANGLE:
@@ -4633,15 +4688,15 @@ void wm_window_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_link_append", F1KEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "link", FALSE);
- RNA_boolean_set(kmi->ptr, "instance_groups", FALSE);
+ RNA_boolean_set(kmi->ptr, "link", false);
+ RNA_boolean_set(kmi->ptr, "instance_groups", false);
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_save_mainfile", WKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "copy", TRUE);
+ RNA_boolean_set(kmi->ptr, "copy", true);
WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "WM_OT_quit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
@@ -4750,57 +4805,57 @@ static EnumPropertyItem *rna_id_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(pt
/* can add more as needed */
EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, false);
}
#if 0 /* UNUSED */
EnumPropertyItem *RNA_action_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, true);
}
#endif
EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, false);
}
EnumPropertyItem *RNA_group_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, true);
}
EnumPropertyItem *RNA_image_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, false);
}
EnumPropertyItem *RNA_image_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, true);
}
EnumPropertyItem *RNA_scene_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, false);
}
EnumPropertyItem *RNA_scene_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, true);
}
EnumPropertyItem *RNA_movieclip_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, false);
}
EnumPropertyItem *RNA_movieclip_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, true);
}
EnumPropertyItem *RNA_mask_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, FALSE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, false);
}
EnumPropertyItem *RNA_mask_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
- return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, TRUE);
+ return rna_id_itemf(C, ptr, r_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, true);
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 329bb875860..69d15675d52 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -53,15 +53,12 @@
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
-#include "BLI_rect.h"
#include "BLI_string.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "BKE_blender.h"
#include "BKE_depsgraph.h"
-#include "BKE_global.h"
#include "BKE_image.h"
#include "GPU_colors.h"
@@ -96,14 +93,17 @@ typedef struct PlayState {
/* playback state */
short direction;
short next_frame;
- short once;
- short turbo;
- short pingpong;
- short noskip;
- short sstep;
- short wait2;
- short stopped;
- short go;
+
+ bool once;
+ bool turbo;
+ bool pingpong;
+ bool noskip;
+ bool sstep;
+ bool wait2;
+ bool stopped;
+ bool go;
+ /* waiting for images to load */
+ bool loading;
int fstep;
@@ -211,7 +211,7 @@ typedef struct PlayAnimPict {
struct PlayAnimPict *next, *prev;
char *mem;
int size;
- char *name;
+ const char *name;
struct ImBuf *ibuf;
struct anim *anim;
int frame;
@@ -219,7 +219,7 @@ typedef struct PlayAnimPict {
} PlayAnimPict;
static struct ListBase picsbase = {NULL, NULL};
-static int fromdisk = FALSE;
+static bool fromdisk = false;
static double ptottime = 0.0, swaptime = 0.04;
static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
@@ -317,7 +317,7 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
GHOST_SwapWindowBuffers(g_WS.ghost_window);
}
-static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid)
+static void build_pict_list_ex(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
{
char *mem, filepath[FILE_MAX];
// short val;
@@ -371,6 +371,7 @@ static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep
*/
while (IMB_ispic(filepath) && totframes) {
+ bool hasevent;
size_t size;
int file;
@@ -397,7 +398,7 @@ static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep
picture->size = size;
picture->IB_flags = IB_rect;
- if (fromdisk == FALSE) {
+ if (fromdisk == false) {
mem = (char *)MEM_mallocN(size, "build pic list");
if (mem == NULL) {
printf("Couldn't get memory\n");
@@ -445,21 +446,28 @@ static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep
BLI_newname(filepath, +fstep);
-#if 0 // XXX25
- while (qtest()) {
- switch (qreadN(&val)) {
- case ESCKEY:
- if (val) return;
- break;
+ while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0))) {
+ if (hasevent) {
+ GHOST_DispatchEvents(g_WS.ghost_system);
+ }
+ if (ps->loading == false) {
+ return;
}
}
-#endif
+
totframes--;
}
}
return;
}
+static void build_pict_list(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
+{
+ ps->loading = true;
+ build_pict_list_ex(ps, first, totframes, fstep, fontid);
+ ps->loading = false;
+}
+
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
{
PlayState *ps = (PlayState *)ps_void;
@@ -473,8 +481,34 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
/* convert ghost event into value keyboard or mouse */
val = ELEM(type, GHOST_kEventKeyDown, GHOST_kEventButtonDown);
+
+ /* first check if we're busy loading files */
+ if (ps->loading) {
+ switch (type) {
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp:
+ {
+ GHOST_TEventKeyData *key_data;
+
+ key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(evt);
+ switch (key_data->key) {
+ case GHOST_kKeyEsc:
+ ps->loading = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 1;
+ }
+
+
if (ps->wait2 && ps->stopped) {
- ps->stopped = FALSE;
+ ps->stopped = false;
}
if (ps->wait2) {
@@ -537,8 +571,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
case GHOST_kKeyLeftArrow:
if (val) {
- ps->sstep = TRUE;
- ps->wait2 = FALSE;
+ ps->sstep = true;
+ ps->wait2 = false;
if (g_WS.qual & WS_QUAL_SHIFT) {
ps->picture = picsbase.first;
ps->next_frame = 0;
@@ -550,20 +584,20 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
case GHOST_kKeyDownArrow:
if (val) {
- ps->wait2 = FALSE;
+ ps->wait2 = false;
if (g_WS.qual & WS_QUAL_SHIFT) {
ps->next_frame = ps->direction = -1;
}
else {
ps->next_frame = -10;
- ps->sstep = TRUE;
+ ps->sstep = true;
}
}
break;
case GHOST_kKeyRightArrow:
if (val) {
- ps->sstep = TRUE;
- ps->wait2 = FALSE;
+ ps->sstep = true;
+ ps->wait2 = false;
if (g_WS.qual & WS_QUAL_SHIFT) {
ps->picture = picsbase.last;
ps->next_frame = 0;
@@ -575,13 +609,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
case GHOST_kKeyUpArrow:
if (val) {
- ps->wait2 = FALSE;
+ ps->wait2 = false;
if (g_WS.qual & WS_QUAL_SHIFT) {
ps->next_frame = ps->direction = 1;
}
else {
ps->next_frame = 10;
- ps->sstep = TRUE;
+ ps->sstep = true;
}
}
break;
@@ -603,29 +637,29 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kKeyNumpad0:
if (val) {
if (ps->once) {
- ps->once = ps->wait2 = FALSE;
+ ps->once = ps->wait2 = false;
}
else {
ps->picture = NULL;
- ps->once = TRUE;
- ps->wait2 = FALSE;
+ ps->once = true;
+ ps->wait2 = false;
}
}
break;
case GHOST_kKeyEnter:
case GHOST_kKeyNumpadEnter:
if (val) {
- ps->wait2 = ps->sstep = FALSE;
+ ps->wait2 = ps->sstep = false;
}
break;
case GHOST_kKeyPeriod:
case GHOST_kKeyNumpadPeriod:
if (val) {
if (ps->sstep) {
- ps->wait2 = FALSE;
+ ps->wait2 = false;
}
else {
- ps->sstep = TRUE;
+ ps->sstep = true;
ps->wait2 = !ps->wait2;
}
}
@@ -655,7 +689,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
}
case GHOST_kKeyEsc:
- ps->go = FALSE;
+ ps->go = false;
break;
default:
break;
@@ -725,8 +759,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
if (ps->picture->next == NULL) break;
ps->picture = ps->picture->next;
}
- ps->sstep = TRUE;
- ps->wait2 = FALSE;
+ ps->sstep = true;
+ ps->wait2 = false;
ps->next_frame = 0;
}
break;
@@ -774,7 +808,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kEventQuit:
case GHOST_kEventWindowClose:
{
- ps->go = FALSE;
+ ps->go = false;
break;
}
case GHOST_kEventDraggingDropDone:
@@ -787,7 +821,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
for (a = 0; a < stra->count; a++) {
BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
- ps->go = FALSE;
+ ps->go = false;
printf("drop file %s\n", stra->strings[a]);
break; /* only one drop element supported now */
}
@@ -816,7 +850,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
/* could optionally start fullscreen */
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
- FALSE /* no stereo */, FALSE);
+ false /* no stereo */, false);
}
static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
@@ -854,21 +888,22 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
PlayState ps = {0};
- /* ps.doubleb = TRUE;*/ /* UNUSED */
- ps.go = TRUE;
- ps.direction = TRUE;
+ /* ps.doubleb = true;*/ /* UNUSED */
+ ps.go = true;
+ ps.direction = true;
ps.next_frame = 1;
- ps.once = FALSE;
- ps.turbo = FALSE;
- ps.pingpong = FALSE;
- ps.noskip = FALSE;
- ps.sstep = FALSE;
- ps.wait2 = FALSE;
- ps.stopped = FALSE;
+ ps.once = false;
+ ps.turbo = false;
+ ps.pingpong = false;
+ ps.noskip = false;
+ ps.sstep = false;
+ ps.wait2 = false;
+ ps.stopped = false;
+ ps.loading = false;
ps.picture = NULL;
ps.dropped_file[0] = 0;
ps.zoom = 1.0f;
- /* resetmap = FALSE */
+ /* resetmap = false */
ps.fstep = 1;
@@ -878,7 +913,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (argv[1][0] == '-') {
switch (argv[1][1]) {
case 'm':
- fromdisk = TRUE;
+ fromdisk = true;
break;
case 'p':
if (argc > 3) {
@@ -1052,7 +1087,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (ps.picture == NULL) {
printf("couldn't find pictures\n");
- ps.go = FALSE;
+ ps.go = false;
}
if (ps.pingpong) {
if (ps.direction == 1) {
@@ -1109,17 +1144,17 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (ps.once) {
if (ps.picture->next == NULL) {
- ps.wait2 = TRUE;
+ ps.wait2 = true;
}
else if (ps.picture->prev == NULL) {
- ps.wait2 = TRUE;
+ ps.wait2 = true;
}
}
ps.next_frame = ps.direction;
- while ( (hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2 != 0) {
+ while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2) {
if (hasevent) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
@@ -1133,15 +1168,15 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
}
}
- if (!ps.go) {
+ if (ps.go == false) {
break;
}
}
ps.wait2 = ps.sstep;
- if (ps.wait2 == 0 && ps.stopped == 0) {
- ps.stopped = TRUE;
+ if (ps.wait2 == false && ps.stopped == false) {
+ ps.stopped = true;
}
pupdate_time();
@@ -1153,10 +1188,10 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
if (ps.once && ps.picture != NULL) {
if (ps.picture->next == NULL) {
- ps.wait2 = TRUE;
+ ps.wait2 = true;
}
else if (ps.picture->prev == NULL) {
- ps.wait2 = TRUE;
+ ps.wait2 = true;
}
}
@@ -1167,7 +1202,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.picture = playanim_step(ps.picture, ps.next_frame);
}
}
- if (ps.go == FALSE) {
+ if (ps.go == false) {
break;
}
}
@@ -1235,7 +1270,7 @@ void WM_main_playanim(int argc, const char **argv)
bool looping = true;
while (looping) {
- char *filepath = wm_main_playanim_intern(argc, argv);
+ const char *filepath = wm_main_playanim_intern(argc, argv);
if (filepath) { /* use simple args */
argv[1] = "-a";
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index e3dcd86b305..86fd46ec0d2 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -46,9 +46,7 @@
#include "BLI_utildefines.h"
#include "BIF_glutil.h"
-
#include "BKE_context.h"
-#include "BKE_global.h"
#include "GPU_matrix.h"
#include "GPU_extensions.h"
@@ -97,7 +95,7 @@ void wm_subwindows_free(wmWindow *win)
}
-int wm_subwindow_get(wmWindow *win)
+int wm_subwindow_get_id(wmWindow *win)
{
if (win->curswin)
return win->curswin->swinid;
@@ -114,56 +112,91 @@ static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid)
return swin;
}
-void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y)
+
+static void wm_swin_size_get(wmSubWindow *swin, int *x, int *y)
+{
+ *x = BLI_rcti_size_x(&swin->winrct) + 1;
+ *y = BLI_rcti_size_y(&swin->winrct) + 1;
+}
+void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y)
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
if (swin) {
- *x = BLI_rcti_size_x(&swin->winrct) + 1;
- *y = BLI_rcti_size_y(&swin->winrct) + 1;
+ wm_swin_size_get(swin, x, y);
}
}
-void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y)
+
+static void wm_swin_origin_get(wmSubWindow *swin, int *x, int *y)
+{
+ *x = swin->winrct.xmin;
+ *y = swin->winrct.ymin;
+}
+void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y)
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
if (swin) {
- *x = swin->winrct.xmin;
- *y = swin->winrct.ymin;
+ wm_swin_origin_get(swin, x, y);
}
}
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4])
+
+static void wm_swin_matrix_get(wmWindow *win, wmSubWindow *swin, float mat[4][4])
+{
+ /* used by UI, should find a better way to get the matrix there */
+ if (swin->swinid == win->screen->mainwin) {
+ int width, height;
+
+ wm_swin_size_get(swin, &width, &height);
+ orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100);
+ }
+ else {
+ gpuGetMatrix(GL_PROJECTION_MATRIX, (float *)mat);
+ }
+}
+void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4])
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
if (swin) {
- /* used by UI, should find a better way to get the matrix there */
- if (swinid == win->screen->mainwin) {
- int width, height;
+ wm_swin_matrix_get(win, swin, mat);
+ }
+}
- wm_subwindow_getsize(win, swin->swinid, &width, &height);
- orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100);
- }
- else {
- gpuGetMatrix(GL_PROJECTION_MATRIX, (float *)mat);
- }
+
+static void wm_swin_rect_get(wmSubWindow *swin, rcti *r_rect)
+{
+ *r_rect = swin->winrct;
+}
+void wm_subwindow_rect_get(wmWindow *win, int swinid, rcti *r_rect)
+{
+ wmSubWindow *swin = swin_from_swinid(win, swinid);
+
+ if (swin) {
+ wm_swin_rect_get(swin, r_rect);
}
}
-void wm_subwindow_getrect(wmWindow *win, int swinid, rcti *r_rect)
+
+static void wm_swin_rect_set(wmSubWindow *swin, const rcti *rect)
+{
+ swin->winrct = *rect;
+}
+void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect)
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
if (swin) {
- *r_rect = swin->winrct;
+ wm_swin_rect_set(swin, rect);
}
}
+
/* always sets pixel-precise 2D window/view matrices */
/* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */
-int wm_subwindow_open(wmWindow *win, rcti *winrct)
+int wm_subwindow_open(wmWindow *win, const rcti *winrct)
{
wmSubWindow *swin;
int width, height;
@@ -183,7 +216,7 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct)
wmSubWindowSet(win, swin->swinid);
/* extra service */
- wm_subwindow_getsize(win, swin->swinid, &width, &height);
+ wm_swin_size_get(swin, &width, &height);
wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS);
gpuLoadIdentity();
@@ -208,7 +241,7 @@ void wm_subwindow_close(wmWindow *win, int swinid)
}
/* pixels go from 0-99 for a 100 pixel window */
-void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
+void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct)
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
@@ -240,7 +273,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
/* extra service */
wmSubWindowSet(win, swinid);
- wm_subwindow_getsize(win, swinid, &width, &height);
+ wm_swin_size_get(swin, &width, &height);
wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS);
}
else {
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 5db40e0e9b1..0c4b1e592f4 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -255,8 +255,8 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
BLI_strncpy(win->screenname, win->screen->id.name + 2, sizeof(win->screenname));
win->screen->winid = win->winid;
- win->screen->do_refresh = TRUE;
- win->screen->do_draw = TRUE;
+ win->screen->do_refresh = true;
+ win->screen->do_draw = true;
win->drawmethod = U.wmdrawmethod;
win->drawdata = NULL;
@@ -373,9 +373,21 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
if (win->eventstate == NULL)
win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
- /* set the state */
+#ifdef __APPLE__
+ /* set the state here, else OSX would not recognize changed screen resolution */
+ /* we agreed to not set any fullscreen or iconized state on startup */
+ GHOST_SetWindowState(ghostwin, GHOST_kWindowStateNormal);
+#endif
+ /* store actual window size in blender window */
+ bounds = GHOST_GetClientBounds(win->ghostwin);
+ win->sizex = GHOST_GetWidthRectangle(bounds);
+ win->sizey = GHOST_GetHeightRectangle(bounds);
+ GHOST_DisposeRectangle(bounds);
+
+#ifndef __APPLE__
+ /* set the state here, so minimized state comes up correct on windows */
GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
-
+#endif
/* until screens get drawn, make it nice gray */
glClearColor(0.55, 0.55, 0.55, 0.0);
/* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */
@@ -388,12 +400,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
BKE_userdef_state();
- /* store actual window size in blender window */
- bounds = GHOST_GetClientBounds(win->ghostwin);
- win->sizex = GHOST_GetWidthRectangle(bounds);
- win->sizey = GHOST_GetHeightRectangle(bounds);
- GHOST_DisposeRectangle(bounds);
-
wm_window_swap_buffers(win);
//GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
@@ -825,7 +831,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
/* stop screencast if resize */
if (type == GHOST_kEventWindowSize) {
- WM_jobs_stop(CTX_wm_manager(C), win->screen, NULL);
+ WM_jobs_stop(wm, win->screen, NULL);
}
/* win32: gives undefined window size when minimized */
@@ -912,7 +918,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
{
PointerRNA props_ptr;
wmWindow *oldWindow;
- char *path = GHOST_GetEventData(evt);
+ const char *path = GHOST_GetEventData(evt);
if (path) {
/* operator needs a valid window in context, ensures
@@ -1440,3 +1446,9 @@ int WM_window_pixels_y(wmWindow *win)
return (int)(f * (float)win->sizey);
}
+
+bool WM_window_is_fullscreen(wmWindow *win)
+{
+ return win->windowstate == GHOST_kWindowStateFullScreen;
+}
+
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index beb7cac24a5..22e38b9b704 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -76,6 +76,10 @@ void wm_autosave_delete(void);
void wm_autosave_read(struct bContext *C, struct ReportList *reports);
void wm_autosave_location(char *filepath);
+/* init operator properties */
+void wm_open_init_load_ui(wmOperator *op, bool use_prefs);
+void wm_open_init_use_scripts(wmOperator *op, bool use_prefs);
+
/* hack to store circle select size - campbell, must replace with nice operator memory */
#define GESTURE_MEMORY
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index b7c1cfa5654..4a274d25170 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -312,8 +312,8 @@ enum {
#define ISHOTKEY(event_type) \
((ISKEYBOARD(event_type) || ISMOUSE(event_type) || ISNDOF(event_type)) && \
(event_type != ESCKEY) && \
- (event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == FALSE && \
- (event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == FALSE)
+ (event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == false && \
+ (event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == false)
/* **************** BLENDER GESTURE EVENTS (0x5000) **************** */
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index a70e7765ecf..bf7b99433c6 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -36,16 +36,17 @@
/* *************** internal api ************** */
void wm_subwindows_free(wmWindow *win);
-int wm_subwindow_open(wmWindow *win, rcti *winrct);
+int wm_subwindow_open(wmWindow *win, const rcti *winrct);
void wm_subwindow_close(wmWindow *win, int swinid);
-int wm_subwindow_get(wmWindow *win); /* returns id */
+int wm_subwindow_get_id(wmWindow *win); /* returns id */
-void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
+void wm_subwindow_position(wmWindow *win, int swinid, const rcti *winrct);
-void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]);
-void wm_subwindow_getrect(wmWindow *win, int swinid, struct rcti *r_rect);
+void wm_subwindow_size_get(wmWindow *win, int swinid, int *x, int *y);
+void wm_subwindow_origin_get(wmWindow *win, int swinid, int *x, int *y);
+void wm_subwindow_matrix_get(wmWindow *win, int swinid, float mat[4][4]);
+void wm_subwindow_rect_get(wmWindow *win, int swinid, struct rcti *r_rect);
+void wm_subwindow_rect_set(wmWindow *win, int swinid, const rcti *rect);
unsigned int index_to_framebuffer(int index);
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 4c345a0e782..a5dc984c3ef 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -175,11 +175,6 @@ endif()
list(APPEND BLENDER_SORTED_LIBS extern_colamd)
if(WITH_MOD_BOOLEAN)
- list(APPEND BLENDER_SORTED_LIBS bf_intern_bsp)
- list(APPEND BLENDER_SORTED_LIBS bf_intern_moto)
- endif()
-
- if(WITH_MOD_BOOLEAN)
list(APPEND BLENDER_SORTED_LIBS extern_carve)
endif()
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index fd768f5a400..af6541e9008 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -226,6 +226,9 @@ void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize,
/* imagetexture.c stub */
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) RET_NONE
+/* Freestyle */
+bool ED_texture_context_check_linestyle(const struct bContext *C) RET_ZERO
+
/* 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
int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage) RET_ZERO
@@ -236,9 +239,6 @@ void RE_free_sample_material(struct Material *mat) RET_NONE
void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob) RET_NONE
-/* skin modifier*/
-void modifier_skin_customdata_ensure(struct Object *ob) RET_NONE
-
/* nodes */
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
@@ -246,7 +246,7 @@ float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float co
/* blenkernel */
void RE_FreeRenderResult(struct RenderResult *res) RET_NONE
void RE_FreeAllRenderResults(void) RET_NONE
-struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty) RET_NULL
+struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty) RET_NULL
struct Scene *RE_GetScene(struct Render *re) RET_NULL
void RE_Database_Free(struct Render *re) RET_NONE
void RE_FreeRender(struct Render *re) RET_NONE
@@ -258,8 +258,8 @@ const unsigned char stipple_quarttone[128];
double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) RET_ZERO
struct Render *RE_NewRender(const char *name) RET_NULL
void RE_SwapResult(struct Render *re, struct RenderResult **rr) RET_NONE
-void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay_override, int frame, const short write_still) RET_NONE
-int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]) RET_ZERO
+void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay_override, int frame, const bool write_still) RET_NONE
+bool RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]) RET_ZERO
/* rna */
float *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d) RET_NULL
@@ -303,6 +303,7 @@ void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, str
void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone) RET_NONE
void object_test_constraints(struct Object *owner) RET_NONE
void ED_armature_ebone_to_mat4(struct EditBone *ebone, float mat[4][4]) RET_NONE
+void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]) RET_NONE
void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr) RET_NONE
void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con) RET_NONE
void ED_node_composit_default(const struct bContext *C, struct Scene *scene) RET_NONE
@@ -311,13 +312,14 @@ void *ED_region_draw_cb_customdata(void *handle) RET_ZERO /* XXX This one looks
void ED_region_draw_cb_exit(struct ARegionType *art, void *handle) RET_NONE
void ED_area_headerprint(struct ScrArea *sa, const char *str) RET_NONE
void UI_view2d_region_to_view(struct View2D *v2d, float x, float y, float *viewx, float *viewy) RET_NONE
-void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *regionx, int *regiony) RET_NONE
-void UI_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, int *regionx, int *region_y) RET_NONE
+bool UI_view2d_view_to_region_clip(struct View2D *v2d, float x, float y, int *regionx, int *regiony) RET_ZERO
+void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *regionx, int *region_y) RET_NONE
+void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v2dcur, int flag) RET_NONE
struct EditBone *ED_armature_bone_get_mirrored(const struct ListBase *edbo, EditBone *ebo) RET_NULL
struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name) RET_NULL
struct ListBase *get_active_constraints (struct Object *ob) RET_NULL
-struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **pchan_r) RET_NULL
+struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan) RET_NULL
bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit) RET_ZERO
bool ED_space_image_show_render(struct SpaceImage *sima) RET_ZERO
@@ -372,8 +374,8 @@ struct ListBase builtin_keyingsets;
void ANIM_keyingset_info_register(struct KeyingSetInfo *ksi) RET_NONE
void ANIM_keyingset_info_unregister(struct Main *bmain, KeyingSetInfo *ksi) RET_NONE
short ANIM_validate_keyingset(struct bContext *C, struct ListBase *dsources, struct KeyingSet *ks) RET_ZERO
-short ANIM_add_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag, int type) RET_ZERO
-short ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag) RET_ZERO
+int ANIM_add_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag, int type) RET_ZERO
+bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag) RET_ZERO
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock) RET_NONE
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r) RET_NULL
void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy) RET_NONE
@@ -457,10 +459,10 @@ float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vert
void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup) RET_NONE
void ED_vgroup_clear(struct Object *ob) RET_NONE
bool ED_vgroup_object_is_edit_mode(struct Object *ob) RET_ZERO
-int mesh_mirrtopo_table(struct Object *ob, char mode) RET_ZERO
-intptr_t mesh_octree_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode) RET_ZERO
+int ED_mesh_mirror_topo_table(struct Object *ob, char mode) RET_ZERO
+int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode) RET_ZERO
-float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const short axis_only) RET_ZERO
+float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only) RET_ZERO
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) RET_NONE
bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima) RET_ZERO
@@ -524,7 +526,8 @@ void uiTemplateHeader(struct uiLayout *layout, struct bContext *C) RET_NONE
void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop) RET_NONE
struct uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr) RET_NULL
struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA *ptr) RET_NULL
-void uiTemplatePreview(struct uiLayout *layout, struct ID *id, int show_buttons, struct ID *parent, struct MTex *slot) RET_NONE
+void uiTemplatePreview(struct uiLayout *layout, struct bContext *C, struct ID *id, int show_buttons, struct ID *parent,
+ struct MTex *slot, const char *preview_id) RET_NONE
void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int rows, int cols) RET_NONE
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type, int levels, int brush) RET_NONE
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int expand) RET_NONE
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index ac8f004c3e4..63294b57697 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -525,7 +525,19 @@ if(UNIX AND NOT APPLE)
PATTERN "*.a" EXCLUDE # ./core/lib/libnpymath.a - for linking, we dont need.
)
endif()
-
+
+ # Copy requests, we need to generalize site-packages
+ if(WITH_PYTHON_INSTALL_REQUESTS)
+ install(
+ DIRECTORY ${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/requests
+ DESTINATION ${TARGETDIR_VER}/python/${_target_LIB}/python${PYTHON_VERSION}/site-packages
+ PATTERN ".svn" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE # * any cache *
+ PATTERN "*.pyc" EXCLUDE # * any cache *
+ PATTERN "*.pyo" EXCLUDE # * any cache *
+ PATTERN "cacert.pem" EXCLUDE # for now we don't deal with security
+ )
+ endif()
unset(_target_LIB)
endif()
@@ -579,6 +591,27 @@ elseif(WIN32)
"
)
+ if(WITH_PYTHON_INSTALL_NUMPY)
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/site-packages\"
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.8.tar.gz\")
+ "
+ )
+ endif()
+
+ # release/site-packages
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy_directory
+ ${LIBDIR}/release/site-packages
+ \"${TARGETDIR_VER}/python/lib/site-packages\")
+ "
+ )
+
+
# doesnt work, todo
# install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
endif()
@@ -641,7 +674,7 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/swscale-2.dll
DESTINATION ${TARGETDIR}
)
- else()
+ elseif(WITH_MINGW64)
install(
FILES
${LIBDIR}/ffmpeg/lib/avcodec-53.dll
@@ -649,16 +682,20 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/avdevice-53.dll
${LIBDIR}/ffmpeg/lib/avutil-51.dll
${LIBDIR}/ffmpeg/lib/swscale-2.dll
+ ${LIBDIR}/ffmpeg/lib/swresample-0.dll
+ ${LIBDIR}/ffmpeg/lib/xvidcore.dll
+ DESTINATION ${TARGETDIR}
+ )
+ else()
+ install(
+ FILES
+ ${LIBDIR}/ffmpeg/lib/avcodec-55.dll
+ ${LIBDIR}/ffmpeg/lib/avformat-55.dll
+ ${LIBDIR}/ffmpeg/lib/avdevice-55.dll
+ ${LIBDIR}/ffmpeg/lib/avutil-52.dll
+ ${LIBDIR}/ffmpeg/lib/swscale-2.dll
DESTINATION ${TARGETDIR}
)
- endif()
- if(WITH_MINGW64)
- install(
- FILES
- ${LIBDIR}/ffmpeg/lib/swresample-0.dll
- ${LIBDIR}/ffmpeg/lib/xvidcore.dll
- DESTINATION ${TARGETDIR}
- )
endif()
endif()
@@ -787,6 +824,13 @@ elseif(APPLE)
\${TARGETDIR}/blender.app/Contents/
)
+ if(WITH_OPENMP AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
+ install(
+ FILES ${LIBDIR}/openmp/lib/libiomp5.dylib
+ DESTINATION ${TARGETDIR}/blender.app/Contents/MacOS
+ )
+ endif()
+
# python
if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
# the python zip is first extract as part of the build process,
@@ -813,6 +857,11 @@ elseif(APPLE)
${CMAKE_CURRENT_BINARY_DIR}/python
\${TARGETDIR_VER}
)
+ # copy site-packages files
+ install_dir(
+ ${LIBDIR}/release/site-packages
+ ${CMAKE_CURRENT_BINARY_DIR}/python/lib/python${PYTHON_VERSION}/site-packages
+ )
endif()
@@ -857,7 +906,7 @@ elseif(APPLE)
endif()
endif()
-
+
endif()
# -----------------------------------------------------------------------------
@@ -919,12 +968,12 @@ endif()
bf_editor_space_outliner
bf_editor_space_script
bf_editor_space_sequencer
+ bf_editor_space_text
bf_editor_space_time
bf_editor_space_userpref
bf_editor_space_view3d
bf_editor_space_clip
- bf_editor_text
bf_editor_transform
bf_editor_util
bf_editor_uvedit
@@ -968,7 +1017,6 @@ endif()
bf_imbuf_openimageio
bf_imbuf_dds
bf_collada
- bf_intern_bsp
bf_intern_elbeem
bf_intern_memutil
bf_intern_guardedalloc
diff --git a/source/creator/creator.c b/source/creator/creator.c
index dbb7bef9723..0dad2fd6b75 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -40,13 +40,6 @@
# include <xmmintrin.h>
#endif
-/* crash handler */
-#ifdef WIN32
-# include <process.h> /* getpid */
-#else
-# include <unistd.h> /* getpid */
-#endif
-
#ifdef WIN32
# include <windows.h>
# include "utfconv.h"
@@ -79,6 +72,8 @@
#include "BLI_callbacks.h"
#include "BLI_blenlib.h"
#include "BLI_mempool.h"
+#include "BLI_system.h"
+#include BLI_SYSTEM_PID_H
#include "DNA_ID.h"
#include "DNA_scene_types.h"
@@ -94,12 +89,12 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
-#include "BKE_packedFile.h"
#include "BKE_scene.h"
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_sound.h"
#include "BKE_image.h"
+#include "BKE_particle.h"
#include "IMB_imbuf.h" /* for IMB_init */
@@ -111,6 +106,7 @@
#include "RE_pipeline.h"
#include "ED_datafiles.h"
+#include "ED_util.h"
#include "WM_api.h"
@@ -208,7 +204,7 @@ static void blender_esc(int sig)
{
static int count = 0;
- G.is_break = TRUE; /* forces render loop to read queue, not sure if its needed */
+ G.is_break = true; /* forces render loop to read queue, not sure if its needed */
if (sig == 2) {
if (count) {
@@ -536,7 +532,7 @@ static void blender_crash_handler_backtrace(FILE *fp)
process = GetCurrentProcess();
- SymInitialize(process, NULL, TRUE);
+ SymInitialize(process, NULL, true);
nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof( char ), "crash Symbol table");
@@ -1253,7 +1249,11 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
BLI_path_cwd(filename);
if (G.background) {
- int retval = BKE_read_file(C, filename, NULL);
+ int retval;
+
+ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
+
+ retval = BKE_read_file(C, filename, NULL);
/* we successfully loaded a blend file, get sure that
* pointcache works */
@@ -1266,7 +1266,7 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
extern void wm_add_default(bContext *C);
/* wm_add_default() needs the screen to be set. */
- CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
+ CTX_wm_screen_set(C, bmain->screen.first);
wm_add_default(C);
}
@@ -1275,7 +1275,9 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
G.relbase_valid = 1;
if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
- DAG_on_visible_update(bmain, TRUE);
+ /* WM_file_read would call normally */
+ ED_editors_init(C);
+ DAG_on_visible_update(bmain, true);
BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C));
}
else {
@@ -1289,6 +1291,8 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
BPY_python_reset(C);
#endif
+ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
+
/* happens for the UI on file reading too (huh? (ton))*/
// XXX BKE_reset_undo();
// BKE_write_undo("original"); /* save current state */
@@ -1468,12 +1472,21 @@ char **environ = NULL;
# endif
#endif
-
+/**
+ * Blender's main function responsabilities are:
+ * - setup subsystems.
+ * - handle arguments.
+ * - run WM_main() event loop,
+ * or exit when running in background mode.
+ */
+int main(
+ int argc,
#ifdef WIN32
-int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
+ const char **UNUSED(argv_c)
#else
-int main(int argc, const char **argv)
+ const char **argv
#endif
+ )
{
bContext *C;
SYS_SystemHandle syshandle;
@@ -1622,6 +1635,7 @@ int main(int argc, const char **argv)
RE_engines_init();
init_nodesystem();
+ psys_init_rng();
/* end second init */
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index d136131e82f..03401f0e8b8 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -361,8 +361,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
camzoom = 2.0;
}
-
- ketsjiengine->SetDrawType(v3d->drawtype);
+ rasterizer->SetDrawingMode(v3d->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_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index a28906254a1..3dd013dfd63 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -35,6 +35,7 @@
#include "BL_ArmatureObject.h"
#include "BL_SkinDeformer.h"
#include "BL_Action.h"
+#include "BL_ActionManager.h"
#include "KX_GameObject.h"
#include "STR_HashedString.h"
#include "MEM_guardedalloc.h"
@@ -93,9 +94,6 @@ BL_ActionActuator::BL_ActionActuator(SCA_IObject *gameobj,
m_priority(priority),
m_layer(layer),
m_ipo_flags(ipo_flags),
- m_pose(NULL),
- m_blendpose(NULL),
- m_userpose(NULL),
m_action(action),
m_propname(propname),
m_framepropname(framepropname)
@@ -106,20 +104,12 @@ BL_ActionActuator::BL_ActionActuator(SCA_IObject *gameobj,
BL_ActionActuator::~BL_ActionActuator()
{
- if (m_pose)
- game_free_pose(m_pose);
- if (m_userpose)
- game_free_pose(m_userpose);
- if (m_blendpose)
- game_free_pose(m_blendpose);
}
void BL_ActionActuator::ProcessReplica()
{
SCA_IActuator::ProcessReplica();
-
- m_pose = NULL;
- m_blendpose = NULL;
+
m_localtime=m_startframe;
m_lastUpdate=-1;
@@ -270,7 +260,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if (m_playtype == ACT_ACTION_PINGPONG)
m_flag ^= ACT_FLAG_REVERSE;
- return false;
+ else
+ return false;
}
// If a different action is playing, we've been overruled and are no longer active
@@ -546,7 +537,7 @@ PyAttributeDef BL_ActionActuator::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ActionActuator, pyattr_get_action, pyattr_set_action),
KX_PYATTRIBUTE_RO_FUNCTION("channelNames", BL_ActionActuator, pyattr_get_channel_names),
KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ActionActuator, m_priority),
- KX_PYATTRIBUTE_SHORT_RW("layer", 0, 7, true, BL_ActionActuator, m_layer),
+ KX_PYATTRIBUTE_SHORT_RW("layer", 0, MAX_ACTION_LAYERS-1, true, BL_ActionActuator, m_layer),
KX_PYATTRIBUTE_FLOAT_RW("layerWeight", 0, 1.0, BL_ActionActuator, m_layer_weight),
KX_PYATTRIBUTE_RW_FUNCTION("frame", BL_ActionActuator, pyattr_get_frame, pyattr_set_frame),
KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, BL_ActionActuator, m_propname),
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 4579a21f554..f488b0c76a6 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -134,9 +134,6 @@ protected:
short m_priority;
short m_layer;
short m_ipo_flags;
- struct bPose* m_pose;
- struct bPose* m_blendpose;
- struct bPose* m_userpose;
struct bAction *m_action;
STR_String m_propname;
STR_String m_framepropname;
diff --git a/source/gameengine/Converter/BL_ArmatureActuator.cpp b/source/gameengine/Converter/BL_ArmatureActuator.cpp
index f0c4b3d32bb..e38cb6eadaf 100644
--- a/source/gameengine/Converter/BL_ArmatureActuator.cpp
+++ b/source/gameengine/Converter/BL_ArmatureActuator.cpp
@@ -155,7 +155,7 @@ bool BL_ArmatureActuator::Update(double curtime, bool frame)
switch (m_type) {
case ACT_ARM_RUN:
result = true;
- obj->SetActiveAction(NULL, 0, curtime);
+ obj->UpdateTimestep(curtime);
break;
case ACT_ARM_ENABLE:
if (m_constraint)
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index 34d706eff03..0392280444d 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -42,7 +42,13 @@
#include "BIK_api.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_object.h"
#include "BKE_library.h"
+#include "BKE_global.h"
+
+extern "C" {
+#include "BKE_animsys.h"
+}
#include "BKE_constraint.h"
#include "CTR_Map.h"
@@ -53,6 +59,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_constraint_types.h"
+#include "RNA_access.h"
#include "KX_PythonSeq.h"
#include "KX_PythonInit.h"
#include "KX_KetsjiEngine.h"
@@ -70,7 +77,7 @@
* When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
* Blender objects and restore after the evaluation.
*/
-void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
+static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
{
bPose *out;
bPoseChannel *pchan, *outpchan;
@@ -85,7 +92,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
return;
}
else if (*dst==src) {
- printf("BKE_pose_copy_data source and target are the same\n");
+ printf("game_copy_pose source and target are the same\n");
*dst=NULL;
return;
}
@@ -113,8 +120,8 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
if (copy_constraint) {
ListBase listb;
// copy all constraint for backward compatibility
- // BKE_copy_constraints NULLs listb, no need to make extern for this operation.
- BKE_copy_constraints(&listb, &pchan->constraints, FALSE);
+ // BKE_constraints_copy NULLs listb, no need to make extern for this operation.
+ BKE_constraints_copy(&listb, &pchan->constraints, false);
pchan->constraints= listb;
}
else {
@@ -142,7 +149,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
/* Only allowed for Poses with identical channels */
-void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
+static void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
{
bPoseChannel *dchan;
const bPoseChannel *schan;
@@ -202,23 +209,6 @@ void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
dst->ctime= src->ctime;
}
-void game_free_pose(bPose *pose)
-{
- if (pose) {
- /* free pose-channels and constraints */
- BKE_pose_channels_free(pose);
-
- /* free IK solver state */
- BIK_clear_data(pose);
-
- /* free IK solver param */
- if (pose->ikparam)
- MEM_freeN(pose->ikparam);
-
- MEM_freeN(pose);
- }
-}
-
BL_ArmatureObject::BL_ArmatureObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -229,26 +219,18 @@ BL_ArmatureObject::BL_ArmatureObject(
: KX_GameObject(sgReplicationInfo,callbacks),
m_controlledConstraints(),
m_poseChannels(),
- m_objArma(armature),
- m_framePose(NULL),
m_scene(scene), // maybe remove later. needed for BKE_pose_where_is
m_lastframe(0.0),
m_timestep(0.040),
- m_activeAct(NULL),
- m_activePriority(999),
m_vert_deform_type(vert_deform_type),
m_constraintNumber(0),
m_channelNumber(0),
m_lastapplyframe(0.0)
{
- m_armature = (bArmature *)armature->data;
-
- /* we make a copy of blender object's pose, and then always swap it with
- * the original pose before calling into blender functions, to deal with
- * replica's or other objects using the same blender object */
- m_pose = NULL;
- game_copy_pose(&m_pose, m_objArma->pose, 1);
- // store the original armature object matrix
+ m_origObjArma = armature; // Keep a copy of the original armature so we can fix drivers later
+ m_objArma = BKE_object_copy(armature);
+ m_objArma->data = BKE_armature_copy((bArmature *)armature->data);
+ m_pose = m_objArma->pose;
memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
}
@@ -262,10 +244,9 @@ BL_ArmatureObject::~BL_ArmatureObject()
while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
delete channel;
}
- if (m_pose)
- game_free_pose(m_pose);
- if (m_framePose)
- game_free_pose(m_framePose);
+
+ if (m_objArma)
+ BKE_libblock_free(G.main, m_objArma);
}
@@ -307,7 +288,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
case CONSTRAINT_TYPE_TRANSFORM:
case CONSTRAINT_TYPE_DISTLIMIT:
case CONSTRAINT_TYPE_TRANSLIKE:
- cti = BKE_constraint_get_typeinfo(pcon);
+ cti = BKE_constraint_typeinfo_get(pcon);
gametarget = gamesubtarget = NULL;
if (cti && cti->get_constraint_targets) {
ListBase listb = { NULL, NULL };
@@ -431,12 +412,12 @@ CValue* BL_ArmatureObject::GetReplica()
void BL_ArmatureObject::ProcessReplica()
{
- bPose *pose= m_pose;
KX_GameObject::ProcessReplica();
- m_pose = NULL;
- m_framePose = NULL;
- game_copy_pose(&m_pose, pose, 1);
+ bArmature* tmp = (bArmature*)m_objArma->data;
+ m_objArma = BKE_object_copy(m_objArma);
+ m_objArma->data = BKE_armature_copy(tmp);
+ m_pose = m_objArma->pose;
}
void BL_ArmatureObject::ReParentLogic()
@@ -506,48 +487,32 @@ void BL_ArmatureObject::SetPose(bPose *pose)
m_lastapplyframe = -1.0;
}
-bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, double curtime)
+void BL_ArmatureObject::SetPoseByAction(bAction *action, float localtime)
+{
+ Object *arm = GetArmatureObject();
+
+ PointerRNA ptrrna;
+ RNA_id_pointer_create(&arm->id, &ptrrna);
+
+ animsys_evaluate_action(&ptrrna, action, NULL, localtime);
+}
+
+void BL_ArmatureObject::BlendInPose(bPose *blend_pose, float weight, short mode)
+{
+ game_blend_poses(m_pose, blend_pose, weight, mode);
+}
+
+bool BL_ArmatureObject::UpdateTimestep(double curtime)
{
if (curtime != m_lastframe) {
- m_activePriority = 9999;
// compute the timestep for the underlying IK algorithm
m_timestep = curtime-m_lastframe;
m_lastframe= curtime;
- m_activeAct = NULL;
- // remember the pose at the start of the frame
- GetPose(&m_framePose);
}
- if (act)
- {
- if (priority<=m_activePriority)
- {
- if (priority<m_activePriority) {
- // this action overwrites the previous ones, start from initial pose to cancel their effects
- SetPose(m_framePose);
- if (m_activeAct && (m_activeAct!=act))
- /* Reset the blend timer since this new action cancels the old one */
- m_activeAct->SetBlendTime(0.0);
- }
- m_activeAct = act;
- m_activePriority = priority;
- m_lastframe = curtime;
-
- return true;
- }
- else {
- act->SetBlendTime(0.0);
- return false;
- }
- }
return false;
}
-BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
-{
- return m_activeAct;
-}
-
void BL_ArmatureObject::GetPose(bPose **pose)
{
/* If the caller supplies a null pose, create a new one. */
@@ -570,22 +535,6 @@ void BL_ArmatureObject::GetPose(bPose **pose)
}
}
-void BL_ArmatureObject::GetMRDPose(bPose **pose)
-{
- /* If the caller supplies a null pose, create a new one. */
- /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
-
- if (!*pose)
- game_copy_pose(pose, m_pose, 0);
- else
- extract_pose_from_pose(*pose, m_pose);
-}
-
-short BL_ArmatureObject::GetActivePriority()
-{
- return m_activePriority;
-}
-
double BL_ArmatureObject::GetLastFrame()
{
return m_lastframe;
@@ -671,7 +620,7 @@ KX_PYMETHODDEF_DOC_NOARGS(BL_ArmatureObject, update,
"This is automatically done if a KX_ArmatureActuator with mode run is active\n"
"or if an action is playing. This function is useful in other cases.\n")
{
- SetActiveAction(NULL, 0, KX_GetActiveEngine()->GetFrameTime());
+ UpdateTimestep(KX_GetActiveEngine()->GetFrameTime());
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h
index 81388355fc4..691e73d6bde 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.h
+++ b/source/gameengine/Converter/BL_ArmatureObject.h
@@ -55,14 +55,11 @@ class BL_ArmatureObject : public KX_GameObject
public:
double GetLastFrame ();
- short GetActivePriority();
virtual void ProcessReplica();
virtual void ReParentLogic();
virtual void Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map);
virtual bool UnlinkObject(SCA_IObject* clientobj);
- class BL_ActionActuator * GetActiveAction();
-
BL_ArmatureObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -73,21 +70,23 @@ public:
virtual ~BL_ArmatureObject();
virtual CValue* GetReplica();
- void GetMRDPose(struct bPose **pose);
void GetPose(struct bPose **pose);
void SetPose (struct bPose *pose);
struct bPose *GetOrigPose() {return m_pose;} // never edit this, only for accessing names
void ApplyPose();
+ void SetPoseByAction(struct bAction* action, float localtime);
+ void BlendInPose(struct bPose *blend_pose, float weight, short mode);
void RestorePose();
- bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
+ bool UpdateTimestep(double curtime);
- struct bArmature *GetArmature() { return m_armature; }
- const struct bArmature * GetArmature() const { return m_armature; }
+ struct bArmature *GetArmature() { return (bArmature*)m_objArma->data; }
+ const struct bArmature * GetArmature() const { return (bArmature*)m_objArma->data; }
const struct Scene * GetScene() const { return m_scene; }
Object* GetArmatureObject() {return m_objArma;}
+ Object* GetOrigArmatureObject() {return m_origObjArma;}
int GetVertDeformType() {return m_vert_deform_type;}
@@ -128,15 +127,12 @@ protected:
/* list element: BL_ArmatureChannel. Use SG_DList to avoid list replication */
SG_DList m_poseChannels;
Object *m_objArma;
- struct bArmature *m_armature;
+ Object *m_origObjArma;
struct bPose *m_pose;
struct bPose *m_armpose;
- struct bPose *m_framePose;
struct Scene *m_scene; // need for BKE_pose_where_is
double m_lastframe;
double m_timestep; // delta since last pose evaluation.
- class BL_ActionActuator *m_activeAct;
- short m_activePriority;
int m_vert_deform_type;
size_t m_constraintNumber;
size_t m_channelNumber;
@@ -146,10 +142,4 @@ protected:
double m_lastapplyframe;
};
-/* Pose function specific to the game engine */
-void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode); /* was blend_poses */
-//void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
-void game_copy_pose(struct bPose **dst, struct bPose *src, int copy_con);
-void game_free_pose(struct bPose *pose);
-
#endif /* __BL_ARMATUREOBJECT_H__ */
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 0ec54412485..e511f01e9c6 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -62,12 +62,16 @@
// Collision & Fuzzics LTD
#include "PHY_Pro.h"
+#include "PHY_IPhysicsEnvironment.h"
+#include "PHY_DynamicTypes.h"
#include "KX_Scene.h"
#include "KX_GameObject.h"
#include "RAS_FramingManager.h"
#include "RAS_MeshObject.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_ILightObject.h"
#include "KX_ConvertActuators.h"
#include "KX_ConvertControllers.h"
@@ -78,6 +82,7 @@
#include "SCA_TimeEventManager.h"
#include "KX_Light.h"
#include "KX_Camera.h"
+#include "KX_ClientObjectInfo.h"
#include "KX_EmptyObject.h"
#include "KX_FontObject.h"
#include "MT_Point3.h"
@@ -177,7 +182,6 @@ extern Material defmaterial; /* material.c */
#include "SG_BBox.h"
#include "SG_Tree.h"
-#include "KX_ConvertPhysicsObject.h"
#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
#include "CcdGraphicController.h"
@@ -610,7 +614,11 @@ static bool ConvertMaterial(
material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
// cast shadows?
- material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
+ material->ras_mode |= ( (mat->mode2 & MA_CASTSHADOW) && (mat->mode & MA_SHADBUF) )?CAST_SHADOW:0;
+
+ // only shadows?
+ material->ras_mode |= ( mat->mode & MA_ONLYCAST )?ONLY_SHADOW:0;
+
MTex *mttmp = 0;
int valid_index = 0;
@@ -938,11 +946,12 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
- if (bucketCreated) {
- // this is needed to free up memory afterwards
- converter->RegisterPolyMaterial(polymat);
- converter->RegisterBlenderMaterial(bl_mat);
- }
+
+ // this is needed to free up memory afterwards.
+ // the converter will also prevent duplicates from being registered,
+ // so just register everything.
+ converter->RegisterPolyMaterial(polymat);
+ converter->RegisterBlenderMaterial(bl_mat);
return bucket;
}
@@ -1305,121 +1314,6 @@ static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
return sqrtf_signed(radius_sq);
}
-
-static void my_tex_space_mesh(Mesh *me)
-{
- KeyBlock *kb;
- float *fp, loc[3], size[3], min[3], max[3];
- int a;
-
- my_boundbox_mesh(me, loc, size);
-
- if (me->texflag & ME_AUTOSPACE) {
- if (me->key) {
- kb= me->key->refkey;
- if (kb) {
-
- INIT_MINMAX(min, max);
-
- fp= (float *)kb->data;
- for (a=0; a<kb->totelem; a++, fp += 3) {
- minmax_v3v3_v3(min, max, fp);
- }
- if (kb->totelem) {
- loc[0] = (min[0]+max[0])/2.0f; loc[1] = (min[1]+max[1])/2.0f; loc[2] = (min[2]+max[2])/2.0f;
- size[0] = (max[0]-min[0])/2.0f; size[1] = (max[1]-min[1])/2.0f; size[2] = (max[2]-min[2])/2.0f;
- }
- else {
- loc[0] = loc[1] = loc[2] = 0.0;
- size[0] = size[1] = size[2] = 0.0;
- }
-
- }
- }
-
- copy_v3_v3(me->loc, loc);
- copy_v3_v3(me->size, size);
- me->rot[0] = me->rot[1] = me->rot[2] = 0.0f;
-
- if (me->size[0] == 0.0f) me->size[0] = 1.0f;
- else if (me->size[0] > 0.0f && me->size[0]< 0.00001f) me->size[0] = 0.00001f;
- else if (me->size[0] < 0.0f && me->size[0]> -0.00001f) me->size[0] = -0.00001f;
-
- if (me->size[1] == 0.0f) me->size[1] = 1.0f;
- else if (me->size[1] > 0.0f && me->size[1]< 0.00001f) me->size[1] = 0.00001f;
- else if (me->size[1] < 0.0f && me->size[1]> -0.00001f) me->size[1] = -0.00001f;
-
- if (me->size[2] == 0.0f) me->size[2] = 1.0f;
- else if (me->size[2] > 0.0f && me->size[2]< 0.00001f) me->size[2] = 0.00001f;
- else if (me->size[2] < 0.0f && me->size[2]> -0.00001f) me->size[2] = -0.00001f;
- }
-
-}
-
-static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, float *size)
-{
- BoundBox *bb= NULL;
- /* uses boundbox, function used by Ketsji */
- switch (ob->type)
- {
- case OB_MESH:
- if (dm)
- {
- float min_r[3], max_r[3];
- INIT_MINMAX(min_r, max_r);
- dm->getMinMax(dm, min_r, max_r);
- size[0] = 0.5f * fabsf(max_r[0] - min_r[0]);
- size[1] = 0.5f * fabsf(max_r[1] - min_r[1]);
- size[2] = 0.5f * fabsf(max_r[2] - min_r[2]);
-
- center[0] = 0.5f * (max_r[0] + min_r[0]);
- center[1] = 0.5f * (max_r[1] + min_r[1]);
- center[2] = 0.5f * (max_r[2] + min_r[2]);
- return;
- } else
- {
- bb= ( (Mesh *)ob->data )->bb;
- if (bb==0)
- {
- my_tex_space_mesh((struct Mesh *)ob->data);
- bb= ( (Mesh *)ob->data )->bb;
- }
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- center[0] = center[1] = center[2] = 0.0;
- size[0] = size[1]=size[2]=0.0;
- break;
- case OB_FONT:
- center[0] = center[1] = center[2] = 0.0;
- size[0] = size[1]=size[2]=1.0;
- break;
- case OB_MBALL:
- bb= ob->bb;
- break;
- }
-
- if (bb==NULL)
- {
- center[0] = center[1] = center[2] = 0.0;
- size[0] = size[1] = size[2] = 1.0;
- }
- else
- {
- size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
- size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
- size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
-
- center[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]);
- center[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]);
- center[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]);
- }
-}
-
-
-
-
//////////////////////////////////////////////////////
@@ -1467,7 +1361,6 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
RAS_MeshObject* meshobj,
KX_Scene* kxscene,
int activeLayerBitInfo,
- e_PhysicsEngine physics_engine,
KX_BlenderSceneConverter *converter,
bool processCompoundChildren
)
@@ -1517,237 +1410,35 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
PHY_MaterialProps* smmaterial =
CreateMaterialFromBlenderObject(blenderobject);
-
- KX_ObjectProperties objprop;
- objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0;
- objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0;
- objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0;
- objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0;
- objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0;
- objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
-
- objprop.m_isCompoundChild = isCompoundChild;
- objprop.m_hasCompoundChildren = hasCompoundChildren;
- objprop.m_margin = blenderobject->margin;
-
- // ACTOR is now a separate feature
- objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
- objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
- objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
- objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
- objprop.m_character = (blenderobject->gameflag & OB_CHARACTER) != 0;
- objprop.m_record_animation = (blenderobject->gameflag & OB_RECORD_ANIMATION) != 0;
-
- ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
- if (objprop.m_angular_rigidbody || !objprop.m_dyna )
- {
- objprop.m_contactProcessingThreshold = blenderobject->m_contactProcessingThreshold;
- } else
- {
- objprop.m_contactProcessingThreshold = 0.f;
- }
- objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0;
-
- if (objprop.m_softbody)
- {
- ///for game soft bodies
- if (blenderobject->bsoft)
- {
- objprop.m_gamesoftFlag = blenderobject->bsoft->flag;
- ///////////////////
- objprop.m_soft_linStiff = blenderobject->bsoft->linStiff;
- objprop.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */
- objprop.m_soft_volume= blenderobject->bsoft->volume; /* volume preservation 0..1 */
-
- objprop.m_soft_viterations= blenderobject->bsoft->viterations; /* Velocities solver iterations */
- objprop.m_soft_piterations= blenderobject->bsoft->piterations; /* Positions solver iterations */
- objprop.m_soft_diterations= blenderobject->bsoft->diterations; /* Drift solver iterations */
- objprop.m_soft_citerations= blenderobject->bsoft->citerations; /* Cluster solver iterations */
-
- objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
- objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
- objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
- objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
-
- objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- objprop.m_soft_kVCF= blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */
- objprop.m_soft_kDP= blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */
-
- objprop.m_soft_kDG= blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */
- objprop.m_soft_kLF= blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */
- objprop.m_soft_kPR= blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */
- objprop.m_soft_kVC= blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */
-
- objprop.m_soft_kDF= blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */
- objprop.m_soft_kMT= blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */
- objprop.m_soft_kCHR= blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */
- objprop.m_soft_kKHR= blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */
-
- objprop.m_soft_kSHR= blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */
- objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */
- objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
- objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/
- //objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */
- /* disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh */
- objprop.m_soft_welding = 0.f;
- objprop.m_margin = blenderobject->bsoft->margin;
- objprop.m_contactProcessingThreshold = 0.f;
- } else
- {
- objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT;
-
- objprop.m_soft_linStiff = 0.5;
- objprop.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */
- objprop.m_soft_volume= 1.f; /* volume preservation 0..1 */
-
-
- objprop.m_soft_viterations= 0;
- objprop.m_soft_piterations= 1;
- objprop.m_soft_diterations= 0;
- objprop.m_soft_citerations= 4;
-
- objprop.m_soft_kSRHR_CL= 0.1f;
- objprop.m_soft_kSKHR_CL= 1.f;
- objprop.m_soft_kSSHR_CL= 0.5;
- objprop.m_soft_kSR_SPLT_CL= 0.5f;
-
- objprop.m_soft_kSK_SPLT_CL= 0.5f;
- objprop.m_soft_kSS_SPLT_CL= 0.5f;
- objprop.m_soft_kVCF= 1;
- objprop.m_soft_kDP= 0;
-
- objprop.m_soft_kDG= 0;
- objprop.m_soft_kLF= 0;
- objprop.m_soft_kPR= 0;
- objprop.m_soft_kVC= 0;
-
- objprop.m_soft_kDF= 0.2f;
- objprop.m_soft_kMT= 0.05f;
- objprop.m_soft_kCHR= 1.0f;
- objprop.m_soft_kKHR= 0.1f;
-
- objprop.m_soft_kSHR= 1.f;
- objprop.m_soft_kAHR= 0.7f;
- objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS;
- objprop.m_soft_numclusteriterations= 16;
- objprop.m_soft_welding = 0.f;
- objprop.m_margin = 0.f;
- objprop.m_contactProcessingThreshold = 0.f;
- }
- }
-
- objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
- objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
- //mmm, for now, taks this for the size of the dynamicobject
- // Blender uses inertia for radius of dynamic object
- objprop.m_radius = blenderobject->inertia;
- objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
- objprop.m_dynamic_parent=NULL;
- objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
- objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
-
- if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gameflag & OB_BOUNDS))
- {
- objprop.m_boundclass = KX_BOUNDMESH;
- }
-
- if ((blenderobject->gameflag & OB_CHARACTER) && !(blenderobject->gameflag & OB_BOUNDS))
- {
- objprop.m_boundclass = KX_BOUNDSPHERE;
- }
-
- KX_BoxBounds bb;
DerivedMesh* dm = NULL;
if (gameobj->GetDeformer())
dm = gameobj->GetDeformer()->GetPhysicsMesh();
- my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends);
- if (blenderobject->gameflag & OB_BOUNDS)
- {
- switch (blenderobject->collision_boundtype)
- {
- case OB_BOUND_BOX:
- objprop.m_boundclass = KX_BOUNDBOX;
- //mmm, has to be divided by 2 to be proper extends
- objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
- objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
- objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
- break;
- case OB_BOUND_CONVEX_HULL:
- if (blenderobject->type == OB_MESH)
- {
- objprop.m_boundclass = KX_BOUNDPOLYTOPE;
- break;
- }
- // Object is not a mesh... fall through OB_BOUND_TRIANGLE_MESH to
- // OB_BOUND_SPHERE
- case OB_BOUND_TRIANGLE_MESH:
- if (blenderobject->type == OB_MESH)
- {
- objprop.m_boundclass = KX_BOUNDMESH;
- break;
- }
- // Object is not a mesh... can't use polyhedron.
- // Fall through and become a sphere.
- case OB_BOUND_SPHERE:
- {
- objprop.m_boundclass = KX_BOUNDSPHERE;
- objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
- break;
- }
- case OB_BOUND_CYLINDER:
- {
- objprop.m_boundclass = KX_BOUNDCYLINDER;
- objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
- objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
- break;
- }
- case OB_BOUND_CONE:
- {
- objprop.m_boundclass = KX_BOUNDCONE;
- objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
- objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
- break;
- }
- case OB_BOUND_CAPSULE:
- {
- objprop.m_boundclass = KX_BOUNDCAPSULE;
- objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
- objprop.m_boundobject.c.m_height = 2.f*(bb.m_extends[2]-objprop.m_boundobject.c.m_radius);
- if (objprop.m_boundobject.c.m_height < 0.f)
- objprop.m_boundobject.c.m_height = 0.f;
- break;
- }
- }
- }
-
- if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) {
- // parented object cannot be dynamic
- KX_GameObject *parentgameobject = converter->FindGameObject(parent);
- objprop.m_dynamic_parent = parentgameobject;
- //cannot be dynamic:
- objprop.m_dyna = false;
- objprop.m_softbody = false;
- shapeprops->m_mass = 0.f;
- }
+ class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
-
- objprop.m_concave = (blenderobject->collision_boundtype == OB_BOUND_TRIANGLE_MESH);
-
- switch (physics_engine)
- {
-#ifdef WITH_BULLET
- case UseBullet:
- KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop);
- break;
+ kxscene->GetPhysicsEnvironment()->ConvertObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, motionstate, activeLayerBitInfo, isCompoundChild, hasCompoundChildren);
-#endif
- case UseNone:
- default:
- break;
+ bool isActor = (blenderobject->gameflag & OB_ACTOR)!=0;
+ bool isSensor = (blenderobject->gameflag & OB_SENSOR) != 0;
+ gameobj->getClientInfo()->m_type =
+ (isSensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
+ (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
+
+ // should we record animation for this object?
+ if ((blenderobject->gameflag & OB_RECORD_ANIMATION) != 0)
+ gameobj->SetRecordAnimation(true);
+
+ // store materialname in auxinfo, needed for touchsensors
+ if (meshobj)
+ {
+ const STR_String& matname=meshobj->GetMaterialName(0);
+ gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
+ } else
+ {
+ gameobj->getClientInfo()->m_auxilary_info = 0;
}
+
delete shapeprops;
delete smmaterial;
if (dm) {
@@ -1762,22 +1453,22 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRasterizer *rasterizer, KX_BlenderSceneConverter *converter)
{
- RAS_LightObject lightobj;
+ RAS_ILightObject *lightobj = rasterizer->CreateLight();
KX_LightObject *gamelight;
- lightobj.m_att1 = la->att1;
- lightobj.m_att2 = (la->mode & LA_QUAD) ? la->att2 : 0.0f;
- lightobj.m_red = la->r;
- lightobj.m_green = la->g;
- lightobj.m_blue = la->b;
- lightobj.m_distance = la->dist;
- lightobj.m_energy = la->energy;
- lightobj.m_layer = layerflag;
- lightobj.m_spotblend = la->spotblend;
- lightobj.m_spotsize = la->spotsize;
+ lightobj->m_att1 = la->att1;
+ lightobj->m_att2 = (la->mode & LA_QUAD) ? la->att2 : 0.0f;
+ lightobj->m_color[0] = la->r;
+ lightobj->m_color[1] = la->g;
+ lightobj->m_color[2] = la->b;
+ lightobj->m_distance = la->dist;
+ lightobj->m_energy = la->energy;
+ lightobj->m_layer = layerflag;
+ lightobj->m_spotblend = la->spotblend;
+ lightobj->m_spotsize = la->spotsize;
- lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
- lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
+ lightobj->m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
+ lightobj->m_nospecular = (la->mode & LA_NO_SPEC) != 0;
bool glslmat = converter->GetGLSLMaterials();
@@ -1785,18 +1476,18 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
if (glslmat==0) {
if (la->mode & LA_NEG)
{
- lightobj.m_red = -lightobj.m_red;
- lightobj.m_green = -lightobj.m_green;
- lightobj.m_blue = -lightobj.m_blue;
+ lightobj->m_color[0] = -lightobj->m_color[0];
+ lightobj->m_color[1] = -lightobj->m_color[1];
+ lightobj->m_color[2] = -lightobj->m_color[2];
}
}
if (la->type==LA_SUN) {
- lightobj.m_type = RAS_LightObject::LIGHT_SUN;
+ lightobj->m_type = RAS_ILightObject::LIGHT_SUN;
} else if (la->type==LA_SPOT) {
- lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
+ lightobj->m_type = RAS_ILightObject::LIGHT_SPOT;
} else {
- lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
+ lightobj->m_type = RAS_ILightObject::LIGHT_NORMAL;
}
gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rasterizer,
@@ -1930,15 +1621,11 @@ static KX_GameObject *gameobject_from_blenderobject(
BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj,
kxscene->GetBlenderScene(), ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
- if (bHasShapeKey && bHasArmature)
- dcont->LoadShapeDrivers(ob->parent);
} else if (bHasShapeKey) {
// not that we can have shape keys without dvert!
BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
- if (bHasArmature)
- dcont->LoadShapeDrivers(ob->parent);
} else if (bHasArmature) {
BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
ob, meshobj);
@@ -2003,7 +1690,7 @@ static KX_GameObject *gameobject_from_blenderobject(
case OB_CURVE:
{
if (ob->curve_cache == NULL) {
- BKE_displist_make_curveTypes(blenderscene, ob, FALSE);
+ BKE_displist_make_curveTypes(blenderscene, ob, false);
}
}
#endif
@@ -2077,10 +1764,6 @@ static void UNUSED_FUNCTION(RBJconstraints)(Object *ob)//not used
}
}
-#include "PHY_IPhysicsEnvironment.h"
-#include "PHY_DynamicTypes.h"
-
-
static KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist)
{
@@ -2121,7 +1804,7 @@ static void bl_ConvertBlenderObject_Single(
MT_Matrix3x3 rotation;
float rotmat[3][3];
- BKE_object_rot_to_mat3(blenderobject, rotmat, FALSE);
+ BKE_object_rot_to_mat3(blenderobject, rotmat, false);
rotation.setValue3x3((float*)rotmat);
MT_Vector3 scale(blenderobject->size);
@@ -2135,7 +1818,7 @@ static void bl_ConvertBlenderObject_Single(
);
float rotmatPrev[3][3];
- BKE_object_rot_to_mat3(blenderobject, rotmatPrev, FALSE);
+ BKE_object_rot_to_mat3(blenderobject, rotmatPrev, false);
float eulxyz[3], eulxyzPrev[3];
mat3_to_eul(eulxyz, rotmat);
@@ -2633,12 +2316,25 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->GetDeformer()->UpdateBuckets();
}
- // Set up armature constraints
+ // Set up armature constraints and shapekey drivers
for (i=0;i<sumolist->GetCount();++i)
{
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
- ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter);
+ {
+ BL_ArmatureObject *armobj = (BL_ArmatureObject*)gameobj;
+ armobj->LoadConstraints(converter);
+
+ CListValue *children = armobj->GetChildren();
+ for (int j=0; j<children->GetCount();++j)
+ {
+ BL_ShapeDeformer *deform = dynamic_cast<BL_ShapeDeformer*>(((KX_GameObject*)children->GetValue(j))->GetDeformer());
+ if (deform)
+ deform->LoadShapeDrivers(armobj);
+ }
+
+ children->Release();
+ }
}
bool processCompoundChildren = false;
@@ -2655,7 +2351,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
meshobj = gameobj->GetMesh(0);
}
int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren);
}
processCompoundChildren = true;
@@ -2671,7 +2367,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
meshobj = gameobj->GetMesh(0);
}
int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren);
}
//set ini linearVel and int angularVel //rcruiz
@@ -2858,7 +2554,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
struct Object* blenderobj = gameobj->GetBlenderObject();
int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
- BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter);
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter, libloading);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp
index 82f49ad5227..71dc1bdec87 100644
--- a/source/gameengine/Converter/BL_ModifierDeformer.cpp
+++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp
@@ -189,14 +189,23 @@ bool BL_ModifierDeformer::Update(void)
/* update the graphic controller */
PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
if (ctrl) {
- float min_r[3], max_r[3];
- INIT_MINMAX(min_r, max_r);
- m_dm->getMinMax(m_dm, min_r, max_r);
- ctrl->SetLocalAabb(min_r, max_r);
+ float min[3], max[3];
+ INIT_MINMAX(min, max);
+ m_dm->getMinMax(m_dm, min, max);
+ ctrl->SetLocalAabb(min, max);
}
}
m_lastModifierUpdate=m_gameobj->GetLastFrame();
bShapeUpdate = true;
+
+ int nmat = m_pMeshObject->NumMaterials();
+ for (int imat=0; imat<nmat; imat++) {
+ RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
+ RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj];
+ if (!slot || !*slot)
+ continue;
+ (*slot)->m_pDerivedMesh = m_dm;
+ }
}
return bShapeUpdate;
}
@@ -206,14 +215,5 @@ bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat)
if (!Update())
return false;
- // drawing is based on derived mesh, must set it in the mesh slots
- int nmat = m_pMeshObject->NumMaterials();
- for (int imat=0; imat<nmat; imat++) {
- RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
- RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj];
- if (!slot || !*slot)
- continue;
- (*slot)->m_pDerivedMesh = m_dm;
- }
return true;
}
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index ca5b26079b1..5e31dabfab1 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -51,6 +51,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_key.h"
+#include "BKE_fcurve.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "MT_Point3.h"
@@ -119,8 +120,35 @@ void BL_ShapeDeformer::ProcessReplica()
m_key = BKE_key_copy(m_key);
}
-bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
+bool BL_ShapeDeformer::LoadShapeDrivers(KX_GameObject* parent)
{
+ // Only load shape drivers if we have a key
+ if (GetKey() == NULL) {
+ m_useShapeDrivers = false;
+ return false;
+ }
+
+ // Fix drivers since BL_ArmatureObject makes copies
+ if (parent->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE && GetKey()->adt) {
+ BL_ArmatureObject *arma = (BL_ArmatureObject*)parent;
+ FCurve *fcu;
+
+ for (fcu = (FCurve*)GetKey()->adt->drivers.first; fcu; fcu = (FCurve*)fcu->next) {
+
+ DriverVar *dvar;
+ for (dvar = (DriverVar*)fcu->driver->variables.first; dvar; dvar = (DriverVar*)dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->id) {
+ if ((Object*)dtar->id == arma->GetOrigArmatureObject())
+ dtar->id = (ID*)arma->GetArmatureObject();
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
+ }
+
// This used to check if we had drivers from this armature,
// now we just assume we want to use shape drivers
// and let the animsys handle things.
@@ -132,15 +160,10 @@ bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
bool BL_ShapeDeformer::ExecuteShapeDrivers(void)
{
if (m_useShapeDrivers && PoseUpdated()) {
- // the shape drivers use the bone matrix as input. Must
- // update the matrix now
- m_armobj->ApplyPose();
-
// We don't need an actual time, just use 0
BKE_animsys_evaluate_animdata(NULL, &GetKey()->id, GetKey()->adt, 0.f, ADT_RECALC_DRIVERS);
ForceUpdate();
- m_armobj->RestorePose();
m_bDynamic = true;
return true;
}
@@ -199,6 +222,9 @@ bool BL_ShapeDeformer::Update(void)
if (m_recalcNormal)
RecalcNormals();
#endif
+
+ // We also need to handle transverts now (used to be in BL_SkinDeformer::Apply())
+ UpdateTransverts();
bSkinUpdate = true;
}
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h
index a506fb9c7f6..f6746dd2302 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.h
+++ b/source/gameengine/Converter/BL_ShapeDeformer.h
@@ -61,7 +61,7 @@ public:
virtual ~BL_ShapeDeformer();
bool Update (void);
- bool LoadShapeDrivers(Object* arma);
+ bool LoadShapeDrivers(KX_GameObject* parent);
bool ExecuteShapeDrivers(void);
struct Key *GetKey();
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index e068a91bf7e..e7137a5c379 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -152,44 +152,8 @@ void BL_SkinDeformer::Relink(CTR_Map<class CTR_HashedPtr, void*>*map)
bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
{
- RAS_MeshSlot::iterator it;
- RAS_MeshMaterial *mmat;
- RAS_MeshSlot *slot;
- size_t i, nmat, imat;
-
- // update the vertex in m_transverts
- if (!Update())
- return false;
-
- if (m_transverts) {
- // the vertex cache is unique to this deformer, no need to update it
- // if it wasn't updated! We must update all the materials at once
- // because we will not get here again for the other material
- nmat = m_pMeshObject->NumMaterials();
- for (imat=0; imat<nmat; imat++) {
- mmat = m_pMeshObject->GetMeshMaterial(imat);
- if (!mmat->m_slots[(void*)m_gameobj])
- continue;
-
- slot = *mmat->m_slots[(void*)m_gameobj];
-
- // for each array
- for (slot->begin(it); !slot->end(it); slot->next(it)) {
- // for each vertex
- // copy the untransformed data from the original mvert
- for (i=it.startvertex; i<it.endvertex; i++) {
- RAS_TexVert& v = it.vertex[i];
- v.SetXYZ(m_transverts[v.getOrigIndex()]);
- if (m_copyNormals)
- v.SetNormal(m_transnors[v.getOrigIndex()]);
- }
- }
- }
-
- if (m_copyNormals)
- m_copyNormals = false;
- }
- return true;
+ // We do everything in UpdateInternal() now so we can thread it.
+ return false;
}
RAS_Deformer *BL_SkinDeformer::GetReplica()
@@ -323,6 +287,43 @@ void BL_SkinDeformer::BGEDeformVerts()
m_copyNormals = true;
}
+void BL_SkinDeformer::UpdateTransverts()
+{
+ RAS_MeshSlot::iterator it;
+ RAS_MeshMaterial *mmat;
+ RAS_MeshSlot *slot;
+ size_t i, nmat, imat;
+
+ if (m_transverts) {
+ // the vertex cache is unique to this deformer, no need to update it
+ // if it wasn't updated! We must update all the materials at once
+ // because we will not get here again for the other material
+ nmat = m_pMeshObject->NumMaterials();
+ for (imat=0; imat<nmat; imat++) {
+ mmat = m_pMeshObject->GetMeshMaterial(imat);
+ if (!mmat->m_slots[(void*)m_gameobj])
+ continue;
+
+ slot = *mmat->m_slots[(void*)m_gameobj];
+
+ // for each array
+ for (slot->begin(it); !slot->end(it); slot->next(it)) {
+ // for each vertex
+ // copy the untransformed data from the original mvert
+ for (i=it.startvertex; i<it.endvertex; i++) {
+ RAS_TexVert& v = it.vertex[i];
+ v.SetXYZ(m_transverts[v.getOrigIndex()]);
+ if (m_copyNormals)
+ v.SetNormal(m_transnors[v.getOrigIndex()]);
+ }
+ }
+ }
+
+ if (m_copyNormals)
+ m_copyNormals = false;
+ }
+}
+
bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
{
/* See if the armature has been updated for this frame */
@@ -331,7 +332,7 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
if (!shape_applied) {
/* store verts locally */
VerifyStorage();
-
+
/* duplicate */
for (int v =0; v<m_bmesh->totvert; v++)
{
@@ -342,15 +343,10 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
m_armobj->ApplyPose();
- switch (m_armobj->GetVertDeformType())
- {
- case ARM_VDEF_BGE_CPU:
- BGEDeformVerts();
- break;
- case ARM_VDEF_BLENDER:
- default:
- BlenderDeformVerts();
- }
+ if (m_armobj->GetVertDeformType() == ARM_VDEF_BGE_CPU)
+ BGEDeformVerts();
+ else
+ BlenderDeformVerts();
/* Update the current frame */
m_lastArmaUpdate=m_armobj->GetLastFrame();
@@ -358,6 +354,9 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
m_armobj->RestorePose();
/* dynamic vertex, cannot use display list */
m_bDynamic = true;
+
+ UpdateTransverts();
+
/* indicate that the m_transverts and normals are up to date */
return true;
}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index 7495deb2257..79043f60db8 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -114,6 +114,8 @@ protected:
void BlenderDeformVerts();
void BGEDeformVerts();
+ void UpdateTransverts();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_SkinDeformer")
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
index be85d89775f..75beb5d0e0e 100644
--- a/source/gameengine/Converter/BlenderWorldInfo.cpp
+++ b/source/gameengine/Converter/BlenderWorldInfo.cpp
@@ -61,6 +61,7 @@
#include "BLI_math.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
/* end of blender include block */
@@ -86,7 +87,7 @@ BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *ble
copy_v3_v3(m_backgroundcolor, &blenderworld->horr);
copy_v3_v3(m_ambientcolor, &blenderworld->ambr);
- if (blenderscene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if (BKE_scene_check_color_management_enabled(blenderscene)) {
linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor);
linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor);
linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index c0c28d15ad3..5930d5e90d2 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -50,7 +50,6 @@
#include "DummyPhysicsEnvironment.h"
-#include "KX_ConvertPhysicsObject.h"
#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
@@ -190,9 +189,6 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
}
m_meshobjects.clear();
-#ifdef WITH_BULLET
- KX_ClearBulletSharedShapes();
-#endif
/* free any data that was dynamically loaded */
while (m_DynamicMaggie.size() != 0)
@@ -233,8 +229,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
Scene *sce;
/**
- * Find the specified scene by name, or the first
- * scene if nothing matches (shouldn't happen).
+ * Find the specified scene by name, or NULL if nothing matches.
*/
if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
return sce;
@@ -246,64 +241,10 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
return sce;
}
- return (Scene*)m_maggie->scene.first;
+ return NULL;
}
-#ifdef WITH_BULLET
-
-#include "LinearMath/btIDebugDraw.h"
-
-
-struct BlenderDebugDraw : public btIDebugDraw
-{
- BlenderDebugDraw () :
- m_debugMode(0)
- {
- }
-
- int m_debugMode;
-
- virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
- {
- if (m_debugMode >0)
- {
- MT_Vector3 kxfrom(from[0],from[1],from[2]);
- MT_Vector3 kxto(to[0],to[1],to[2]);
- MT_Vector3 kxcolor(color[0],color[1],color[2]);
-
- KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
- }
- }
-
- virtual void reportErrorWarning(const char* warningString)
- {
-
- }
-
- virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
- {
- //not yet
- }
-
- virtual void setDebugMode(int debugMode)
- {
- m_debugMode = debugMode;
- }
- virtual int getDebugMode() const
- {
- return m_debugMode;
- }
- ///todo: find out if Blender can do this
- virtual void draw3dText(const btVector3& location,const char* textString)
- {
-
- }
-
-};
-
-#endif
-
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
class RAS_IRasterizer* rendertools,
class RAS_ICanvas* canvas,
@@ -312,8 +253,9 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
//find out which physics engine
Scene *blenderscene = destinationscene->GetBlenderScene();
+ PHY_IPhysicsEnvironment *phy_env = NULL;
+
e_PhysicsEngine physics_engine = UseBullet;
- bool useDbvtCulling = false;
// hook for registration function during conversion.
m_currentScene = destinationscene;
destinationscene->SetSceneConverter(this);
@@ -322,56 +264,31 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
// when doing threaded conversion, so it's disabled for now.
// SG_SetActiveStage(SG_STAGE_CONVERTER);
- if (blenderscene)
+ switch (blenderscene->gm.physicsEngine)
{
-
- switch (blenderscene->gm.physicsEngine)
+#ifdef WITH_BULLET
+ case WOPHY_BULLET:
{
- case WOPHY_BULLET:
- {
- physics_engine = UseBullet;
- useDbvtCulling = (blenderscene->gm.mode & WO_DBVT_CULLING) != 0;
- break;
- }
- default:
- case WOPHY_NONE:
- {
- physics_engine = UseNone;
- break;
- }
- }
- }
+ SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
+ int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
- switch (physics_engine)
- {
-#ifdef WITH_BULLET
- case UseBullet:
- {
- CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
- ccdPhysEnv->SetDebugDrawer(new BlenderDebugDraw());
- ccdPhysEnv->SetDeactivationLinearTreshold(blenderscene->gm.lineardeactthreshold);
- ccdPhysEnv->SetDeactivationAngularTreshold(blenderscene->gm.angulardeactthreshold);
- ccdPhysEnv->SetDeactivationTime(blenderscene->gm.deactivationtime);
-
- SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
- int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
- if (visualizePhysics)
- ccdPhysEnv->SetDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
-
- //todo: get a button in blender ?
- //disable / enable debug drawing (contact points, aabb's etc)
- //ccdPhysEnv->setDebugMode(1);
- destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
- break;
- }
+ phy_env = CcdPhysicsEnvironment::Create(blenderscene, visualizePhysics);
+ physics_engine = UseBullet;
+ break;
+ }
#endif
- default:
- case UseNone:
+ default:
+ case WOPHY_NONE:
+ {
+ // We should probably use some sort of factory here
+ phy_env = new DummyPhysicsEnvironment();
physics_engine = UseNone;
- destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
break;
+ }
}
+ destinationscene->SetPhysicsEnvironment(phy_env);
+
BL_ConvertBlenderObjects(m_maggie,
destinationscene,
m_ketsjiEngine,
@@ -393,12 +310,6 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
//This cache mecanism is buggy so I leave it disable and the memory leak
//that would result from this is fixed in RemoveScene()
m_map_mesh_to_gamemesh.clear();
-
-#ifndef WITH_BULLET
- /* quiet compiler warning */
- (void)useDbvtCulling;
-#endif
-
}
// This function removes all entities stored in the converter for that scene
@@ -1547,6 +1458,20 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
{
/* Find a mesh in the current main */
ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2));
+ Main *from_maggie = m_maggie;
+
+ if (me == NULL) {
+ // The mesh wasn't in the current main, try any dynamic (i.e., LibLoaded) ones
+ vector<Main*>::iterator it;
+
+ for (it = GetMainDynamic().begin(); it != GetMainDynamic().end(); it++) {
+ me = static_cast<ID *>(BLI_findstring(&(*it)->mesh, name, offsetof(ID, name) + 2));
+ from_maggie = *it;
+
+ if (me)
+ break;
+ }
+ }
if (me==NULL) {
printf("Could not be found \"%s\"\n", name);
@@ -1556,10 +1481,10 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
/* Watch this!, if its used in the original scene can cause big troubles */
if (me->us > 0) {
printf("Mesh has a user \"%s\"\n", name);
- me = (ID*)BKE_mesh_copy((Mesh*)me);
+ me = (ID*)BKE_mesh_copy_ex(from_maggie, (Mesh*)me);
me->us--;
}
- BLI_remlink(&m_maggie->mesh, me); /* even if we made the copy it needs to be removed */
+ BLI_remlink(&from_maggie->mesh, me); /* even if we made the copy it needs to be removed */
BLI_addtail(&maggie->mesh, me);
@@ -1585,7 +1510,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
mat_new->id.flag |= LIB_DOIT;
mat_old->id.us--;
- BLI_remlink(&m_maggie->mat, mat_new);
+ BLI_remlink(&G.main->mat, mat_new); // BKE_material_copy uses G.main, and there is no BKE_material_copy_ex
BLI_addtail(&maggie->mat, mat_new);
mesh->mat[i] = mat_new;
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 26401fcd868..b59c26ab90b 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -758,7 +758,9 @@ void BL_ConvertActuators(const char* maggiename,
mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
if (sceneact->camera)
{
- cam = (KX_Camera*) converter->FindGameObject(sceneact->camera);
+ KX_GameObject *tmp = converter->FindGameObject(sceneact->camera);
+ if (tmp && tmp->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
+ cam = (KX_Camera*)tmp;
}
break;
case ACT_SCENE_RESTART:
@@ -1104,7 +1106,7 @@ void BL_ConvertActuators(const char* maggiename,
; /* generate some error */
}
- if (baseact)
+ if (baseact && !(bact->flag & ACT_DEACTIVATE))
{
baseact->SetExecutePriority(executePriority++);
uniquename += "#ACT#";
@@ -1120,6 +1122,8 @@ void BL_ConvertActuators(const char* maggiename,
// done with baseact, release it
baseact->Release();
}
+ else if (baseact)
+ baseact->Release();
bact = bact->next;
}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 5d3d0f33bec..0215b604fdd 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -94,7 +94,8 @@ void BL_ConvertControllers(
SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
- KX_BlenderSceneConverter* converter
+ KX_BlenderSceneConverter* converter,
+ bool libloading
) {
int uniqueint=0;
int count = 0;
@@ -157,8 +158,9 @@ void BL_ConvertControllers(
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
gamecontroller = pyctrl;
#ifdef WITH_PYTHON
- PyGILState_STATE gstate = PyGILState_Ensure();
- pyctrl->SetNamespace(converter->GetPyNamespace());
+ // When libloading, this is delayed to KX_Scene::MergeScene_LogicBrick to avoid GIL issues
+ if (!libloading)
+ pyctrl->SetNamespace(converter->GetPyNamespace());
if (pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
if (pycont->text)
@@ -185,8 +187,6 @@ void BL_ConvertControllers(
pyctrl->SetDebug(true);
}
}
-
- PyGILState_Release(gstate);
#endif // WITH_PYTHON
break;
@@ -197,7 +197,7 @@ void BL_ConvertControllers(
}
}
- if (gamecontroller)
+ if (gamecontroller && !(bcontr->flag & CONT_DEACTIVATE))
{
LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
gamecontroller->SetExecutePriority(executePriority++);
@@ -219,8 +219,8 @@ void BL_ConvertControllers(
converter->RegisterGameController(gamecontroller, bcontr);
#ifdef WITH_PYTHON
- PyGILState_STATE gstate = PyGILState_Ensure();
- if (bcontr->type==CONT_PYTHON) {
+ // When libloading, this is delayed to KX_Scene::MergeScene_LogicBrick to avoid GIL issues
+ if (!libloading && bcontr->type==CONT_PYTHON) {
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
/* not strictly needed but gives syntax errors early on and
* gives more predictable performance for larger scripts */
@@ -235,12 +235,13 @@ void BL_ConvertControllers(
}
}
- PyGILState_Release(gstate);
#endif // WITH_PYTHON
//done with gamecontroller
gamecontroller->Release();
}
+ else if (gamecontroller)
+ gamecontroller->Release();
bcontr = bcontr->next;
}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h
index 817a49e1b2f..babe3e2e73f 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.h
+++ b/source/gameengine/Converter/KX_ConvertControllers.h
@@ -40,7 +40,8 @@ void BL_ConvertControllers(
class SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
- class KX_BlenderSceneConverter* converter
+ class KX_BlenderSceneConverter* converter,
+ bool libloading
);
#endif /* __KX_CONVERTCONTROLLERS_H__ */
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 2e2ebda47e2..b3c6f6ddd24 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -49,6 +49,7 @@
#include "DNA_object_types.h"
#include "DNA_material_types.h"
#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
#include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
* probably misplaced */
/* end of blender include block */
@@ -575,7 +576,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
}
}
- if (gamesensor)
+ if (gamesensor && !(sens->flag & SENS_DEACTIVATE))
{
gamesensor->SetExecutePriority(executePriority++);
STR_String uniquename = sens->name;
@@ -606,16 +607,19 @@ void BL_ConvertSensors(struct Object* blenderobject,
{
bController* linkedcont = (bController*) sens->links[i];
if (linkedcont) {
- SCA_IController* gamecont = converter->FindGameController(linkedcont);
+ // If the controller is deactived doesn't register it
+ if (!(linkedcont->flag & CONT_DEACTIVATE)) {
+ SCA_IController* gamecont = converter->FindGameController(linkedcont);
- if (gamecont) {
- logicmgr->RegisterToSensor(gamecont,gamesensor);
- }
- else {
- printf("Warning, sensor \"%s\" could not find its controller "
- "(link %d of %d) from object \"%s\"\n"
- "\tthere has been an error converting the blender controller for the game engine,"
- "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ if (gamecont) {
+ logicmgr->RegisterToSensor(gamecont,gamesensor);
+ }
+ else {
+ printf("Warning, sensor \"%s\" could not find its controller "
+ "(link %d of %d) from object \"%s\"\n"
+ "\tthere has been an error converting the blender controller for the game engine,"
+ "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ }
}
}
else {
@@ -636,6 +640,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
gamesensor->Release();
}
+ else if (gamesensor)
+ gamesensor->Release();
+
sens=sens->next;
}
}
diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
index fcdaaaa761a..877aebff556 100644
--- a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
+++ b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
@@ -36,7 +36,6 @@
#include "MT_assert.h"
-#include "KX_ConvertPhysicsObject.h"
#include "KX_SoftBodyDeformer.h"
#include "RAS_MeshObject.h"
#include "CTR_Map.h"
diff --git a/source/gameengine/Expressions/IfExpr.cpp b/source/gameengine/Expressions/IfExpr.cpp
index baf91e4a5c3..152ca8704ce 100644
--- a/source/gameengine/Expressions/IfExpr.cpp
+++ b/source/gameengine/Expressions/IfExpr.cpp
@@ -64,8 +64,8 @@ CIfExpr::~CIfExpr()
/**
* pre:
- * ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE
- * a new object containing the value of m_e2 if m_guard is a boolean FALSE
+ * ret: a new object containing the value of m_e1 if m_guard is a boolean true
+ * a new object containing the value of m_e2 if m_guard is a boolean false
* an new errorvalue if m_guard is not a boolean
*/
CValue* CIfExpr::Calculate()
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 83322fe8243..eb9a6d9aca1 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -77,7 +77,6 @@ public:
void Replace_LogicManager(SCA_LogicManager* logicmgr) { m_logicmgr= logicmgr; }
- virtual void Replace_PhysicsScene(class PHY_IPhysicsEnvironment* env) { } /* only for event managers that use one */
protected:
EVENT_MANAGER_TYPE m_mgrtype;
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 1ce6650831e..b85d4b40ca8 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -187,7 +187,7 @@ static POINT scr_save_mouse_pos;
static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- BOOL close = FALSE;
+ BOOL close = false;
switch (uMsg)
{
case WM_MOUSEMOVE:
@@ -199,7 +199,7 @@ static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wPara
if (abs(dx) > SCR_SAVE_MOUSE_MOVE_THRESHOLD
|| abs(dy) > SCR_SAVE_MOUSE_MOVE_THRESHOLD)
{
- close = TRUE;
+ close = true;
}
scr_save_mouse_pos = pt;
break;
@@ -208,7 +208,7 @@ static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wPara
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
- close = TRUE;
+ close = true;
}
if (close)
PostMessage(hwnd,WM_CLOSE,0,0);
@@ -218,11 +218,11 @@ static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wPara
BOOL CALLBACK findGhostWindowHWNDProc(HWND hwnd, LPARAM lParam)
{
GHOST_IWindow *p = (GHOST_IWindow*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
- BOOL ret = TRUE;
+ BOOL ret = true;
if (p == ghost_window_to_find)
{
found_ghost_window_hwnd = hwnd;
- ret = FALSE;
+ ret = false;
}
return ret;
}
@@ -268,7 +268,7 @@ bool GPG_Application::startScreenSaverPreview(
LONG_PTR exstyle = GetWindowLongPtr(ghost_hwnd, GWL_EXSTYLE);
RECT adjrc = { 0, 0, windowWidth, windowHeight };
- AdjustWindowRectEx(&adjrc, style, FALSE, exstyle);
+ AdjustWindowRectEx(&adjrc, style, false, exstyle);
style = (style & (~(WS_POPUP|WS_OVERLAPPEDWINDOW|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_TILEDWINDOW ))) | WS_CHILD;
SetWindowLongPtr(ghost_hwnd, GWL_STYLE, style);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
index e0559385ee6..35c7c62a67d 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
@@ -91,7 +91,7 @@ void GPG_Canvas::SetMouseState(RAS_MouseState mousestate)
m_window->setCursorVisibility(true);
break;
case MOUSE_NORMAL:
- m_window->setCursorShape(GHOST_kStandardCursorRightArrow);
+ m_window->setCursorShape(GHOST_kStandardCursorDefault);
m_window->setCursorVisibility(true);
break;
}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 44e02ee00c9..31fafd86db7 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -149,13 +149,13 @@ static BOOL scr_saver_init(int argc, char **argv)
{
scr_saver_mode = SCREEN_SAVER_MODE_NONE;
scr_saver_hwnd = NULL;
- BOOL ret = FALSE;
+ BOOL ret = false;
int len = ::strlen(argv[0]);
if (len > 4 && !::stricmp(".scr", argv[0] + len - 4))
{
scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION;
- ret = TRUE;
+ ret = true;
if (argc >= 2)
{
if (argc >= 3)
@@ -195,7 +195,7 @@ static void usage(const char* program, bool isBlenderPlayer)
const char * example_pathname = "";
#ifdef _WIN32
- consoleoption = "-c ";
+ consoleoption = "[-c] ";
#else
consoleoption = "";
#endif
@@ -208,33 +208,40 @@ static void usage(const char* program, bool isBlenderPlayer)
example_pathname = "/home/user/";
#endif
}
-
- printf("usage: %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
- "[-s stereomode] [-m aasamples] %s\n", program, consoleoption, example_filename);
+ printf("\n");
+ printf("usage: %s [--options] %s\n\n", program, example_filename);
+ printf("Available options are: [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] ", consoleoption);
+ printf("[-s stereomode] [-m aasamples]\n");
+ printf("Optional parameters must be passed in order.\n");
+ printf("Default values are set in the blend file.\n\n");
printf(" -h: Prints this command summary\n\n");
printf(" -w: display in a window\n");
printf(" --Optional parameters--\n");
printf(" w = window width\n");
- printf(" h = window height\n\n");
+ printf(" h = window height\n");
printf(" l = window left coordinate\n");
printf(" t = window top coordinate\n");
- printf(" Note: If w or h is defined, both must be defined.\n");
- printf(" Also, if l or t is defined, all options must be used.\n\n");
- printf(" -f: start game in full screen mode\n");
+ printf(" Note: To define 'w' or 'h', both must be used.");
+ printf("Also, to define 'l' or 't', all four parameters must be used.\n");
+ printf(" Example: -w or -w 500 300 or -w 500 300 0 0\n\n");
+ printf(" -f: start game in fullscreen mode\n");
printf(" --Optional parameters--\n");
- printf(" fw = full screen mode pixel width\n");
- printf(" fh = full screen mode pixel height\n\n");
- printf(" fb = full screen mode bits per pixel\n");
- printf(" ff = full screen mode frequency\n");
- printf(" Note: If fw or fh is defined, both must be defined.\n");
- printf(" Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
- printf(" -s: start player in stereo\n");
- printf(" stereomode: hwpageflip (Quad buffered shutter glasses)\n");
- printf(" syncdoubling (Above Below)\n");
- printf(" sidebyside (Left Right)\n");
+ printf(" fw = fullscreen mode pixel width (use 0 to detect automatically)\n");
+ printf(" fh = fullscreen mode pixel height (use 0 to detect automatically)\n");
+ printf(" fb = fullscreen mode bits per pixel (default unless set in the blend file: 32)\n");
+ printf(" ff = fullscreen mode frequency (default unless set in the blend file: 60)\n");
+ printf(" Note: To define 'fw'' or 'fh'', both must be used.\n");
+ printf(" Example: -f or -f 1024 768 or -f 0 0 16 or -f 1024 728 16 30\n\n");
+ printf(" -s: start player in stereoscopy mode (requires 3D capable hardware)\n");
+ printf(" stereomode: nostereo (default unless stereo is set in the blend file)\n");
printf(" anaglyph (Red-Blue glasses)\n");
+ printf(" sidebyside (Left Right)\n");
+ printf(" syncdoubling (Above Below)\n");
+ printf(" 3dtvtopbottom (Squashed Top-Bottom for passive glasses)\n");
+ printf(" interlace (Interlace horizontally)\n");
printf(" vinterlace (Vertical interlace for autostereo display)\n");
- printf(" depending on the type of stereo you want\n\n");
+ printf(" hwpageflip (Quad buffered shutter glasses)\n");
+ printf(" Example: -s sidebyside or -s vinterlace\n\n");
printf(" -D: start player in dome mode\n");
printf(" --Optional parameters--\n");
printf(" angle = field of view in degrees\n");
@@ -245,9 +252,9 @@ static void usage(const char* program, bool isBlenderPlayer)
printf(" truncatedrear (Rear-Truncated)\n");
printf(" cubemap (Cube Map)\n");
printf(" sphericalpanoramic (Spherical Panoramic)\n");
- printf(" depending on the type of dome you are using\n\n");
+ printf(" Example: -D or -D mode cubemap\n\n");
printf(" -m: maximum anti-aliasing (eg. 2,4,8,16)\n\n");
- printf(" -i: parent windows ID\n\n");
+ printf(" -i: parent window's ID\n\n");
#ifdef _WIN32
printf(" -c: keep console window open\n\n");
#endif
@@ -265,7 +272,7 @@ static void usage(const char* program, bool isBlenderPlayer)
printf("\n");
printf(" - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
printf("\n");
- printf("example: %s -w 320 200 10 10 -g noaudio%s%s\n", program, example_pathname, example_filename);
+ printf("example: %s -w 320 200 10 10 -g noaudio %s%s\n", program, example_pathname, example_filename);
printf("example: %s -g show_framerate = 0 %s%s\n", program, example_pathname, example_filename);
printf("example: %s -i 232421 -m 16 %s%s\n\n", program, example_pathname, example_filename);
}
@@ -412,7 +419,7 @@ int main(int argc, char** argv)
int fullScreenBpp = 32;
int fullScreenFrequency = 60;
GHOST_TEmbedderWindowID parentWindow = 0;
- bool isBlenderPlayer = false;
+ bool isBlenderPlayer = false; //true when lauching from blender or command line. false for bundled player
int validArguments=0;
bool samplesParFound = false;
GHOST_TUns16 aasamples = 0;
@@ -502,13 +509,20 @@ int main(int argc, char** argv)
set_free_windowmanager_cb(wm_free);
- /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
+ /* if running blenderplayer the last argument can't be parsed since it has to be the filename. else it is bundled */
isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
if (isBlenderPlayer)
validArguments = argc - 1;
else
validArguments = argc;
+
+ /* Parsing command line arguments (can be set from WM_OT_blenderplayer_start) */
+#if defined(DEBUG)
+ printf("Parsing command line arguments...\n");
+ printf("Num of arguments is: %i\n", validArguments-1); //-1 because i starts at 1
+#endif
+
for (i = 1; (i < validArguments) && !error
#ifdef WIN32
&& scr_saver_mode == SCREEN_SAVER_MODE_NONE
@@ -517,7 +531,7 @@ int main(int argc, char** argv)
{
#if defined(DEBUG)
- printf("argv[%d] = '%s', %i\n", i, argv[i],argc);
+ printf("argv[%d] = '%s'\n", i, argv[i]);
#endif
if (argv[i][0] == '-')
{
@@ -529,44 +543,43 @@ int main(int argc, char** argv)
switch (argv[i][1])
{
- case 'g':
- // Parse game options
+ case 'g': //game engine options (show_framerate, fixedtime, etc)
+ {
+ i++;
+ if (i <= validArguments)
{
- i++;
- if (i <= validArguments)
+ char* paramname = argv[i];
+ // Check for single value versus assignment
+ if (i+1 <= validArguments && (*(argv[i+1]) == '='))
{
- char* paramname = argv[i];
- // Check for single value versus assignment
- if (i+1 <= validArguments && (*(argv[i+1]) == '='))
+ i++;
+ if (i + 1 <= validArguments)
{
i++;
- if (i + 1 <= validArguments)
- {
- i++;
- // Assignment
- SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
- SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
- SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
+ // Assignment
+ SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
+ SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
+ SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
#if defined(DEBUG)
- printf("%s = '%s'\n", paramname, argv[i]);
+ printf("%s = '%s'\n", paramname, argv[i]);
#endif
- i++;
- }
- else
- {
- error = true;
- printf("error: argument assignment %s without value.\n", paramname);
- }
+ i++;
}
else
{
-// SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
+ error = true;
+ printf("error: argument assignment %s without value.\n", paramname);
}
}
+ else
+ {
+// SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
+ }
}
break;
-
- case 'd':
+ }
+ case 'd': //debug on
+ {
i++;
G.debug |= G_DEBUG;
MEM_set_memory_debug();
@@ -574,8 +587,9 @@ int main(int argc, char** argv)
BLI_mempool_set_memory_debug();
#endif
break;
-
- case 'f':
+ }
+ case 'f': //fullscreen mode
+ {
i++;
fullScreen = true;
fullScreenParFound = true;
@@ -590,30 +604,51 @@ int main(int argc, char** argv)
fullScreenFrequency = atoi(argv[i++]);
}
}
+ else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
+ {
+ error = true;
+ printf("error: to define fullscreen width or height, both options must be used.\n");
+ }
break;
- case 'w':
- // Parse window position and size options
+ }
+ case 'w': //display in a window
+ {
i++;
fullScreen = false;
windowParFound = true;
+ // Parse window position and size options
if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
{
windowWidth = atoi(argv[i++]);
windowHeight = atoi(argv[i++]);
+
if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
{
windowLeft = atoi(argv[i++]);
windowTop = atoi(argv[i++]);
}
+ else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
+ {
+ error = true;
+ printf("error: to define the window left or right coordinates, both options must be used.\n");
+ }
+ }
+ else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
+ {
+ error = true;
+ printf("error: to define the window's width or height, both options must be used.\n");
}
break;
-
- case 'h':
+ }
+ case 'h': //display help
+ {
usage(argv[0], isBlenderPlayer);
return 0;
break;
- case 'i':
+ }
+ case 'i': //parent window ID
+ {
i++;
if ( (i + 1) <= validArguments )
parentWindow = atoi(argv[i++]);
@@ -625,7 +660,9 @@ int main(int argc, char** argv)
printf("XWindows ID = %d\n", parentWindow);
#endif // defined(DEBUG)
break;
- case 'm':
+ }
+ case 'm': //maximum anti-aliasing (eg. 2,4,8,16)
+ {
i++;
samplesParFound = true;
if ((i+1) <= validArguments )
@@ -636,22 +673,28 @@ int main(int argc, char** argv)
printf("error: No argument supplied for -m");
}
break;
- case 'c':
+ }
+ case 'c': //keep console (windows only)
+ {
i++;
#ifdef WIN32
closeConsole = false;
#endif
break;
- case 's': // stereo
+ }
+ case 's': //stereo mode
+ {
i++;
if ((i + 1) <= validArguments)
{
- stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
- if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
- stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+ stereoParFound = true;
+ stereoFlag = STEREO_ENABLED;
- if (!strcmp(argv[i], "nostereo")) // ok, redundant but clear
+ if (!strcmp(argv[i], "nostereo")) // may not be redundant if the file has different setting
+ {
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+ stereoFlag = STEREO_NOSTEREO;
+ }
// only the hardware pageflip method needs a stereo window
else if (!strcmp(argv[i], "hwpageflip")) {
@@ -670,6 +713,9 @@ int main(int argc, char** argv)
else if (!strcmp(argv[i], "sidebyside"))
stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
+ else if (!strcmp(argv[i], "interlace"))
+ stereomode = RAS_IRasterizer::RAS_STEREO_INTERLACED;
+
else if (!strcmp(argv[i], "vinterlace"))
stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
@@ -678,10 +724,13 @@ int main(int argc, char** argv)
// else if (!strcmp(argv[i], "stencil")
// stereomode = RAS_STEREO_STENCIL;
#endif
+ else
+ {
+ error = true;
+ printf("error: stereomode '%s' unrecognized.\n", argv[i]);
+ }
i++;
- stereoParFound = true;
- stereoFlag = STEREO_ENABLED;
}
else
{
@@ -689,7 +738,9 @@ int main(int argc, char** argv)
printf("error: too few options for stereo argument.\n");
}
break;
- case 'D':
+ }
+ case 'D': //dome mode
+ {
stereoFlag = STEREO_DOME;
stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
i++;
@@ -730,10 +781,13 @@ int main(int argc, char** argv)
i++;
}
break;
- default:
+ }
+ default: //not recognized
+ {
printf("Unknown argument: %s\n", argv[i++]);
break;
}
+ }
}
else
{
@@ -825,8 +879,10 @@ int main(int argc, char** argv)
else {
bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
}
-
- //::printf("game data loaded from %s\n", filename);
+
+#if defined(DEBUG)
+ printf("Game data loaded from %s\n", filename);
+#endif
if (!bfd) {
usage(argv[0], isBlenderPlayer);
@@ -834,6 +890,7 @@ int main(int argc, char** argv)
exitcode = KX_EXIT_REQUEST_QUIT_GAME;
}
else {
+ /* Setting options according to the blend file if not overriden in the command line */
#ifdef WIN32
#if !defined(DEBUG)
if (closeConsole) {
@@ -877,8 +934,9 @@ int main(int argc, char** argv)
}
- // Check whether the game should be displayed in stereo
+ // Check whether the game should be displayed in stereo (dome included)
if (!stereoParFound) {
+ // Only use file settings when command line did not override
if (scene->gm.stereoflag == STEREO_ENABLED) {
stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
@@ -892,6 +950,7 @@ int main(int argc, char** argv)
if (!samplesParFound)
aasamples = scene->gm.aasamples;
+ // Dome specific settings
if (stereoFlag == STEREO_DOME) {
stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
scene->gm.stereoflag = STEREO_DOME;
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index a974ffbf672..a50c07a486a 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -51,10 +51,14 @@ extern "C" {
#include "DNA_material_types.h"
}
+#include "MEM_guardedalloc.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+
BL_Action::BL_Action(class KX_GameObject* gameobj)
:
m_action(NULL),
- m_pose(NULL),
+ m_tmpaction(NULL),
m_blendpose(NULL),
m_blendinpose(NULL),
m_obj(gameobj),
@@ -77,13 +81,16 @@ BL_Action::BL_Action(class KX_GameObject* gameobj)
BL_Action::~BL_Action()
{
- if (m_pose)
- game_free_pose(m_pose);
if (m_blendpose)
- game_free_pose(m_blendpose);
+ BKE_pose_free(m_blendpose);
if (m_blendinpose)
- game_free_pose(m_blendinpose);
+ BKE_pose_free(m_blendinpose);
ClearControllerList();
+
+ if (m_tmpaction) {
+ BKE_libblock_free(G.main, m_tmpaction);
+ m_tmpaction = NULL;
+ }
}
void BL_Action::ClearControllerList()
@@ -139,6 +146,13 @@ bool BL_Action::Play(const char* name,
&& m_priority == priority && m_speed == playback_speed)
return false;
+ // Keep a copy of the action for threading purposes
+ if (m_tmpaction) {
+ BKE_libblock_free(G.main, m_tmpaction);
+ m_tmpaction = NULL;
+ }
+ m_tmpaction = BKE_action_copy(m_action);
+
// First get rid of any old controllers
ClearControllerList();
@@ -208,7 +222,7 @@ bool BL_Action::Play(const char* name,
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
{
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
- obj->GetMRDPose(&m_blendinpose);
+ obj->GetPose(&m_blendinpose);
}
else
{
@@ -402,22 +416,12 @@ void BL_Action::Update(float curtime)
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
{
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
- obj->GetPose(&m_pose);
-
- // Extract the pose from the action
- {
- Object *arm = obj->GetArmatureObject();
- bPose *temp = arm->pose;
-
- arm->pose = m_pose;
-
- PointerRNA ptrrna;
- RNA_id_pointer_create(&arm->id, &ptrrna);
- animsys_evaluate_action(&ptrrna, m_action, NULL, m_localtime);
+ if (m_layer_weight >= 0)
+ obj->GetPose(&m_blendpose);
- arm->pose = temp;
- }
+ // Extract the pose from the action
+ obj->SetPoseByAction(m_tmpaction, m_localtime);
// Handle blending between armature actions
if (m_blendin && m_blendframe<m_blendin)
@@ -428,20 +432,15 @@ void BL_Action::Update(float curtime)
float weight = 1.f - (m_blendframe/m_blendin);
// Blend the poses
- game_blend_poses(m_pose, m_blendinpose, weight, ACT_BLEND_BLEND);
+ obj->BlendInPose(m_blendinpose, weight, ACT_BLEND_BLEND);
}
// Handle layer blending
if (m_layer_weight >= 0)
- {
- obj->GetMRDPose(&m_blendpose);
- game_blend_poses(m_pose, m_blendpose, m_layer_weight, m_blendmode);
- }
-
- obj->SetPose(m_pose);
+ obj->BlendInPose(m_blendpose, m_layer_weight, m_blendmode);
- obj->SetActiveAction(NULL, 0, curtime);
+ obj->UpdateTimestep(curtime);
}
else
{
@@ -456,7 +455,7 @@ void BL_Action::Update(float curtime)
PointerRNA ptrrna;
RNA_id_pointer_create(&key->id, &ptrrna);
- animsys_evaluate_action(&ptrrna, m_action, NULL, m_localtime);
+ animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localtime);
// Handle blending between shape actions
if (m_blendin && m_blendframe < m_blendin)
@@ -486,8 +485,15 @@ void BL_Action::Update(float curtime)
}
}
- m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ // This isn't thread-safe, so we move it into it's own function for now
+ //m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
if (m_done)
ClearControllerList();
}
+
+void BL_Action::UpdateIPOs()
+{
+ if (!m_done)
+ m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+}
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
index e9d09916517..dd1cd1f69ff 100644
--- a/source/gameengine/Ketsji/BL_Action.h
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -38,7 +38,7 @@ class BL_Action
{
private:
struct bAction* m_action;
- struct bPose* m_pose;
+ struct bAction* m_tmpaction;
struct bPose* m_blendpose;
struct bPose* m_blendinpose;
std::vector<class SG_Controller*> m_sg_contr_list;
@@ -105,6 +105,10 @@ public:
* Update the action's frame, etc.
*/
void Update(float curtime);
+ /**
+ * Update object IPOs (note: not thread-safe!)
+ */
+ void UpdateIPOs();
// Accessors
float GetFrame();
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
index 2e882ceba74..07adce73b4a 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.cpp
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -24,44 +24,72 @@
* \ingroup ketsji
*/
-#include "BL_ActionManager.h"
#include "BL_Action.h"
+#include "BL_ActionManager.h"
-BL_ActionManager::BL_ActionManager(class KX_GameObject *obj)
+BL_ActionManager::BL_ActionManager(class KX_GameObject *obj):
+ m_obj(obj)
{
- for (int i=0; i<MAX_ACTION_LAYERS; ++i)
- m_layers[i] = new BL_Action(obj);
}
BL_ActionManager::~BL_ActionManager()
{
- for (int i=0; i<MAX_ACTION_LAYERS; ++i)
- delete m_layers[i];
+ BL_ActionMap::iterator it;
+
+ for (it = m_layers.begin(); it != m_layers.end(); it++)
+ delete it->second;
+
+ m_layers.clear();
+}
+
+BL_Action *BL_ActionManager::GetAction(short layer)
+{
+ BL_ActionMap::iterator it = m_layers.find(layer);
+
+ return (it != m_layers.end()) ? it->second : 0;
+}
+
+BL_Action* BL_ActionManager::AddAction(short layer)
+{
+ BL_Action *action = new BL_Action(m_obj);
+ m_layers[layer] = action;
+
+ return action;
}
float BL_ActionManager::GetActionFrame(short layer)
{
- return m_layers[layer]->GetFrame();
+ BL_Action *action = GetAction(layer);
+
+ return action ? action->GetFrame() : 0.f;
}
void BL_ActionManager::SetActionFrame(short layer, float frame)
{
- m_layers[layer]->SetFrame(frame);
+ BL_Action *action = GetAction(layer);
+
+ if (action) action->SetFrame(frame);
}
struct bAction *BL_ActionManager::GetCurrentAction(short layer)
{
- return m_layers[layer]->GetAction();
+ BL_Action *action = GetAction(layer);
+
+ return action ? action->GetAction() : 0;
}
void BL_ActionManager::SetPlayMode(short layer, short mode)
{
- m_layers[layer]->SetPlayMode(mode);
+ BL_Action *action = GetAction(layer);
+
+ if (action) action->SetPlayMode(mode);
}
void BL_ActionManager::SetTimes(short layer, float start, float end)
{
- m_layers[layer]->SetTimes(start, end);
+ BL_Action *action = GetAction(layer);
+
+ if (action) action->SetTimes(start, end);
}
bool BL_ActionManager::PlayAction(const char* name,
@@ -76,29 +104,53 @@ bool BL_ActionManager::PlayAction(const char* name,
float playback_speed,
short blend_mode)
{
+ // Only this method will create layer if non-existent
+ BL_Action *action = GetAction(layer);
+ if (!action)
+ action = AddAction(layer);
+
// Disable layer blending on the first layer
if (layer == 0) layer_weight = -1.f;
- return m_layers[layer]->Play(name, start, end, priority, blendin, play_mode, layer_weight, ipo_flags, playback_speed, blend_mode);
+ return action->Play(name, start, end, priority, blendin, play_mode, layer_weight, ipo_flags, playback_speed, blend_mode);
}
void BL_ActionManager::StopAction(short layer)
{
- m_layers[layer]->Stop();
+ BL_Action *action = GetAction(layer);
+
+ if (action) action->Stop();
}
bool BL_ActionManager::IsActionDone(short layer)
{
- return m_layers[layer]->IsDone();
+ BL_Action *action = GetAction(layer);
+
+ return action ? action->IsDone() : true;
}
void BL_ActionManager::Update(float curtime)
{
- for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ BL_ActionMap::iterator it;
+ for (it = m_layers.begin(); it != m_layers.end(); )
{
- if (!m_layers[i]->IsDone())
- {
- m_layers[i]->Update(curtime);
+ if (it->second->IsDone()) {
+ delete it->second;
+ m_layers.erase(it++);
}
+ else {
+ it->second->Update(curtime);
+ ++it;
+ }
+ }
+}
+
+void BL_ActionManager::UpdateIPOs()
+{
+ BL_ActionMap::iterator it;
+ for (it = m_layers.begin(); it != m_layers.end(); ++it)
+ {
+ if (!it->second->IsDone())
+ it->second->UpdateIPOs();
}
}
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
index 8c5b8e909da..5b340257881 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.h
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -31,7 +31,12 @@
#include "MEM_guardedalloc.h"
#endif
-#define MAX_ACTION_LAYERS 8
+#include <map>
+
+// Currently, we use the max value of a short.
+// We should switch to unsigned short; doesn't make sense to support negative layers.
+// This will also give us 64k layers instead of 32k.
+#define MAX_ACTION_LAYERS 32767
class BL_Action;
@@ -41,7 +46,20 @@ class BL_Action;
class BL_ActionManager
{
private:
- BL_Action* m_layers[MAX_ACTION_LAYERS];
+ typedef std::map<short,BL_Action*> BL_ActionMap;
+
+ class KX_GameObject* m_obj;
+ BL_ActionMap m_layers;
+
+ /**
+ * Check if an action exists
+ */
+ BL_Action* GetAction(short layer);
+
+ /**
+ * Add new action with given layer
+ */
+ BL_Action* AddAction(short layer);
public:
BL_ActionManager(class KX_GameObject* obj);
@@ -98,6 +116,11 @@ public:
*/
void Update(float);
+ /**
+ * Update object IPOs (note: not thread-safe!)
+ */
+ void UpdateIPOs();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_ActionManager")
#endif
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index be66e2ec84d..83f9b601e0d 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -144,7 +144,8 @@ enum BL_ras_mode
WIRE=64,
CAST_SHADOW=128,
TEX=256,
- TWOSIDED=512
+ TWOSIDED=512,
+ ONLY_SHADOW=1024,
};
// -------------------------------------
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 141dd5e25f3..09ef1677d7c 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -77,7 +77,6 @@ set(SRC
KX_CharacterWrapper.cpp
KX_ConstraintActuator.cpp
KX_ConstraintWrapper.cpp
- KX_ConvertPhysicsObjects.cpp
KX_Dome.cpp
KX_EmptyObject.cpp
KX_FontObject.cpp
@@ -151,7 +150,6 @@ set(SRC
KX_ClientObjectInfo.h
KX_ConstraintActuator.h
KX_ConstraintWrapper.h
- KX_ConvertPhysicsObject.h
KX_Dome.h
KX_EmptyObject.h
KX_FontObject.h
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index efaaed7b567..68a71218b8c 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -110,6 +110,7 @@ void KX_BlenderMaterial::Initialize(
m_flag |= ((mMaterial->ras_mode & USE_LIGHT)!=0)? RAS_MULTILIGHT: 0;
m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
+ m_flag |= ((mMaterial->ras_mode & ONLY_SHADOW)!=0)? RAS_ONLYSHADOW: 0;
// test the sum of the various modes for equality
// so we can ether accept or reject this material
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index 0c5e21322df..e5662b54b83 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -342,7 +342,6 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
KX_GameObject *parent = obj->GetParent();
if (parent) {
spc = parent->GetPhysicsController();
- parent->Release();
}
}
KX_RayCast::Callback<KX_ConstraintActuator> callback(this,dynamic_cast<PHY_IPhysicsController*>(spc));
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
deleted file mode 100644
index 0ebaec9c3ab..00000000000
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ /dev/null
@@ -1,155 +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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file KX_ConvertPhysicsObject.h
- * \ingroup ketsji
- */
-
-#ifndef __KX_CONVERTPHYSICSOBJECT_H__
-#define __KX_CONVERTPHYSICSOBJECT_H__
-
-class RAS_MeshObject;
-class KX_Scene;
-struct DerivedMesh;
-
-typedef enum {
- KX_BOUNDBOX,
- KX_BOUNDSPHERE,
- KX_BOUNDCYLINDER,
- KX_BOUNDCONE,
- KX_BOUNDMESH,
- KX_BOUNDPOLYTOPE,
- KX_BOUND_DYN_MESH,
- KX_BOUNDCAPSULE
-} KX_BoundBoxClass;
-
-struct KX_BoxBounds
-{
- float m_center[3];
- float m_extends[3];
-};
-
-/* Cone/Cylinder */
-struct KX_CBounds
-{
- float m_radius;
- float m_height;
-};
-
-
-struct KX_ObjectProperties
-{
- bool m_dyna;
- bool m_softbody;
- double m_radius;
- bool m_angular_rigidbody;
- bool m_in_active_layer;
- bool m_ghost;
- class KX_GameObject* m_dynamic_parent;
- bool m_isactor;
- bool m_record_animation;
- bool m_sensor;
- bool m_character;
- bool m_concave;
- bool m_isdeformable;
- bool m_disableSleeping;
- bool m_hasCompoundChildren;
- bool m_isCompoundChild;
-
- /////////////////////////
-
- int m_gamesoftFlag;
- float m_soft_linStiff; /* linear stiffness 0..1 */
- float m_soft_angStiff; /* angular stiffness 0..1 */
- float m_soft_volume; /* volume preservation 0..1 */
-
- int m_soft_viterations; /* Velocities solver iterations */
- int m_soft_piterations; /* Positions solver iterations */
- int m_soft_diterations; /* Drift solver iterations */
- int m_soft_citerations; /* Cluster solver iterations */
-
- float m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
- float m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
- float m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
- float m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
-
- float m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- float m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- float m_soft_kVCF; /* Velocities correction factor (Baumgarte) */
- float m_soft_kDP; /* Damping coefficient [0,1] */
-
- float m_soft_kDG; /* Drag coefficient [0,+inf] */
- float m_soft_kLF; /* Lift coefficient [0,+inf] */
- float m_soft_kPR; /* Pressure coefficient [-inf,+inf] */
- float m_soft_kVC; /* Volume conversation coefficient [0,+inf] */
-
- float m_soft_kDF; /* Dynamic friction coefficient [0,1] */
- float m_soft_kMT; /* Pose matching coefficient [0,1] */
- float m_soft_kCHR; /* Rigid contacts hardness [0,1] */
- float m_soft_kKHR; /* Kinetic contacts hardness [0,1] */
-
- float m_soft_kSHR; /* Soft contacts hardness [0,1] */
- float m_soft_kAHR; /* Anchors hardness [0,1] */
- int m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
- int m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/
- float m_soft_welding; /* threshold to remove duplicate/nearby vertices */
-
- /////////////////////////
-
- bool m_lockXaxis;
- bool m_lockYaxis;
- bool m_lockZaxis;
- bool m_lockXRotaxis;
- bool m_lockYRotaxis;
- bool m_lockZRotaxis;
-
- /////////////////////////
- double m_margin;
- float m_contactProcessingThreshold;
-
- KX_BoundBoxClass m_boundclass;
- union {
- KX_BoxBounds box;
- KX_CBounds c;
- } m_boundobject;
-};
-
-#ifdef WITH_BULLET
-
-void KX_ConvertBulletObject( class KX_GameObject* gameobj,
- class RAS_MeshObject* meshobj,
- struct DerivedMesh* dm,
- class KX_Scene* kxscene,
- struct PHY_ShapeProps* shapeprops,
- struct PHY_MaterialProps* smmaterial,
- struct KX_ObjectProperties* objprop);
-
-void KX_ClearBulletSharedShapes();
-bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj);
-
-#endif
-#endif /* __KX_CONVERTPHYSICSOBJECT_H__ */
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
deleted file mode 100644
index ff5522ee7d2..00000000000
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ /dev/null
@@ -1,584 +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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
- * \ingroup ketsji
- */
-
-#ifdef _MSC_VER
-# pragma warning (disable:4786)
-#endif
-
-#include "MT_assert.h"
-
-#include "KX_SoftBodyDeformer.h"
-#include "KX_ConvertPhysicsObject.h"
-#include "BL_DeformableGameObject.h"
-#include "RAS_MeshObject.h"
-#include "KX_Scene.h"
-#include "BL_System.h"
-
-#include "PHY_Pro.h" //todo cleanup
-#include "KX_ClientObjectInfo.h"
-
-#include "CTR_Map.h"
-#include "CTR_HashedPtr.h"
-
-#include "KX_PhysicsEngineEnums.h"
-
-#include "KX_MotionState.h" // bridge between motionstate and scenegraph node
-
-extern "C"{
- #include "BLI_utildefines.h"
- #include "BKE_DerivedMesh.h"
-}
-
-#ifdef WITH_BULLET
-#include "BulletSoftBody/btSoftBody.h"
-
-#include "CcdPhysicsEnvironment.h"
-#include "CcdPhysicsController.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
-
-#include "btBulletDynamicsCommon.h"
-
-#ifdef WIN32
-#if defined(_MSC_VER) && (_MSC_VER >= 1310)
-//only use SIMD Hull code under Win32
-//#define TEST_HULL 1
-#ifdef TEST_HULL
-#define USE_HULL 1
-//#define TEST_SIMD_HULL 1
-
-#include "NarrowPhaseCollision/Hull.h"
-#endif //#ifdef TEST_HULL
-
-#endif //_MSC_VER
-#endif //WIN32
-
-
-
-// forward declarations
-
-void KX_ConvertBulletObject( class KX_GameObject* gameobj,
- class RAS_MeshObject* meshobj,
- struct DerivedMesh* dm,
- class KX_Scene* kxscene,
- struct PHY_ShapeProps* shapeprops,
- struct PHY_MaterialProps* smmaterial,
- struct KX_ObjectProperties* objprop)
-{
-
- CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
- assert(env);
-
-
- bool isbulletdyna = false;
- bool isbulletsensor = false;
- bool isbulletchar = false;
- bool useGimpact = false;
- CcdConstructionInfo ci;
- class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
- class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
-
-
- if (!objprop->m_dyna)
- {
- ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
- }
- if (objprop->m_ghost)
- {
- ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
- }
-
- ci.m_MotionState = motionstate;
- ci.m_gravity = btVector3(0,0,0);
- ci.m_linearFactor = btVector3(objprop->m_lockXaxis? 0 : 1,
- objprop->m_lockYaxis? 0 : 1,
- objprop->m_lockZaxis? 0 : 1);
- ci.m_angularFactor = btVector3(objprop->m_lockXRotaxis? 0 : 1,
- objprop->m_lockYRotaxis? 0 : 1,
- objprop->m_lockZRotaxis? 0 : 1);
- ci.m_localInertiaTensor =btVector3(0,0,0);
- ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
- ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
- ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
- ci.m_margin = objprop->m_margin;
- ci.m_stepHeight = objprop->m_character ? shapeprops->m_step_height : 0.f;
- ci.m_jumpSpeed = objprop->m_character ? shapeprops->m_jump_speed : 0.f;
- ci.m_fallSpeed = objprop->m_character ? shapeprops->m_fall_speed : 0.f;
- shapeInfo->m_radius = objprop->m_radius;
- isbulletdyna = objprop->m_dyna;
- isbulletsensor = objprop->m_sensor;
- isbulletchar = objprop->m_character;
- useGimpact = ((isbulletdyna || isbulletsensor) && !objprop->m_softbody);
-
- ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
-
- btCollisionShape* bm = 0;
-
- switch (objprop->m_boundclass)
- {
- case KX_BOUNDSPHERE:
- {
- //float radius = objprop->m_radius;
- //btVector3 inertiaHalfExtents (
- // radius,
- // radius,
- // radius);
-
- //blender doesn't support multisphere, but for testing:
-
- //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
- shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- };
- case KX_BOUNDBOX:
- {
- shapeInfo->m_halfExtend.setValue(
- objprop->m_boundobject.box.m_extends[0],
- objprop->m_boundobject.box.m_extends[1],
- objprop->m_boundobject.box.m_extends[2]);
-
- shapeInfo->m_halfExtend /= 2.0;
- shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
- shapeInfo->m_shapeType = PHY_SHAPE_BOX;
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- };
- case KX_BOUNDCYLINDER:
- {
- shapeInfo->m_halfExtend.setValue(
- objprop->m_boundobject.c.m_radius,
- objprop->m_boundobject.c.m_radius,
- objprop->m_boundobject.c.m_height * 0.5f
- );
- shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- }
-
- case KX_BOUNDCONE:
- {
- shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
- shapeInfo->m_height = objprop->m_boundobject.c.m_height;
- shapeInfo->m_shapeType = PHY_SHAPE_CONE;
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- }
- case KX_BOUNDPOLYTOPE:
- {
- shapeInfo->SetMesh(meshobj, dm,true);
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- }
- case KX_BOUNDCAPSULE:
- {
- shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
- shapeInfo->m_height = objprop->m_boundobject.c.m_height;
- shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE;
- bm = shapeInfo->CreateBulletShape(ci.m_margin);
- break;
- }
- case KX_BOUNDMESH:
- {
- // mesh shapes can be shared, check first if we already have a shape on that mesh
- class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false);
- if (sharedShapeInfo != NULL)
- {
- shapeInfo->Release();
- shapeInfo = sharedShapeInfo;
- shapeInfo->AddRef();
- } else
- {
- shapeInfo->SetMesh(meshobj, dm, false);
- }
-
- // Soft bodies can benefit from welding, don't do it on non-soft bodies
- if (objprop->m_softbody)
- {
- shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
- }
-
- bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !objprop->m_softbody);
- //should we compute inertia for dynamic shape?
- //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-
- break;
- }
- case KX_BOUND_DYN_MESH:
- /* do nothing */
- break;
- }
-
-
-// ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
-
- if (!bm)
- {
- delete motionstate;
- shapeInfo->Release();
- return;
- }
-
- //bm->setMargin(ci.m_margin);
-
-
- if (objprop->m_isCompoundChild)
- {
- //find parent, compound shape and add to it
- //take relative transform into account!
- CcdPhysicsController* parentCtrl = (CcdPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
- assert(parentCtrl);
- CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
- btRigidBody* rigidbody = parentCtrl->GetRigidBody();
- btCollisionShape* colShape = rigidbody->getCollisionShape();
- assert(colShape->isCompound());
- btCompoundShape* compoundShape = (btCompoundShape*)colShape;
-
- // compute the local transform from parent, this may include several node in the chain
- SG_Node* gameNode = gameobj->GetSGNode();
- SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode();
- // relative transform
- MT_Vector3 parentScale = parentNode->GetWorldScaling();
- parentScale[0] = MT_Scalar(1.0)/parentScale[0];
- parentScale[1] = MT_Scalar(1.0)/parentScale[1];
- parentScale[2] = MT_Scalar(1.0)/parentScale[2];
- MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
- MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
- MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
- MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
-
- shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
- bm->setLocalScaling(shapeInfo->m_childScale);
- shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
- float rot[12];
- relativeRot.getValue(rot);
- shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
-
- parentShapeInfo->AddShape(shapeInfo);
- compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
- //do some recalc?
- //recalc inertia for rigidbody
- if (!rigidbody->isStaticOrKinematicObject())
- {
- btVector3 localInertia;
- float mass = 1.f/rigidbody->getInvMass();
- compoundShape->calculateLocalInertia(mass,localInertia);
- rigidbody->setMassProps(mass,localInertia);
- }
- shapeInfo->Release();
- // delete motionstate as it's not used
- delete motionstate;
- return;
- }
-
- if (objprop->m_hasCompoundChildren)
- {
- // create a compound shape info
- CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
- compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
- compoundShapeInfo->AddShape(shapeInfo);
- // create the compound shape manually as we already have the child shape
- btCompoundShape* compoundShape = new btCompoundShape();
- compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
- // now replace the shape
- bm = compoundShape;
- shapeInfo->Release();
- shapeInfo = compoundShapeInfo;
- }
-
-
-
-
-
-
-#ifdef TEST_SIMD_HULL
- if (bm->IsPolyhedral())
- {
- PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
- if (!polyhedron->m_optionalHull)
- {
- //first convert vertices in 'Point3' format
- int numPoints = polyhedron->GetNumVertices();
- Point3* points = new Point3[numPoints+1];
- //first 4 points should not be co-planar, so add central point to satisfy MakeHull
- points[0] = Point3(0.f,0.f,0.f);
-
- btVector3 vertex;
- for (int p=0;p<numPoints;p++)
- {
- polyhedron->GetVertex(p,vertex);
- points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
- }
-
- Hull* hull = Hull::MakeHull(numPoints+1,points);
- polyhedron->m_optionalHull = hull;
- }
-
- }
-#endif //TEST_SIMD_HULL
-
-
- ci.m_collisionShape = bm;
- ci.m_shapeInfo = shapeInfo;
- ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
- ci.m_restitution = smmaterial->m_restitution;
- ci.m_physicsEnv = env;
- // drag / damping is inverted
- ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
- ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
- //need a bit of damping, else system doesn't behave well
- ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behavior
-
- ci.m_do_anisotropic = shapeprops->m_do_anisotropic;
- ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]);
-
-
-//////////
- //do Fh, do Rot Fh
- ci.m_do_fh = shapeprops->m_do_fh;
- ci.m_do_rot_fh = shapeprops->m_do_rot_fh;
- ci.m_fh_damping = smmaterial->m_fh_damping;
- ci.m_fh_distance = smmaterial->m_fh_distance;
- ci.m_fh_normal = smmaterial->m_fh_normal;
- ci.m_fh_spring = smmaterial->m_fh_spring;
- ci.m_radius = objprop->m_radius;
-
-
- ///////////////////
- ci.m_gamesoftFlag = objprop->m_gamesoftFlag;
- ci.m_soft_linStiff = objprop->m_soft_linStiff;
- ci.m_soft_angStiff = objprop->m_soft_angStiff; /* angular stiffness 0..1 */
- ci.m_soft_volume= objprop->m_soft_volume; /* volume preservation 0..1 */
-
- ci.m_soft_viterations= objprop->m_soft_viterations; /* Velocities solver iterations */
- ci.m_soft_piterations= objprop->m_soft_piterations; /* Positions solver iterations */
- ci.m_soft_diterations= objprop->m_soft_diterations; /* Drift solver iterations */
- ci.m_soft_citerations= objprop->m_soft_citerations; /* Cluster solver iterations */
-
- ci.m_soft_kSRHR_CL= objprop->m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
- ci.m_soft_kSKHR_CL= objprop->m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
- ci.m_soft_kSSHR_CL= objprop->m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
- ci.m_soft_kSR_SPLT_CL= objprop->m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
-
- ci.m_soft_kSK_SPLT_CL= objprop->m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- ci.m_soft_kSS_SPLT_CL= objprop->m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
- ci.m_soft_kVCF= objprop->m_soft_kVCF; /* Velocities correction factor (Baumgarte) */
- ci.m_soft_kDP= objprop->m_soft_kDP; /* Damping coefficient [0,1] */
-
- ci.m_soft_kDG= objprop->m_soft_kDG; /* Drag coefficient [0,+inf] */
- ci.m_soft_kLF= objprop->m_soft_kLF; /* Lift coefficient [0,+inf] */
- ci.m_soft_kPR= objprop->m_soft_kPR; /* Pressure coefficient [-inf,+inf] */
- ci.m_soft_kVC= objprop->m_soft_kVC; /* Volume conversation coefficient [0,+inf] */
-
- ci.m_soft_kDF= objprop->m_soft_kDF; /* Dynamic friction coefficient [0,1] */
- ci.m_soft_kMT= objprop->m_soft_kMT; /* Pose matching coefficient [0,1] */
- ci.m_soft_kCHR= objprop->m_soft_kCHR; /* Rigid contacts hardness [0,1] */
- ci.m_soft_kKHR= objprop->m_soft_kKHR; /* Kinetic contacts hardness [0,1] */
-
- ci.m_soft_kSHR= objprop->m_soft_kSHR; /* Soft contacts hardness [0,1] */
- ci.m_soft_kAHR= objprop->m_soft_kAHR; /* Anchors hardness [0,1] */
- ci.m_soft_collisionflags= objprop->m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
- ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/
-
- ////////////////////
- ci.m_collisionFilterGroup =
- (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
- (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) :
- (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) :
- short(CcdConstructionInfo::StaticFilter);
- ci.m_collisionFilterMask =
- (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
- (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
- (isbulletchar) ? short(CcdConstructionInfo::AllFilter) :
- short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
- ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
-
- ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so
- ci.m_bSoft = objprop->m_softbody;
- ci.m_bDyna = isbulletdyna;
- ci.m_bSensor = isbulletsensor;
- ci.m_bCharacter = isbulletchar;
- ci.m_bGimpact = useGimpact;
- MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
- ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
- CcdPhysicsController* physicscontroller = new CcdPhysicsController(ci);
- // shapeInfo is reference counted, decrement now as we don't use it anymore
- if (shapeInfo)
- shapeInfo->Release();
-
- gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
-
- // record animation for dynamic objects
- if (isbulletdyna)
- gameobj->SetRecordAnimation(true);
-
- // don't add automatically sensor object, they are added when a collision sensor is registered
- if (!isbulletsensor && objprop->m_in_active_layer)
- {
- env->AddCcdPhysicsController( physicscontroller);
- }
- physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
- {
- btRigidBody* rbody = physicscontroller->GetRigidBody();
-
- if (rbody)
- {
- if (objprop->m_angular_rigidbody)
- {
- rbody->setLinearFactor(ci.m_linearFactor);
- rbody->setAngularFactor(ci.m_angularFactor);
- }
-
- if (rbody && objprop->m_disableSleeping)
- {
- rbody->setActivationState(DISABLE_DEACTIVATION);
- }
- }
- }
-
- CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (CcdPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0;
- physicscontroller->SetParentCtrl(parentCtrl);
-
-
- //Now done directly in ci.m_collisionFlags so that it propagates to replica
- //if (objprop->m_ghost)
- //{
- // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- //}
-
- if (objprop->m_dyna && !objprop->m_angular_rigidbody)
- {
-#if 0
- //setting the inertia could achieve similar results to constraint the up
- //but it is prone to instability, so use special 'Angular' constraint
- btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
- inertia.setX(0.f);
- inertia.setZ(0.f);
-
- physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
- physicscontroller->GetRigidBody()->updateInertiaTensor();
-#endif
-
- //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
-
- //Now done directly in ci.m_bRigid so that it propagates to replica
- //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
- ;
- }
-
- bool isActor = objprop->m_isactor;
- gameobj->getClientInfo()->m_type =
- (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
- (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
-
- // should we record animation for this object?
- if (objprop->m_record_animation)
- gameobj->SetRecordAnimation(true);
-
- // store materialname in auxinfo, needed for touchsensors
- if (meshobj)
- {
- const STR_String& matname=meshobj->GetMaterialName(0);
- gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
- } else
- {
- gameobj->getClientInfo()->m_auxilary_info = 0;
- }
-
-
-
- STR_String materialname;
- if (meshobj)
- materialname = meshobj->GetMaterialName(0);
-
-
-#if 0
- ///test for soft bodies
- if (objprop->m_softbody && physicscontroller)
- {
- btSoftBody* softBody = physicscontroller->GetSoftBody();
- if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
- {
- //should be a mesh then, so add a soft body deformer
- KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
- gameobj->SetDeformer(softbodyDeformer);
- }
- }
-#endif
-
-}
-
-
-void KX_ClearBulletSharedShapes()
-{
-}
-
-/* Refresh the physics object from either an object or a mesh.
- * gameobj must be valid
- * from_gameobj and from_meshobj can be NULL
- *
- * when setting the mesh, the following vars get priority
- * 1) from_meshobj - creates the phys mesh from RAS_MeshObject
- * 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
- * 3) gameobj - update the phys mesh from DerivedMesh or RAS_MeshObject
- *
- * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
- */
-bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj)
-{
- CcdPhysicsController *spc= static_cast<CcdPhysicsController*>(gameobj->GetPhysicsController());
- CcdShapeConstructionInfo *shapeInfo;
-
- /* if this is the child of a compound shape this can happen
- * don't support compound shapes for now */
- if (spc==NULL)
- return false;
-
- shapeInfo = spc->GetShapeInfo();
-
- if (shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
- return false;
-
- spc->DeleteControllerShape();
-
- if (from_gameobj==NULL && from_meshobj==NULL)
- from_gameobj= gameobj;
-
- /* updates the arrays used for making the new bullet mesh */
- shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
-
- /* create the new bullet mesh */
- CcdConstructionInfo& cci = spc->GetConstructionInfo();
- btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft);
-
- spc->ReplaceControllerShape(bm);
- return true;
-}
-#endif // WITH_BULLET
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index 43d74487542..71d7257a907 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -61,7 +61,7 @@ KX_Dome::KX_Dome (
):
dlistSupported(false),
canvaswidth(-1), canvasheight(-1),
- m_drawingmode(engine->GetDrawType()),
+ m_drawingmode(rasterizer->GetDrawingMode()),
m_resolution(res),
m_mode(mode),
m_angle(angle),
diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp
index a0266a54411..9789a8294ee 100644
--- a/source/gameengine/Ketsji/KX_FontObject.cpp
+++ b/source/gameengine/Ketsji/KX_FontObject.cpp
@@ -166,7 +166,7 @@ int GetFontId(VFont *vfont)
return fontid;
}
-void KX_FontObject::DrawText()
+void KX_FontObject::DrawFontText()
{
/* Allow for some logic brick control */
if (this->GetProperty("Text"))
diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h
index 8b66accb797..209ab6ca69f 100644
--- a/source/gameengine/Ketsji/KX_FontObject.h
+++ b/source/gameengine/Ketsji/KX_FontObject.h
@@ -45,7 +45,7 @@ public:
virtual ~KX_FontObject();
- void DrawText();
+ void DrawFontText();
/**
* Inherited from CValue -- return a new copy of this
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index b6844a6900f..9ea76980c20 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -63,7 +63,6 @@ typedef unsigned long uint_ptr;
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
#include "KX_PythonSeq.h"
-#include "KX_ConvertPhysicsObject.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
#include "SCA_IController.h"
@@ -307,9 +306,6 @@ KX_GameObject* KX_GameObject::GetParent()
if (node)
result = (KX_GameObject*)node->GetSGClientObject();
}
-
- if (result)
- result->AddRef();
return result;
@@ -466,6 +462,11 @@ void KX_GameObject::UpdateActionManager(float curtime)
GetActionManager()->Update(curtime);
}
+void KX_GameObject::UpdateActionIPOs()
+{
+ GetActionManager()->UpdateIPOs();
+}
+
float KX_GameObject::GetActionFrame(short layer)
{
return GetActionManager()->GetActionFrame(layer);
@@ -759,7 +760,7 @@ void KX_GameObject::UpdateLod(MT_Vector3 &cam_pos)
Object *bob = this->GetBlenderObject();
LodLevel *lod = (LodLevel*) bob->lodlevels.first;
for (; lod; lod = lod->next, level++) {
- if (!lod->source) level--;
+ if (!lod->source || lod->source->type != OB_MESH) level--;
if (!lod->next || lod->next->distance * lod->next->distance > distance2) break;
}
@@ -1908,11 +1909,11 @@ PyObject *KX_GameObject::PyReinstancePhysicsMesh(PyObject *args)
) {
return NULL;
}
-#ifdef WITH_BULLET
+
/* gameobj and mesh can be NULL */
- if (KX_ReInstanceBulletShapeFromMesh(this, gameobj, mesh))
+ if (GetPhysicsController() && GetPhysicsController()->ReinstancePhysicsShape(gameobj, mesh))
Py_RETURN_TRUE;
-#endif
+
Py_RETURN_FALSE;
}
@@ -2114,7 +2115,6 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
KX_GameObject* parent = self->GetParent();
if (parent) {
- parent->Release(); /* self->GetParent() AddRef's */
return parent->GetProxy();
}
Py_RETURN_NONE;
@@ -3032,7 +3032,8 @@ PyObject *KX_GameObject::PyApplyImpulse(PyObject *args)
PyObject *KX_GameObject::PySuspendDynamics()
{
- GetPhysicsController()->SuspendDynamics();
+ if (GetPhysicsController())
+ GetPhysicsController()->SuspendDynamics();
Py_RETURN_NONE;
}
@@ -3040,7 +3041,8 @@ PyObject *KX_GameObject::PySuspendDynamics()
PyObject *KX_GameObject::PyRestoreDynamics()
{
- GetPhysicsController()->RestoreDynamics();
+ if (GetPhysicsController())
+ GetPhysicsController()->RestoreDynamics();
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index ac0afca91eb..7450be4fdef 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -300,6 +300,12 @@ public:
*/
void UpdateActionManager(float curtime);
+ /**
+ * Have the action manager update IPOs
+ * note: not thread-safe!
+ */
+ void UpdateActionIPOs();
+
/*********************************
* End Animation API
*********************************/
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 3aa5a9f4f0e..96a3845a439 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -37,6 +37,8 @@
#include <iostream>
#include <stdio.h>
+#include "BLI_task.h"
+
#include "KX_KetsjiEngine.h"
#include "ListValue.h"
@@ -49,6 +51,7 @@
#include "RAS_Rect.h"
#include "RAS_IRasterizer.h"
#include "RAS_ICanvas.h"
+#include "RAS_ILightObject.h"
#include "MT_Vector3.h"
#include "MT_Transform.h"
#include "SCA_IInputDevice.h"
@@ -142,8 +145,7 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_exitcode(KX_EXIT_REQUEST_NO_REQUEST),
m_exitstring(""),
-
- m_drawingmode(5),
+
m_cameraZoom(1.0),
m_overrideCam(false),
@@ -184,6 +186,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
#ifdef WITH_PYTHON
m_pyprofiledict = PyDict_New();
#endif
+
+ m_taskscheduler = BLI_task_scheduler_create(TASK_SCHEDULER_AUTO_THREADS);
}
@@ -200,6 +204,9 @@ KX_KetsjiEngine::~KX_KetsjiEngine()
#ifdef WITH_PYTHON
Py_CLEAR(m_pyprofiledict);
#endif
+
+ if (m_taskscheduler)
+ BLI_task_scheduler_free(m_taskscheduler);
}
@@ -487,7 +494,7 @@ bool KX_KetsjiEngine::BeginFrame()
{
ClearFrame();
- m_rasterizer->BeginFrame(m_drawingmode , m_kxsystem->GetTimeInSeconds());
+ m_rasterizer->BeginFrame(m_kxsystem->GetTimeInSeconds());
return true;
}
@@ -837,7 +844,7 @@ void KX_KetsjiEngine::Render()
// clear the entire game screen with the border color
// only once per frame
m_canvas->BeginDraw();
- if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) {
+ if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
if (m_overrideFrameColor)
{
@@ -1018,7 +1025,7 @@ void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi)
{
if (wi->hasWorld())
{
- if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
+ if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
{
m_rasterizer->SetBackColor(
wi->getBackColorRed(),
@@ -1043,7 +1050,7 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
wi->getAmbientColorBlue()
);
- if (m_drawingmode >= RAS_IRasterizer::KX_SOLID)
+ if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID)
{
if (wi->hasMist())
{
@@ -1060,13 +1067,6 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
}
-
-void KX_KetsjiEngine::SetDrawType(int drawingmode)
-{
- m_drawingmode = drawingmode;
-}
-
-
void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene)
{
@@ -1163,10 +1163,11 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
KX_GameObject *gameobj = (KX_GameObject*)lightlist->GetValue(i);
KX_LightObject *light = (KX_LightObject*)gameobj;
+ RAS_ILightObject *raslight = light->GetLightData();
- light->Update();
+ raslight->Update();
- if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
+ if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED && raslight->HasShadowBuffer()) {
/* make temporary camera */
RAS_CameraData camdata = RAS_CameraData();
KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, true, true);
@@ -1179,10 +1180,10 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
/* binds framebuffer object, sets up camera .. */
- light->BindShadowBuffer(m_rasterizer, m_canvas, cam, camtrans);
+ raslight->BindShadowBuffer(m_canvas, cam, camtrans);
/* update scene */
- scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
+ scene->CalculateVisibleMeshes(m_rasterizer, cam, raslight->GetShadowLayer());
/* render */
m_rasterizer->ClearDepthBuffer();
@@ -1190,7 +1191,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
scene->RenderBuckets(camtrans, m_rasterizer);
/* unbind framebuffer object, restore drawmode, free camera */
- light->UnbindShadowBuffer(m_rasterizer);
+ raslight->UnbindShadowBuffer();
m_rasterizer->SetDrawingMode(drawmode);
cam->Release();
}
@@ -1702,6 +1703,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
{
Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
+ if (!scene)
+ return NULL;
return CreateScene(scene);
}
@@ -1717,8 +1720,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
{
STR_String scenename = *scenenameit;
KX_Scene* tmpscene = CreateScene(scenename);
- m_scenes.push_back(tmpscene);
- PostProcessScene(tmpscene);
+ if (tmpscene) {
+ m_scenes.push_back(tmpscene);
+ PostProcessScene(tmpscene);
+ } else {
+ printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+ }
}
m_addingOverlayScenes.clear();
}
@@ -1731,9 +1738,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
{
STR_String scenename = *scenenameit;
KX_Scene* tmpscene = CreateScene(scenename);
- m_scenes.insert(m_scenes.begin(),tmpscene);
- PostProcessScene(tmpscene);
-
+ if (tmpscene) {
+ m_scenes.insert(m_scenes.begin(),tmpscene);
+ PostProcessScene(tmpscene);
+ } else {
+ printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+ }
}
m_addingBackgroundScenes.clear();
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index e7fb250c2d9..9e5d1893320 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -42,6 +42,7 @@
#include "KX_WorldInfo.h"
#include <vector>
+struct TaskScheduler;
class KX_TimeCategoryLogger;
#define LEFT_EYE 1
@@ -127,12 +128,7 @@ private:
int m_exitcode;
STR_String m_exitstring;
- /**
- * Some drawing parameters, the drawing mode
- * (wire/flat/texture), and the camera zoom
- * factor.
- */
- int m_drawingmode;
+
float m_cameraZoom;
bool m_overrideCam;
@@ -200,6 +196,9 @@ private:
/** Settings that doesn't go away with Game Actuator */
GlobalSettings m_globalsettings;
+ /** Task scheduler for multi-threading */
+ TaskScheduler* m_taskscheduler;
+
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
void PostRenderScene(KX_Scene* scene);
void RenderDebugProperties();
@@ -230,6 +229,8 @@ public:
SCA_IInputDevice* GetKeyboardDevice() { return m_keyboarddevice; }
SCA_IInputDevice* GetMouseDevice() { return m_mousedevice; }
+ TaskScheduler* GetTaskScheduler() { return m_taskscheduler; }
+
/// Dome functions
void InitDome(short res, short mode, short angle, float resbuf, short tilt, struct Text* text);
void EndDome();
@@ -261,9 +262,6 @@ public:
void GetSceneViewport(KX_Scene* scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport);
- void SetDrawType(int drawingtype);
- int GetDrawType() { return m_drawingmode; }
-
void SetCameraZoom(float camzoom);
void EnableCameraOverride(const STR_String& forscene);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 20db6d2dd37..37c36da0db3 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -35,19 +35,17 @@
#include <stdio.h>
-#include "GL/glew.h"
-
#include "KX_Light.h"
#include "KX_Camera.h"
#include "RAS_IRasterizer.h"
#include "RAS_ICanvas.h"
+#include "RAS_ILightObject.h"
#include "KX_PyMath.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_lamp_types.h"
-#include "GPU_material.h"
#include "BKE_scene.h"
#include "MEM_guardedalloc.h"
@@ -56,16 +54,16 @@
KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
RAS_IRasterizer* rasterizer,
- const RAS_LightObject& lightobj,
+ RAS_ILightObject* lightobj,
bool glsl)
: KX_GameObject(sgReplicationInfo,callbacks),
m_rasterizer(rasterizer)
{
m_lightobj = lightobj;
- m_lightobj.m_scene = sgReplicationInfo;
- m_lightobj.m_light = this;
- m_rasterizer->AddLight(&m_lightobj);
- m_glsl = glsl;
+ m_lightobj->m_scene = sgReplicationInfo;
+ m_lightobj->m_light = this;
+ m_rasterizer->AddLight(m_lightobj);
+ m_lightobj->m_glsl = glsl;
m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene();
m_base = NULL;
};
@@ -73,18 +71,11 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
KX_LightObject::~KX_LightObject()
{
- GPULamp *lamp;
- Lamp *la = (Lamp*)GetBlenderObject()->data;
-
- if ((lamp = GetGPULamp())) {
- float obmat[4][4] = {{0}};
- GPU_lamp_update(lamp, 0, 0, obmat);
- GPU_lamp_update_distance(lamp, la->dist, la->att1, la->att2);
- GPU_lamp_update_spot(lamp, la->spotsize, la->spotblend);
+ if (m_lightobj) {
+ m_rasterizer->RemoveLight(m_lightobj);
+ delete(m_lightobj);
}
- m_rasterizer->RemoveLight(&m_lightobj);
-
if (m_base) {
BKE_scene_base_unlink(m_blenderscene, m_base);
MEM_freeN(m_base);
@@ -99,225 +90,25 @@ CValue* KX_LightObject::GetReplica()
replica->ProcessReplica();
- replica->m_lightobj.m_light = replica;
- m_rasterizer->AddLight(&replica->m_lightobj);
+ replica->m_lightobj = m_lightobj->Clone();
+ replica->m_lightobj->m_light = replica;
+ m_rasterizer->AddLight(replica->m_lightobj);
if (m_base)
m_base = NULL;
return replica;
}
-bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot)
-{
- KX_Scene* lightscene = (KX_Scene*)m_lightobj.m_scene;
- float vec[4];
- int scenelayer = ~0;
-
- if (kxscene && kxscene->GetBlenderScene())
- scenelayer = kxscene->GetBlenderScene()->lay;
-
- /* only use lights in the same layer as the object */
- if (!(m_lightobj.m_layer & oblayer))
- return false;
- /* only use lights in the same scene, and in a visible layer */
- if (kxscene != lightscene || !(m_lightobj.m_layer & scenelayer))
- return false;
-
- // lights don't get their openGL matrix updated, do it now
- if (GetSGNode()->IsDirty())
- GetOpenGLMatrix();
-
- MT_CmMatrix4x4& worldmatrix= *GetOpenGLMatrixPtr();
-
- vec[0] = worldmatrix(0,3);
- vec[1] = worldmatrix(1,3);
- vec[2] = worldmatrix(2,3);
- vec[3] = 1.0f;
-
- if (m_lightobj.m_type==RAS_LightObject::LIGHT_SUN) {
-
- vec[0] = worldmatrix(0,2);
- vec[1] = worldmatrix(1,2);
- vec[2] = worldmatrix(2,2);
- //vec[0] = base->object->obmat[2][0];
- //vec[1] = base->object->obmat[2][1];
- //vec[2] = base->object->obmat[2][2];
- vec[3] = 0.0;
- glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec);
- }
- else {
- //vec[3] = 1.0;
- glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec);
- glLightf((GLenum)(GL_LIGHT0+slot), GL_CONSTANT_ATTENUATION, 1.0);
- glLightf((GLenum)(GL_LIGHT0+slot), GL_LINEAR_ATTENUATION, m_lightobj.m_att1/m_lightobj.m_distance);
- // without this next line it looks backward compatible.
- //attennuation still is acceptable
- glLightf((GLenum)(GL_LIGHT0+slot), GL_QUADRATIC_ATTENUATION, m_lightobj.m_att2/(m_lightobj.m_distance*m_lightobj.m_distance));
-
- if (m_lightobj.m_type==RAS_LightObject::LIGHT_SPOT) {
- vec[0] = -worldmatrix(0,2);
- vec[1] = -worldmatrix(1,2);
- vec[2] = -worldmatrix(2,2);
- //vec[0] = -base->object->obmat[2][0];
- //vec[1] = -base->object->obmat[2][1];
- //vec[2] = -base->object->obmat[2][2];
- glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPOT_DIRECTION, vec);
- glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, RAD2DEGF(m_lightobj.m_spotsize * 0.5f));
- glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0f * m_lightobj.m_spotblend);
- }
- else {
- glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, 180.0);
- }
- }
-
- if (m_lightobj.m_nodiffuse) {
- vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
- }
- else {
- vec[0] = m_lightobj.m_energy*m_lightobj.m_red;
- vec[1] = m_lightobj.m_energy*m_lightobj.m_green;
- vec[2] = m_lightobj.m_energy*m_lightobj.m_blue;
- vec[3] = 1.0;
- }
-
- glLightfv((GLenum)(GL_LIGHT0+slot), GL_DIFFUSE, vec);
- if (m_lightobj.m_nospecular)
- {
- vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
- }
- else if (m_lightobj.m_nodiffuse) {
- vec[0] = m_lightobj.m_energy*m_lightobj.m_red;
- vec[1] = m_lightobj.m_energy*m_lightobj.m_green;
- vec[2] = m_lightobj.m_energy*m_lightobj.m_blue;
- vec[3] = 1.0;
- }
-
- glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPECULAR, vec);
- glEnable((GLenum)(GL_LIGHT0+slot));
-
- return true;
-}
-
-GPULamp *KX_LightObject::GetGPULamp()
-{
- if (m_glsl)
- return GPU_lamp_from_blender(m_blenderscene, GetBlenderObject(), GetBlenderGroupObject());
- else
- return NULL;
-}
-
-void KX_LightObject::Update()
-{
- GPULamp *lamp;
-
- if ((lamp = GetGPULamp()) != NULL && GetSGNode()) {
- float obmat[4][4];
- // lights don't get their openGL matrix updated, do it now
- if (GetSGNode()->IsDirty())
- GetOpenGLMatrix();
- double *dobmat = GetOpenGLMatrixPtr()->getPointer();
-
- for (int i=0; i<4; i++)
- for (int j=0; j<4; j++, dobmat++)
- obmat[i][j] = (float)*dobmat;
-
- GPU_lamp_update(lamp, m_lightobj.m_layer, 0, obmat);
- GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green,
- m_lightobj.m_blue, m_lightobj.m_energy);
- GPU_lamp_update_distance(lamp, m_lightobj.m_distance, m_lightobj.m_att1, m_lightobj.m_att2);
- GPU_lamp_update_spot(lamp, m_lightobj.m_spotsize, m_lightobj.m_spotblend);
- }
-}
-
void KX_LightObject::UpdateScene(KX_Scene *kxscene)
{
- m_lightobj.m_scene = (void*)kxscene;
+ m_lightobj->m_scene = (void*)kxscene;
m_blenderscene = kxscene->GetBlenderScene();
m_base = BKE_scene_base_add(m_blenderscene, GetBlenderObject());
}
-bool KX_LightObject::HasShadowBuffer()
-{
- GPULamp *lamp;
-
- if ((lamp = GetGPULamp()))
- return GPU_lamp_has_shadow_buffer(lamp);
- else
- return false;
-}
-
-int KX_LightObject::GetShadowLayer()
-{
- GPULamp *lamp;
-
- if ((lamp = GetGPULamp()))
- return GPU_lamp_shadow_layer(lamp);
- else
- return 0;
-}
-
-void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans)
-{
- GPULamp *lamp;
- float viewmat[4][4], winmat[4][4];
- int winsize;
-
- /* bind framebuffer */
- lamp = GetGPULamp();
- GPU_lamp_shadow_buffer_bind(lamp, viewmat, &winsize, winmat);
-
- if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
- ras->SetUsingOverrideShader(true);
-
- /* GPU_lamp_shadow_buffer_bind() changes the viewport, so update the canvas */
- canvas->UpdateViewPort(0, 0, winsize, winsize);
-
- /* setup camera transformation */
- MT_Matrix4x4 modelviewmat((float*)viewmat);
- MT_Matrix4x4 projectionmat((float*)winmat);
-
- MT_Transform trans = MT_Transform((float*)viewmat);
- camtrans.invert(trans);
-
- cam->SetModelviewMatrix(modelviewmat);
- cam->SetProjectionMatrix(projectionmat);
-
- cam->NodeSetLocalPosition(camtrans.getOrigin());
- cam->NodeSetLocalOrientation(camtrans.getBasis());
- cam->NodeUpdateGS(0);
-
- /* setup rasterizer transformations */
- /* SetViewMatrix may use stereomode which we temporarily disable here */
- RAS_IRasterizer::StereoMode stereomode = ras->GetStereoMode();
- ras->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO);
- ras->SetProjectionMatrix(projectionmat);
- ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
- ras->SetStereoMode(stereomode);
-}
-
-void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
+void KX_LightObject::SetLayer(int layer)
{
- GPULamp *lamp = GetGPULamp();
- GPU_lamp_shadow_buffer_unbind(lamp);
-
- if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
- ras->SetUsingOverrideShader(false);
-}
-
-struct Image *KX_LightObject::GetTextureImage(short texslot)
-{
- Lamp *la = (Lamp*)GetBlenderObject()->data;
-
- if (texslot >= MAX_MTEX || texslot < 0)
- {
- printf("KX_LightObject::GetTextureImage(): texslot exceeds slot bounds (0-%d)\n", MAX_MTEX-1);
- return NULL;
- }
-
- if (la->mtex[texslot])
- return la->mtex[texslot]->tex->ima;
-
- return NULL;
+ m_lightobj->m_layer = layer;
}
#ifdef WITH_PYTHON
@@ -358,14 +149,14 @@ PyMethodDef KX_LightObject::Methods[] = {
};
PyAttributeDef KX_LightObject::Attributes[] = {
- KX_PYATTRIBUTE_INT_RW("layer", 1, 20, true, KX_LightObject, m_lightobj.m_layer),
- KX_PYATTRIBUTE_FLOAT_RW("energy", 0, 10, KX_LightObject, m_lightobj.m_energy),
- KX_PYATTRIBUTE_FLOAT_RW("distance", 0.01, 5000, KX_LightObject, m_lightobj.m_distance),
+ KX_PYATTRIBUTE_RW_FUNCTION("layer", KX_LightObject, pyattr_get_layer, pyattr_set_layer),
+ KX_PYATTRIBUTE_RW_FUNCTION("energy", KX_LightObject, pyattr_get_energy, pyattr_set_energy),
+ KX_PYATTRIBUTE_RW_FUNCTION("distance", KX_LightObject, pyattr_get_distance, pyattr_set_distance),
KX_PYATTRIBUTE_RW_FUNCTION("color", KX_LightObject, pyattr_get_color, pyattr_set_color),
- KX_PYATTRIBUTE_FLOAT_RW("lin_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att1),
- KX_PYATTRIBUTE_FLOAT_RW("quad_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att2),
+ KX_PYATTRIBUTE_RW_FUNCTION("lin_attenuation", KX_LightObject, pyattr_get_lin_attenuation, pyattr_set_lin_attenuation),
+ KX_PYATTRIBUTE_RW_FUNCTION("quad_attenuation", KX_LightObject, pyattr_get_quad_attenuation, pyattr_set_quad_attenuation),
KX_PYATTRIBUTE_RW_FUNCTION("spotsize", KX_LightObject, pyattr_get_spotsize, pyattr_set_spotsize),
- KX_PYATTRIBUTE_FLOAT_RW("spotblend", 0, 1, KX_LightObject, m_lightobj.m_spotblend),
+ KX_PYATTRIBUTE_RW_FUNCTION("spotblend", KX_LightObject, pyattr_get_spotblend, pyattr_set_spotblend),
KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst),
KX_PYATTRIBUTE_RO_FUNCTION("SUN", KX_LightObject, pyattr_get_typeconst),
KX_PYATTRIBUTE_RO_FUNCTION("NORMAL", KX_LightObject, pyattr_get_typeconst),
@@ -373,10 +164,85 @@ PyAttributeDef KX_LightObject::Attributes[] = {
{ NULL } //Sentinel
};
+PyObject *KX_LightObject::pyattr_get_layer(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyLong_FromLong(self->m_lightobj->m_layer);
+}
+
+int KX_LightObject::pyattr_set_layer(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyLong_Check(value)) {
+ int val = PyLong_AsLong(value);
+ if (val < 1)
+ val = 1;
+ else if (val > 20)
+ val = 20;
+
+ self->m_lightobj->m_layer = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject *KX_LightObject::pyattr_get_energy(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyFloat_FromDouble(self->m_lightobj->m_energy);
+}
+
+int KX_LightObject::pyattr_set_energy(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0)
+ val = 0;
+ else if (val > 10)
+ val = 10;
+
+ self->m_lightobj->m_energy = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject *KX_LightObject::pyattr_get_distance(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyFloat_FromDouble(self->m_lightobj->m_distance);
+}
+
+int KX_LightObject::pyattr_set_distance(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0.01)
+ val = 0.01;
+ else if (val > 5000.f)
+ val = 5000.f;
+
+ self->m_lightobj->m_energy = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+
PyObject *KX_LightObject::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
- return Py_BuildValue("[fff]", self->m_lightobj.m_red, self->m_lightobj.m_green, self->m_lightobj.m_blue);
+ return Py_BuildValue("[fff]", self->m_lightobj->m_color[0], self->m_lightobj->m_color[1], self->m_lightobj->m_color[1]);
}
int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -386,34 +252,111 @@ int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *att
MT_Vector3 color;
if (PyVecTo(value, color))
{
- self->m_lightobj.m_red = color[0];
- self->m_lightobj.m_green = color[1];
- self->m_lightobj.m_blue = color[2];
+ self->m_lightobj->m_color[0] = color[0];
+ self->m_lightobj->m_color[1] = color[1];
+ self->m_lightobj->m_color[2] = color[2];
return PY_SET_ATTR_SUCCESS;
}
return PY_SET_ATTR_FAIL;
}
+PyObject *KX_LightObject::pyattr_get_lin_attenuation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyFloat_FromDouble(self->m_lightobj->m_att1);
+}
+
+int KX_LightObject::pyattr_set_lin_attenuation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0.f)
+ val = 0.f;
+ else if (val > 1.f)
+ val = 1.f;
+
+ self->m_lightobj->m_att1 = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject *KX_LightObject::pyattr_get_quad_attenuation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyFloat_FromDouble(self->m_lightobj->m_att2);
+}
+
+int KX_LightObject::pyattr_set_quad_attenuation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0.f)
+ val = 0.f;
+ else if (val > 1.f)
+ val = 1.f;
+
+ self->m_lightobj->m_att2 = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+
PyObject *KX_LightObject::pyattr_get_spotsize(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
- return Py_BuildValue("f", RAD2DEGF(self->m_lightobj.m_spotsize));
+ return PyFloat_FromDouble(RAD2DEG(self->m_lightobj->m_spotsize));
}
int KX_LightObject::pyattr_set_spotsize(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
- float spotsize = (float)PyFloat_AsDouble(value);
- if (PyErr_Occurred())
- return PY_SET_ATTR_FAIL;
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0.f)
+ val = 0.f;
+ else if (val > 180.f)
+ val = 180.f;
- if (spotsize < 1.0f)
- spotsize = 1.0f;
- else if (spotsize > 180.0f)
- spotsize = 180.0f;
- self->m_lightobj.m_spotsize = DEG2RADF(spotsize);
- return PY_SET_ATTR_SUCCESS;
+ self->m_lightobj->m_spotsize = DEG2RAD(val);
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+}
+PyObject *KX_LightObject::pyattr_get_spotblend(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyFloat_FromDouble(self->m_lightobj->m_spotblend);
+}
+
+int KX_LightObject::pyattr_set_spotblend(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ if (PyFloat_Check(value)) {
+ float val = PyFloat_AsDouble(value);
+ if (val < 0.f)
+ val = 0.f;
+ else if (val > 1.f)
+ val = 1.f;
+
+ self->m_lightobj->m_spotblend = val;
+ return PY_SET_ATTR_SUCCESS;
+ }
+
+ PyErr_Format(PyExc_TypeError, "expected float value for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
}
PyObject *KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -423,11 +366,11 @@ PyObject *KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT
const char* type = attrdef->m_name;
if (!strcmp(type, "SPOT")) {
- retvalue = PyLong_FromLong(RAS_LightObject::LIGHT_SPOT);
+ retvalue = PyLong_FromLong(RAS_ILightObject::LIGHT_SPOT);
} else if (!strcmp(type, "SUN")) {
- retvalue = PyLong_FromLong(RAS_LightObject::LIGHT_SUN);
+ retvalue = PyLong_FromLong(RAS_ILightObject::LIGHT_SUN);
} else if (!strcmp(type, "NORMAL")) {
- retvalue = PyLong_FromLong(RAS_LightObject::LIGHT_NORMAL);
+ retvalue = PyLong_FromLong(RAS_ILightObject::LIGHT_NORMAL);
}
else {
/* should never happen */
@@ -441,7 +384,7 @@ PyObject *KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT
PyObject *KX_LightObject::pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
- return PyLong_FromLong(self->m_lightobj.m_type);
+ return PyLong_FromLong(self->m_lightobj->m_type);
}
int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -455,13 +398,13 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr
switch (val) {
case 0:
- self->m_lightobj.m_type = self->m_lightobj.LIGHT_SPOT;
+ self->m_lightobj->m_type = self->m_lightobj->LIGHT_SPOT;
break;
case 1:
- self->m_lightobj.m_type = self->m_lightobj.LIGHT_SUN;
+ self->m_lightobj->m_type = self->m_lightobj->LIGHT_SUN;
break;
case 2:
- self->m_lightobj.m_type = self->m_lightobj.LIGHT_NORMAL;
+ self->m_lightobj->m_type = self->m_lightobj->LIGHT_NORMAL;
break;
}
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index d6892875042..503ed7411e9 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -32,7 +32,6 @@
#ifndef __KX_LIGHT_H__
#define __KX_LIGHT_H__
-#include "RAS_LightObject.h"
#include "KX_GameObject.h"
struct GPULamp;
@@ -40,46 +39,47 @@ struct Scene;
struct Base;
class KX_Camera;
class RAS_IRasterizer;
+class RAS_ILightObject;
class MT_Transform;
class KX_LightObject : public KX_GameObject
{
Py_Header
protected:
- RAS_LightObject m_lightobj;
+ RAS_ILightObject* m_lightobj;
class RAS_IRasterizer* m_rasterizer; //needed for registering and replication of lightobj
- bool m_glsl;
Scene* m_blenderscene;
Base* m_base;
public:
- KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,RAS_IRasterizer* rasterizer,const RAS_LightObject& lightobj, bool glsl);
+ KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,RAS_IRasterizer* rasterizer,RAS_ILightObject* lightobj, bool glsl);
virtual ~KX_LightObject();
virtual CValue* GetReplica();
- RAS_LightObject* GetLightData() { return &m_lightobj;}
-
- /* OpenGL Light */
- bool ApplyLight(KX_Scene *kxscene, int oblayer, int slot);
-
- /* GLSL Light */
- struct GPULamp *GetGPULamp();
- bool HasShadowBuffer();
- int GetShadowLayer();
- void BindShadowBuffer(RAS_IRasterizer *ras, class RAS_ICanvas *canvas, class KX_Camera *cam, class MT_Transform& camtrans);
- void UnbindShadowBuffer(RAS_IRasterizer *ras);
- struct Image *GetTextureImage(short texslot);
- void Update();
+ RAS_ILightObject* GetLightData() { return m_lightobj;}
void UpdateScene(class KX_Scene *kxscene);
+ void SetLayer(int layer);
virtual int GetGameObjectType() { return OBJ_LIGHT; }
#ifdef WITH_PYTHON
/* attributes */
+ static PyObject* pyattr_get_layer(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_layer(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_lin_attenuation(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_lin_attenuation(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_quad_attenuation(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_quad_attenuation(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_spotsize(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_spotsize(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_spotblend(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_spotblend(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_typeconst(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.cpp b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp
index 1e65c6a6fc5..6b641f7a63f 100644
--- a/source/gameengine/Ketsji/KX_LightIpoSGController.cpp
+++ b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp
@@ -33,7 +33,7 @@
#include "KX_LightIpoSGController.h"
#include "KX_ScalarInterpolator.h"
#include "KX_Light.h"
-#include "RAS_LightObject.h"
+#include "RAS_ILightObject.h"
#if defined(_WIN64)
typedef unsigned __int64 uint_ptr;
@@ -50,7 +50,7 @@ bool KX_LightIpoSGController::Update(double currentTime)
(*i)->Execute(m_ipotime);//currentTime);
}
- RAS_LightObject *lightobj;
+ RAS_ILightObject *lightobj;
SG_Spatial* ob = (SG_Spatial*)m_pObject;
KX_LightObject* kxlight = (KX_LightObject*) ob->GetSGClientObject();
@@ -62,9 +62,9 @@ bool KX_LightIpoSGController::Update(double currentTime)
}
if (m_modify_color) {
- lightobj->m_red = m_col_rgb[0];
- lightobj->m_green = m_col_rgb[1];
- lightobj->m_blue = m_col_rgb[2];
+ lightobj->m_color[0] = m_col_rgb[0];
+ lightobj->m_color[1] = m_col_rgb[1];
+ lightobj->m_color[2] = m_col_rgb[2];
}
if (m_modify_dist) {
diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h
index c82fe7bcad5..151ced6b8f8 100644
--- a/source/gameengine/Ketsji/KX_LightIpoSGController.h
+++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h
@@ -37,7 +37,7 @@
#include "KX_IInterpolator.h"
-struct RAS_LightObject;
+class RAS_ILightObject;
class KX_LightIpoSGController : public SG_Controller
{
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index c288c647fa2..a6f2f728674 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -42,7 +42,6 @@
#include "KX_BlenderMaterial.h"
#include "KX_PyMath.h"
-#include "KX_ConvertPhysicsObject.h"
#include "PyObjectPlus.h"
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 6459f35192d..92ab8f412d9 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -284,8 +284,8 @@ PyMethodDef KX_NearSensor::Methods[] = {
};
PyAttributeDef KX_NearSensor::Attributes[] = {
- KX_PYATTRIBUTE_FLOAT_RW_CHECK("distance", 0, 100, KX_NearSensor, m_Margin, CheckResetDistance),
- KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance),
+ KX_PYATTRIBUTE_FLOAT_RW_CHECK("distance", 0, 10000, KX_NearSensor, m_Margin, CheckResetDistance),
+ KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 10000, KX_NearSensor, m_ResetMargin, CheckResetDistance),
{NULL} //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 5d0c6a8bb83..234d03ab618 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -130,6 +130,7 @@ extern "C" {
#include "PHY_IPhysicsEnvironment.h"
#include "BKE_main.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BLI_blenlib.h"
#include "GPU_material.h"
#include "MEM_guardedalloc.h"
@@ -752,7 +753,7 @@ static PyObject *gLibNew(PyObject *, PyObject *args)
return NULL;
}
- Main *maggie= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
+ Main *maggie=BKE_main_new();
kx_scene->GetSceneConverter()->GetMainDynamic().push_back(maggie);
strncpy(maggie->name, path, sizeof(maggie->name)-1);
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index 84e615b61ab..0f47dfd922b 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -265,9 +265,6 @@ bool KX_RaySensor::Evaluate()
if (!spc && parent)
spc = parent->GetPhysicsController();
- if (parent)
- parent->Release();
-
PHY_IPhysicsEnvironment* physics_environment = this->m_scene->GetPhysicsEnvironment();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index b66201f4b47..c826f39517a 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -49,6 +49,7 @@
//#include "SCA_RandomEventManager.h"
//#include "KX_RayEventManager.h"
#include "SCA_2DFilterActuator.h"
+#include "SCA_PythonController.h"
#include "KX_TouchEventManager.h"
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
@@ -83,6 +84,7 @@
#include "NG_NetworkScene.h"
#include "PHY_IPhysicsEnvironment.h"
#include "PHY_IGraphicController.h"
+#include "PHY_IPhysicsController.h"
#include "KX_BlenderSceneConverter.h"
#include "KX_MotionState.h"
@@ -93,15 +95,14 @@
#ifdef WITH_BULLET
#include "KX_SoftBodyDeformer.h"
-#include "KX_ConvertPhysicsObject.h"
-#include "CcdPhysicsEnvironment.h"
-#include "CcdPhysicsController.h"
#endif
#include "KX_Light.h"
#include <stdio.h>
+#include "BLI_task.h"
+
static void *KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
@@ -562,7 +563,6 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
newobj->SetGraphicController(newctrl);
}
-#ifdef WITH_BULLET
// replicate physics controller
if (orgobj->GetPhysicsController())
{
@@ -575,11 +575,7 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
newctrl->SetNewClientInfo(newobj->getClientInfo());
newobj->SetPhysicsController(newctrl, newobj->IsDynamic());
newctrl->PostProcessReplica(motionstate, parentctrl);
-
- if (parent)
- parent->Release();
}
-#endif
return newobj;
}
@@ -759,8 +755,6 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
KX_GameObject *parent = gameobj->GetParent();
if (parent != NULL)
{
- parent->Release(); // GetParent() increased the refcount
-
// this object is not a top parent. Either it is the child of another
// object in the group and it will be added automatically when the parent
// is added. Or it is the child of an object outside the group and the group
@@ -837,7 +831,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
- lightobj->GetLightData()->m_layer = groupobj->GetLayer();
+ lightobj->SetLayer(groupobj->GetLayer());
}
}
@@ -947,7 +941,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
- lightobj->GetLightData()->m_layer = parentobj->GetLayer();
+ lightobj->SetLayer(parentobj->GetLayer());
}
}
@@ -1196,7 +1190,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
- modifierDeformer->LoadShapeDrivers(blendobj->parent);
+ modifierDeformer->LoadShapeDrivers(parentobj);
}
else
{
@@ -1224,7 +1218,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
- shapeDeformer->LoadShapeDrivers(blendobj->parent);
+ shapeDeformer->LoadShapeDrivers(parentobj);
}
else
{
@@ -1276,11 +1270,10 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
gameobj->AddMeshUser();
}
-#ifdef WITH_BULLET
if (use_phys) { /* update the new assigned mesh with the physics mesh */
- KX_ReInstanceBulletShapeFromMesh(gameobj, NULL, use_gfx?NULL:mesh);
+ if (gameobj->GetPhysicsController())
+ gameobj->GetPhysicsController()->ReinstancePhysicsShape(NULL, use_gfx?NULL:mesh);
}
-#endif
}
/* Font Object routines */
@@ -1596,51 +1589,81 @@ void KX_Scene::AddAnimatedObject(CValue* gameobj)
m_animatedlist->Add(gameobj);
}
-void KX_Scene::UpdateAnimations(double curtime)
+static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(threadid))
{
- KX_GameObject *gameobj;
+ KX_GameObject *gameobj, *child;
+ CListValue *children;
bool needs_update;
+ double curtime = *(double*)BLI_task_pool_userdata(pool);
- for (int i=0; i<m_animatedlist->GetCount(); ++i) {
- gameobj = (KX_GameObject*)m_animatedlist->GetValue(i);
-
- // Non-armature updates are fast enough, so just update them
- needs_update = gameobj->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE;
+ gameobj = (KX_GameObject*)taskdata;
- if (!needs_update) {
- // If we got here, we're looking to update an armature, so check its children meshes
- // to see if we need to bother with a more expensive pose update
- CListValue *children = gameobj->GetChildren();
- KX_GameObject *child;
+ // Non-armature updates are fast enough, so just update them
+ needs_update = gameobj->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE;
- bool has_mesh = false, has_non_mesh = false;
+ if (!needs_update) {
+ // If we got here, we're looking to update an armature, so check its children meshes
+ // to see if we need to bother with a more expensive pose update
+ children = gameobj->GetChildren();
- // Check for meshes that haven't been culled
- for (int j=0; j<children->GetCount(); ++j) {
- child = (KX_GameObject*)children->GetValue(j);
+ bool has_mesh = false, has_non_mesh = false;
- if (!child->GetCulled()) {
- needs_update = true;
- break;
- }
+ // Check for meshes that haven't been culled
+ for (int j=0; j<children->GetCount(); ++j) {
+ child = (KX_GameObject*)children->GetValue(j);
- if (child->GetMeshCount() == 0)
- has_non_mesh = true;
- else
- has_mesh = true;
+ if (!child->GetCulled()) {
+ needs_update = true;
+ break;
}
- // If we didn't find a non-culled mesh, check to see
- // if we even have any meshes, and update if this
- // armature has only non-mesh children.
- if (!needs_update && !has_mesh && has_non_mesh)
- needs_update = true;
+ if (child->GetMeshCount() == 0)
+ has_non_mesh = true;
+ else
+ has_mesh = true;
+ }
+
+ // If we didn't find a non-culled mesh, check to see
+ // if we even have any meshes, and update if this
+ // armature has only non-mesh children.
+ if (!needs_update && !has_mesh && has_non_mesh)
+ needs_update = true;
- children->Release();
+ children->Release();
+ }
+
+ if (needs_update) {
+ gameobj->UpdateActionManager(curtime);
+ children = gameobj->GetChildren();
+
+ if (gameobj->GetDeformer())
+ gameobj->GetDeformer()->Update();
+
+ for (int j=0; j<children->GetCount(); ++j) {
+ child = (KX_GameObject*)children->GetValue(j);
+
+ if (child->GetDeformer()) {
+ child->GetDeformer()->Update();
+ }
}
- if (needs_update)
- gameobj->UpdateActionManager(curtime);
+ children->Release();
+ }
+}
+
+void KX_Scene::UpdateAnimations(double curtime)
+{
+ TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime);
+
+ for (int i=0; i<m_animatedlist->GetCount(); ++i) {
+ BLI_task_pool_push(pool, update_anim_thread_func, m_animatedlist->GetValue(i), false, TASK_PRIORITY_LOW);
+ }
+
+ BLI_task_pool_work_and_wait(pool);
+ BLI_task_pool_free(pool);
+
+ for (int i=0; i<m_animatedlist->GetCount(); ++i) {
+ ((KX_GameObject*)m_animatedlist->GetValue(i))->UpdateActionIPOs();
}
}
@@ -1721,7 +1744,7 @@ void KX_Scene::RenderFonts()
{
list<KX_FontObject*>::iterator it = m_fonts.begin();
while (it != m_fonts.end()) {
- (*it)->DrawText();
+ (*it)->DrawFontText();
++it;
}
}
@@ -1848,7 +1871,7 @@ short KX_Scene::GetAnimationFPS()
return m_blenderScene->r.frs_sec;
}
-static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
+static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *from, KX_Scene *to)
{
SCA_LogicManager *logicmgr= to->GetLogicManager();
@@ -1856,12 +1879,13 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
brick->Replace_NetworkScene(to->GetNetworkScene());
/* near sensors have physics controllers */
-#ifdef WITH_BULLET
KX_TouchSensor *touch_sensor = dynamic_cast<class KX_TouchSensor *>(brick);
if (touch_sensor) {
+ KX_TouchEventManager *tmgr = (KX_TouchEventManager*)from->GetLogicManager()->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ touch_sensor->UnregisterSumo(tmgr);
touch_sensor->GetPhysicsController()->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+ touch_sensor->RegisterSumo(tmgr);
}
-#endif
// If we end up replacing a KX_TouchEventManager, we need to make sure
// physics controllers are properly in place. In other words, do this
@@ -1875,11 +1899,20 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
if (filter_actuator) {
filter_actuator->SetScene(to);
}
-}
-#ifdef WITH_BULLET
-#include "CcdGraphicController.h" // XXX ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+#ifdef WITH_PYTHON
+ // Python must be called from the main thread unless we want to deal
+ // with GIL issues. So, this is delayed until here in case of async
+ // libload (originally in KX_ConvertControllers)
+ SCA_PythonController *pyctrl = dynamic_cast<SCA_PythonController*>(brick);
+ if (pyctrl) {
+ pyctrl->SetNamespace(KX_GetActiveEngine()->GetPyNamespace());
+
+ if (pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
+ pyctrl->Compile();
+ }
#endif
+}
static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene *from)
{
@@ -1889,7 +1922,7 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
for (ita = actuators.begin(); !(ita==actuators.end()); ++ita)
{
- MergeScene_LogicBrick(*ita, to);
+ MergeScene_LogicBrick(*ita, from, to);
}
}
@@ -1900,7 +1933,7 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
for (its = sensors.begin(); !(its==sensors.end()); ++its)
{
- MergeScene_LogicBrick(*its, to);
+ MergeScene_LogicBrick(*its, from, to);
}
}
@@ -1911,17 +1944,17 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
for (itc = controllers.begin(); !(itc==controllers.end()); ++itc)
{
SCA_IController *cont= *itc;
- MergeScene_LogicBrick(cont, to);
+ MergeScene_LogicBrick(cont, from, to);
vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());++ita) {
- MergeScene_LogicBrick(*ita, to);
+ MergeScene_LogicBrick(*ita, from, to);
}
for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());++its) {
- MergeScene_LogicBrick(*its, to);
+ MergeScene_LogicBrick(*its, from, to);
}
}
}
@@ -1933,12 +1966,10 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
}
-#ifdef WITH_BULLET
ctrl = gameobj->GetPhysicsController();
if (ctrl) {
ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
}
-#endif
/* SG_Node can hold a scene reference */
SG_Node *sg= gameobj->GetSGNode();
@@ -1969,9 +2000,8 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
bool KX_Scene::MergeScene(KX_Scene *other)
{
-#ifdef WITH_BULLET
- CcdPhysicsEnvironment *env= dynamic_cast<CcdPhysicsEnvironment *>(this->GetPhysicsEnvironment());
- CcdPhysicsEnvironment *env_other= dynamic_cast<CcdPhysicsEnvironment *>(other->GetPhysicsEnvironment());
+ PHY_IPhysicsEnvironment *env = this->GetPhysicsEnvironment();
+ PHY_IPhysicsEnvironment *env_other = other->GetPhysicsEnvironment();
if ((env==NULL) != (env_other==NULL)) /* TODO - even when both scenes have NONE physics, the other is loaded with bullet enabled, ??? */
{
@@ -1979,7 +2009,6 @@ bool KX_Scene::MergeScene(KX_Scene *other)
printf("\tsource %d, terget %d\n", (int)(env!=NULL), (int)(env_other!=NULL));
return false;
}
-#endif // WITH_BULLET
if (GetSceneConverter() != other->GetSceneConverter()) {
printf("KX_Scene::MergeScene: converters differ, aborting\n");
@@ -2021,10 +2050,8 @@ bool KX_Scene::MergeScene(KX_Scene *other)
GetLightList()->MergeList(other->GetLightList());
other->GetLightList()->ReleaseAndRemoveAll();
-#ifdef WITH_BULLET
- if (env) /* bullet scene? - dummy scenes don't need touching */
+ if (env)
env->MergeEnvironment(env_other);
-#endif
/* move materials across, assume they both use the same scene-converters
* Do this after lights are merged so materials can use the lights in shaders
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index 63e9d15959e..bd4903c1545 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -77,7 +77,6 @@ public:
virtual void RemoveSensor(SCA_ISensor* sensor);
SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
PHY_IPhysicsEnvironment *GetPhysicsEnvironment() { return m_physEnv; }
- virtual void Replace_PhysicsScene(PHY_IPhysicsEnvironment* env) { m_physEnv= env; }
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 1b8ef09aec8..5cb1d5f3620 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -208,10 +208,6 @@ bool KX_TouchSensor::BroadPhaseSensorFilterCollision(void*obj1,void*obj2)
KX_ClientObjectInfo *my_client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->GetNewClientInfo());
KX_GameObject* otherobj = ( client_info ? client_info->m_gameobject : NULL);
- // first, decrement refcount as GetParent() increases it
- if (myparent)
- myparent->Release();
-
// we can only check on persistent characteristic: m_link and m_suspended are not
// good candidate because they are transient. That must be handled at another level
if (!otherobj ||
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index 44a6e2fd7ee..90b7850946b 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -79,8 +79,6 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
m_parentlocalmat = m_parentobj->GetSGNode()->GetLocalOrientation();
// use registration mechanism rather than AddRef, it creates zombie objects
m_parentobj->RegisterActuator(this);
- // GetParent did AddRef, undo here
- m_parentobj->Release();
}
}
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 33726018268..c98cf212265 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1625,6 +1625,41 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplicaForSensors()
return replica;
}
+/* Refresh the physics object from either an object or a mesh.
+ * from_gameobj and from_meshobj can be NULL
+ *
+ * when setting the mesh, the following vars get priority
+ * 1) from_meshobj - creates the phys mesh from RAS_MeshObject
+ * 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
+ * 3) this - update the phys mesh from DerivedMesh or RAS_MeshObject
+ *
+ * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
+ */
+bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject *from_meshobj)
+{
+ CcdShapeConstructionInfo *shapeInfo;
+
+ shapeInfo = this->GetShapeInfo();
+
+ if (shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
+ return false;
+
+ this->DeleteControllerShape();
+
+ if (from_gameobj==NULL && from_meshobj==NULL)
+ from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)this->GetNewClientInfo());
+
+ /* updates the arrays used for making the new bullet mesh */
+ shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
+
+ /* create the new bullet mesh */
+ CcdConstructionInfo& cci = this->GetConstructionInfo();
+ btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft);
+
+ this->ReplaceControllerShape(bm);
+ return true;
+}
+
///////////////////////////////////////////////////////////
///A small utility class, DefaultMotionState
///
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 0d6d40861c5..25a8f0306bd 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -287,8 +287,8 @@ struct CcdConstructionInfo
m_fh_spring(0.f),
m_fh_damping(0.f),
m_fh_distance(1.f),
- m_fh_normal(false),
- m_contactProcessingThreshold(1e10f)
+ m_fh_normal(false)
+ // m_contactProcessingThreshold(1e10f)
{
}
@@ -390,8 +390,7 @@ struct CcdConstructionInfo
///however, rigid body stacking is more stable when positive contacts are still passed into the constraint solver
///this might sometimes lead to collisions with 'internal edges' such as a sliding character controller
///so disable/set m_contactProcessingThreshold to zero for sliding characters etc.
- float m_contactProcessingThreshold;///< Process contacts with positive distance in range [0..INF]
-
+ // float m_contactProcessingThreshold;///< Process contacts with positive distance in range [0..INF]
};
class btRigidBody;
@@ -704,6 +703,8 @@ protected:
return GetConstructionInfo().m_shapeInfo->m_shapeType == PHY_SHAPE_COMPOUND;
}
+ virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdPhysicsController")
#endif
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index b6a46b4307e..bbc3968347c 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -39,11 +39,22 @@ subject to the following restrictions:
#include "PHY_IMotionState.h"
#include "PHY_ICharacter.h"
+#include "PHY_Pro.h"
#include "KX_GameObject.h"
+#include "KX_PythonInit.h" // for KX_RasterizerDrawDebugLine
#include "RAS_MeshObject.h"
#include "RAS_Polygon.h"
#include "RAS_TexVert.h"
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+#include "DNA_object_force.h"
+
+extern "C" {
+ #include "BLI_utildefines.h"
+ #include "BKE_object.h"
+}
+
#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
#ifdef NEW_BULLET_VEHICLE_SUPPORT
@@ -57,6 +68,7 @@ static btRaycastVehicle::btVehicleTuning gTuning;
#include "LinearMath/btAabbUtil2.h"
#include "MT_Matrix4x4.h"
#include "MT_Vector3.h"
+#include "MT_MinMax.h"
#ifdef WIN32
void DrawRasterizerLine(const float* from,const float* to,int color);
@@ -69,6 +81,21 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
#include <stdio.h>
#include <string.h> // for memset
+// This was copied from the old KX_ConvertPhysicsObjects
+#ifdef WIN32
+#if defined(_MSC_VER) && (_MSC_VER >= 1310)
+//only use SIMD Hull code under Win32
+//#define TEST_HULL 1
+#ifdef TEST_HULL
+#define USE_HULL 1
+//#define TEST_SIMD_HULL 1
+
+#include "NarrowPhaseCollision/Hull.h"
+#endif //#ifdef TEST_HULL
+
+#endif //_MSC_VER
+#endif //WIN32
+
#ifdef NEW_BULLET_VEHICLE_SUPPORT
class WrapperVehicle : public PHY_IVehicle
{
@@ -1871,8 +1898,14 @@ btDispatcher* CcdPhysicsEnvironment::GetDispatcher()
return m_dynamicsWorld->getDispatcher();
}
-void CcdPhysicsEnvironment::MergeEnvironment(CcdPhysicsEnvironment *other)
+void CcdPhysicsEnvironment::MergeEnvironment(PHY_IPhysicsEnvironment *other_env)
{
+ CcdPhysicsEnvironment *other = dynamic_cast<CcdPhysicsEnvironment*>(other_env);
+ if (other == NULL) {
+ printf("KX_Scene::MergeScene: Other scene is not using Bullet physics, not merging physics.\n");
+ return;
+ }
+
std::set<CcdPhysicsController*>::iterator it;
while (other->m_controllers.begin() != other->m_controllers.end())
@@ -2891,3 +2924,510 @@ void CcdPhysicsEnvironment::ExportFile(const char* filename)
}
}
+struct BlenderDebugDraw : public btIDebugDraw
+{
+ BlenderDebugDraw () :
+ m_debugMode(0)
+ {
+ }
+
+ int m_debugMode;
+
+ virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
+ {
+ if (m_debugMode >0)
+ {
+ MT_Vector3 kxfrom(from[0],from[1],from[2]);
+ MT_Vector3 kxto(to[0],to[1],to[2]);
+ MT_Vector3 kxcolor(color[0],color[1],color[2]);
+
+ KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
+ }
+ }
+
+ virtual void reportErrorWarning(const char* warningString)
+ {
+
+ }
+
+ virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
+ {
+ //not yet
+ }
+
+ virtual void setDebugMode(int debugMode)
+ {
+ m_debugMode = debugMode;
+ }
+ virtual int getDebugMode() const
+ {
+ return m_debugMode;
+ }
+ ///todo: find out if Blender can do this
+ virtual void draw3dText(const btVector3& location,const char* textString)
+ {
+
+ }
+
+};
+
+CcdPhysicsEnvironment *CcdPhysicsEnvironment::Create(Scene *blenderscene, bool visualizePhysics)
+{
+ CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment((blenderscene->gm.mode & WO_DBVT_CULLING) != 0);
+ ccdPhysEnv->SetDebugDrawer(new BlenderDebugDraw());
+ ccdPhysEnv->SetDeactivationLinearTreshold(blenderscene->gm.lineardeactthreshold);
+ ccdPhysEnv->SetDeactivationAngularTreshold(blenderscene->gm.angulardeactthreshold);
+ ccdPhysEnv->SetDeactivationTime(blenderscene->gm.deactivationtime);
+
+ if (visualizePhysics)
+ ccdPhysEnv->SetDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
+
+ return ccdPhysEnv;
+}
+
+void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject *meshobj, DerivedMesh *dm, KX_Scene *kxscene, PHY_ShapeProps *shapeprops, PHY_MaterialProps *smmaterial, PHY_IMotionState *motionstate, int activeLayerBitInfo, bool isCompoundChild, bool hasCompoundChildren)
+{
+ Object* blenderobject = gameobj->GetBlenderObject();
+
+ bool isbulletdyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;;
+ bool isbulletsensor = (blenderobject->gameflag & OB_SENSOR) != 0;
+ bool isbulletchar = (blenderobject->gameflag & OB_CHARACTER) != 0;
+ bool isbulletsoftbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
+ bool isbulletrigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
+ bool useGimpact = false;
+ CcdConstructionInfo ci;
+ class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
+
+ KX_GameObject *parent = gameobj->GetParent();
+ if (parent)
+ {
+ isbulletdyna = false;
+ isbulletsoftbody = false;
+ shapeprops->m_mass = 0.f;
+ }
+
+ if (!isbulletdyna)
+ {
+ ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
+ }
+ if ((blenderobject->gameflag & (OB_GHOST | OB_SENSOR | OB_CHARACTER)) != 0)
+ {
+ ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
+ }
+
+ ci.m_MotionState = motionstate;
+ ci.m_gravity = btVector3(0,0,0);
+ ci.m_linearFactor = btVector3(((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0)? 0 : 1,
+ ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0)? 0 : 1,
+ ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0)? 0 : 1);
+ ci.m_angularFactor = btVector3(((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0)? 0 : 1,
+ ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0)? 0 : 1,
+ ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0)? 0 : 1);
+ ci.m_localInertiaTensor =btVector3(0,0,0);
+ ci.m_mass = isbulletdyna ? shapeprops->m_mass : 0.f;
+ ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
+ ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
+ ci.m_stepHeight = isbulletchar ? shapeprops->m_step_height : 0.f;
+ ci.m_jumpSpeed = isbulletchar ? shapeprops->m_jump_speed : 0.f;
+ ci.m_fallSpeed = isbulletchar ? shapeprops->m_fall_speed : 0.f;
+
+ //mmm, for now, take this for the size of the dynamicobject
+ // Blender uses inertia for radius of dynamic object
+ shapeInfo->m_radius = ci.m_radius = blenderobject->inertia;
+ useGimpact = ((isbulletdyna || isbulletsensor) && !isbulletsoftbody);
+
+ if (isbulletsoftbody)
+ {
+ if (blenderobject->bsoft)
+ {
+ ci.m_margin = blenderobject->bsoft->margin;
+ }
+ else
+ {
+ ci.m_margin = 0.f;
+ }
+ }
+ else
+ {
+ ci.m_margin = blenderobject->margin;
+ }
+
+ ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
+
+ btCollisionShape* bm = 0;
+
+ char bounds;
+ if (blenderobject->gameflag & OB_BOUNDS)
+ {
+ bounds = blenderobject->collision_boundtype;
+ }
+ else
+ {
+ if (blenderobject->gameflag & OB_SOFT_BODY)
+ bounds = OB_BOUND_TRIANGLE_MESH;
+ else if (blenderobject->gameflag & OB_CHARACTER)
+ bounds = OB_BOUND_SPHERE;
+ else if (isbulletdyna)
+ bounds = OB_BOUND_SPHERE;
+ else
+ bounds = OB_BOUND_TRIANGLE_MESH;
+ }
+
+ // Can't use triangle mesh or convex hull on a non-mesh object, fall-back to sphere
+ if (ELEM(bounds, OB_BOUND_TRIANGLE_MESH, OB_BOUND_CONVEX_HULL) && blenderobject->type != OB_MESH)
+ bounds = OB_BOUND_SPHERE;
+
+ // Get bounds information
+ float bounds_center[3], bounds_extends[3];
+ BoundBox *bb= BKE_object_boundbox_get(blenderobject);
+ if (bb==NULL)
+ {
+ bounds_center[0] = bounds_center[1] = bounds_center[2] = 0.0;
+ bounds_extends[0] = bounds_extends[1] = bounds_extends[2] = 1.0;
+ }
+ else
+ {
+ bounds_extends[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
+ bounds_extends[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
+ bounds_extends[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
+
+ bounds_center[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]);
+ bounds_center[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]);
+ bounds_center[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]);
+ }
+
+ switch (bounds)
+ {
+ case OB_BOUND_SPHERE:
+ {
+ //float radius = objprop->m_radius;
+ //btVector3 inertiaHalfExtents (
+ // radius,
+ // radius,
+ // radius);
+
+ //blender doesn't support multisphere, but for testing:
+
+ //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
+ shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
+ // XXX We calculated the radius but didn't use it?
+ // objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ };
+ case OB_BOUND_BOX:
+ {
+ shapeInfo->m_halfExtend.setValue(
+ 2.f * bounds_extends[0],
+ 2.f * bounds_extends[1],
+ 2.f * bounds_extends[2]);
+
+ shapeInfo->m_halfExtend /= 2.0;
+ shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
+ shapeInfo->m_shapeType = PHY_SHAPE_BOX;
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ };
+ case OB_BOUND_CYLINDER:
+ {
+ float radius = MT_max(bounds_extends[0], bounds_extends[1]);
+ shapeInfo->m_halfExtend.setValue(
+ radius,
+ radius,
+ bounds_extends[2]
+ );
+ shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ }
+
+ case OB_BOUND_CONE:
+ {
+ shapeInfo->m_radius = MT_max(bounds_extends[0], bounds_extends[1]);
+ shapeInfo->m_height = 2.f * bounds_extends[2];
+ shapeInfo->m_shapeType = PHY_SHAPE_CONE;
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ }
+ case OB_BOUND_CONVEX_HULL:
+ {
+ shapeInfo->SetMesh(meshobj, dm,true);
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ }
+ case OB_BOUND_CAPSULE:
+ {
+ shapeInfo->m_radius = MT_max(bounds_extends[0], bounds_extends[1]);
+ shapeInfo->m_height = 2.f * (bounds_extends[2] - shapeInfo->m_radius);
+ if (shapeInfo->m_height < 0.f)
+ shapeInfo->m_height = 0.f;
+ shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE;
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ break;
+ }
+ case OB_BOUND_TRIANGLE_MESH:
+ {
+ // mesh shapes can be shared, check first if we already have a shape on that mesh
+ class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false);
+ if (sharedShapeInfo != NULL)
+ {
+ shapeInfo->Release();
+ shapeInfo = sharedShapeInfo;
+ shapeInfo->AddRef();
+ } else
+ {
+ shapeInfo->SetMesh(meshobj, dm, false);
+ }
+
+ // Soft bodies can benefit from welding, don't do it on non-soft bodies
+ if (isbulletsoftbody)
+ {
+ // disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh
+ // shapeInfo->setVertexWeldingThreshold1((blenderobject->bsoft) ? blenderobject->bsoft->welding ? 0.f);
+ shapeInfo->setVertexWeldingThreshold1(0.f); //todo: expose this to the UI
+ }
+
+ bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !isbulletsoftbody);
+ //should we compute inertia for dynamic shape?
+ //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+
+ break;
+ }
+ }
+
+
+// ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
+
+ if (!bm)
+ {
+ delete motionstate;
+ shapeInfo->Release();
+ return;
+ }
+
+ //bm->setMargin(ci.m_margin);
+
+
+ if (isCompoundChild)
+ {
+ //find parent, compound shape and add to it
+ //take relative transform into account!
+ CcdPhysicsController* parentCtrl = (CcdPhysicsController*)parent->GetPhysicsController();
+ assert(parentCtrl);
+ CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
+ btRigidBody* rigidbody = parentCtrl->GetRigidBody();
+ btCollisionShape* colShape = rigidbody->getCollisionShape();
+ assert(colShape->isCompound());
+ btCompoundShape* compoundShape = (btCompoundShape*)colShape;
+
+ // compute the local transform from parent, this may include several node in the chain
+ SG_Node* gameNode = gameobj->GetSGNode();
+ SG_Node* parentNode = parent->GetSGNode();
+ // relative transform
+ MT_Vector3 parentScale = parentNode->GetWorldScaling();
+ parentScale[0] = MT_Scalar(1.0)/parentScale[0];
+ parentScale[1] = MT_Scalar(1.0)/parentScale[1];
+ parentScale[2] = MT_Scalar(1.0)/parentScale[2];
+ MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
+ MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
+ MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
+ MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
+
+ shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
+ bm->setLocalScaling(shapeInfo->m_childScale);
+ shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
+ float rot[12];
+ relativeRot.getValue(rot);
+ shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
+
+ parentShapeInfo->AddShape(shapeInfo);
+ compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
+ //do some recalc?
+ //recalc inertia for rigidbody
+ if (!rigidbody->isStaticOrKinematicObject())
+ {
+ btVector3 localInertia;
+ float mass = 1.f/rigidbody->getInvMass();
+ compoundShape->calculateLocalInertia(mass,localInertia);
+ rigidbody->setMassProps(mass,localInertia);
+ }
+ shapeInfo->Release();
+ // delete motionstate as it's not used
+ delete motionstate;
+ return;
+ }
+
+ if (hasCompoundChildren)
+ {
+ // create a compound shape info
+ CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
+ compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
+ compoundShapeInfo->AddShape(shapeInfo);
+ // create the compound shape manually as we already have the child shape
+ btCompoundShape* compoundShape = new btCompoundShape();
+ compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
+ // now replace the shape
+ bm = compoundShape;
+ shapeInfo->Release();
+ shapeInfo = compoundShapeInfo;
+ }
+
+
+
+
+
+
+#ifdef TEST_SIMD_HULL
+ if (bm->IsPolyhedral())
+ {
+ PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
+ if (!polyhedron->m_optionalHull)
+ {
+ //first convert vertices in 'Point3' format
+ int numPoints = polyhedron->GetNumVertices();
+ Point3* points = new Point3[numPoints+1];
+ //first 4 points should not be co-planar, so add central point to satisfy MakeHull
+ points[0] = Point3(0.f,0.f,0.f);
+
+ btVector3 vertex;
+ for (int p=0;p<numPoints;p++)
+ {
+ polyhedron->GetVertex(p,vertex);
+ points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
+ }
+
+ Hull* hull = Hull::MakeHull(numPoints+1,points);
+ polyhedron->m_optionalHull = hull;
+ }
+
+ }
+#endif //TEST_SIMD_HULL
+
+
+ ci.m_collisionShape = bm;
+ ci.m_shapeInfo = shapeInfo;
+ ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
+ ci.m_restitution = smmaterial->m_restitution;
+ ci.m_physicsEnv = this;
+ // drag / damping is inverted
+ ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
+ ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
+ //need a bit of damping, else system doesn't behave well
+ ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behavior
+
+ ci.m_do_anisotropic = shapeprops->m_do_anisotropic;
+ ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]);
+
+
+//////////
+ //do Fh, do Rot Fh
+ ci.m_do_fh = shapeprops->m_do_fh;
+ ci.m_do_rot_fh = shapeprops->m_do_rot_fh;
+ ci.m_fh_damping = smmaterial->m_fh_damping;
+ ci.m_fh_distance = smmaterial->m_fh_distance;
+ ci.m_fh_normal = smmaterial->m_fh_normal;
+ ci.m_fh_spring = smmaterial->m_fh_spring;
+
+ ci.m_collisionFilterGroup =
+ (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
+ (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) :
+ (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) :
+ short(CcdConstructionInfo::StaticFilter);
+ ci.m_collisionFilterMask =
+ (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
+ (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
+ (isbulletchar) ? short(CcdConstructionInfo::AllFilter) :
+ short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
+ ci.m_bRigid = isbulletdyna && isbulletrigidbody;
+ ci.m_bSoft = isbulletsoftbody;
+ ci.m_bDyna = isbulletdyna;
+ ci.m_bSensor = isbulletsensor;
+ ci.m_bCharacter = isbulletchar;
+ ci.m_bGimpact = useGimpact;
+ MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
+ ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
+ CcdPhysicsController* physicscontroller = new CcdPhysicsController(ci);
+ // shapeInfo is reference counted, decrement now as we don't use it anymore
+ if (shapeInfo)
+ shapeInfo->Release();
+
+ gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
+
+ // record animation for dynamic objects
+ if (isbulletdyna)
+ gameobj->SetRecordAnimation(true);
+
+ // don't add automatically sensor object, they are added when a collision sensor is registered
+ if (!isbulletsensor && (blenderobject->lay & activeLayerBitInfo) != 0)
+ {
+ this->AddCcdPhysicsController( physicscontroller);
+ }
+ physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
+ {
+ btRigidBody* rbody = physicscontroller->GetRigidBody();
+
+ if (rbody)
+ {
+ if (isbulletrigidbody)
+ {
+ rbody->setLinearFactor(ci.m_linearFactor);
+ rbody->setAngularFactor(ci.m_angularFactor);
+ }
+
+ if (rbody && (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0)
+ {
+ rbody->setActivationState(DISABLE_DEACTIVATION);
+ }
+ }
+ }
+
+ CcdPhysicsController* parentCtrl = parent ? (CcdPhysicsController*)parent->GetPhysicsController() : 0;
+ physicscontroller->SetParentCtrl(parentCtrl);
+
+
+ //Now done directly in ci.m_collisionFlags so that it propagates to replica
+ //if (objprop->m_ghost)
+ //{
+ // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
+ //}
+
+ if (isbulletdyna && !isbulletrigidbody)
+ {
+#if 0
+ //setting the inertia could achieve similar results to constraint the up
+ //but it is prone to instability, so use special 'Angular' constraint
+ btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
+ inertia.setX(0.f);
+ inertia.setZ(0.f);
+
+ physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
+ physicscontroller->GetRigidBody()->updateInertiaTensor();
+#endif
+
+ //this->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
+
+ //Now done directly in ci.m_bRigid so that it propagates to replica
+ //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
+ ;
+ }
+
+
+ STR_String materialname;
+ if (meshobj)
+ materialname = meshobj->GetMaterialName(0);
+
+
+#if 0
+ ///test for soft bodies
+ if (objprop->m_softbody && physicscontroller)
+ {
+ btSoftBody* softBody = physicscontroller->GetSoftBody();
+ if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
+ {
+ //should be a mesh then, so add a soft body deformer
+ KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
+ gameobj->SetDeformer(softbodyDeformer);
+ }
+ }
+#endif
+}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 0e8ac9417f0..a94e205b160 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -258,7 +258,20 @@ protected:
class btConstraintSolver* GetConstraintSolver();
- void MergeEnvironment(CcdPhysicsEnvironment *other);
+ void MergeEnvironment(PHY_IPhysicsEnvironment *other_env);
+
+ static CcdPhysicsEnvironment *Create(struct Scene *blenderscene, bool visualizePhysics);
+
+ virtual void ConvertObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ DerivedMesh* dm,
+ KX_Scene* kxscene,
+ PHY_ShapeProps* shapeprops,
+ PHY_MaterialProps* smmaterial,
+ PHY_IMotionState *motionstate,
+ int activeLayerBitInfo,
+ bool isCompoundChild,
+ bool hasCompoundChildren);
protected:
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index 41462f91840..a645af1e471 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -33,6 +33,7 @@
#define __DUMMYPHYSICSENVIRONMENT_H__
#include "PHY_IPhysicsEnvironment.h"
+#include "PHY_IMotionState.h"
/**
* DummyPhysicsEnvironment is an empty placeholder
@@ -103,6 +104,25 @@ public:
return 0.f;
}
+ virtual void MergeEnvironment(PHY_IPhysicsEnvironment *other_env)
+ {
+ // Dummy, nothing to do here
+ }
+
+ virtual void ConvertObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ DerivedMesh* dm,
+ KX_Scene* kxscene,
+ PHY_ShapeProps* shapeprops,
+ PHY_MaterialProps* smmaterial,
+ PHY_IMotionState *motionstate,
+ int activeLayerBitInfo,
+ bool isCompoundChild,
+ bool hasCompoundChildren)
+ {
+ // All we need to do is handle the motionstate (we're supposed to own it)
+ delete motionstate;
+ }
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:DummyPhysicsEnvironment")
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index a1d0972a950..2ffb115e3b2 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -41,6 +41,9 @@ class MT_Vector3;
class MT_Point3;
class MT_Matrix3x3;
+class KX_GameObject;
+class RAS_MeshObject;
+
/**
* PHY_IPhysicsController is the abstract simplified Interface to a physical object.
* It contains the IMotionState and IDeformableMesh Interfaces.
@@ -124,6 +127,8 @@ class PHY_IPhysicsController : public PHY_IController
virtual bool IsDynamic() = 0;
virtual bool IsCompound() = 0;
+ virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj) = 0;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsController")
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index b1a0480ab14..81a45f93993 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -46,6 +46,16 @@ class PHY_ICharacter;
class RAS_MeshObject;
class PHY_IPhysicsController;
+
+class RAS_MeshObject;
+struct DerivedMesh;
+class KX_GameObject;
+class KX_Scene;
+
+struct PHY_ShapeProps;
+struct PHY_MaterialProps;
+class PHY_IMotionState;
+
/**
* pass back information from rayTest
*/
@@ -188,6 +198,19 @@ class PHY_IPhysicsEnvironment
virtual void ExportFile(const char* filename) {};
+ virtual void MergeEnvironment(PHY_IPhysicsEnvironment *other_env) = 0;
+
+ virtual void ConvertObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ DerivedMesh* dm,
+ KX_Scene* kxscene,
+ PHY_ShapeProps* shapeprops,
+ PHY_MaterialProps* smmaterial,
+ PHY_IMotionState *motionstate,
+ int activeLayerBitInfo,
+ bool isCompoundChild,
+ bool hasCompoundChildren) = 0;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsEnvironment")
diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt
index 879115add47..e254bf9b1c5 100644
--- a/source/gameengine/Rasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/CMakeLists.txt
@@ -61,7 +61,7 @@ set(SRC
RAS_ICanvas.h
RAS_IPolygonMaterial.h
RAS_IRasterizer.h
- RAS_LightObject.h
+ RAS_ILightObject.h
RAS_MaterialBucket.h
RAS_MeshObject.h
RAS_ObjectColor.h
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index e85b57f1769..abbe65738d4 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -395,10 +395,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
return;
const int *viewport = canvas->GetViewPort();
- RAS_Rect rect = canvas->GetWindowArea();
- int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1;
- if (texturewidth != rect_width || textureheight != rect_height)
+ if (texturewidth != viewport[2] || textureheight != viewport[3])
{
UpdateOffsetMatrix(canvas);
UpdateCanvasTextureCoord(viewport);
@@ -414,22 +412,22 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if (need_depth) {
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0);
}
if (need_luminance) {
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0);
}
// reverting to texunit 0, without this we get bug [#28462]
glActiveTextureARB(GL_TEXTURE0);
- canvas->SetViewPort(0, 0, rect_width-1, rect_height-1);
// We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport,
// but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen.
RAS_Rect scissor_rect = canvas->GetDisplayArea();
+
glScissor(scissor_rect.GetLeft() + viewport[0],
scissor_rect.GetBottom() + viewport[1],
scissor_rect.GetWidth() + 1,
@@ -459,7 +457,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -473,8 +471,6 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517]
- canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_ILightObject.h
index 79818def5f0..28c5d9aedd7 100644
--- a/source/gameengine/Rasterizer/RAS_LightObject.h
+++ b/source/gameengine/Rasterizer/RAS_ILightObject.h
@@ -20,7 +20,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Mitchell Stokes
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -32,10 +32,18 @@
#ifndef __RAS_LIGHTOBJECT_H__
#define __RAS_LIGHTOBJECT_H__
-#include "MT_CmMatrix4x4.h"
+class RAS_ICanvas;
-struct RAS_LightObject
+class KX_Camera;
+class KX_Scene;
+
+class MT_Transform;
+
+struct Image;
+
+class RAS_ILightObject
{
+public:
enum LightType {
LIGHT_SPOT,
LIGHT_SUN,
@@ -48,10 +56,8 @@ struct RAS_LightObject
float m_energy;
float m_distance;
-
- float m_red;
- float m_green;
- float m_blue;
+
+ float m_color[3];
float m_att1;
float m_att2;
@@ -62,6 +68,17 @@ struct RAS_LightObject
bool m_nodiffuse;
bool m_nospecular;
+ bool m_glsl;
+
+ virtual ~RAS_ILightObject() {}
+ virtual RAS_ILightObject* Clone() = 0;
+
+ virtual bool HasShadowBuffer() = 0;
+ virtual int GetShadowLayer() = 0;
+ virtual void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans) = 0;
+ virtual void UnbindShadowBuffer() = 0;
+ virtual Image *GetTextureImage(short texslot) = 0;
+ virtual void Update() = 0;
};
#endif /* __RAS_LIGHTOBJECT_H__ */
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 47e52318b33..03f6e567771 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -282,6 +282,11 @@ bool RAS_IPolyMaterial::CastsShadows() const
return (m_flag & RAS_CASTSHADOW) != 0;
}
+bool RAS_IPolyMaterial::OnlyShadow() const
+{
+ return (m_flag & RAS_ONLYSHADOW) != 0;
+}
+
bool RAS_IPolyMaterial::UsesObjectColor() const
{
return !(m_flag & RAS_BLENDERGLSL);
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 2db71c3a2fe..14223fc59bd 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -61,7 +61,8 @@ enum MaterialProps
RAS_NORMAL =256,
RAS_DEFMULTI =512,
RAS_BLENDERGLSL =1024,
- RAS_CASTSHADOW =2048
+ RAS_CASTSHADOW =2048,
+ RAS_ONLYSHADOW =4096,
};
/**
@@ -174,6 +175,7 @@ public:
virtual bool UsesLighting(RAS_IRasterizer *rasty) const;
virtual bool UsesObjectColor() const;
virtual bool CastsShadows() const;
+ virtual bool OnlyShadow() const;
virtual void Replace_IScene(SCA_IScene *val) {} /* overridden by KX_BlenderMaterial */
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index 0776a02a79a..d7b52213191 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -53,6 +53,7 @@ using namespace std;
class RAS_ICanvas;
class RAS_IPolyMaterial;
class RAS_MeshSlot;
+class RAS_ILightObject;
typedef vector<unsigned short> KX_IndexArray;
typedef vector<RAS_TexVert> KX_VertexArray;
@@ -195,7 +196,7 @@ public:
/**
* BeginFrame is called at the start of each frame.
*/
- virtual bool BeginFrame(int drawingmode, double time) = 0;
+ virtual bool BeginFrame(double time) = 0;
/**
* ClearColorBuffer clears the color buffer.
@@ -470,9 +471,11 @@ public:
virtual void PopMatrix() = 0;
- virtual void AddLight(struct RAS_LightObject *lightobject) = 0;
+ virtual RAS_ILightObject *CreateLight() = 0;
- virtual void RemoveLight(struct RAS_LightObject *lightobject) = 0;
+ virtual void AddLight(RAS_ILightObject *lightobject) = 0;
+
+ virtual void RemoveLight(RAS_ILightObject *lightobject) = 0;
virtual void MotionBlur() = 0;
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 0c715524218..4b5fc6510e0 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -587,6 +587,9 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && !m_material->CastsShadows())
return false;
+ if (rasty->GetDrawingMode() != RAS_IRasterizer::KX_SHADOW && m_material->OnlyShadow())
+ return false;
+
if (!rasty->SetMaterial(*m_material))
return false;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
index 76ac6316e38..f0410ba891d 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
@@ -50,6 +50,7 @@ set(INC_SYS
set(SRC
RAS_GLExtensionManager.cpp
RAS_ListRasterizer.cpp
+ RAS_OpenGLLight.cpp
RAS_OpenGLRasterizer.cpp
RAS_StorageIM.cpp
RAS_StorageVA.cpp
@@ -58,6 +59,7 @@ set(SRC
RAS_GLExtensionManager.h
RAS_IStorage.h
RAS_ListRasterizer.h
+ RAS_OpenGLLight.h
RAS_OpenGLRasterizer.h
RAS_StorageIM.h
RAS_StorageVA.h
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
new file mode 100644
index 00000000000..91ad2838ccd
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
@@ -0,0 +1,276 @@
+/*
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mitchell Stokes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GL/glew.h"
+
+#include "RAS_OpenGLLight.h"
+#include "RAS_OpenGLRasterizer.h"
+#include "RAS_ICanvas.h"
+
+#include "MT_CmMatrix4x4.h"
+
+#include "KX_Camera.h"
+#include "KX_Light.h"
+#include "KX_Scene.h"
+
+#include "DNA_lamp_types.h"
+#include "DNA_scene_types.h"
+
+#include "GPU_material.h"
+
+RAS_OpenGLLight::RAS_OpenGLLight(RAS_OpenGLRasterizer *ras)
+ :m_rasterizer(ras)
+{
+}
+
+RAS_OpenGLLight::~RAS_OpenGLLight()
+{
+ GPULamp *lamp;
+ KX_LightObject* kxlight = (KX_LightObject*)m_light;
+ Lamp *la = (Lamp*)kxlight->GetBlenderObject()->data;
+
+ if ((lamp = GetGPULamp())) {
+ float obmat[4][4] = {{0}};
+ GPU_lamp_update(lamp, 0, 0, obmat);
+ GPU_lamp_update_distance(lamp, la->dist, la->att1, la->att2);
+ GPU_lamp_update_spot(lamp, la->spotsize, la->spotblend);
+ }
+}
+
+bool RAS_OpenGLLight::ApplyFixedFunctionLighting(KX_Scene *kxscene, int oblayer, int slot)
+{
+ KX_Scene* lightscene = (KX_Scene*)m_scene;
+ KX_LightObject* kxlight = (KX_LightObject*)m_light;
+ float vec[4];
+ int scenelayer = ~0;
+
+ if (kxscene && kxscene->GetBlenderScene())
+ scenelayer = kxscene->GetBlenderScene()->lay;
+
+ /* only use lights in the same layer as the object */
+ if (!(m_layer & oblayer))
+ return false;
+ /* only use lights in the same scene, and in a visible layer */
+ if (kxscene != lightscene || !(m_layer & scenelayer))
+ return false;
+
+ // lights don't get their openGL matrix updated, do it now
+ if (kxlight->GetSGNode()->IsDirty())
+ kxlight->GetOpenGLMatrix();
+
+ MT_CmMatrix4x4& worldmatrix= *kxlight->GetOpenGLMatrixPtr();
+
+ vec[0] = worldmatrix(0,3);
+ vec[1] = worldmatrix(1,3);
+ vec[2] = worldmatrix(2,3);
+ vec[3] = 1.0f;
+
+ if (m_type==RAS_ILightObject::LIGHT_SUN) {
+
+ vec[0] = worldmatrix(0,2);
+ vec[1] = worldmatrix(1,2);
+ vec[2] = worldmatrix(2,2);
+ //vec[0] = base->object->obmat[2][0];
+ //vec[1] = base->object->obmat[2][1];
+ //vec[2] = base->object->obmat[2][2];
+ vec[3] = 0.0;
+ glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec);
+ }
+ else {
+ //vec[3] = 1.0;
+ glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec);
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_LINEAR_ATTENUATION, m_att1/m_distance);
+ // without this next line it looks backward compatible.
+ //attennuation still is acceptable
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_QUADRATIC_ATTENUATION, m_att2/(m_distance*m_distance));
+
+ if (m_type==RAS_ILightObject::LIGHT_SPOT) {
+ vec[0] = -worldmatrix(0,2);
+ vec[1] = -worldmatrix(1,2);
+ vec[2] = -worldmatrix(2,2);
+ //vec[0] = -base->object->obmat[2][0];
+ //vec[1] = -base->object->obmat[2][1];
+ //vec[2] = -base->object->obmat[2][2];
+ glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPOT_DIRECTION, vec);
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, m_spotsize / 2.0f);
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0f * m_spotblend);
+ }
+ else {
+ glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, 180.0);
+ }
+ }
+
+ if (m_nodiffuse) {
+ vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
+ }
+ else {
+ vec[0] = m_energy*m_color[0];
+ vec[1] = m_energy*m_color[1];
+ vec[2] = m_energy*m_color[2];
+ vec[3] = 1.0;
+ }
+
+ glLightfv((GLenum)(GL_LIGHT0+slot), GL_DIFFUSE, vec);
+ if (m_nospecular)
+ {
+ vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
+ }
+ else if (m_nodiffuse) {
+ vec[0] = m_energy*m_color[0];
+ vec[1] = m_energy*m_color[1];
+ vec[2] = m_energy*m_color[2];
+ vec[3] = 1.0;
+ }
+
+ glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPECULAR, vec);
+ glEnable((GLenum)(GL_LIGHT0+slot));
+
+ return true;
+}
+
+GPULamp *RAS_OpenGLLight::GetGPULamp()
+{
+ KX_LightObject* kxlight = (KX_LightObject*)m_light;
+
+ if (m_glsl)
+ return GPU_lamp_from_blender(kxlight->GetScene()->GetBlenderScene(), kxlight->GetBlenderObject(), kxlight->GetBlenderGroupObject());
+ else
+ return NULL;
+}
+
+
+bool RAS_OpenGLLight::HasShadowBuffer()
+{
+ GPULamp *lamp;
+
+ if ((lamp = GetGPULamp()))
+ return GPU_lamp_has_shadow_buffer(lamp);
+ else
+ return false;
+}
+
+int RAS_OpenGLLight::GetShadowLayer()
+{
+ GPULamp *lamp;
+
+ if ((lamp = GetGPULamp()))
+ return GPU_lamp_shadow_layer(lamp);
+ else
+ return 0;
+}
+
+void RAS_OpenGLLight::BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans)
+{
+ GPULamp *lamp;
+ float viewmat[4][4], winmat[4][4];
+ int winsize;
+
+ /* bind framebuffer */
+ lamp = GetGPULamp();
+ GPU_lamp_shadow_buffer_bind(lamp, viewmat, &winsize, winmat);
+
+ if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
+ m_rasterizer->SetUsingOverrideShader(true);
+
+ /* GPU_lamp_shadow_buffer_bind() changes the viewport, so update the canvas */
+ canvas->UpdateViewPort(0, 0, winsize, winsize);
+
+ /* setup camera transformation */
+ MT_Matrix4x4 modelviewmat((float*)viewmat);
+ MT_Matrix4x4 projectionmat((float*)winmat);
+
+ MT_Transform trans = MT_Transform((float*)viewmat);
+ camtrans.invert(trans);
+
+ cam->SetModelviewMatrix(modelviewmat);
+ cam->SetProjectionMatrix(projectionmat);
+
+ cam->NodeSetLocalPosition(camtrans.getOrigin());
+ cam->NodeSetLocalOrientation(camtrans.getBasis());
+ cam->NodeUpdateGS(0);
+
+ /* setup rasterizer transformations */
+ /* SetViewMatrix may use stereomode which we temporarily disable here */
+ RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
+ m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO);
+ m_rasterizer->SetProjectionMatrix(projectionmat);
+ m_rasterizer->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
+ m_rasterizer->SetStereoMode(stereomode);
+}
+
+void RAS_OpenGLLight::UnbindShadowBuffer()
+{
+ GPULamp *lamp = GetGPULamp();
+ GPU_lamp_shadow_buffer_unbind(lamp);
+
+ if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
+ m_rasterizer->SetUsingOverrideShader(false);
+}
+
+Image *RAS_OpenGLLight::GetTextureImage(short texslot)
+{
+ KX_LightObject* kxlight = (KX_LightObject*)m_light;
+ Lamp *la = (Lamp*)kxlight->GetBlenderObject()->data;
+
+ if (texslot >= MAX_MTEX || texslot < 0)
+ {
+ printf("KX_LightObject::GetTextureImage(): texslot exceeds slot bounds (0-%d)\n", MAX_MTEX-1);
+ return NULL;
+ }
+
+ if (la->mtex[texslot])
+ return la->mtex[texslot]->tex->ima;
+
+ return NULL;
+}
+
+void RAS_OpenGLLight::Update()
+{
+ GPULamp *lamp;
+ KX_LightObject* kxlight = (KX_LightObject*)m_light;
+
+ if ((lamp = GetGPULamp()) != NULL && kxlight->GetSGNode()) {
+ float obmat[4][4];
+ // lights don't get their openGL matrix updated, do it now
+ if (kxlight->GetSGNode()->IsDirty())
+ kxlight->GetOpenGLMatrix();
+ double *dobmat = kxlight->GetOpenGLMatrixPtr()->getPointer();
+
+ for (int i=0; i<4; i++)
+ for (int j=0; j<4; j++, dobmat++)
+ obmat[i][j] = (float)*dobmat;
+
+ GPU_lamp_update(lamp, m_layer, 0, obmat);
+ GPU_lamp_update_colors(lamp, m_color[0], m_color[1],
+ m_color[2], m_energy);
+ GPU_lamp_update_distance(lamp, m_distance, m_att1, m_att2);
+ GPU_lamp_update_spot(lamp, m_spotsize, m_spotblend);
+ }
+}
+
+
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h
index b6cb303942a..0c4e5bf41c4 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h
@@ -15,41 +15,40 @@
* 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mitchell Stokes
+ *
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLENDERTEXTUREMANAGER_H__
-#define __BLENDERTEXTUREMANAGER_H__
+#include "RAS_ILightObject.h"
-/** \file blender/freestyle/intern/blender_interface/BlenderTextureManager.h
- * \ingroup freestyle
- */
+class RAS_OpenGLRasterizer;
+struct GPULamp;
+struct Image;
-# include "../stroke/StrokeRenderer.h"
-# include "../stroke/StrokeRep.h"
-# include "../system/FreestyleConfig.h"
+class RAS_OpenGLLight : public RAS_ILightObject
+{
-namespace Freestyle {
+ RAS_OpenGLRasterizer *m_rasterizer;
-/*! Class to load textures */
-class LIB_RENDERING_EXPORT BlenderTextureManager : public TextureManager
-{
+ GPULamp *GetGPULamp();
public:
- BlenderTextureManager();
- virtual ~BlenderTextureManager();
-
-protected:
- virtual unsigned int loadBrush(string fileName, Stroke::MediumType=Stroke::OPAQUE_MEDIUM);
+ RAS_OpenGLLight(RAS_OpenGLRasterizer *ras);
+ ~RAS_OpenGLLight();
-protected:
- virtual void loadStandardBrushes();
+ bool ApplyFixedFunctionLighting(KX_Scene *kxscene, int oblayer, int slot);
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderTextureManager")
-#endif
+ RAS_OpenGLLight* Clone() { return new RAS_OpenGLLight(*this); }
+ bool HasShadowBuffer();
+ int GetShadowLayer();
+ void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans);
+ void UnbindShadowBuffer();
+ Image *GetTextureImage(short texslot);
+ void Update();
};
-
-} /* namespace Freestyle */
-
-#endif // __BLENDERTEXTUREMANAGER_H__
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index e03be54e87b..0960fdaab4f 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -42,9 +42,11 @@
#include "RAS_TexVert.h"
#include "RAS_MeshObject.h"
#include "RAS_Polygon.h"
-#include "RAS_LightObject.h"
+#include "RAS_ILightObject.h"
#include "MT_CmMatrix4x4.h"
+#include "RAS_OpenGLLight.h"
+
#include "RAS_StorageIM.h"
#include "RAS_StorageVA.h"
#include "RAS_StorageVBO.h"
@@ -59,7 +61,6 @@ extern "C"{
// XXX Clean these up <<<
#include "Value.h"
-#include "KX_Light.h"
#include "KX_Scene.h"
#include "KX_RayCast.h"
#include "KX_GameObject.h"
@@ -100,6 +101,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
m_usingoverrideshader(false),
m_clientobject(NULL),
m_auxilaryClientInfo(NULL),
+ m_drawingmode(KX_TEXTURED),
m_texco_num(0),
m_attrib_num(0),
//m_last_alphablend(GPU_BLEND_SOLID),
@@ -330,10 +332,9 @@ void RAS_OpenGLRasterizer::Exit()
EndFrame();
}
-bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
+bool RAS_OpenGLRasterizer::BeginFrame(double time)
{
m_time = time;
- SetDrawingMode(drawingmode);
// Blender camera routine destroys the settings
if (m_drawingmode < KX_SOLID)
@@ -1187,7 +1188,7 @@ void RAS_OpenGLRasterizer::ProcessLighting(bool uselights, const MT_Transform& v
KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo;
float glviewmat[16];
unsigned int count;
- std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin();
+ std::vector<RAS_OpenGLLight*>::iterator lit = m_lights.begin();
for (count=0; count<m_numgllights; count++)
glDisable((GLenum)(GL_LIGHT0+count));
@@ -1198,10 +1199,9 @@ void RAS_OpenGLRasterizer::ProcessLighting(bool uselights, const MT_Transform& v
glLoadMatrixf(glviewmat);
for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
{
- RAS_LightObject* lightdata = (*lit);
- KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light;
+ RAS_OpenGLLight* light = (*lit);
- if (kxlight->ApplyLight(kxscene, layer, count))
+ if (light->ApplyFixedFunctionLighting(kxscene, layer, count))
count++;
}
glPopMatrix();
@@ -1243,15 +1243,25 @@ void RAS_OpenGLRasterizer::DisableOpenGLLights()
m_lastlighting = false;
}
-void RAS_OpenGLRasterizer::AddLight(struct RAS_LightObject* lightobject)
+RAS_ILightObject *RAS_OpenGLRasterizer::CreateLight()
{
- m_lights.push_back(lightobject);
+ return new RAS_OpenGLLight(this);
}
-void RAS_OpenGLRasterizer::RemoveLight(struct RAS_LightObject* lightobject)
+void RAS_OpenGLRasterizer::AddLight(RAS_ILightObject* lightobject)
{
- std::vector<struct RAS_LightObject*>::iterator lit =
- std::find(m_lights.begin(),m_lights.end(),lightobject);
+ RAS_OpenGLLight* gllight = dynamic_cast<RAS_OpenGLLight*>(lightobject);
+ assert(gllight);
+ m_lights.push_back(gllight);
+}
+
+void RAS_OpenGLRasterizer::RemoveLight(RAS_ILightObject* lightobject)
+{
+ RAS_OpenGLLight* gllight = dynamic_cast<RAS_OpenGLLight*>(lightobject);
+ assert(gllight);
+
+ std::vector<RAS_OpenGLLight*>::iterator lit =
+ std::find(m_lights.begin(),m_lights.end(),gllight);
if (!(lit==m_lights.end()))
m_lights.erase(lit);
@@ -1365,8 +1375,6 @@ void RAS_OpenGLRasterizer::applyTransform(double* oglmatrix,int objectdrawmode )
KX_GameObject *parent = gameobj->GetParent();
if (!physics_controller && parent)
physics_controller = parent->GetPhysicsController();
- if (parent)
- parent->Release();
KX_RayCast::Callback<RAS_OpenGLRasterizer> callback(this, physics_controller, oglmatrix);
if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index d03e06c3b31..1334ddb2a26 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -46,6 +46,7 @@ using namespace std;
class RAS_IStorage;
class RAS_ICanvas;
+class RAS_OpenGLLight;
#define RAS_MAX_TEXCO 8 /* match in BL_Material */
#define RAS_MAX_ATTRIB 16 /* match in BL_BlenderShader */
@@ -117,7 +118,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
/* Render tools */
void *m_clientobject;
void *m_auxilaryClientInfo;
- std::vector<struct RAS_LightObject *> m_lights;
+ std::vector<RAS_OpenGLLight *> m_lights;
int m_lastlightlayer;
bool m_lastlighting;
void *m_lastauxinfo;
@@ -166,7 +167,7 @@ public:
virtual bool SetMaterial(const RAS_IPolyMaterial &mat);
virtual bool Init();
virtual void Exit();
- virtual bool BeginFrame(int drawingmode, double time);
+ virtual bool BeginFrame(double time);
virtual void ClearColorBuffer();
virtual void ClearDepthBuffer();
virtual void ClearCachingInfo(void);
@@ -315,9 +316,11 @@ public:
bool RayHit(struct KX_ClientObjectInfo *client, class KX_RayCast *result, void * const data);
bool NeedRayCast(struct KX_ClientObjectInfo *) { return true; }
- void AddLight(struct RAS_LightObject *lightobject);
- void RemoveLight(struct RAS_LightObject *lightobject);
- int ApplyLights(int objectlayer, const MT_Transform &viewmat);
+ RAS_ILightObject* CreateLight();
+ void AddLight(RAS_ILightObject* lightobject);
+
+ void RemoveLight(RAS_ILightObject* lightobject);
+ int ApplyLights(int objectlayer, const MT_Transform& viewmat);
void MotionBlur();
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
index 06f85b143d2..6aa90fbd6ef 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -57,7 +57,7 @@ VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
this->vertex_offset = (void*)(((RAS_TexVert*)0)->getXYZ());
this->normal_offset = (void*)(((RAS_TexVert*)0)->getNormal());
this->tangent_offset = (void*)(((RAS_TexVert*)0)->getTangent());
- this->color_offset = (void*)(((RAS_TexVert*)0)->getRGBA());;
+ this->color_offset = (void*)(((RAS_TexVert*)0)->getRGBA());
this->uv_offset = (void*)(((RAS_TexVert*)0)->getUV(0));
}
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index aaaf70728fe..e6edc064200 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -120,7 +120,7 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
}
-// compare two vertices, and return TRUE if both are almost identical (they can be shared)
+// compare two vertices, and return true if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
const float eps = FLT_EPSILON;
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 6908bc6db9c..18474932879 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -199,7 +199,7 @@ void ImageRender::Render()
m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1);
m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
- m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime());
+ m_rasterizer->BeginFrame(m_engine->GetClockTime());
m_engine->SetWorldSettings(m_scene->GetWorldInfo());
m_rasterizer->SetAuxilaryClientInfo(m_scene);
m_rasterizer->DisplayFog();
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index c187f7c41c1..35a73193a24 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -36,6 +36,7 @@
#include "KX_GameObject.h"
#include "KX_Light.h"
#include "RAS_MeshObject.h"
+#include "RAS_ILightObject.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_image_types.h"
@@ -237,7 +238,7 @@ static int Texture_init(Texture *self, PyObject *args, PyObject *kwds)
}
else if (lamp != NULL)
{
- self->m_imgTexture = lamp->GetTextureImage(texID);
+ self->m_imgTexture = lamp->GetLightData()->GetTextureImage(texID);
self->m_useMatTexture = false;
}
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 44017f37d29..179f1ced03b 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -1005,9 +1005,20 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
{
if (packet.stream_index == m_videoStream)
{
- avcodec_decode_video2(m_codecCtx,
- m_frame, &frameFinished,
+ if (m_isImage)
+ {
+ // If we're an image, we're probably not going to be here often,
+ // so we don't want to deal with delayed frames from threading.
+ // There might be a better way to handle this, but I'll leave that
+ // for people more knowledgeable with ffmpeg than myself. We don't
+ // need threading for a single image anyways.
+ m_codecCtx->thread_count = 1;
+ }
+
+ avcodec_decode_video2(m_codecCtx,
+ m_frame, &frameFinished,
&packet);
+
// remember dts to compute exact frame number
dts = packet.dts;
if (frameFinished && !posFound)
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt
index 0f29e26a66f..85c68693792 100644
--- a/source/tests/CMakeLists.txt
+++ b/source/tests/CMakeLists.txt
@@ -22,6 +22,9 @@
# Use '--write-blend=/tmp/test.blend' to view output
+# Some tests are interesting but take too long to run
+# and don't give deterministic results
+set(USE_EXPERIMENTAL_TESTS FALSE)
set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/../lib/tests)
set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests)
@@ -63,9 +66,11 @@ add_test(script_load_modules ${TEST_BLENDER_EXE}
)
# test running operators doesn't segfault under various conditions
-add_test(script_run_operators ${TEST_BLENDER_EXE}
- --python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py
-)
+if(USE_EXPERIMENTAL_TESTS)
+ add_test(script_run_operators ${TEST_BLENDER_EXE}
+ --python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py
+ )
+endif()
# test running mathutils testing script
add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE}
diff --git a/source/tests/bl_pyapi_mathutils.py b/source/tests/bl_pyapi_mathutils.py
index bbb4d7f355f..c31244462cd 100644
--- a/source/tests/bl_pyapi_mathutils.py
+++ b/source/tests/bl_pyapi_mathutils.py
@@ -3,6 +3,32 @@ import unittest
from test import support
from mathutils import Matrix, Vector
from mathutils import kdtree
+import math
+
+# keep globals immutable
+vector_data = (
+ (1.0, 0.0, 0.0),
+ (0.0, 1.0, 0.0),
+ (0.0, 0.0, 1.0),
+
+ (1.0, 1.0, 1.0),
+
+ (0.33783, 0.715698, -0.611206),
+ (-0.944031, -0.326599, -0.045624),
+ (-0.101074, -0.416443, -0.903503),
+ (0.799286, 0.49411, -0.341949),
+ (-0.854645, 0.518036, 0.033936),
+ (0.42514, -0.437866, -0.792114),
+ (-0.358948, 0.597046, 0.717377),
+ (-0.985413,0.144714, 0.089294),
+ )
+
+# get data at different scales
+vector_data = sum(
+ (tuple(tuple(a * scale for a in v) for v in vector_data)
+ for scale in (s * sign for s in (0.0001, 0.1, 1.0, 10.0, 1000.0, 100000.0)
+ for sign in (1.0, -1.0))), ()) + ((0.0, 0.0, 0.0),)
+
class MatrixTesting(unittest.TestCase):
def test_matrix_column_access(self):
@@ -149,6 +175,17 @@ class MatrixTesting(unittest.TestCase):
self.assertEqual(mat * mat, prod_mat)
+class VectorTesting(unittest.TestCase):
+
+ def test_orthogonal(self):
+
+ angle_90d = math.pi / 2.0
+ for v in vector_data:
+ v = Vector(v)
+ if v.length_squared != 0.0:
+ self.assertAlmostEqual(v.angle(v.orthogonal()), angle_90d)
+
+
class KDTreeTesting(unittest.TestCase):
@staticmethod
@@ -256,6 +293,7 @@ class KDTreeTesting(unittest.TestCase):
def test_main():
try:
support.run_unittest(MatrixTesting)
+ support.run_unittest(VectorTesting)
support.run_unittest(KDTreeTesting)
except:
import traceback
diff --git a/source/tests/bl_rna_wiki_reference.py b/source/tests/bl_rna_wiki_reference.py
index c394107d8d1..8cb20aaf7f6 100644
--- a/source/tests/bl_rna_wiki_reference.py
+++ b/source/tests/bl_rna_wiki_reference.py
@@ -118,7 +118,7 @@ def test_urls():
print(" %s ... " % url_full, end="")
sys.stdout.flush()
try:
- urllib.request.urlopen(url_full)
+ urlopen(url_full)
print(color_green + "OK" + color_normal)
except urllib.error.HTTPError:
print(color_red + "FAIL!" + color_normal)
diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py
index 13bf615b8dc..e14b0ce6d32 100644
--- a/source/tests/bl_run_operators.py
+++ b/source/tests/bl_run_operators.py
@@ -105,7 +105,7 @@ def blend_list(mainpath):
def is_blend(filename):
ext = splitext(filename)[1]
- return (ext in {".blend",})
+ return (ext in {".blend", })
return list(sorted(file_list(mainpath, is_blend)))
diff --git a/source/tests/pep8.py b/source/tests/pep8.py
index 3ae1828c59a..cca49d54ac0 100644
--- a/source/tests/pep8.py
+++ b/source/tests/pep8.py
@@ -20,15 +20,16 @@
import os
-# depends on pep8, pyflakes, pylint
+# depends on pep8, frosted, pylint
# for Ubuntu
#
-# sudo apt-get install pylint pyflakes
+# sudo apt-get install pylint
#
# sudo apt-get install python-setuptools python-pip
# sudo pip install pep8
+# sudo pip install frosted
#
-# in Debian install pylint pyflakes pep8 with apt-get/aptitude/etc
+# in Debian install pylint pep8 with apt-get/aptitude/etc
#
# on *nix run
# python source/tests/pep8.py > test_pep8.log 2>&1
@@ -54,7 +55,7 @@ def is_pep8(path):
print("\nfile contains BOM, remove first 3 bytes: %r\n" % path)
# templates don't have a header but should be pep8
- for d in ("presets", "templates", "examples"):
+ for d in ("presets", "templates_py", "examples"):
if ("%s%s%s" % (os.sep, d, os.sep)) in path:
return 1
@@ -118,10 +119,10 @@ def main():
os.system("pep8 --repeat --ignore=%s '%s'" % (",".join(ignore_tmp), f))
- # pyflakes
- print("\n\n\n# running pyflakes...")
+ # frosted
+ print("\n\n\n# running frosted...")
for f, pep8_type in files:
- os.system("pyflakes '%s'" % f)
+ os.system("frosted '%s'" % f)
print("\n\n\n# running pylint...")
for f, pep8_type in files:
diff --git a/source/tests/rst_to_doctree_mini.py b/source/tests/rst_to_doctree_mini.py
index cb7b0291296..6a885a108f8 100644
--- a/source/tests/rst_to_doctree_mini.py
+++ b/source/tests/rst_to_doctree_mini.py
@@ -50,7 +50,6 @@ def parse_rst_py(filepath):
indent_map = {}
indent_prev = 0
f = open(filepath, encoding="utf-8")
- indent_lists = []
for i, line in enumerate(f):
line_strip = line.lstrip()
# ^\.\.\s[a-zA-Z09\-]+::.*$